summaryrefslogtreecommitdiffstats
path: root/external
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /external
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'external')
-rw-r--r--external/Makefile7
-rw-r--r--external/Module_external.mk107
-rw-r--r--external/README.md3
-rw-r--r--external/beanshell/ExternalPackage_beanshell.mk16
-rw-r--r--external/beanshell/ExternalProject_beanshell.mk30
-rw-r--r--external/beanshell/Makefile7
-rw-r--r--external/beanshell/Module_beanshell.mk18
-rw-r--r--external/beanshell/README4
-rw-r--r--external/beanshell/UnpackedTarball_beanshell.mk24
-rw-r--r--external/beanshell/beanshell-invoke.patch78
-rw-r--r--external/beanshell/bsh-2.0b1-src.patch50
-rw-r--r--external/beanshell/java9.patch.025
-rw-r--r--external/bluez_bluetooth/README4
-rw-r--r--external/bluez_bluetooth/inc/bluetooth/bluetooth.h70
-rw-r--r--external/bluez_bluetooth/inc/bluetooth/hci.h718
-rw-r--r--external/bluez_bluetooth/inc/bluetooth/hci_lib.h23
-rw-r--r--external/bluez_bluetooth/inc/bluetooth/l2cap.h87
-rw-r--r--external/bluez_bluetooth/inc/bluetooth/rfcomm.h47
-rw-r--r--external/bluez_bluetooth/inc/bluetooth/sco.h32
-rw-r--r--external/boost/Makefile7
-rw-r--r--external/boost/Module_boost.mk21
-rw-r--r--external/boost/README4
-rw-r--r--external/boost/StaticLibrary_boost_date_time.mk37
-rw-r--r--external/boost/StaticLibrary_boost_filesystem.mk43
-rw-r--r--external/boost/StaticLibrary_boost_iostreams.mk35
-rw-r--r--external/boost/StaticLibrary_boost_locale.mk59
-rw-r--r--external/boost/StaticLibrary_boost_system.mk29
-rw-r--r--external/boost/UnpackedTarball_boost.mk46
-rw-r--r--external/boost/boost-emscripten-noshm.patch.011
-rw-r--r--external/boost/boost-emscripten-nowasm.patch.011
-rw-r--r--external/boost/boost.6142.warnings.patch.138
-rw-r--r--external/boost/boost.between.warning.patch13
-rw-r--r--external/boost/boost.fallback.encoding.patch13
-rw-r--r--external/boost/boost.noiconv.patch51
-rw-r--r--external/boost/boost_1_59_0.mpl.config.wundef.patch11
-rw-r--r--external/boost/boost_1_59_0.property_tree.wreturn-type.patch14
-rw-r--r--external/boost/boost_1_63_0.undef.warning.patch.112
-rw-r--r--external/boost/clang-cl.patch.020
-rw-r--r--external/boost/include/boost/algorithm/string.hpp31
-rw-r--r--external/boost/include/boost/algorithm/string/predicate.hpp31
-rw-r--r--external/boost/include/boost/archive/iterators/base64_from_binary.hpp31
-rw-r--r--external/boost/include/boost/archive/iterators/binary_from_base64.hpp31
-rw-r--r--external/boost/include/boost/archive/iterators/remove_whitespace.hpp31
-rw-r--r--external/boost/include/boost/archive/iterators/transform_width.hpp31
-rw-r--r--external/boost/include/boost/bind.hpp31
-rw-r--r--external/boost/include/boost/cast.hpp31
-rw-r--r--external/boost/include/boost/circular_buffer.hpp31
-rw-r--r--external/boost/include/boost/cstdint.hpp31
-rw-r--r--external/boost/include/boost/current_function.hpp31
-rw-r--r--external/boost/include/boost/date_time.hpp31
-rw-r--r--external/boost/include/boost/date_time/posix_time/posix_time.hpp31
-rw-r--r--external/boost/include/boost/filesystem.hpp31
-rw-r--r--external/boost/include/boost/filesystem/path.hpp31
-rw-r--r--external/boost/include/boost/functional/hash.hpp31
-rw-r--r--external/boost/include/boost/fusion/adapted/std_pair.hpp31
-rw-r--r--external/boost/include/boost/fusion/include/adapt_struct.hpp31
-rw-r--r--external/boost/include/boost/intrusive/circular_list_algorithms.hpp31
-rw-r--r--external/boost/include/boost/intrusive_ptr.hpp31
-rw-r--r--external/boost/include/boost/io/ios_state.hpp31
-rw-r--r--external/boost/include/boost/iostreams/filter/gzip.hpp31
-rw-r--r--external/boost/include/boost/iostreams/filtering_stream.hpp31
-rw-r--r--external/boost/include/boost/iterator/iterator_facade.hpp31
-rw-r--r--external/boost/include/boost/lexical_cast.hpp31
-rw-r--r--external/boost/include/boost/locale.hpp31
-rw-r--r--external/boost/include/boost/locale/gnu_gettext.hpp31
-rw-r--r--external/boost/include/boost/make_shared.hpp31
-rw-r--r--external/boost/include/boost/math/common_factor_rt.hpp31
-rw-r--r--external/boost/include/boost/math/special_functions/expm1.hpp31
-rw-r--r--external/boost/include/boost/math/special_functions/sinc.hpp31
-rw-r--r--external/boost/include/boost/multi_array.hpp31
-rw-r--r--external/boost/include/boost/multi_index/composite_key.hpp31
-rw-r--r--external/boost/include/boost/multi_index/identity.hpp31
-rw-r--r--external/boost/include/boost/multi_index/mem_fun.hpp31
-rw-r--r--external/boost/include/boost/multi_index/ordered_index.hpp31
-rw-r--r--external/boost/include/boost/multi_index/random_access_index.hpp31
-rw-r--r--external/boost/include/boost/multi_index_container.hpp31
-rw-r--r--external/boost/include/boost/noncopyable.hpp31
-rw-r--r--external/boost/include/boost/none.hpp31
-rw-r--r--external/boost/include/boost/numeric/conversion/cast.hpp31
-rw-r--r--external/boost/include/boost/operators.hpp31
-rw-r--r--external/boost/include/boost/optional.hpp31
-rw-r--r--external/boost/include/boost/program_options.hpp31
-rw-r--r--external/boost/include/boost/property_tree/json_parser.hpp31
-rw-r--r--external/boost/include/boost/property_tree/ptree.hpp31
-rw-r--r--external/boost/include/boost/property_tree/ptree_fwd.hpp31
-rw-r--r--external/boost/include/boost/range/adaptor/reversed.hpp31
-rw-r--r--external/boost/include/boost/range/iterator_range.hpp31
-rw-r--r--external/boost/include/boost/rational.hpp31
-rw-r--r--external/boost/include/boost/scoped_ptr.hpp31
-rw-r--r--external/boost/include/boost/shared_ptr.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/classic.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/classic_core.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/classic_error_handling.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/classic_file_iterator.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/classic_utility.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/phoenix.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/qi.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/qi_attr.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/qi_lit.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/qi_optional.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/qi_parse_attr.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/qi_sequence.hpp31
-rw-r--r--external/boost/include/boost/spirit/include/qi_symbols.hpp31
-rw-r--r--external/boost/include/boost/unordered_map.hpp31
-rw-r--r--external/boost/include/boost/uuid/uuid_generators.hpp31
-rw-r--r--external/boost/include/boost/uuid/uuid_io.hpp31
-rw-r--r--external/boost/include/boost/variant.hpp31
-rw-r--r--external/boost/include/boost/variant/recursive_variant.hpp31
-rw-r--r--external/boost/include/boost/version.hpp31
-rw-r--r--external/boost/msvc2017.patch.017
-rwxr-xr-xexternal/boost/repack_tarball.sh60
-rw-r--r--external/boost/rtti.patch.013
-rw-r--r--external/boost/windows-no-utf8-locales.patch.020
-rw-r--r--external/box2d/Makefile7
-rw-r--r--external/box2d/Module_box2d.mk20
-rw-r--r--external/box2d/README3
-rw-r--r--external/box2d/StaticLibrary_box2d.mk72
-rw-r--r--external/box2d/UnpackedTarball_box2d.mk16
-rw-r--r--external/breakpad/0001-Handle-race-between-ExceptionHandler-SignalHandler-a.patch.133
-rw-r--r--external/breakpad/ExternalProject_breakpad.mk39
-rw-r--r--external/breakpad/Makefile14
-rw-r--r--external/breakpad/Module_breakpad.mk25
-rw-r--r--external/breakpad/README21
-rw-r--r--external/breakpad/SIGSTKSZ.patch11
-rw-r--r--external/breakpad/StaticLibrary_breakpad.mk37
-rw-r--r--external/breakpad/UnpackedTarball_breakpad.mk48
-rw-r--r--external/breakpad/breakpad-dump_syms.patch.134
-rw-r--r--external/breakpad/breakpad-no-env.patch.113
-rw-r--r--external/breakpad/breakpad-stackwalk.patch.132
-rw-r--r--external/breakpad/breakpad-use-correct-http-header.patch.114
-rw-r--r--external/breakpad/breakpad-wshadow.patch.165
-rw-r--r--external/breakpad/c++20-allocator.patch12
-rw-r--r--external/breakpad/dump_syms.sln25
-rw-r--r--external/breakpad/dump_syms.vcxproj108
-rw-r--r--external/breakpad/include.patch10
-rw-r--r--external/breakpad/sanitizer.patch29
-rw-r--r--external/breakpad/ubsan.patch21
-rw-r--r--external/bzip2/ExternalProject_bzip2.mk34
-rw-r--r--external/bzip2/Makefile14
-rw-r--r--external/bzip2/Module_bzip2.mk17
-rw-r--r--external/bzip2/README1
-rw-r--r--external/bzip2/UnpackedTarball_bzip2.mk24
-rw-r--r--external/cairo/ExternalPackage_cairo.mk18
-rw-r--r--external/cairo/ExternalPackage_pixman.mk18
-rw-r--r--external/cairo/ExternalProject_cairo.mk84
-rw-r--r--external/cairo/ExternalProject_pixman.mk36
-rw-r--r--external/cairo/Makefile7
-rw-r--r--external/cairo/Module_cairo.mk21
-rw-r--r--external/cairo/README6
-rw-r--r--external/cairo/UnpackedTarball_cairo.mk46
-rw-r--r--external/cairo/UnpackedTarball_pixman.mk19
-rw-r--r--external/cairo/cairo/0025-libtool-pass-use-ld.patch16
-rw-r--r--external/cairo/cairo/cairo-1.10.2.ios.patch27
-rw-r--r--external/cairo/cairo/cairo-1.10.2.no-atsui.patch22
-rw-r--r--external/cairo/cairo/cairo-libtool-rpath.patch.112
-rw-r--r--external/cairo/cairo/cairo.GL_RGBA.patch49
-rw-r--r--external/cairo/cairo/cairo.RGB24_888.patch105
-rw-r--r--external/cairo/cairo/cairo.buildfix.patch122
-rw-r--r--external/cairo/cairo/cairo.ofz46165.patch.116
-rw-r--r--external/cairo/cairo/cairo.oldfreetype.patch42
-rwxr-xr-xexternal/cairo/cairo/dummy_pkg_config3
-rw-r--r--external/cairo/cairo/san.patch.0103
-rw-r--r--external/cairo/pixman/pixman-0.24.4.patch91
-rw-r--r--external/cairo/pixman/pixman-ubsan.patch76
-rw-r--r--external/clew/Library_clew.mk41
-rw-r--r--external/clew/Makefile7
-rw-r--r--external/clew/Module_clew.mk16
-rw-r--r--external/clew/README5
-rw-r--r--external/clew/source/clew.c325
-rw-r--r--external/clew/source/include/clew/clew.h1187
-rw-r--r--external/clucene/Library_clucene.mk234
-rw-r--r--external/clucene/Makefile7
-rw-r--r--external/clucene/Module_clucene.mk17
-rw-r--r--external/clucene/README4
-rw-r--r--external/clucene/UnpackedTarball_clucene.mk81
-rw-r--r--external/clucene/configs/_clucene-config-LINUX.h114
-rw-r--r--external/clucene/configs/_clucene-config-MSVC.h114
-rw-r--r--external/clucene/configs/_clucene-config-generic.h114
-rw-r--r--external/clucene/configs/clucene-config-GCC-atomic.h150
-rw-r--r--external/clucene/configs/clucene-config-MSVC.h149
-rw-r--r--external/clucene/configs/clucene-config-generic.h150
-rw-r--r--external/clucene/inc/pch/precompiled_clucene.cxx12
-rw-r--r--external/clucene/inc/pch/precompiled_clucene.hxx108
-rw-r--r--external/clucene/patches/binary_function.patch34
-rw-r--r--external/clucene/patches/c++20.patch11
-rw-r--r--external/clucene/patches/clucene-aix.patch40
-rw-r--r--external/clucene/patches/clucene-asan.patch26
-rw-r--r--external/clucene/patches/clucene-debug.patch11
-rw-r--r--external/clucene/patches/clucene-git1-win64.patch45
-rw-r--r--external/clucene/patches/clucene-libcpp.patch42
-rw-r--r--external/clucene/patches/clucene-mixes-uptemplate-parameter-msvc-14.patch53
-rw-r--r--external/clucene/patches/clucene-multimap-put.patch9
-rw-r--r--external/clucene/patches/clucene-mutex.patch13
-rw-r--r--external/clucene/patches/clucene-narrowing-conversions.patch36
-rw-r--r--external/clucene/patches/clucene-nullptr.patch22
-rw-r--r--external/clucene/patches/clucene-ub.patch33
-rw-r--r--external/clucene/patches/clucene-warnings.patch124
-rw-r--r--external/clucene/patches/contribs-lib-makefile.patch23
-rw-r--r--external/clucene/patches/heap-buffer-overflow.patch11
-rw-r--r--external/clucene/patches/nullstring.patch11
-rw-r--r--external/clucene/patches/ostream-wchar_t.patch29
-rw-r--r--external/clucene/patches/write-strings.patch22
-rw-r--r--external/coinmp/ExternalPackage_coinmp.mk41
-rw-r--r--external/coinmp/ExternalProject_coinmp.mk59
-rw-r--r--external/coinmp/Makefile7
-rw-r--r--external/coinmp/Module_coinmp.mk18
-rw-r--r--external/coinmp/README5
-rw-r--r--external/coinmp/UnpackedTarball_coinmp.mk52
-rw-r--r--external/coinmp/Wnon-c-typedef-for-linkage.patch14
-rw-r--r--external/coinmp/coinmp-msvc-disable-sse2.patch.110
-rw-r--r--external/coinmp/configure-exit.patch33
-rw-r--r--external/coinmp/libtool.patch162
-rw-r--r--external/coinmp/no-binaries.patch.125
-rw-r--r--external/coinmp/osi_cuts_iterator.patch.012
-rw-r--r--external/coinmp/pedantic-errors.patch11
-rw-r--r--external/coinmp/register.patch369
-rw-r--r--external/coinmp/rpath.patch60
-rw-r--r--external/coinmp/ubsan.patch.011
-rw-r--r--external/coinmp/werror-format-pedantic.patch.010
-rw-r--r--external/coinmp/werror-format-security.patch.012
-rw-r--r--external/coinmp/werror-undef.patch.011
-rw-r--r--external/coinmp/windows.build.patch.13241
-rw-r--r--external/cppunit/CPPUNIT_PLUGIN_EXPORT.patch.011
-rw-r--r--external/cppunit/ExternalProject_cppunit.mk62
-rw-r--r--external/cppunit/Makefile7
-rw-r--r--external/cppunit/Module_cppunit.mk17
-rw-r--r--external/cppunit/README3
-rw-r--r--external/cppunit/UnpackedTarball_cppunit.mk33
-rw-r--r--external/cppunit/disable-dynloading.patch25
-rw-r--r--external/cppunit/enable-win32-debug.patch34
-rw-r--r--external/cppunit/order.patch.025
-rw-r--r--external/cppunit/rtti.patch.015
-rw-r--r--external/cppunit/unix.patch10
-rw-r--r--external/cppunit/windows-arm64.patch.1786
-rw-r--r--external/cppunit/windows.patch50
-rw-r--r--external/curl/ExternalPackage_curl.mk28
-rw-r--r--external/curl/ExternalProject_curl.mk99
-rw-r--r--external/curl/Makefile7
-rw-r--r--external/curl/Module_curl.mk18
-rw-r--r--external/curl/README1
-rw-r--r--external/curl/UnpackedTarball_curl.mk48
-rw-r--r--external/curl/asan-poison-nsspem.patch.011
-rw-r--r--external/curl/clang-cl.patch.011
-rw-r--r--external/curl/configurable-z-option.patch.020
-rw-r--r--external/curl/curl-msvc-disable-protocols.patch.136
-rw-r--r--external/curl/curl-msvc-zlib.patch.116
-rw-r--r--external/curl/curl-msvc.patch.127
-rw-r--r--external/curl/curl-nss.patch.117
-rw-r--r--external/curl/zlib.patch.090
-rw-r--r--external/dragonbox/Module_dragonbox.mk16
-rw-r--r--external/dragonbox/README4
-rw-r--r--external/dragonbox/UnpackedTarball_dragonbox.mk14
-rw-r--r--external/dtoa/Makefile14
-rw-r--r--external/dtoa/Module_dtoa.mk17
-rw-r--r--external/dtoa/README10
-rw-r--r--external/dtoa/StaticLibrary_dtoa.mk30
-rw-r--r--external/dtoa/UnpackedTarball_dtoa.mk22
-rw-r--r--external/dtoa/coverity.patch51
-rw-r--r--external/dtoa/include_header.patch100
-rw-r--r--external/dtoa/source/dtoa.cxx15
-rw-r--r--external/dtoa/ubsan.patch.011
-rw-r--r--external/epm/ExternalProject_epm.mk26
-rw-r--r--external/epm/Makefile7
-rw-r--r--external/epm/Module_epm.mk21
-rw-r--r--external/epm/README3
-rw-r--r--external/epm/UnpackedTarball_epm.mk19
-rw-r--r--external/epm/asan.patch.016
-rw-r--r--external/epm/epm-3.7.patch666
-rw-r--r--external/epoxy/Library_epoxy.mk65
-rw-r--r--external/epoxy/Makefile7
-rw-r--r--external/epoxy/Module_epoxy.mk17
-rw-r--r--external/epoxy/README5
-rw-r--r--external/epoxy/UnpackedTarball_epoxy.mk37
-rw-r--r--external/epoxy/clang-cl.patch14
-rw-r--r--external/epoxy/epoxy.noegl.by.default.patch28
-rw-r--r--external/epoxy/epoxy.visibility.patch5
-rw-r--r--external/epoxy/epoxy.windows.api.patch12
-rw-r--r--external/expat/ExternalProject_expat.mk25
-rw-r--r--external/expat/Makefile7
-rw-r--r--external/expat/Module_expat.mk30
-rw-r--r--external/expat/README4
-rw-r--r--external/expat/StaticLibrary_expat.mk51
-rw-r--r--external/expat/StaticLibrary_expat_x64.mk33
-rw-r--r--external/expat/UnpackedTarball_expat.mk34
-rw-r--r--external/expat/expat-winapi.patch25
-rw-r--r--external/firebird/0001-Fix-checks-for-null-HANDLE-in-Windows-only-code.patch.141
-rw-r--r--external/firebird/0001-Fix-warning-on-Win64-build-231.patch.137
-rw-r--r--external/firebird/0001-Make-comparison-operator-member-functions-const.patch.149
-rw-r--r--external/firebird/0001-extern-cloop-Missing-dependencies-of-compilations-on.patch.141
-rw-r--r--external/firebird/0001-extern-cloop-Missing-dependency-of-BIN_DIR-cloop-on-.patch.167
-rw-r--r--external/firebird/ExternalPackage_firebird.mk28
-rw-r--r--external/firebird/ExternalProject_firebird.mk107
-rw-r--r--external/firebird/Makefile7
-rw-r--r--external/firebird/Module_firebird.mk18
-rw-r--r--external/firebird/README3
-rw-r--r--external/firebird/UnpackedTarball_firebird.mk82
-rw-r--r--external/firebird/asan.patch252
-rw-r--r--external/firebird/c++17.patch311
-rw-r--r--external/firebird/configure-c99.patch23
-rw-r--r--external/firebird/firebird-307.patch.112
-rw-r--r--external/firebird/firebird-Engine12.patch16
-rw-r--r--external/firebird/firebird-btyacc-add-explicit-rule.patch12
-rw-r--r--external/firebird/firebird-cygwin-msvc-warnings.patch300
-rw-r--r--external/firebird/firebird-cygwin-msvc.patch686
-rw-r--r--external/firebird/firebird-macosx-sandbox.patch.113
-rw-r--r--external/firebird/firebird-macosx.patch.187
-rw-r--r--external/firebird/firebird-rpath.patch.011
-rw-r--r--external/firebird/firebird-tdf125284.patch.127
-rw-r--r--external/firebird/firebird-vs2017.patch.112
-rw-r--r--external/firebird/firebird.disable-ib-util-not-found.patch.117
-rw-r--r--external/firebird/macos-arm64.patch.0109
-rw-r--r--external/firebird/macosx-elcapitan-dyld.patch58
-rw-r--r--external/firebird/msvc.patch11
-rw-r--r--external/firebird/sanitizer.patch63
-rw-r--r--external/firebird/ubsan.patch307
-rw-r--r--external/firebird/wnt-dbgutil.patch63
-rw-r--r--external/firebird/wnt-per-process-trace-storage.patch.118
-rw-r--r--external/fontconfig/ExternalPackage_fontconfig_data.mk58
-rw-r--r--external/fontconfig/ExternalProject_fontconfig.mk48
-rw-r--r--external/fontconfig/Makefile7
-rw-r--r--external/fontconfig/Module_fontconfig.mk18
-rw-r--r--external/fontconfig/README6
-rw-r--r--external/fontconfig/UnpackedTarball_fontconfig.mk18
-rw-r--r--external/fontconfig/fontconfig-2.12.1.patch.1135
-rw-r--r--external/freetype/ExternalProject_freetype.mk38
-rw-r--r--external/freetype/Makefile7
-rw-r--r--external/freetype/Module_freetype.mk17
-rw-r--r--external/freetype/README6
-rw-r--r--external/freetype/UnpackedTarball_freetype.mk21
-rw-r--r--external/freetype/freetype-2.6.5.patch.1157
-rw-r--r--external/freetype/ubsan.patch11
-rw-r--r--external/glm/Makefile7
-rw-r--r--external/glm/Module_glm.mk16
-rw-r--r--external/glm/README3
-rw-r--r--external/glm/UnpackedTarball_glm.mk23
-rw-r--r--external/glm/c++20.patch.011
-rw-r--r--external/glm/clang-cl.patch.014
-rwxr-xr-xexternal/gpgmepp/0001-cpp-Fix-building-with-C-11.patch.172
-rw-r--r--external/gpgmepp/ExternalPackage_gpgmepp.mk40
-rw-r--r--external/gpgmepp/ExternalProject_gpgmepp.mk81
-rw-r--r--external/gpgmepp/Library_gpgmepp.mk91
-rw-r--r--external/gpgmepp/Makefile14
-rw-r--r--external/gpgmepp/Module_gpgmepp.mk26
-rw-r--r--external/gpgmepp/README7
-rw-r--r--external/gpgmepp/UnpackedTarball_gpgmepp.mk40
-rwxr-xr-xexternal/gpgmepp/Wincompatible-function-pointer-types.patch31
-rw-r--r--external/gpgmepp/asan.patch12
-rw-r--r--external/gpgmepp/c++20.patch11
-rw-r--r--external/gpgmepp/clang-cl.patch20
-rw-r--r--external/gpgmepp/configure.patch34
-rw-r--r--external/gpgmepp/find-libgpg-error-libassuan.patch66
-rw-r--r--external/gpgmepp/fix-autoconf-macros.patch39
-rw-r--r--external/gpgmepp/gcc9.patch10
-rw-r--r--external/gpgmepp/macos-include.patch10
-rw-r--r--external/gpgmepp/rpath.patch12
-rw-r--r--external/gpgmepp/ubsan.patch52
-rw-r--r--external/gpgmepp/w32-add-initializer.patch.116
-rw-r--r--external/gpgmepp/w32-build-fixes-2.patch22
-rw-r--r--external/gpgmepp/w32-build-fixes.patch.1138
-rw-r--r--external/gpgmepp/w32-disable-docs.patch.115
-rw-r--r--external/gpgmepp/w32-fix-libtool.patch.138
-rw-r--r--external/gpgmepp/w32-fix-win32-macro.patch.1176
-rw-r--r--external/gpgmepp/w32-include.patch42
-rw-r--r--external/graphite/Makefile7
-rw-r--r--external/graphite/Module_graphite.mk17
-rw-r--r--external/graphite/README7
-rw-r--r--external/graphite/StaticLibrary_graphite.mk79
-rw-r--r--external/graphite/UnpackedTarball_graphite.mk20
-rw-r--r--external/graphite/ubsan.patch11
-rw-r--r--external/harfbuzz/ExternalProject_harfbuzz.mk58
-rw-r--r--external/harfbuzz/Makefile7
-rw-r--r--external/harfbuzz/Module_harfbuzz.mk17
-rw-r--r--external/harfbuzz/README1
-rw-r--r--external/harfbuzz/UnpackedTarball_harfbuzz.mk21
-rw-r--r--external/hsqldb/ExternalPackage_hsqldb.mk16
-rw-r--r--external/hsqldb/ExternalProject_hsqldb.mk38
-rw-r--r--external/hsqldb/Makefile7
-rw-r--r--external/hsqldb/Module_hsqldb.mk18
-rw-r--r--external/hsqldb/README11
-rw-r--r--external/hsqldb/UnpackedTarball_hsqldb.mk33
-rw-r--r--external/hsqldb/patches/disable-dump-script.patch14
-rw-r--r--external/hsqldb/patches/fdo36824.patch11
-rw-r--r--external/hsqldb/patches/hsqldb-runFinalizersOnExit.patch14
-rw-r--r--external/hsqldb/patches/i103528.patch11
-rw-r--r--external/hsqldb/patches/i104901.patch27
-rw-r--r--external/hsqldb/patches/i96823.patch94
-rw-r--r--external/hsqldb/patches/i97032.patch10
-rw-r--r--external/hsqldb/patches/jdbc-4.1.patch320
-rw-r--r--external/hsqldb/patches/limit_as_table_alias.patch11
-rw-r--r--external/hsqldb/patches/multipleResultSets.patch11
-rw-r--r--external/hunspell/0001-invalid-read-memory-access-624.patch25
-rw-r--r--external/hunspell/ExternalProject_hunspell.mk39
-rw-r--r--external/hunspell/Makefile7
-rw-r--r--external/hunspell/Module_hunspell.mk25
-rw-r--r--external/hunspell/README4
-rw-r--r--external/hunspell/StaticLibrary_hunspell.mk41
-rw-r--r--external/hunspell/UnpackedTarball_hunspell.mk28
-rw-r--r--external/hyphen/ExternalProject_hyphen.mk33
-rw-r--r--external/hyphen/Makefile7
-rw-r--r--external/hyphen/Module_hyphen.mk30
-rw-r--r--external/hyphen/README1
-rw-r--r--external/hyphen/StaticLibrary_hyphen.mk22
-rw-r--r--external/hyphen/UnpackedTarball_hyphen.mk21
-rw-r--r--external/hyphen/hyphen-build.patch38
-rw-r--r--external/hyphen/hyphen-fdo48017-wfopen.patch49
-rw-r--r--external/icu/ExternalPackage_icu.mk42
-rw-r--r--external/icu/ExternalPackage_icu_ure.mk48
-rw-r--r--external/icu/ExternalProject_icu.mk100
-rw-r--r--external/icu/Makefile7
-rw-r--r--external/icu/Module_icu.mk19
-rw-r--r--external/icu/README1
-rw-r--r--external/icu/UnpackedTarball_icu.mk51
-rw-r--r--external/icu/Wdeprecated-copy-dtor.patch25
-rw-r--r--external/icu/c++20-comparison.patch.182
-rwxr-xr-xexternal/icu/cross-bin/icu-config12
-rw-r--r--external/icu/do-not-reset-useful-cache-to-empty-in-populateNear.patch.237
-rw-r--r--external/icu/gcc9.patch26
-rw-r--r--external/icu/icu4c-aix.patch.1143
-rw-r--r--external/icu/icu4c-android.patch.175
-rw-r--r--external/icu/icu4c-build.patch.191
-rw-r--r--external/icu/icu4c-clang-cl.patch.128
-rw-r--r--external/icu/icu4c-emscripten-cross.patch.199
-rw-r--r--external/icu/icu4c-icudata-stdlibs.patch.114
-rw-r--r--external/icu/icu4c-khmerbreakengine.patch.1836
-rw-r--r--external/icu/icu4c-macosx.patch.120
-rw-r--r--external/icu/icu4c-mkdir.patch.117
-rw-r--r--external/icu/icu4c-rpath.patch.136
-rw-r--r--external/icu/icu4c-rtti.patch.112
-rw-r--r--external/icu/icu4c-scriptrun.patch.160
-rw-r--r--external/icu/icu4c-solarisgcc.patch.112
-rw-r--r--external/icu/icu4c-ubsan.patch.114
-rw-r--r--external/icu/icu4c-use-pkgdata-single-ccode-file-mode.patch.112
-rw-r--r--external/icu/icu4c-warnings.patch.111
-rw-r--r--external/icu/icu4c-windows-cygwin-cross.patch.1131
-rw-r--r--external/icu/khmerdict.dictbin0 -> 263537 bytes
-rw-r--r--external/icu/strict_ansi.patch15
-rw-r--r--external/icu/ubsan.patch.131
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_flow_engine.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_flute.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_libbase.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_libfonts.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_libformula.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_liblayout.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_libloader.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_librepository.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_libserializer.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_libxml.mk19
-rw-r--r--external/jfreereport/ExternalPackage_jfreereport_sac.mk16
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_flow_engine.mk40
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_flute.mk36
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_libbase.mk36
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_libfonts.mk36
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_libformula.mk36
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_liblayout.mk53
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_libloader.mk36
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_librepository.mk36
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_libserializer.mk36
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_libxml.mk36
-rw-r--r--external/jfreereport/ExternalProject_jfreereport_sac.mk31
-rw-r--r--external/jfreereport/Makefile7
-rw-r--r--external/jfreereport/Module_jfreereport.mk48
-rw-r--r--external/jfreereport/README1
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_flow_engine.mk24
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_flute.mk22
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_libbase.mk27
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_libfonts.mk27
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_libformula.mk27
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_liblayout.mk23
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_libloader.mk27
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_librepository.mk27
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_libserializer.mk23
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_libxml.mk23
-rw-r--r--external/jfreereport/UnpackedTarball_jfreereport_sac.mk16
-rw-r--r--external/jfreereport/java/sac/build.xml64
-rw-r--r--external/jfreereport/nbprojects/flute/nbproject/project.xml42
-rw-r--r--external/jfreereport/nbprojects/jcommon-serializer/nbproject/project.xml42
-rw-r--r--external/jfreereport/nbprojects/jfreereport/nbproject/project.xml42
-rw-r--r--external/jfreereport/nbprojects/libfonts/nbproject/project.xml42
-rw-r--r--external/jfreereport/nbprojects/libformula/nbproject/project.xml42
-rw-r--r--external/jfreereport/nbprojects/liblayout/nbproject/project.xml42
-rw-r--r--external/jfreereport/nbprojects/libloader/nbproject/project.xml42
-rw-r--r--external/jfreereport/nbprojects/librepository/nbproject/project.xml42
-rw-r--r--external/jfreereport/nbprojects/libxml/nbproject/project.xml42
-rw-r--r--external/jfreereport/patches/common_build.patch119
-rw-r--r--external/jfreereport/patches/flow-engine.patch18
-rw-r--r--external/jfreereport/patches/flow-engine_date_is_datetime.patch.113
-rw-r--r--external/jfreereport/patches/libbase-1.1.3-remove-commons-logging.patch.1903
-rw-r--r--external/jfreereport/patches/libbase-1.1.6-deprecated.patch53
-rw-r--r--external/jfreereport/patches/libfonts-1.1.3-remove-commons-logging.patch.1506
-rw-r--r--external/jfreereport/patches/libfonts-1.1.6-deprecated.patch11
-rw-r--r--external/jfreereport/patches/libformula-1.1.3-remove-commons-logging.patch.1266
-rw-r--r--external/jfreereport/patches/libformula-datevalue_truncation.patch.129
-rw-r--r--external/jfreereport/patches/libformula-minutes_truncation.patch.114
-rw-r--r--external/jfreereport/patches/libformula-seconds_rounding.patch.137
-rw-r--r--external/jfreereport/patches/libformula-time-notz.patch22
-rw-r--r--external/jfreereport/patches/liblayout-0.2.10-remove-commons-logging.patch.1860
-rw-r--r--external/jfreereport/patches/liblayout.patch21
-rw-r--r--external/jfreereport/patches/libloader-1.1.3-remove-commons-logging.patch.1635
-rw-r--r--external/jfreereport/patches/libloader-1.1.6-deprecated.patch34
-rw-r--r--external/jfreereport/patches/librepository-1.1.3-remove-commons-logging.patch.1117
-rw-r--r--external/jfreereport/patches/librepository-1.1.6-deprecated.patch37
-rw-r--r--external/jfreereport/patches/libserializer-1.1.2-remove-commons-logging.patch.131
-rw-r--r--external/jfreereport/patches/libxml-1.1.3-remove-commons-logging.patch.1313
-rw-r--r--external/jfreereport/patches/pentaho-reporting-flow-engine-0.9.4-remove-commons-logging.patch.1101
-rw-r--r--external/jfreereport/patches/sac.patch73
-rw-r--r--external/jfreereport/version.mk10
-rw-r--r--external/lcms2/ExternalPackage_lcms2.mk28
-rw-r--r--external/lcms2/ExternalProject_lcms2.mk46
-rw-r--r--external/lcms2/Makefile7
-rw-r--r--external/lcms2/Module_lcms2.mk18
-rw-r--r--external/lcms2/README3
-rw-r--r--external/lcms2/UnpackedTarball_lcms2.mk27
-rw-r--r--external/lcms2/c++17.patch.113
-rw-r--r--external/lcms2/lcms2-2.4-windows.patch20
-rw-r--r--external/lcms2/lcms2-win-arm64.patch.11537
-rw-r--r--external/lcms2/lcms2_slnbin0 -> 27136 bytes
-rw-r--r--external/libabw/ExternalProject_libabw.mk47
-rw-r--r--external/libabw/Makefile7
-rw-r--r--external/libabw/Module_libabw.mk17
-rw-r--r--external/libabw/README3
-rw-r--r--external/libabw/UnpackedTarball_libabw.mk16
-rw-r--r--external/libassuan/ExternalPackage_libassuan.mk28
-rw-r--r--external/libassuan/ExternalProject_libassuan.mk67
-rw-r--r--external/libassuan/Makefile14
-rw-r--r--external/libassuan/Module_libassuan.mk18
-rw-r--r--external/libassuan/README3
-rw-r--r--external/libassuan/UnpackedTarball_libassuan.mk25
-rw-r--r--external/libassuan/find-libgpg-error.patch18
-rw-r--r--external/libassuan/fix-autoconf-macros.patch27
-rw-r--r--external/libassuan/rpath.patch11
-rw-r--r--external/libassuan/w32-build-fixes-2.patch12
-rw-r--r--external/libassuan/w32-build-fixes.patch.173
-rw-r--r--external/libassuan/w32-stdc.patch74
-rw-r--r--external/libatomic_ops/ExternalProject_libatomic_ops.mk33
-rw-r--r--external/libatomic_ops/Makefile7
-rw-r--r--external/libatomic_ops/Module_libatomic_ops.mk17
-rw-r--r--external/libatomic_ops/README4
-rw-r--r--external/libatomic_ops/UnpackedTarball_libatomic_ops.mk16
-rw-r--r--external/libcdr/ExternalProject_libcdr.mk49
-rw-r--r--external/libcdr/Makefile7
-rw-r--r--external/libcdr/Module_libcdr.mk17
-rw-r--r--external/libcdr/README3
-rw-r--r--external/libcdr/UnpackedTarball_libcdr.mk23
-rw-r--r--external/libcdr/ax_gcc_func_attribute.m4.patch11
-rw-r--r--external/libcdr/libcdr-visibility-win.patch11
-rw-r--r--external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch69
-rw-r--r--external/libcmis/Makefile7
-rw-r--r--external/libcmis/Module_libcmis.mk17
-rw-r--r--external/libcmis/README8
-rw-r--r--external/libcmis/StaticLibrary_libcmis.mk104
-rw-r--r--external/libcmis/UnpackedTarball_libcmis.mk25
-rw-r--r--external/libcmis/inc/pch/precompiled_libcmis.cxx12
-rw-r--r--external/libcmis/inc/pch/precompiled_libcmis.hxx70
-rw-r--r--external/libcmis/libcmis-boost-string.patch11
-rw-r--r--external/libcmis/libcmis-libxml2_compatibility.patch14
-rw-r--r--external/libcmis/libcmis_gdrive.patch.1702
-rw-r--r--external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1185
-rw-r--r--external/libcmis/libcmis_onedrive.patch445
-rw-r--r--external/libebook/ExternalProject_libebook.mk54
-rw-r--r--external/libebook/Makefile7
-rw-r--r--external/libebook/Module_libebook.mk17
-rw-r--r--external/libebook/README3
-rw-r--r--external/libebook/UnpackedTarball_libebook.mk23
-rw-r--r--external/libebook/include.patch10
-rw-r--r--external/libebook/libebook-no-icu-boolean.patch.112
-rw-r--r--external/libeot/ExternalProject_libeot.mk31
-rw-r--r--external/libeot/Makefile7
-rw-r--r--external/libeot/Module_libeot.mk17
-rw-r--r--external/libeot/README2
-rw-r--r--external/libeot/UnpackedTarball_libeot.mk14
-rw-r--r--external/libepubgen/ExternalProject_libepubgen.mk43
-rw-r--r--external/libepubgen/Makefile7
-rw-r--r--external/libepubgen/Module_libepubgen.mk17
-rw-r--r--external/libepubgen/README3
-rw-r--r--external/libepubgen/UnpackedTarball_libepubgen.mk25
-rw-r--r--external/libepubgen/tdf-120491.patch33
-rw-r--r--external/libetonyek/0001-allow-0-size-message.patch.130
-rw-r--r--external/libetonyek/0001-fix-build-with-MSVC.patch.128
-rw-r--r--external/libetonyek/0002-fix-build-with-MSVC.patch.155
-rw-r--r--external/libetonyek/ExternalPackage_libetonyek.mk22
-rw-r--r--external/libetonyek/ExternalProject_libetonyek.mk67
-rw-r--r--external/libetonyek/Library_etonyek.mk193
-rw-r--r--external/libetonyek/Makefile7
-rw-r--r--external/libetonyek/Module_libetonyek.mk31
-rw-r--r--external/libetonyek/README3
-rw-r--r--external/libetonyek/UnpackedTarball_libetonyek.mk38
-rw-r--r--external/libetonyek/inc/pch/precompiled_etonyek.cxx12
-rw-r--r--external/libetonyek/inc/pch/precompiled_etonyek.hxx79
-rw-r--r--external/libetonyek/libetonyek-bundled-soname.patch.011
-rw-r--r--external/libetonyek/rpath.patch10
-rw-r--r--external/libetonyek/ubsan.patch11
-rw-r--r--external/libetonyek/warnings.patch11
-rw-r--r--external/libetonyek/win_build.patch.113
-rw-r--r--external/libexttextcat/ExternalPackage_fingerprint.mk194
-rw-r--r--external/libexttextcat/ExternalProject_libexttextcat.mk31
-rw-r--r--external/libexttextcat/Makefile7
-rw-r--r--external/libexttextcat/Module_libexttextcat.mk26
-rw-r--r--external/libexttextcat/README6
-rw-r--r--external/libexttextcat/StaticLibrary_libexttextcat.mk25
-rw-r--r--external/libexttextcat/UnpackedTarball_libexttextcat.mk16
-rw-r--r--external/libffi/ExternalPackage_libffi.mk20
-rw-r--r--external/libffi/ExternalProject_libffi.mk52
-rw-r--r--external/libffi/Makefile7
-rw-r--r--external/libffi/Module_libffi.mk18
-rw-r--r--external/libffi/README3
-rw-r--r--external/libffi/UnpackedTarball_libffi.mk14
-rw-r--r--external/libfreehand/ExternalProject_libfreehand.mk49
-rw-r--r--external/libfreehand/Makefile7
-rw-r--r--external/libfreehand/Module_libfreehand.mk17
-rw-r--r--external/libfreehand/README3
-rw-r--r--external/libfreehand/UnpackedTarball_libfreehand.mk24
-rw-r--r--external/libfreehand/icu-65-api-macros-with-semicolon.patch.112
-rw-r--r--external/libgpg-error/ExternalPackage_libgpg-error.mk28
-rw-r--r--external/libgpg-error/ExternalProject_libgpg-error.mk53
-rw-r--r--external/libgpg-error/Makefile14
-rw-r--r--external/libgpg-error/Module_libgpg-error.mk18
-rw-r--r--external/libgpg-error/README2
-rw-r--r--external/libgpg-error/UnpackedTarball_libgpg-error.mk27
-rw-r--r--external/libgpg-error/clang-cl.patch11
-rw-r--r--external/libgpg-error/libgpgerror-bundled-soname.patch.122
-rw-r--r--external/libgpg-error/w32-build-fixes-2.patch.131
-rw-r--r--external/libgpg-error/w32-build-fixes-3.patch.157
-rw-r--r--external/libgpg-error/w32-build-fixes-4.patch13
-rw-r--r--external/libgpg-error/w32-build-fixes-5.patch145
-rw-r--r--external/libgpg-error/w32-build-fixes.patch121
-rw-r--r--external/libgpg-error/w32-disable-dllinit.patch.155
-rw-r--r--external/libjpeg-turbo/Makefile7
-rw-r--r--external/libjpeg-turbo/Module_libjpeg-turbo.mk17
-rw-r--r--external/libjpeg-turbo/README6
-rw-r--r--external/libjpeg-turbo/StaticLibrary_libjpeg-turbo.mk214
-rw-r--r--external/libjpeg-turbo/UnpackedTarball_libjpeg-turbo.mk23
-rw-r--r--external/libjpeg-turbo/jconfig.h86
-rw-r--r--external/libjpeg-turbo/jconfigint.h51
-rw-r--r--external/liblangtag/ExternalPackage_liblangtag.mk20
-rw-r--r--external/liblangtag/ExternalPackage_liblangtag_data.mk37
-rw-r--r--external/liblangtag/ExternalProject_liblangtag.mk54
-rw-r--r--external/liblangtag/Makefile7
-rw-r--r--external/liblangtag/Module_liblangtag.mk25
-rw-r--r--external/liblangtag/README10
-rw-r--r--external/liblangtag/UnpackedTarball_liblangtag.mk35
-rw-r--r--external/liblangtag/clang-cl.patch.041
-rw-r--r--external/liblangtag/langtag-libtool-rpath.patch.023
-rw-r--r--external/liblangtag/liblangtag-bundled-soname.patch.010
-rw-r--r--external/libmspub/ExternalProject_libmspub.mk47
-rw-r--r--external/libmspub/Makefile7
-rw-r--r--external/libmspub/Module_libmspub.mk17
-rw-r--r--external/libmspub/README3
-rw-r--r--external/libmspub/UnpackedTarball_libmspub.mk31
-rw-r--r--external/libmspub/libmspub_android_arm.patch.112
-rw-r--r--external/libmspub/stdint.patch10
-rw-r--r--external/libmspub/ubsan.patch12
-rw-r--r--external/libmwaw/ExternalPackage_libmwaw.mk22
-rw-r--r--external/libmwaw/ExternalProject_libmwaw.mk54
-rw-r--r--external/libmwaw/Library_mwaw.mk223
-rw-r--r--external/libmwaw/Makefile7
-rw-r--r--external/libmwaw/Module_libmwaw.mk31
-rw-r--r--external/libmwaw/README3
-rw-r--r--external/libmwaw/UnpackedTarball_libmwaw.mk32
-rw-r--r--external/libmwaw/inc/pch/precompiled_mwaw.cxx12
-rw-r--r--external/libmwaw/inc/pch/precompiled_mwaw.hxx58
-rw-r--r--external/libmwaw/libmwaw-bundled-soname.patch.014
-rw-r--r--external/libmwaw/rpath.patch10
-rw-r--r--external/libnumbertext/ExternalPackage_numbertext.mk66
-rw-r--r--external/libnumbertext/ExternalProject_libnumbertext.mk41
-rw-r--r--external/libnumbertext/MSVCNonBMPBug.patch169
-rw-r--r--external/libnumbertext/Makefile7
-rw-r--r--external/libnumbertext/Module_libnumbertext.mk28
-rw-r--r--external/libnumbertext/README3
-rw-r--r--external/libnumbertext/StaticLibrary_libnumbertext.mk22
-rw-r--r--external/libnumbertext/UnpackedTarball_libnumbertext.mk23
-rw-r--r--external/libnumbertext/WinUnicodePath.patch120
-rw-r--r--external/libodfgen/ExternalPackage_libodfgen.mk22
-rw-r--r--external/libodfgen/ExternalProject_libodfgen.mk56
-rw-r--r--external/libodfgen/Library_odfgen.mk57
-rw-r--r--external/libodfgen/Makefile7
-rw-r--r--external/libodfgen/Module_libodfgen.mk31
-rw-r--r--external/libodfgen/README1
-rw-r--r--external/libodfgen/UnpackedTarball_libodfgen.mk39
-rw-r--r--external/libodfgen/ellipticalarc.patch13
-rw-r--r--external/libodfgen/libodfgen-bundled-soname.patch.013
-rw-r--r--external/libodfgen/rpath.patch10
-rw-r--r--external/liborcus/ExternalPackage_liborcus.mk22
-rw-r--r--external/liborcus/ExternalProject_liborcus.mk122
-rw-r--r--external/liborcus/Library_orcus-parser.mk73
-rw-r--r--external/liborcus/Library_orcus.mk148
-rw-r--r--external/liborcus/Makefile7
-rw-r--r--external/liborcus/Module_liborcus.mk32
-rw-r--r--external/liborcus/README2
-rw-r--r--external/liborcus/UnpackedTarball_liborcus.mk52
-rw-r--r--external/liborcus/fix-pch.patch.011
-rw-r--r--external/liborcus/forcepoint-83.patch.138
-rw-r--r--external/liborcus/forcepoint-84.patch.138
-rw-r--r--external/liborcus/forcepoint-87.patch.127
-rw-r--r--external/liborcus/forcepoint-88.patch.142
-rw-r--r--external/liborcus/forcepoint-95.patch.111
-rw-r--r--external/liborcus/gcc9.patch.028
-rw-r--r--external/liborcus/inc/pch/precompiled_orcus-parser.cxx12
-rw-r--r--external/liborcus/inc/pch/precompiled_orcus-parser.hxx88
-rw-r--r--external/liborcus/inc/pch/precompiled_orcus.cxx12
-rw-r--r--external/liborcus/inc/pch/precompiled_orcus.hxx109
-rw-r--r--external/liborcus/include.patch.020
-rw-r--r--external/liborcus/liborcus_newline.patch.117
-rw-r--r--external/liborcus/libtool.patch.011
-rw-r--r--external/liborcus/overrun.patch.063
-rw-r--r--external/liborcus/rpath.patch.010
-rw-r--r--external/liborcus/std-get-busted.patch.1418
-rw-r--r--external/liborcus/win_path_utf16.patch33
-rw-r--r--external/liborcus/windows-constants-hack.patch15
-rw-r--r--external/libpagemaker/ExternalProject_libpagemaker.mk45
-rw-r--r--external/libpagemaker/Makefile7
-rw-r--r--external/libpagemaker/Module_libpagemaker.mk17
-rw-r--r--external/libpagemaker/README3
-rw-r--r--external/libpagemaker/UnpackedTarball_libpagemaker.mk16
-rw-r--r--external/libpng/Makefile7
-rw-r--r--external/libpng/Module_libpng.mk17
-rw-r--r--external/libpng/README1
-rw-r--r--external/libpng/StaticLibrary_libpng.mk72
-rw-r--r--external/libpng/UnpackedTarball_libpng.mk18
-rw-r--r--external/libpng/configs/pnglibconf.h214
-rw-r--r--external/libqxp/ExternalProject_libqxp.mk48
-rw-r--r--external/libqxp/Makefile7
-rw-r--r--external/libqxp/Module_libqxp.mk17
-rw-r--r--external/libqxp/README4
-rw-r--r--external/libqxp/UnpackedTarball_libqxp.mk23
-rw-r--r--external/libqxp/android-workaround.patch.149
-rw-r--r--external/libqxp/ax_gcc_func_attribute.m4.patch11
-rw-r--r--external/librevenge/ExternalPackage_librevenge.mk22
-rw-r--r--external/librevenge/ExternalProject_librevenge.mk50
-rw-r--r--external/librevenge/Library_revenge.mk48
-rw-r--r--external/librevenge/Makefile7
-rw-r--r--external/librevenge/Module_librevenge.mk31
-rw-r--r--external/librevenge/README3
-rw-r--r--external/librevenge/UnpackedTarball_librevenge.mk30
-rw-r--r--external/librevenge/librevenge-bundled-soname.patch.011
-rw-r--r--external/librevenge/rpath.patch11
-rw-r--r--external/libstaroffice/ExternalPackage_libstaroffice.mk22
-rw-r--r--external/libstaroffice/ExternalProject_libstaroffice.mk54
-rw-r--r--external/libstaroffice/Library_staroffice.mk114
-rw-r--r--external/libstaroffice/Makefile7
-rw-r--r--external/libstaroffice/Module_libstaroffice.mk31
-rw-r--r--external/libstaroffice/README3
-rw-r--r--external/libstaroffice/UnpackedTarball_libstaroffice.mk32
-rw-r--r--external/libstaroffice/inc/pch/precompiled_staroffice.cxx12
-rw-r--r--external/libstaroffice/inc/pch/precompiled_staroffice.hxx59
-rw-r--r--external/libstaroffice/libstaroffice-bundled-soname.patch.011
-rw-r--r--external/libstaroffice/rpath.patch10
-rw-r--r--external/libtiff/ExternalProject_libtiff.mk72
-rw-r--r--external/libtiff/Makefile7
-rw-r--r--external/libtiff/Module_libtiff.mk17
-rw-r--r--external/libtiff/README3
-rw-r--r--external/libtiff/UnpackedTarball_libtiff.mk20
-rw-r--r--external/libtiff/libtiff.linknolibs.patch11
-rw-r--r--external/libtommath/ExternalProject_libtommath.mk38
-rw-r--r--external/libtommath/Makefile7
-rw-r--r--external/libtommath/Module_libtommath.mk17
-rw-r--r--external/libtommath/README6
-rw-r--r--external/libtommath/UnpackedTarball_libtommath.mk21
-rw-r--r--external/libtommath/clang-cl.patch16
-rw-r--r--external/libtommath/libtommath-msvc.patch12
-rw-r--r--external/libvisio/ExternalProject_libvisio.mk48
-rw-r--r--external/libvisio/Makefile7
-rw-r--r--external/libvisio/Module_libvisio.mk17
-rw-r--r--external/libvisio/README3
-rw-r--r--external/libvisio/UnpackedTarball_libvisio.mk22
-rw-r--r--external/libvisio/ubsan.patch11
-rw-r--r--external/libwebp/ExternalProject_libwebp.mk58
-rw-r--r--external/libwebp/Makefile7
-rw-r--r--external/libwebp/Makefile.vc.patch148
-rw-r--r--external/libwebp/Module_libwebp.mk17
-rw-r--r--external/libwebp/README1
-rw-r--r--external/libwebp/UnpackedTarball_libwebp.mk20
-rw-r--r--external/libwpd/ExternalPackage_libwpd.mk22
-rw-r--r--external/libwpd/ExternalProject_libwpd.mk53
-rw-r--r--external/libwpd/Library_wpd.mk211
-rw-r--r--external/libwpd/Makefile7
-rw-r--r--external/libwpd/Module_libwpd.mk31
-rw-r--r--external/libwpd/README1
-rw-r--r--external/libwpd/UnpackedTarball_libwpd.mk34
-rw-r--r--external/libwpd/inc/pch/precompiled_wpd.cxx12
-rw-r--r--external/libwpd/inc/pch/precompiled_wpd.hxx52
-rw-r--r--external/libwpd/include.patch10
-rw-r--r--external/libwpd/libwpd-bundled-soname.patch.011
-rw-r--r--external/libwpd/libwpd-vs2013.patch.125
-rw-r--r--external/libwpd/rpath.patch10
-rw-r--r--external/libwpg/ExternalPackage_libwpg.mk22
-rw-r--r--external/libwpg/ExternalProject_libwpg.mk51
-rw-r--r--external/libwpg/Library_wpg.mk48
-rw-r--r--external/libwpg/Makefile7
-rw-r--r--external/libwpg/Module_libwpg.mk31
-rw-r--r--external/libwpg/README1
-rw-r--r--external/libwpg/UnpackedTarball_libwpg.mk32
-rw-r--r--external/libwpg/libwpg-bundled-soname.patch.011
-rw-r--r--external/libwpg/rpath.patch10
-rw-r--r--external/libwps/ExternalPackage_libwps.mk22
-rw-r--r--external/libwps/ExternalProject_libwps.mk63
-rw-r--r--external/libwps/Library_wps.mk102
-rw-r--r--external/libwps/Makefile7
-rw-r--r--external/libwps/Module_libwps.mk31
-rw-r--r--external/libwps/README1
-rw-r--r--external/libwps/UnpackedTarball_libwps.mk31
-rw-r--r--external/libwps/inc/pch/precompiled_wps.cxx12
-rw-r--r--external/libwps/inc/pch/precompiled_wps.hxx64
-rw-r--r--external/libwps/libtool.patch.012
-rw-r--r--external/libwps/libwps-bundled-soname.patch.011
-rw-r--r--external/libwps/rpath.patch.010
-rw-r--r--external/libxml2/ExternalPackage_libxml2.mk28
-rw-r--r--external/libxml2/ExternalProject_libxml2.mk53
-rw-r--r--external/libxml2/Makefile7
-rw-r--r--external/libxml2/Module_libxml2.mk18
-rw-r--r--external/libxml2/README1
-rw-r--r--external/libxml2/UnpackedTarball_libxml2.mk27
-rw-r--r--external/libxml2/libxml2-android.patch11
-rw-r--r--external/libxml2/libxml2-global-symbols.patch59
-rw-r--r--external/libxml2/libxml2-icu-sym.patch.037
-rw-r--r--external/libxml2/libxml2-icu.patch.033
-rw-r--r--external/libxml2/libxml2-vc10.patch12
-rw-r--r--external/libxml2/xml2-config.in28
-rw-r--r--external/libxslt/ExternalPackage_libxslt.mk32
-rw-r--r--external/libxslt/ExternalProject_libxslt.mk55
-rw-r--r--external/libxslt/Makefile7
-rw-r--r--external/libxslt/Module_libxslt.mk18
-rw-r--r--external/libxslt/README1
-rw-r--r--external/libxslt/UnpackedTarball_libxslt.mk26
-rw-r--r--external/libxslt/libxslt-1.1.26-memdump.patch10
-rw-r--r--external/libxslt/libxslt-config.patch.135
-rw-r--r--external/libxslt/libxslt-internal-symbols.patch.113
-rw-r--r--external/libxslt/libxslt-msvc-sym.patch.216
-rw-r--r--external/libxslt/libxslt-msvc.patch.210
-rw-r--r--external/libxslt/rpath.patch.010
-rw-r--r--external/libzmf/ExternalProject_libzmf.mk49
-rw-r--r--external/libzmf/Makefile7
-rw-r--r--external/libzmf/Module_libzmf.mk17
-rw-r--r--external/libzmf/README4
-rw-r--r--external/libzmf/UnpackedTarball_libzmf.mk20
-rw-r--r--external/libzmf/android-workaround.patch.114
-rw-r--r--external/lpsolve/ExternalPackage_lpsolve.mk24
-rw-r--r--external/lpsolve/ExternalProject_lpsolve.mk37
-rw-r--r--external/lpsolve/Makefile7
-rw-r--r--external/lpsolve/Module_lpsolve.mk18
-rw-r--r--external/lpsolve/README1
-rw-r--r--external/lpsolve/UnpackedTarball_lpsolve.mk37
-rw-r--r--external/lpsolve/ccc.static11
-rw-r--r--external/lpsolve/lp_solve-aix.patch39
-rw-r--r--external/lpsolve/lp_solve-fixed-warn.patch84
-rw-r--r--external/lpsolve/lp_solve_5.5-windows.patch60
-rw-r--r--external/lpsolve/lp_solve_5.5.patch95
-rw-r--r--external/lpsolve/lpsolve-ubsan.patch.022
-rw-r--r--external/lxml/ExternalProject_lxml.mk45
-rw-r--r--external/lxml/Makefile7
-rw-r--r--external/lxml/Module_lxml.mk17
-rw-r--r--external/lxml/README7
-rw-r--r--external/lxml/UnpackedTarball_lxml.mk14
-rw-r--r--external/mariadb-connector-c/Makefile7
-rw-r--r--external/mariadb-connector-c/Module_mariadb-connector-c.mk17
-rw-r--r--external/mariadb-connector-c/README8
-rw-r--r--external/mariadb-connector-c/StaticLibrary_mariadb-connector-c.mk82
-rw-r--r--external/mariadb-connector-c/UnpackedTarball_mariadb-connector-c.mk57
-rw-r--r--external/mariadb-connector-c/clang-cl.patch.011
-rw-r--r--external/mariadb-connector-c/configs/linux_my_config.h142
-rw-r--r--external/mariadb-connector-c/configs/mac_my_config.h142
-rw-r--r--external/mariadb-connector-c/configs/mariadb_version.h38
-rw-r--r--external/mariadb-connector-c/configs/wnt_ma_config.h154
-rw-r--r--external/mdds/Makefile7
-rw-r--r--external/mdds/Module_mdds.mk16
-rw-r--r--external/mdds/README4
-rw-r--r--external/mdds/UnpackedTarball_mdds.mk20
-rw-r--r--external/mdds/use-after-free.patch12
-rw-r--r--external/mdnsresponder/Makefile7
-rw-r--r--external/mdnsresponder/Module_mdnsresponder.mk20
-rw-r--r--external/mdnsresponder/README4
-rw-r--r--external/mdnsresponder/StaticLibrary_mDNSResponder.mk37
-rw-r--r--external/mdnsresponder/UnpackedTarball_mDNSResponder.mk14
-rw-r--r--external/misc_extensions/ExtensionPackageSet_misc_extensions.mk16
-rw-r--r--external/misc_extensions/Makefile7
-rw-r--r--external/misc_extensions/Module_misc_extensions.mk16
-rw-r--r--external/misc_extensions/README1
-rw-r--r--external/more_fonts/ExternalPackage_EmojiOne_Color.mk16
-rw-r--r--external/more_fonts/ExternalPackage_alef.mk17
-rw-r--r--external/more_fonts/ExternalPackage_amiri.mk20
-rw-r--r--external/more_fonts/ExternalPackage_caladea.mk19
-rw-r--r--external/more_fonts/ExternalPackage_carlito.mk19
-rw-r--r--external/more_fonts/ExternalPackage_culmus.mk33
-rw-r--r--external/more_fonts/ExternalPackage_dejavu.mk37
-rw-r--r--external/more_fonts/ExternalPackage_gentium.mk23
-rw-r--r--external/more_fonts/ExternalPackage_kacst.mk17
-rw-r--r--external/more_fonts/ExternalPackage_liberation.mk27
-rw-r--r--external/more_fonts/ExternalPackage_liberation_narrow.mk19
-rw-r--r--external/more_fonts/ExternalPackage_libertineg.mk25
-rw-r--r--external/more_fonts/ExternalPackage_libre_hebrew.mk25
-rw-r--r--external/more_fonts/ExternalPackage_noto.mk63
-rw-r--r--external/more_fonts/ExternalPackage_reem.mk17
-rw-r--r--external/more_fonts/ExternalPackage_scheherazade.mk17
-rw-r--r--external/more_fonts/ExternalPackage_sourcecode.mk29
-rw-r--r--external/more_fonts/ExternalPackage_sourcesans.mk27
-rw-r--r--external/more_fonts/ExternalPackage_sourceserif.mk27
-rw-r--r--external/more_fonts/Makefile7
-rw-r--r--external/more_fonts/Module_more_fonts.mk53
-rw-r--r--external/more_fonts/README1
-rw-r--r--external/more_fonts/UnpackedTarball_EmojiOne_Color.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_alef.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_amiri.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_caladea.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_carlito.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_culmus.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_dejavu.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_gentium.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_kacst.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_liberation.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_liberation_narrow.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_libertineg.mk15
-rw-r--r--external/more_fonts/UnpackedTarball_libre_hebrew.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_noto.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_reem.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_scheherazade.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_sourcecode.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_sourcesans.mk14
-rw-r--r--external/more_fonts/UnpackedTarball_sourceserif.mk14
-rw-r--r--external/more_fonts/fc_local.snippet29
-rw-r--r--external/msc-externals/Makefile7
-rw-r--r--external/msc-externals/Module_msc-externals.mk29
-rw-r--r--external/msc-externals/Package_msvc_dlls.mk16
-rw-r--r--external/msc-externals/Package_ucrt.mk21
-rw-r--r--external/msc-externals/README1
-rw-r--r--external/mythes/ExternalProject_mythes.mk32
-rw-r--r--external/mythes/Makefile7
-rw-r--r--external/mythes/Module_mythes.mk25
-rw-r--r--external/mythes/README1
-rw-r--r--external/mythes/StaticLibrary_mythes.mk21
-rw-r--r--external/mythes/UnpackedTarball_mythes.mk21
-rw-r--r--external/mythes/mythes-1.2.0-vanilla-th-gen-idx.patch90
-rw-r--r--external/mythes/mythes-fdo48017-wfopen.patch77
-rw-r--r--external/nss/ExternalPackage_nss.mk67
-rw-r--r--external/nss/ExternalProject_nss.mk103
-rw-r--r--external/nss/Makefile7
-rw-r--r--external/nss/Module_nss.mk18
-rw-r--r--external/nss/README37
-rw-r--r--external/nss/UnpackedTarball_nss.mk49
-rw-r--r--external/nss/asan.patch.112
-rw-r--r--external/nss/clang-cl.patch.0122
-rw-r--r--external/nss/macos-dlopen.patch.025
-rw-r--r--external/nss/nsinstall.py169
-rw-r--r--external/nss/nss-android.patch.193
-rw-r--r--external/nss/nss-bz1646594.patch.115
-rw-r--r--external/nss/nss-ios.patch300
-rw-r--r--external/nss/nss-restore-manual-pre-dependencies.patch.183
-rw-r--r--external/nss/nss-win32-make.patch.120
-rw-r--r--external/nss/nss.aix.patch140
-rw-r--r--external/nss/nss.bzmozilla1238154.patch12
-rw-r--r--external/nss/nss.cygwin64.in32bit.patch14
-rw-r--r--external/nss/nss.nowerror.patch12
-rw-r--r--external/nss/nss.patch155
-rw-r--r--external/nss/nss.utf8bom.patch.121
-rw-r--r--external/nss/nss.vs2015.patch12
-rw-r--r--external/nss/nss.vs2015.pdb.patch22
-rw-r--r--external/nss/nss.windows.patch33
-rw-r--r--external/nss/nss_macosx.patch90
-rw-r--r--external/nss/ubsan.patch.038
-rw-r--r--external/openldap/ExternalProject_openldap.mk65
-rw-r--r--external/openldap/Makefile7
-rw-r--r--external/openldap/Module_openldap.mk17
-rw-r--r--external/openldap/README3
-rw-r--r--external/openldap/UnpackedTarball_openldap.mk26
-rw-r--r--external/openldap/configure-c99.patch11
-rw-r--r--external/openldap/openldap-2.4.44.patch.185
-rw-r--r--external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1222
-rw-r--r--external/openssl/ExternalPackage_openssl.mk29
-rw-r--r--external/openssl/ExternalProject_openssl.mk97
-rw-r--r--external/openssl/Makefile7
-rw-r--r--external/openssl/Module_openssl.mk18
-rw-r--r--external/openssl/README7
-rw-r--r--external/openssl/UnpackedTarball_openssl.mk21
-rw-r--r--external/openssl/configurable-z-option.patch.034
-rw-r--r--external/openssl/openssl-no-_umul128-on-aarch64.patch.158
-rw-r--r--external/openssl/openssl-no-multilib.patch.038
-rw-r--r--external/pdfium/AndroidNDK19.patch.116
-rw-r--r--external/pdfium/Library_pdfium.mk733
-rw-r--r--external/pdfium/Makefile7
-rw-r--r--external/pdfium/Module_pdfium.mk17
-rw-r--r--external/pdfium/README17
-rw-r--r--external/pdfium/UnpackedTarball_pdfium.mk61
-rw-r--r--external/pdfium/build.patch.1147
-rw-r--r--external/pdfium/c++20-comparison.patch13
-rw-r--r--external/pdfium/cg-instead-of-carbon.patch.123
-rw-r--r--external/pdfium/gcc-c++20-comparison.patch18
-rw-r--r--external/pdfium/inc/pch/precompiled_pdfium.cxx12
-rw-r--r--external/pdfium/inc/pch/precompiled_pdfium.hxx496
-rw-r--r--external/pdfium/include.patch11
-rw-r--r--external/pdfium/ubsan.patch24
-rw-r--r--external/pdfium/windows7.patch.134
-rw-r--r--external/poppler/ExternalPackage_poppler_data.mk297
-rw-r--r--external/poppler/Makefile7
-rw-r--r--external/poppler/Module_poppler.mk19
-rw-r--r--external/poppler/README1
-rw-r--r--external/poppler/StaticLibrary_poppler.mk146
-rw-r--r--external/poppler/UnpackedTarball_poppler.mk29
-rw-r--r--external/poppler/UnpackedTarball_poppler_data.mk13
-rw-r--r--external/poppler/disable-freetype.patch.141
-rw-r--r--external/poppler/gcc7-EntityInfo.patch.148
-rw-r--r--external/poppler/inc/pch/precompiled_poppler.cxx12
-rw-r--r--external/poppler/inc/pch/precompiled_poppler.hxx81
-rw-r--r--external/poppler/pch.patch.011
-rw-r--r--external/poppler/poppler-config.patch.1486
-rw-r--r--external/poppler/sanitizer.patch18
-rw-r--r--external/postgresql/ExternalPackage_postgresql.mk16
-rw-r--r--external/postgresql/ExternalProject_postgresql.mk86
-rw-r--r--external/postgresql/Makefile7
-rw-r--r--external/postgresql/Module_postgresql.mk23
-rw-r--r--external/postgresql/README3
-rw-r--r--external/postgresql/UnpackedTarball_postgresql.mk27
-rw-r--r--external/postgresql/arm64.patch.153
-rw-r--r--external/postgresql/config.pl1
-rw-r--r--external/postgresql/postgres-msvc-build.patch.1110
-rw-r--r--external/postgresql/postgresql.exit.patch.019
-rw-r--r--external/postgresql/windows.patch.011
-rw-r--r--external/python3/ExternalPackage_python3.mk892
-rw-r--r--external/python3/ExternalProject_python3.mk213
-rw-r--r--external/python3/GeneratedPackage_python3.mk18
-rw-r--r--external/python3/Makefile7
-rw-r--r--external/python3/Module_python3.mk22
-rw-r--r--external/python3/README1
-rw-r--r--external/python3/UnpackedTarball_python3.mk52
-rw-r--r--external/python3/darwin.patch.010
-rw-r--r--external/python3/i100492-freebsd.patch.135
-rw-r--r--external/python3/internal-zlib.patch.055
-rw-r--r--external/python3/macos-11.patch.034
-rw-r--r--external/python3/python-3.3.0-darwin.patch.165
-rw-r--r--external/python3/python-3.3.3-disable-obmalloc.patch.021
-rw-r--r--external/python3/python-3.3.3-elf-rpath.patch.125
-rw-r--r--external/python3/python-3.5.4-msvc-disable.patch.158
-rw-r--r--external/python3/python-3.5.tweak.strip.soabi.patch12
-rw-r--r--external/python3/python-3.7.6-msvc-ssl.patch.125
-rw-r--r--external/python3/python-3.8-msvc-sdk.patch.1173
-rw-r--r--external/python3/tsan.patch.010
-rw-r--r--external/python3/ubsan.patch.043
-rw-r--r--external/redland/ExternalPackage_raptor.mk22
-rw-r--r--external/redland/ExternalPackage_rasqal.mk22
-rw-r--r--external/redland/ExternalPackage_redland.mk22
-rw-r--r--external/redland/ExternalProject_raptor.mk47
-rw-r--r--external/redland/ExternalProject_rasqal.mk54
-rw-r--r--external/redland/ExternalProject_redland.mk57
-rw-r--r--external/redland/Library_raptor.mk88
-rw-r--r--external/redland/Library_rasqal.mk127
-rw-r--r--external/redland/Library_rdf.mk78
-rw-r--r--external/redland/Makefile7
-rw-r--r--external/redland/Module_redland.mk34
-rw-r--r--external/redland/README24
-rw-r--r--external/redland/UnpackedTarball_raptor.mk35
-rw-r--r--external/redland/UnpackedTarball_rasqal.mk34
-rw-r--r--external/redland/UnpackedTarball_redland.mk38
-rw-r--r--external/redland/raptor/0001-CVE-2020-25713-raptor2-malformed-input-file-can-lead.patch.133
-rw-r--r--external/redland/raptor/0001-Calcualte-max-nspace-declarations-correctly-for-XML-.patch.143
-rw-r--r--external/redland/raptor/libtool.patch27
-rw-r--r--external/redland/raptor/raptor-android.patch.113
-rw-r--r--external/redland/raptor/raptor-bundled-soname.patch.113
-rw-r--r--external/redland/raptor/raptor-freebsd.patch.128
-rw-r--r--external/redland/raptor/raptor-msvc.patch.123
-rw-r--r--external/redland/raptor/raptor2.h2187
-rw-r--r--external/redland/raptor/raptor_config.h402
-rw-r--r--external/redland/raptor/rpath.patch21
-rw-r--r--external/redland/raptor/ubsan.patch25
-rw-r--r--external/redland/raptor/xml2-config.patch22
-rw-r--r--external/redland/rasqal/clang-cl.patch11
-rw-r--r--external/redland/rasqal/libtool.patch27
-rw-r--r--external/redland/rasqal/rasqal-aix.patch.125
-rw-r--r--external/redland/rasqal/rasqal-android.patch.114
-rw-r--r--external/redland/rasqal/rasqal-bundled-soname.patch.113
-rw-r--r--external/redland/rasqal/rasqal-freebsd.patch.128
-rw-r--r--external/redland/rasqal/rasqal-msvc.patch.164
-rw-r--r--external/redland/rasqal/rasqal-pkgconfig.patch.114
-rw-r--r--external/redland/rasqal/rasqal-xcompile.patch.116
-rw-r--r--external/redland/rasqal/rasqal.h2259
-rw-r--r--external/redland/rasqal/rpath.patch21
-rw-r--r--external/redland/redland/clang-cl.patch20
-rw-r--r--external/redland/redland/librdf.h434
-rw-r--r--external/redland/redland/libtool.patch27
-rw-r--r--external/redland/redland/redland-android.patch.114
-rw-r--r--external/redland/redland/redland-bundled-soname.patch.113
-rw-r--r--external/redland/redland/redland-format.patch.010
-rw-r--r--external/redland/redland/redland-freebsd.patch.128
-rw-r--r--external/redland/redland/redland-msvc.patch.1123
-rw-r--r--external/redland/redland/redland-xcompile.patch.115
-rw-r--r--external/redland/redland/rpath.patch10
-rw-r--r--external/rhino/ExternalPackage_rhino.mk16
-rw-r--r--external/rhino/ExternalProject_rhino.mk32
-rw-r--r--external/rhino/Makefile7
-rw-r--r--external/rhino/Module_rhino.mk22
-rw-r--r--external/rhino/OfficeScriptInfo.java118
-rw-r--r--external/rhino/README14
-rw-r--r--external/rhino/UnpackedTarball_rhino.mk25
-rw-r--r--external/rhino/rhino-classpath.patch.113
-rw-r--r--external/rhino/rhino1_5R5-find_swing.patch16
-rw-r--r--external/rhino/rhino1_5R5-updateToolTip.patch23
-rw-r--r--external/rhino/rhino1_5R5.patch1067
-rw-r--r--external/sane/README1
-rw-r--r--external/sane/inc/sane/sane.h213
-rw-r--r--external/skia/Library_skia.mk1017
-rw-r--r--external/skia/Makefile7
-rw-r--r--external/skia/Module_skia.mk18
-rw-r--r--external/skia/README33
-rw-r--r--external/skia/UnpackedTarball_skia.mk53
-rw-r--r--external/skia/allow-no-es2restrictions.patch.113
-rw-r--r--external/skia/clang-attributes-warning.patch.131
-rw-r--r--external/skia/clang11-flax-vector-conversion.patch.011
-rw-r--r--external/skia/fast-png-write.patch.115
-rw-r--r--external/skia/fix-alpha-difference-copy.patch.113
-rw-r--r--external/skia/fix-ddi.patch9
-rw-r--r--external/skia/fix-graphite-ifdef.patch.148
-rw-r--r--external/skia/fix-pch.patch.1106
-rw-r--r--external/skia/fix-warnings.patch.139
-rw-r--r--external/skia/fix-windows-dwrite.patch.140
-rw-r--r--external/skia/fix-without-gl.patch.150
-rw-r--r--external/skia/fontconfig-get-typeface.patch.040
-rw-r--r--external/skia/inc/pch/precompiled_skia.cxx12
-rw-r--r--external/skia/inc/pch/precompiled_skia.hxx618
-rw-r--r--external/skia/inc/skia_compiler.hxx13
-rw-r--r--external/skia/inc/skia_opts.hxx28
-rw-r--r--external/skia/make-api-visible.patch.182
-rw-r--r--external/skia/missing-include.patch.020
-rw-r--r--external/skia/no-trace-resources-on-exit.patch.113
-rw-r--r--external/skia/share-grcontext.patch.1872
-rw-r--r--external/skia/skia_sk_cpu_sse_level_0_by_default.patch.115
-rw-r--r--external/skia/source/SkMemory_malloc.cxx68
-rw-r--r--external/skia/source/skia_compiler.cxx20
-rw-r--r--external/skia/source/skia_opts.cxx77
-rw-r--r--external/skia/source/skia_opts_internal.hxx81
-rw-r--r--external/skia/source/skia_opts_ssse3.cxx17
-rw-r--r--external/skia/swap-buffers-rect.patch.1153
-rw-r--r--external/skia/tdf148624.patch.160
-rw-r--r--external/skia/ubsan.patch.142
-rw-r--r--external/skia/vk_mem_alloc.patch.119639
-rw-r--r--external/skia/windows-do-not-modify-logfont.patch.029
-rw-r--r--external/skia/windows-force-unicode-api.patch.031
-rw-r--r--external/skia/windows-libraries-system32.patch.113
-rw-r--r--external/skia/windows-raster-surface-no-copies.patch.139
-rw-r--r--external/skia/windows-text-gamma.patch.070
-rw-r--r--external/skia/windows-typeface-directwrite.patch.048
-rw-r--r--external/twain_dsm/Module_twain_dsm.mk20
-rw-r--r--external/twain_dsm/README1
-rw-r--r--external/twain_dsm/UnpackedTarball_twain_dsm.mk14
-rw-r--r--external/ucpp/Executable_ucpp.mk33
-rw-r--r--external/ucpp/Makefile14
-rw-r--r--external/ucpp/Module_ucpp.mk20
-rw-r--r--external/ucpp/README3
-rw-r--r--external/ucpp/UnpackedTarball_ucpp.mk20
-rw-r--r--external/ucpp/ucpp.patch11
-rw-r--r--external/unixODBC/README1
-rw-r--r--external/unixODBC/inc/odbc/sql.h824
-rw-r--r--external/unixODBC/inc/odbc/sqlext.h2122
-rw-r--r--external/unixODBC/inc/odbc/sqltypes.h470
-rw-r--r--external/unixODBC/inc/odbc/sqlucode.h789
-rw-r--r--external/xmlsec/ExternalPackage_xmlsec.mk19
-rw-r--r--external/xmlsec/ExternalProject_xmlsec.mk79
-rw-r--r--external/xmlsec/Makefile7
-rw-r--r--external/xmlsec/Module_xmlsec.mk18
-rw-r--r--external/xmlsec/README5
-rw-r--r--external/xmlsec/UnpackedTarball_xmlsec.mk22
-rw-r--r--external/xsltml/Makefile7
-rw-r--r--external/xsltml/Module_xsltml.mk20
-rw-r--r--external/xsltml/README14
-rw-r--r--external/xsltml/UnpackedTarball_xsltml.mk28
-rw-r--r--external/xsltml/xsltml_2.1.2.patch1718
-rw-r--r--external/zlib/Makefile14
-rw-r--r--external/zlib/Module_zlib.mk23
-rw-r--r--external/zlib/README1
-rw-r--r--external/zlib/StaticLibrary_zlib.mk36
-rw-r--r--external/zlib/StaticLibrary_zlib_x64.mk39
-rw-r--r--external/zlib/UnpackedTarball_zlib.mk21
-rw-r--r--external/zxing/0001-Use-a-patch-file-to-document-changes-from-upstream-s.patch35
-rw-r--r--external/zxing/0002-Update-stb_image_write-from-1.14-to-1.16.patch361
-rw-r--r--external/zxing/0003-Update-stb_image-from-2.25-to-2.27.patch1162
-rw-r--r--external/zxing/0004-Apply-stb-PR-1223-to-stb_image.patch98
-rw-r--r--external/zxing/Makefile7
-rw-r--r--external/zxing/Module_zxing.mk20
-rw-r--r--external/zxing/README3
-rw-r--r--external/zxing/StaticLibrary_zxing.mk142
-rw-r--r--external/zxing/UnpackedTarball_zxing.mk25
-rw-r--r--external/zxing/inc/pch/precompiled_zxing.cxx12
-rw-r--r--external/zxing/inc/pch/precompiled_zxing.hxx91
-rw-r--r--external/zxing/include.patch.010
-rw-r--r--external/zxing/zxing_newline.patch.121
1180 files changed, 93065 insertions, 0 deletions
diff --git a/external/Makefile b/external/Makefile
new file mode 100644
index 000000000..ccb1c85a0
--- /dev/null
+++ b/external/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/Module_external.mk b/external/Module_external.mk
new file mode 100644
index 000000000..366fff2a3
--- /dev/null
+++ b/external/Module_external.mk
@@ -0,0 +1,107 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,external))
+
+ifeq ($(COM),MSC)
+$(eval $(call gb_Module_add_moduledir,external,msc-externals))
+endif
+
+$(eval $(call gb_Module_add_moduledirs,external,\
+ $(call gb_Helper_optional,XMLSEC,xmlsec) \
+ $(call gb_Helper_optional,ABW,libabw) \
+ $(call gb_Helper_optional,BOOST,boost) \
+ $(call gb_Helper_optional,BOX2D,box2d) \
+ $(call gb_Helper_optional,BREAKPAD,breakpad) \
+ $(call gb_Helper_optional,BSH,beanshell) \
+ $(call gb_Helper_optional,BZIP2,bzip2) \
+ $(call gb_Helper_optional,CAIRO,cairo) \
+ $(call gb_Helper_optional,CDR,libcdr) \
+ $(call gb_Helper_optional,OPENCL,clew) \
+ $(call gb_Helper_optional,CLUCENE,clucene) \
+ $(call gb_Helper_optional,LIBCMIS,libcmis) \
+ $(call gb_Helper_optional,COINMP,coinmp) \
+ $(call gb_Helper_optional,CPPUNIT,cppunit) \
+ $(call gb_Helper_optional,CURL,curl) \
+ $(call gb_Helper_optional,DRAGONBOX,dragonbox) \
+ dtoa \
+ $(call gb_Helper_optional,EBOOK,libebook) \
+ $(call gb_Helper_optional,EPM,epm) \
+ $(call gb_Helper_optional,EPOXY,epoxy) \
+ $(call gb_Helper_optional,EPUBGEN,libepubgen) \
+ $(call gb_Helper_optional,ETONYEK,libetonyek) \
+ $(call gb_Helper_optional,EXPAT,expat) \
+ $(call gb_Helper_optional,FIREBIRD,firebird) \
+ $(call gb_Helper_optional,FONTCONFIG,fontconfig) \
+ $(call gb_Helper_optional,FREEHAND,libfreehand) \
+ $(call gb_Helper_optional,FREETYPE,freetype) \
+ $(call gb_Helper_optional,GLM,glm) \
+ $(call gb_Helper_optional,GPGMEPP,gpgmepp) \
+ $(call gb_Helper_optional,GRAPHITE,graphite) \
+ $(call gb_Helper_optional,HARFBUZZ,harfbuzz) \
+ $(call gb_Helper_optional,HSQLDB,hsqldb) \
+ $(call gb_Helper_optional,HUNSPELL,hunspell) \
+ $(call gb_Helper_optional,HYPHEN,hyphen) \
+ $(call gb_Helper_optional,ICU,icu) \
+ $(call gb_Helper_optional,JFREEREPORT,jfreereport) \
+ $(call gb_Helper_optional,LIBJPEG_TURBO,libjpeg-turbo) \
+ $(call gb_Helper_optional,LCMS2,lcms2) \
+ $(call gb_Helper_optional,LIBASSUAN,libassuan) \
+ $(call gb_Helper_optional,LIBATOMIC_OPS,libatomic_ops) \
+ $(call gb_Helper_optional,LIBEOT,libeot) \
+ $(call gb_Helper_optional,LIBEXTTEXTCAT,libexttextcat) \
+ $(call gb_Helper_optional,LIBFFI,libffi) \
+ $(call gb_Helper_optional,LIBGPGERROR,libgpg-error) \
+ $(call gb_Helper_optional,LIBLANGTAG,liblangtag) \
+ $(call gb_Helper_optional,LIBNUMBERTEXT,libnumbertext) \
+ $(call gb_Helper_optional,LIBPNG,libpng) \
+ $(call gb_Helper_optional,LIBTIFF,libtiff) \
+ $(call gb_Helper_optional,LIBWEBP,libwebp) \
+ $(call gb_Helper_optional,LIBXML2,libxml2) \
+ $(call gb_Helper_optional,LIBXSLT,libxslt) \
+ $(call gb_Helper_optional,LPSOLVE,lpsolve) \
+ $(call gb_Helper_optional,LIBTOMMATH,libtommath) \
+ $(call gb_Helper_optional,LXML,lxml) \
+ $(call gb_Helper_optional,MARIADB_CONNECTOR_C,mariadb-connector-c) \
+ $(call gb_Helper_optional,MDDS,mdds) \
+ $(call gb_Helper_optional,MDNSRESPONDER,mdnsresponder) \
+ $(if $(WITH_EXTRA_EXTENSIONS),misc_extensions) \
+ $(call gb_Helper_optional,MORE_FONTS,more_fonts) \
+ $(call gb_Helper_optional,MSPUB,libmspub) \
+ $(call gb_Helper_optional,MWAW,libmwaw) \
+ $(call gb_Helper_optional,MYTHES,mythes) \
+ $(call gb_Helper_optional,NSS,nss) \
+ $(call gb_Helper_optional,ODFGEN,libodfgen) \
+ $(call gb_Helper_optional,OPENLDAP,openldap) \
+ $(call gb_Helper_optional,OPENSSL,openssl) \
+ $(call gb_Helper_optional,ORCUS,liborcus) \
+ $(call gb_Helper_optional,PAGEMAKER,libpagemaker) \
+ $(call gb_Helper_optional,PDFIUM,pdfium) \
+ $(call gb_Helper_optional,POPPLER,poppler) \
+ $(call gb_Helper_optional,POSTGRESQL,postgresql) \
+ $(call gb_Helper_optional,PYTHON,python3) \
+ $(call gb_Helper_optional,QXP,libqxp) \
+ $(call gb_Helper_optional,ZXING,zxing) \
+ $(call gb_Helper_optional,REDLAND,redland) \
+ $(call gb_Helper_optional,REVENGE,librevenge) \
+ $(call gb_Helper_optional,RHINO,rhino) \
+ $(call gb_Helper_optional,SKIA,skia) \
+ $(call gb_Helper_optional,STAROFFICE,libstaroffice) \
+ $(if $(filter WNT,$(OS)),twain_dsm) \
+ $(call gb_Helper_optional,UCPP,ucpp) \
+ $(call gb_Helper_optional,VISIO,libvisio) \
+ $(call gb_Helper_optional,WPD,libwpd) \
+ $(call gb_Helper_optional,WPG,libwpg) \
+ $(call gb_Helper_optional,WPS,libwps) \
+ $(call gb_Helper_optional,XSLTML,xsltml) \
+ $(call gb_Helper_optional,ZLIB,zlib) \
+ $(call gb_Helper_optional,ZMF,libzmf) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/README.md b/external/README.md
new file mode 100644
index 000000000..29a2c9098
--- /dev/null
+++ b/external/README.md
@@ -0,0 +1,3 @@
+# External Projects
+
+External projects bundled with LibreOffice.
diff --git a/external/beanshell/ExternalPackage_beanshell.mk b/external/beanshell/ExternalPackage_beanshell.mk
new file mode 100644
index 000000000..ea22d8394
--- /dev/null
+++ b/external/beanshell/ExternalPackage_beanshell.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,beanshell,beanshell))
+
+$(eval $(call gb_ExternalPackage_use_external_project,beanshell,beanshell))
+
+$(eval $(call gb_ExternalPackage_add_file,beanshell,$(LIBO_SHARE_JAVA_FOLDER)/bsh.jar,dist/bsh-2.0b6.jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/beanshell/ExternalProject_beanshell.mk b/external/beanshell/ExternalProject_beanshell.mk
new file mode 100644
index 000000000..450ac2b70
--- /dev/null
+++ b/external/beanshell/ExternalProject_beanshell.mk
@@ -0,0 +1,30 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,beanshell))
+
+$(eval $(call gb_ExternalProject_register_targets,beanshell,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,beanshell,build) :
+ $(call gb_Trace_StartRange,beanshell,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ $(if $(debug),-Dbuild.debug="on") \
+ )
+ $(call gb_Trace_EndRange,beanshell,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/beanshell/Makefile b/external/beanshell/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/beanshell/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/beanshell/Module_beanshell.mk b/external/beanshell/Module_beanshell.mk
new file mode 100644
index 000000000..14432fd2a
--- /dev/null
+++ b/external/beanshell/Module_beanshell.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,beanshell))
+
+$(eval $(call gb_Module_add_targets,beanshell,\
+ ExternalPackage_beanshell \
+ ExternalProject_beanshell \
+ UnpackedTarball_beanshell \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/beanshell/README b/external/beanshell/README
new file mode 100644
index 000000000..0b03fd35a
--- /dev/null
+++ b/external/beanshell/README
@@ -0,0 +1,4 @@
+Java interpreter from [http://www.beanshell.org/] with some patches.
+
+So you can write java in command shell; interactive java good for prototyping/macros.
+
diff --git a/external/beanshell/UnpackedTarball_beanshell.mk b/external/beanshell/UnpackedTarball_beanshell.mk
new file mode 100644
index 000000000..dc0ce6dc6
--- /dev/null
+++ b/external/beanshell/UnpackedTarball_beanshell.mk
@@ -0,0 +1,24 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,beanshell))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,beanshell,$(BSH_TARBALL),,beanshell))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,beanshell,\
+ engine/src/TestBshScriptEngine.java \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,beanshell,\
+ external/beanshell/bsh-2.0b1-src.patch \
+ external/beanshell/beanshell-invoke.patch \
+ external/beanshell/java9.patch.0 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/beanshell/beanshell-invoke.patch b/external/beanshell/beanshell-invoke.patch
new file mode 100644
index 000000000..b78f1db61
--- /dev/null
+++ b/external/beanshell/beanshell-invoke.patch
@@ -0,0 +1,78 @@
+--- old/beanshell/engine/src/bsh/engine/BshScriptEngine.java
++++ new/beanshell/engine/src/bsh/engine/BshScriptEngine.java
+@@ -229,6 +229,12 @@
+ }
+ }
+
++ public Object invoke( Object thiz, String name, Object... args )
++ throws ScriptException, NoSuchMethodException
++ {
++ return invokeMethod( thiz, name, args );
++ }
++
+ /**
+ * Same as invoke(Object, String, Object...) with <code>null</code> as the
+ * first argument. Used to call top-level procedures defined in scripts.
+@@ -249,6 +255,12 @@
+ return invokeMethod( getGlobal(), name, args );
+ }
+
++ public Object invoke( String name, Object... args )
++ throws ScriptException, NoSuchMethodException
++ {
++ return invokeFunction( name, args );
++ }
++
+ /**
+ * Returns an implementation of an interface using procedures compiled in the
+ * interpreter. The methods of the interface may be implemented using the
+--- old/beanshell/engine/src/TestBshScriptEngine.java
++++ new/beanshell/engine/src/TestBshScriptEngine.java
+@@ -2,11 +2,12 @@
+ import java.io.*;
+ import javax.script.*;
+ import static javax.script.ScriptContext.*;
++import java.lang.reflect.*;
+
+ public class TestBshScriptEngine
+ {
+ public static void main( String [] args )
+- throws ScriptException, NoSuchMethodException, IOException
++ throws ScriptException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, IOException
+ {
+ ScriptEngineManager manager =
+ new ScriptEngineManager( bsh.Interpreter.class.getClassLoader() );
+@@ -39,11 +40,23 @@
+ assertTrue( engine.get("bar").equals("gee") );
+ assertTrue( engine.eval("bar").equals("gee") );
+
++ // use reflection to pick available method
++ Method invokeMe = null;
++ try {
++ invokeMe = Invocable.class.getMethod( "invokeFunction", String.class, Object[].class );
++ } catch ( Exception e ) { }
++ if (invokeMe == null)
++ {
++ try {
++ invokeMe = Invocable.class.getMethod( "invoke", String.class, Object[].class );
++ } catch ( Exception e ) { }
++ }
++
+ // install and invoke a method
+ engine.eval("foo() { return foo+1; }");
+ // invoke a method
+ Invocable invocable = (Invocable) engine;
+- int foo = (Integer)invocable.invokeFunction( "foo" );
++ int foo = (Integer)invokeMe.invoke( invocable, "foo", (Object) new Object[]{} );
+ assertTrue( foo == 43 );
+
+ // get interface
+@@ -58,7 +71,7 @@
+ engine.eval(
+ "flag2=false; myObj() { run() { flag2=true; } return this; }");
+ assertTrue( (Boolean)engine.get("flag2") == false );
+- Object scriptedObject = invocable.invokeFunction("myObj");
++ Object scriptedObject = invokeMe.invoke( invocable, "myObj", (Object) new Object[]{} );
+ assertTrue( scriptedObject instanceof bsh.This );
+ runnable =
+ (Runnable)invocable.getInterface( scriptedObject, Runnable.class );
diff --git a/external/beanshell/bsh-2.0b1-src.patch b/external/beanshell/bsh-2.0b1-src.patch
new file mode 100644
index 000000000..6124f18d1
--- /dev/null
+++ b/external/beanshell/bsh-2.0b1-src.patch
@@ -0,0 +1,50 @@
+--- misc/BeanShell/build.xml Fri Dec 19 17:14:27 2003
++++ misc/build/BeanShell/build.xml Fri Mar 28 15:55:04 2008
+@@ -10,7 +10,7 @@
+ - Why can't I nest filesets? This seems like it would be so easy and
+ useful...
+ -->
+-<project name="beanshell" default="compile" basedir=".">
++<project name="beanshell" default="jarall" basedir=".">
+
+ <!-- Project Configuration -->
+
+@@ -65,6 +65,9 @@
+ <property name="exclude-engine" value="bsh/engine/**"/>
+ -->
+
++ <property name="exclude-bsf"
++ value="bsh/util/BeanShellBSFEngine.java,TestBshBSF.java"/>
++
+ <!-- Uncomment to build without the ASM class generator code.
+ <property name="exclude-classgen"
+ value="bsh/org/objectweb/asm/**,bsh/ClassGeneratorImpl.java,bsh/ClassGeneratorUtil.java,bsh/DelayedEvalBshMethod.java"/>
+@@ -75,6 +78,9 @@
+ value="bsh/servlet/*"/>
+ -->
+
++ <property name="exclude-servlet"
++ value="bsh/servlet/*"/>
++
+ <!-- Legacy excludes. Comment this *out* to build these legacy items -->
+ <property name="excludes-legacy"
+ value="bsh/JThis.java"/>
+--- misc/BeanShell/src/bsh/classpath/BshClassPath.java 2003-12-19 17:14:28.000000000 +0100
++++ misc/build/BeanShell/src/bsh/classpath/BshClassPath.java 2014-07-22 21:02:52.000000000 +0200
+@@ -36,6 +36,7 @@
+ import bsh.StringUtil;
+ import bsh.ClassPathException;
+ import java.lang.ref.WeakReference;
++import java.lang.SecurityException;
+ import bsh.NameSource;
+
+ /**
+@@ -659,6 +660,8 @@
+ URL url = new File( rtjar ).toURI().toURL();
+ bootClassPath = new BshClassPath(
+ "Boot Class Path", new URL[] { url } );
++ } catch ( SecurityException e ) {
++ throw new ClassPathException(" can't access to boot jar: "+e);
+ } catch ( MalformedURLException e ) {
+ throw new ClassPathException(" can't find boot jar: "+e);
+ }
diff --git a/external/beanshell/java9.patch.0 b/external/beanshell/java9.patch.0
new file mode 100644
index 000000000..824e54286
--- /dev/null
+++ b/external/beanshell/java9.patch.0
@@ -0,0 +1,25 @@
+--- build.xml
++++ build.xml
+@@ -176,7 +176,6 @@
+ deprecation="${deprecation}"
+ optimize="on"
+ debug="on"
+- target="1.5"
+ includes="**/*.java"
+ excludes="${excludes},**/bak/**"
+ >
+--- src/bsh/util/AWTConsole.java
++++ src/bsh/util/AWTConsole.java
+@@ -214,8 +214,11 @@
+ Great. What a piece of crap.
+ */
+ public void setCaretPosition( int pos ) {
+- ((java.awt.peer.TextComponentPeer)getPeer()).setCaretPosition(
++ try {
++ ((java.awt.peer.TextComponentPeer)getClass().getMethod("getPeer").invoke(this, null)).setCaretPosition(
+ pos + countNLs() );
++ } catch (Exception e) {
++ }
+ }
+
+ /*
diff --git a/external/bluez_bluetooth/README b/external/bluez_bluetooth/README
new file mode 100644
index 000000000..6668cc4d6
--- /dev/null
+++ b/external/bluez_bluetooth/README
@@ -0,0 +1,4 @@
+Cleaned linux bluez headers.
+
+Originally gotten from:
+http://gitorious.org/0xdroid/system_bluetooth/trees/59ca0be6dc8ef3f30f8f863d8fb805a55bf12fe5/bluez-clean-headers
diff --git a/external/bluez_bluetooth/inc/bluetooth/bluetooth.h b/external/bluez_bluetooth/inc/bluetooth/bluetooth.h
new file mode 100644
index 000000000..a2b88e71b
--- /dev/null
+++ b/external/bluez_bluetooth/inc/bluetooth/bluetooth.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Bluez header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to Android. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __BLUETOOTH_H
+#define __BLUETOOTH_H
+
+#ifdef __cplusplus
+#endif
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <endian.h>
+#include <byteswap.h>
+#ifndef AF_BLUETOOTH
+#define AF_BLUETOOTH 31
+#define PF_BLUETOOTH AF_BLUETOOTH
+#endif
+#ifndef SOL_BLUETOOTH
+#define SOL_BLUETOOTH 274
+#endif
+#define BTPROTO_L2CAP 0
+#define BTPROTO_HCI 1
+#define BTPROTO_SCO 2
+#define BTPROTO_RFCOMM 3
+#define BTPROTO_BNEP 4
+#define BTPROTO_CMTP 5
+#define BTPROTO_HIDP 6
+#define BTPROTO_AVDTP 7
+#define SOL_HCI 0
+#define SOL_L2CAP 6
+#define SOL_SCO 17
+#define SOL_RFCOMM 18
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htobs(d) (d)
+#define htobl(d) (d)
+#define btohs(d) (d)
+#define btohl(d) (d)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define htobs(d) bswap_16(d)
+#define htobl(d) bswap_32(d)
+#define btohs(d) bswap_16(d)
+#define btohl(d) bswap_32(d)
+#else
+#error "Unknown byte order"
+#endif
+#define bt_get_unaligned(ptr) ({ struct __attribute__((packed)) { typeof(*(ptr)) __v; } *__p = (void *) (ptr); __p->__v; })
+#define bt_put_unaligned(val, ptr) do { struct __attribute__((packed)) { typeof(*(ptr)) __v; } *__p = (void *) (ptr); __p->__v = (val); } while(0)
+#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
+#define BDADDR_ALL (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
+#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
+#ifdef __cplusplus
+#endif
+typedef struct
+{
+ uint8_t b[6];
+} __attribute__ ((packed)) bdaddr_t;
+static inline void
+bacpy (bdaddr_t * dst, const bdaddr_t * src)
+{
+ memcpy (dst, src, sizeof (bdaddr_t));
+}
+#endif
diff --git a/external/bluez_bluetooth/inc/bluetooth/hci.h b/external/bluez_bluetooth/inc/bluetooth/hci.h
new file mode 100644
index 000000000..7a5b6ab0a
--- /dev/null
+++ b/external/bluez_bluetooth/inc/bluetooth/hci.h
@@ -0,0 +1,718 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Bluez header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to Android. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __HCI_H
+#define __HCI_H
+
+#ifdef __cplusplus
+#endif
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#define HCI_MAX_DEV 16
+#define HCI_MAX_ACL_SIZE 1024
+#define HCI_MAX_SCO_SIZE 255
+#define HCI_MAX_EVENT_SIZE 260
+#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
+#define HCI_DEV_REG 1
+#define HCI_DEV_UNREG 2
+#define HCI_DEV_UP 3
+#define HCI_DEV_DOWN 4
+#define HCI_DEV_SUSPEND 5
+#define HCI_DEV_RESUME 6
+#define HCI_VIRTUAL 0
+#define HCI_USB 1
+#define HCI_PCCARD 2
+#define HCI_UART 3
+#define HCI_RS232 4
+#define HCI_PCI 5
+#define HCI_SDIO 6
+#define HCIDEVUP _IOW('H', 201, int)
+#define HCIDEVDOWN _IOW('H', 202, int)
+#define HCIDEVRESET _IOW('H', 203, int)
+#define HCIDEVRESTAT _IOW('H', 204, int)
+#define HCIGETDEVLIST _IOR('H', 210, int)
+#define HCIGETDEVINFO _IOR('H', 211, int)
+#define HCIGETCONNLIST _IOR('H', 212, int)
+#define HCIGETCONNINFO _IOR('H', 213, int)
+#define HCIGETAUTHINFO _IOR('H', 215, int)
+#define HCISETRAW _IOW('H', 220, int)
+#define HCISETSCAN _IOW('H', 221, int)
+#define HCISETAUTH _IOW('H', 222, int)
+#define HCISETENCRYPT _IOW('H', 223, int)
+#define HCISETPTYPE _IOW('H', 224, int)
+#define HCISETLINKPOL _IOW('H', 225, int)
+#define HCISETLINKMODE _IOW('H', 226, int)
+#define HCISETACLMTU _IOW('H', 227, int)
+#define HCISETSCOMTU _IOW('H', 228, int)
+#define HCISETSECMGR _IOW('H', 230, int)
+#define HCIINQUIRY _IOR('H', 240, int)
+#ifndef __NO_HCI_DEFS
+#define HCI_COMMAND_PKT 0x01
+#define HCI_ACLDATA_PKT 0x02
+#define HCI_SCODATA_PKT 0x03
+#define HCI_EVENT_PKT 0x04
+#define HCI_VENDOR_PKT 0xff
+#define HCI_2DH1 0x0002
+#define HCI_3DH1 0x0004
+#define HCI_DM1 0x0008
+#define HCI_DH1 0x0010
+#define HCI_2DH3 0x0100
+#define HCI_3DH3 0x0200
+#define HCI_DM3 0x0400
+#define HCI_DH3 0x0800
+#define HCI_2DH5 0x1000
+#define HCI_3DH5 0x2000
+#define HCI_DM5 0x4000
+#define HCI_DH5 0x8000
+#define HCI_HV1 0x0020
+#define HCI_HV2 0x0040
+#define HCI_HV3 0x0080
+#define HCI_EV3 0x0008
+#define HCI_EV4 0x0010
+#define HCI_EV5 0x0020
+#define HCI_2EV3 0x0040
+#define HCI_3EV3 0x0080
+#define HCI_2EV5 0x0100
+#define HCI_3EV5 0x0200
+#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
+#define ACL_PTYPE_MASK (HCI_DM1 | HCI_DH1 | HCI_DM3 | HCI_DH3 | HCI_DM5 | HCI_DH5)
+#define ESCO_HV1 0x0001
+#define ESCO_HV2 0x0002
+#define ESCO_HV3 0x0004
+#define ESCO_EV3 0x0008
+#define ESCO_EV4 0x0010
+#define ESCO_EV5 0x0020
+#define ESCO_2EV3 0x0040
+#define ESCO_3EV3 0x0080
+#define ESCO_2EV5 0x0100
+#define ESCO_3EV5 0x0200
+#define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3)
+#define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5)
+#define ALL_ESCO_MASK (SCO_ESCO_MASK | ESCO_EV3 | ESCO_EV4 | ESCO_EV5 | EDR_ESCO_MASK)
+#define HCI_UNKNOWN_COMMAND 0x01
+#define HCI_NO_CONNECTION 0x02
+#define HCI_HARDWARE_FAILURE 0x03
+#define HCI_PAGE_TIMEOUT 0x04
+#define HCI_AUTHENTICATION_FAILURE 0x05
+#define HCI_PIN_OR_KEY_MISSING 0x06
+#define HCI_MEMORY_FULL 0x07
+#define HCI_CONNECTION_TIMEOUT 0x08
+#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09
+#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a
+#define HCI_ACL_CONNECTION_EXISTS 0x0b
+#define HCI_COMMAND_DISALLOWED 0x0c
+#define HCI_REJECTED_LIMITED_RESOURCES 0x0d
+#define HCI_REJECTED_SECURITY 0x0e
+#define HCI_REJECTED_PERSONAL 0x0f
+#define HCI_HOST_TIMEOUT 0x10
+#define HCI_UNSUPPORTED_FEATURE 0x11
+#define HCI_INVALID_PARAMETERS 0x12
+#define HCI_OE_USER_ENDED_CONNECTION 0x13
+#define HCI_OE_LOW_RESOURCES 0x14
+#define HCI_OE_POWER_OFF 0x15
+#define HCI_CONNECTION_TERMINATED 0x16
+#define HCI_REPEATED_ATTEMPTS 0x17
+#define HCI_PAIRING_NOT_ALLOWED 0x18
+#define HCI_UNKNOWN_LMP_PDU 0x19
+#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a
+#define HCI_SCO_OFFSET_REJECTED 0x1b
+#define HCI_SCO_INTERVAL_REJECTED 0x1c
+#define HCI_AIR_MODE_REJECTED 0x1d
+#define HCI_INVALID_LMP_PARAMETERS 0x1e
+#define HCI_UNSPECIFIED_ERROR 0x1f
+#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20
+#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21
+#define HCI_LMP_RESPONSE_TIMEOUT 0x22
+#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23
+#define HCI_LMP_PDU_NOT_ALLOWED 0x24
+#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25
+#define HCI_UNIT_LINK_KEY_USED 0x26
+#define HCI_QOS_NOT_SUPPORTED 0x27
+#define HCI_INSTANT_PASSED 0x28
+#define HCI_PAIRING_NOT_SUPPORTED 0x29
+#define HCI_TRANSACTION_COLLISION 0x2a
+#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c
+#define HCI_QOS_REJECTED 0x2d
+#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e
+#define HCI_INSUFFICIENT_SECURITY 0x2f
+#define HCI_PARAMETER_OUT_OF_RANGE 0x30
+#define HCI_ROLE_SWITCH_PENDING 0x32
+#define HCI_SLOT_VIOLATION 0x34
+#define HCI_ROLE_SWITCH_FAILED 0x35
+#define HCI_EIR_TOO_LARGE 0x36
+#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37
+#define HCI_HOST_BUSY_PAIRING 0x38
+#define ACL_CONT 0x01
+#define ACL_START 0x02
+#define ACL_ACTIVE_BCAST 0x04
+#define ACL_PICO_BCAST 0x08
+#define SCO_LINK 0x00
+#define ACL_LINK 0x01
+#define ESCO_LINK 0x02
+#define LMP_3SLOT 0x01
+#define LMP_5SLOT 0x02
+#define LMP_ENCRYPT 0x04
+#define LMP_SOFFSET 0x08
+#define LMP_TACCURACY 0x10
+#define LMP_RSWITCH 0x20
+#define LMP_HOLD 0x40
+#define LMP_SNIFF 0x80
+#define LMP_PARK 0x01
+#define LMP_RSSI 0x02
+#define LMP_QUALITY 0x04
+#define LMP_SCO 0x08
+#define LMP_HV2 0x10
+#define LMP_HV3 0x20
+#define LMP_ULAW 0x40
+#define LMP_ALAW 0x80
+#define LMP_CVSD 0x01
+#define LMP_PSCHEME 0x02
+#define LMP_PCONTROL 0x04
+#define LMP_TRSP_SCO 0x08
+#define LMP_BCAST_ENC 0x80
+#define LMP_EDR_ACL_2M 0x02
+#define LMP_EDR_ACL_3M 0x04
+#define LMP_ENH_ISCAN 0x08
+#define LMP_ILACE_ISCAN 0x10
+#define LMP_ILACE_PSCAN 0x20
+#define LMP_RSSI_INQ 0x40
+#define LMP_ESCO 0x80
+#define LMP_EV4 0x01
+#define LMP_EV5 0x02
+#define LMP_AFH_CAP_SLV 0x08
+#define LMP_AFH_CLS_SLV 0x10
+#define LMP_EDR_3SLOT 0x80
+#define LMP_EDR_5SLOT 0x01
+#define LMP_SNIFF_SUBR 0x02
+#define LMP_PAUSE_ENC 0x04
+#define LMP_AFH_CAP_MST 0x08
+#define LMP_AFH_CLS_MST 0x10
+#define LMP_EDR_ESCO_2M 0x20
+#define LMP_EDR_ESCO_3M 0x40
+#define LMP_EDR_3S_ESCO 0x80
+#define LMP_EXT_INQ 0x01
+#define LMP_SIMPLE_PAIR 0x08
+#define LMP_ENCAPS_PDU 0x10
+#define LMP_ERR_DAT_REP 0x20
+#define LMP_NFLUSH_PKTS 0x40
+#define LMP_LSTO 0x01
+#define LMP_INQ_TX_PWR 0x02
+#define LMP_EXT_FEAT 0x80
+#define HCI_LP_RSWITCH 0x0001
+#define HCI_LP_HOLD 0x0002
+#define HCI_LP_SNIFF 0x0004
+#define HCI_LP_PARK 0x0008
+#define HCI_LM_ACCEPT 0x8000
+#define HCI_LM_MASTER 0x0001
+#define HCI_LM_AUTH 0x0002
+#define HCI_LM_ENCRYPT 0x0004
+#define HCI_LM_TRUSTED 0x0008
+#define HCI_LM_RELIABLE 0x0010
+#define HCI_LM_SECURE 0x0020
+#define OGF_LINK_CTL 0x01
+#define OCF_INQUIRY 0x0001
+#define INQUIRY_CP_SIZE 5
+#define STATUS_BDADDR_RP_SIZE 7
+#define OCF_INQUIRY_CANCEL 0x0002
+#define OCF_PERIODIC_INQUIRY 0x0003
+#define PERIODIC_INQUIRY_CP_SIZE 9
+#define OCF_EXIT_PERIODIC_INQUIRY 0x0004
+#define OCF_CREATE_CONN 0x0005
+#define CREATE_CONN_CP_SIZE 13
+#define OCF_DISCONNECT 0x0006
+#define DISCONNECT_CP_SIZE 3
+#define OCF_ADD_SCO 0x0007
+#define ADD_SCO_CP_SIZE 4
+#define OCF_CREATE_CONN_CANCEL 0x0008
+#define CREATE_CONN_CANCEL_CP_SIZE 6
+#define OCF_ACCEPT_CONN_REQ 0x0009
+#define ACCEPT_CONN_REQ_CP_SIZE 7
+#define OCF_REJECT_CONN_REQ 0x000A
+#define REJECT_CONN_REQ_CP_SIZE 7
+#define OCF_LINK_KEY_REPLY 0x000B
+#define LINK_KEY_REPLY_CP_SIZE 22
+#define OCF_LINK_KEY_NEG_REPLY 0x000C
+#define OCF_PIN_CODE_REPLY 0x000D
+#define PIN_CODE_REPLY_CP_SIZE 23
+#define OCF_PIN_CODE_NEG_REPLY 0x000E
+#define OCF_SET_CONN_PTYPE 0x000F
+#define SET_CONN_PTYPE_CP_SIZE 4
+#define OCF_AUTH_REQUESTED 0x0011
+#define AUTH_REQUESTED_CP_SIZE 2
+#define OCF_SET_CONN_ENCRYPT 0x0013
+#define SET_CONN_ENCRYPT_CP_SIZE 3
+#define OCF_CHANGE_CONN_LINK_KEY 0x0015
+#define CHANGE_CONN_LINK_KEY_CP_SIZE 2
+#define OCF_MASTER_LINK_KEY 0x0017
+#define MASTER_LINK_KEY_CP_SIZE 1
+#define OCF_REMOTE_NAME_REQ 0x0019
+#define REMOTE_NAME_REQ_CP_SIZE 10
+#define OCF_REMOTE_NAME_REQ_CANCEL 0x001A
+#define REMOTE_NAME_REQ_CANCEL_CP_SIZE 6
+#define OCF_READ_REMOTE_FEATURES 0x001B
+#define READ_REMOTE_FEATURES_CP_SIZE 2
+#define OCF_READ_REMOTE_EXT_FEATURES 0x001C
+#define READ_REMOTE_EXT_FEATURES_CP_SIZE 3
+#define OCF_READ_REMOTE_VERSION 0x001D
+#define READ_REMOTE_VERSION_CP_SIZE 2
+#define OCF_READ_CLOCK_OFFSET 0x001F
+#define READ_CLOCK_OFFSET_CP_SIZE 2
+#define OCF_READ_LMP_HANDLE 0x0020
+#define OCF_SETUP_SYNC_CONN 0x0028
+#define SETUP_SYNC_CONN_CP_SIZE 17
+#define OCF_ACCEPT_SYNC_CONN_REQ 0x0029
+#define ACCEPT_SYNC_CONN_REQ_CP_SIZE 21
+#define OCF_REJECT_SYNC_CONN_REQ 0x002A
+#define REJECT_SYNC_CONN_REQ_CP_SIZE 7
+#define OCF_IO_CAPABILITY_REPLY 0x002B
+#define IO_CAPABILITY_REPLY_CP_SIZE 9
+#define OCF_USER_CONFIRM_REPLY 0x002C
+#define USER_CONFIRM_REPLY_CP_SIZE 6
+#define OCF_USER_CONFIRM_NEG_REPLY 0x002D
+#define OCF_USER_PASSKEY_REPLY 0x002E
+#define USER_PASSKEY_REPLY_CP_SIZE 10
+#define OCF_USER_PASSKEY_NEG_REPLY 0x002F
+#define OCF_REMOTE_OOB_DATA_REPLY 0x0030
+#define REMOTE_OOB_DATA_REPLY_CP_SIZE 38
+#define OCF_REMOTE_OOB_DATA_NEG_REPLY 0x0033
+#define OCF_IO_CAPABILITY_NEG_REPLY 0x0034
+#define IO_CAPABILITY_NEG_REPLY_CP_SIZE 7
+#define OGF_LINK_POLICY 0x02
+#define OCF_HOLD_MODE 0x0001
+#define HOLD_MODE_CP_SIZE 6
+#define OCF_SNIFF_MODE 0x0003
+#define SNIFF_MODE_CP_SIZE 10
+#define OCF_EXIT_SNIFF_MODE 0x0004
+#define EXIT_SNIFF_MODE_CP_SIZE 2
+#define OCF_PARK_MODE 0x0005
+#define PARK_MODE_CP_SIZE 6
+#define OCF_EXIT_PARK_MODE 0x0006
+#define EXIT_PARK_MODE_CP_SIZE 2
+#define OCF_QOS_SETUP 0x0007
+#define HCI_QOS_CP_SIZE 17
+#define QOS_SETUP_CP_SIZE (3 + HCI_QOS_CP_SIZE)
+#define OCF_ROLE_DISCOVERY 0x0009
+#define ROLE_DISCOVERY_CP_SIZE 2
+#define ROLE_DISCOVERY_RP_SIZE 4
+#define OCF_SWITCH_ROLE 0x000B
+#define SWITCH_ROLE_CP_SIZE 7
+#define OCF_READ_LINK_POLICY 0x000C
+#define READ_LINK_POLICY_CP_SIZE 2
+#define READ_LINK_POLICY_RP_SIZE 5
+#define OCF_WRITE_LINK_POLICY 0x000D
+#define WRITE_LINK_POLICY_CP_SIZE 4
+#define WRITE_LINK_POLICY_RP_SIZE 3
+#define OCF_READ_DEFAULT_LINK_POLICY 0x000E
+#define OCF_WRITE_DEFAULT_LINK_POLICY 0x000F
+#define OCF_FLOW_SPECIFICATION 0x0010
+#define OCF_SNIFF_SUBRATING 0x0011
+#define SNIFF_SUBRATING_CP_SIZE 8
+#define OGF_HOST_CTL 0x03
+#define OCF_SET_EVENT_MASK 0x0001
+#define SET_EVENT_MASK_CP_SIZE 8
+#define OCF_RESET 0x0003
+#define OCF_SET_EVENT_FLT 0x0005
+#define SET_EVENT_FLT_CP_SIZE 2
+#define FLT_CLEAR_ALL 0x00
+#define FLT_INQ_RESULT 0x01
+#define FLT_CONN_SETUP 0x02
+#define INQ_RESULT_RETURN_ALL 0x00
+#define INQ_RESULT_RETURN_CLASS 0x01
+#define INQ_RESULT_RETURN_BDADDR 0x02
+#define CONN_SETUP_ALLOW_ALL 0x00
+#define CONN_SETUP_ALLOW_CLASS 0x01
+#define CONN_SETUP_ALLOW_BDADDR 0x02
+#define CONN_SETUP_AUTO_OFF 0x01
+#define CONN_SETUP_AUTO_ON 0x02
+#define OCF_FLUSH 0x0008
+#define OCF_READ_PIN_TYPE 0x0009
+#define READ_PIN_TYPE_RP_SIZE 2
+#define OCF_WRITE_PIN_TYPE 0x000A
+#define WRITE_PIN_TYPE_CP_SIZE 1
+#define OCF_CREATE_NEW_UNIT_KEY 0x000B
+#define OCF_READ_STORED_LINK_KEY 0x000D
+#define READ_STORED_LINK_KEY_CP_SIZE 7
+#define READ_STORED_LINK_KEY_RP_SIZE 5
+#define OCF_WRITE_STORED_LINK_KEY 0x0011
+#define WRITE_STORED_LINK_KEY_CP_SIZE 1
+#define READ_WRITE_LINK_KEY_RP_SIZE 2
+#define OCF_DELETE_STORED_LINK_KEY 0x0012
+#define DELETE_STORED_LINK_KEY_CP_SIZE 7
+#define DELETE_STORED_LINK_KEY_RP_SIZE 3
+#define OCF_CHANGE_LOCAL_NAME 0x0013
+#define CHANGE_LOCAL_NAME_CP_SIZE 248
+#define OCF_READ_LOCAL_NAME 0x0014
+#define READ_LOCAL_NAME_RP_SIZE 249
+#define OCF_READ_CONN_ACCEPT_TIMEOUT 0x0015
+#define READ_CONN_ACCEPT_TIMEOUT_RP_SIZE 3
+#define OCF_WRITE_CONN_ACCEPT_TIMEOUT 0x0016
+#define WRITE_CONN_ACCEPT_TIMEOUT_CP_SIZE 2
+#define OCF_READ_PAGE_TIMEOUT 0x0017
+#define READ_PAGE_TIMEOUT_RP_SIZE 3
+#define OCF_WRITE_PAGE_TIMEOUT 0x0018
+#define WRITE_PAGE_TIMEOUT_CP_SIZE 2
+#define OCF_READ_SCAN_ENABLE 0x0019
+#define READ_SCAN_ENABLE_RP_SIZE 2
+#define OCF_WRITE_SCAN_ENABLE 0x001A
+#define SCAN_DISABLED 0x00
+#define SCAN_INQUIRY 0x01
+#define SCAN_PAGE 0x02
+#define OCF_READ_PAGE_ACTIVITY 0x001B
+#define READ_PAGE_ACTIVITY_RP_SIZE 5
+#define OCF_WRITE_PAGE_ACTIVITY 0x001C
+#define WRITE_PAGE_ACTIVITY_CP_SIZE 4
+#define OCF_READ_INQ_ACTIVITY 0x001D
+#define READ_INQ_ACTIVITY_RP_SIZE 5
+#define OCF_WRITE_INQ_ACTIVITY 0x001E
+#define WRITE_INQ_ACTIVITY_CP_SIZE 4
+#define OCF_READ_AUTH_ENABLE 0x001F
+#define OCF_WRITE_AUTH_ENABLE 0x0020
+#define AUTH_DISABLED 0x00
+#define AUTH_ENABLED 0x01
+#define OCF_READ_ENCRYPT_MODE 0x0021
+#define OCF_WRITE_ENCRYPT_MODE 0x0022
+#define ENCRYPT_DISABLED 0x00
+#define ENCRYPT_P2P 0x01
+#define ENCRYPT_BOTH 0x02
+#define OCF_READ_CLASS_OF_DEV 0x0023
+#define READ_CLASS_OF_DEV_RP_SIZE 4
+#define OCF_WRITE_CLASS_OF_DEV 0x0024
+#define WRITE_CLASS_OF_DEV_CP_SIZE 3
+#define OCF_READ_VOICE_SETTING 0x0025
+#define READ_VOICE_SETTING_RP_SIZE 3
+#define OCF_WRITE_VOICE_SETTING 0x0026
+#define WRITE_VOICE_SETTING_CP_SIZE 2
+#define OCF_READ_AUTOMATIC_FLUSH_TIMEOUT 0x0027
+#define OCF_WRITE_AUTOMATIC_FLUSH_TIMEOUT 0x0028
+#define OCF_READ_NUM_BROADCAST_RETRANS 0x0029
+#define OCF_WRITE_NUM_BROADCAST_RETRANS 0x002A
+#define OCF_READ_HOLD_MODE_ACTIVITY 0x002B
+#define OCF_WRITE_HOLD_MODE_ACTIVITY 0x002C
+#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D
+#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3
+#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4
+#define OCF_READ_SYNC_FLOW_ENABLE 0x002E
+#define OCF_WRITE_SYNC_FLOW_ENABLE 0x002F
+#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031
+#define OCF_HOST_BUFFER_SIZE 0x0033
+#define HOST_BUFFER_SIZE_CP_SIZE 7
+#define OCF_HOST_NUM_COMP_PKTS 0x0035
+#define HOST_NUM_COMP_PKTS_CP_SIZE 1
+#define OCF_READ_LINK_SUPERVISION_TIMEOUT 0x0036
+#define READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE 5
+#define OCF_WRITE_LINK_SUPERVISION_TIMEOUT 0x0037
+#define WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE 4
+#define WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE 3
+#define OCF_READ_NUM_SUPPORTED_IAC 0x0038
+#define MAX_IAC_LAP 0x40
+#define OCF_READ_CURRENT_IAC_LAP 0x0039
+#define READ_CURRENT_IAC_LAP_RP_SIZE 2 + 3 * MAX_IAC_LAP
+#define OCF_WRITE_CURRENT_IAC_LAP 0x003A
+#define WRITE_CURRENT_IAC_LAP_CP_SIZE 1 + 3 * MAX_IAC_LAP
+#define OCF_READ_PAGE_SCAN_PERIOD_MODE 0x003B
+#define OCF_WRITE_PAGE_SCAN_PERIOD_MODE 0x003C
+#define OCF_READ_PAGE_SCAN_MODE 0x003D
+#define OCF_WRITE_PAGE_SCAN_MODE 0x003E
+#define OCF_SET_AFH_CLASSIFICATION 0x003F
+#define SET_AFH_CLASSIFICATION_CP_SIZE 10
+#define SET_AFH_CLASSIFICATION_RP_SIZE 1
+#define OCF_READ_INQUIRY_SCAN_TYPE 0x0042
+#define READ_INQUIRY_SCAN_TYPE_RP_SIZE 2
+#define OCF_WRITE_INQUIRY_SCAN_TYPE 0x0043
+#define WRITE_INQUIRY_SCAN_TYPE_CP_SIZE 1
+#define WRITE_INQUIRY_SCAN_TYPE_RP_SIZE 1
+#define OCF_READ_INQUIRY_MODE 0x0044
+#define READ_INQUIRY_MODE_RP_SIZE 2
+#define OCF_WRITE_INQUIRY_MODE 0x0045
+#define WRITE_INQUIRY_MODE_CP_SIZE 1
+#define WRITE_INQUIRY_MODE_RP_SIZE 1
+#define OCF_READ_PAGE_SCAN_TYPE 0x0046
+#define OCF_WRITE_PAGE_SCAN_TYPE 0x0047
+#define OCF_READ_AFH_MODE 0x0048
+#define READ_AFH_MODE_RP_SIZE 2
+#define OCF_WRITE_AFH_MODE 0x0049
+#define WRITE_AFH_MODE_CP_SIZE 1
+#define WRITE_AFH_MODE_RP_SIZE 1
+#define OCF_READ_EXT_INQUIRY_RESPONSE 0x0051
+#define READ_EXT_INQUIRY_RESPONSE_RP_SIZE 242
+#define OCF_WRITE_EXT_INQUIRY_RESPONSE 0x0052
+#define WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE 241
+#define WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE 1
+#define OCF_REFRESH_ENCRYPTION_KEY 0x0053
+#define REFRESH_ENCRYPTION_KEY_CP_SIZE 2
+#define REFRESH_ENCRYPTION_KEY_RP_SIZE 1
+#define OCF_READ_SIMPLE_PAIRING_MODE 0x0055
+#define READ_SIMPLE_PAIRING_MODE_RP_SIZE 2
+#define OCF_WRITE_SIMPLE_PAIRING_MODE 0x0056
+#define WRITE_SIMPLE_PAIRING_MODE_CP_SIZE 1
+#define WRITE_SIMPLE_PAIRING_MODE_RP_SIZE 1
+#define OCF_READ_LOCAL_OOB_DATA 0x0057
+#define READ_LOCAL_OOB_DATA_RP_SIZE 33
+#define OCF_READ_INQUIRY_TRANSMIT_POWER_LEVEL 0x0058
+#define READ_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE 2
+#define OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL 0x0059
+#define WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_CP_SIZE 1
+#define WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE 1
+#define OCF_READ_DEFAULT_ERROR_DATA_REPORTING 0x005A
+#define READ_DEFAULT_ERROR_DATA_REPORTING_RP_SIZE 2
+#define OCF_WRITE_DEFAULT_ERROR_DATA_REPORTING 0x005B
+#define WRITE_DEFAULT_ERROR_DATA_REPORTING_CP_SIZE 1
+#define WRITE_DEFAULT_ERROR_DATA_REPORTING_RP_SIZE 1
+#define OCF_ENHANCED_FLUSH 0x005F
+#define ENHANCED_FLUSH_CP_SIZE 3
+#define OCF_SEND_KEYPRESS_NOTIFY 0x0060
+#define SEND_KEYPRESS_NOTIFY_CP_SIZE 7
+#define SEND_KEYPRESS_NOTIFY_RP_SIZE 1
+#define OGF_INFO_PARAM 0x04
+#define OCF_READ_LOCAL_VERSION 0x0001
+#define READ_LOCAL_VERSION_RP_SIZE 9
+#define OCF_READ_LOCAL_COMMANDS 0x0002
+#define READ_LOCAL_COMMANDS_RP_SIZE 65
+#define OCF_READ_LOCAL_FEATURES 0x0003
+#define READ_LOCAL_FEATURES_RP_SIZE 9
+#define OCF_READ_LOCAL_EXT_FEATURES 0x0004
+#define READ_LOCAL_EXT_FEATURES_CP_SIZE 1
+#define READ_LOCAL_EXT_FEATURES_RP_SIZE 11
+#define OCF_READ_BUFFER_SIZE 0x0005
+#define READ_BUFFER_SIZE_RP_SIZE 8
+#define OCF_READ_COUNTRY_CODE 0x0007
+#define OCF_READ_BD_ADDR 0x0009
+#define READ_BD_ADDR_RP_SIZE 7
+#define OGF_STATUS_PARAM 0x05
+#define OCF_READ_FAILED_CONTACT_COUNTER 0x0001
+#define READ_FAILED_CONTACT_COUNTER_RP_SIZE 4
+#define OCF_RESET_FAILED_CONTACT_COUNTER 0x0002
+#define RESET_FAILED_CONTACT_COUNTER_RP_SIZE 4
+#define OCF_READ_LINK_QUALITY 0x0003
+#define READ_LINK_QUALITY_RP_SIZE 4
+#define OCF_READ_RSSI 0x0005
+#define READ_RSSI_RP_SIZE 4
+#define OCF_READ_AFH_MAP 0x0006
+#define READ_AFH_MAP_RP_SIZE 14
+#define OCF_READ_CLOCK 0x0007
+#define READ_CLOCK_CP_SIZE 3
+#define READ_CLOCK_RP_SIZE 9
+#define OGF_TESTING_CMD 0x3e
+#define OCF_READ_LOOPBACK_MODE 0x0001
+#define OCF_WRITE_LOOPBACK_MODE 0x0002
+#define OCF_ENABLE_DEVICE_UNDER_TEST_MODE 0x0003
+#define OCF_WRITE_SIMPLE_PAIRING_DEBUG_MODE 0x0004
+#define WRITE_SIMPLE_PAIRING_DEBUG_MODE_CP_SIZE 1
+#define WRITE_SIMPLE_PAIRING_DEBUG_MODE_RP_SIZE 1
+#define OGF_VENDOR_CMD 0x3f
+#define EVT_INQUIRY_COMPLETE 0x01
+#define EVT_INQUIRY_RESULT 0x02
+#define INQUIRY_INFO_SIZE 14
+#define EVT_CONN_COMPLETE 0x03
+#define EVT_CONN_COMPLETE_SIZE 13
+#define EVT_CONN_REQUEST 0x04
+#define EVT_CONN_REQUEST_SIZE 10
+#define EVT_DISCONN_COMPLETE 0x05
+#define EVT_DISCONN_COMPLETE_SIZE 4
+#define EVT_AUTH_COMPLETE 0x06
+#define EVT_AUTH_COMPLETE_SIZE 3
+#define EVT_REMOTE_NAME_REQ_COMPLETE 0x07
+#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
+#define EVT_ENCRYPT_CHANGE 0x08
+#define EVT_ENCRYPT_CHANGE_SIZE 5
+#define EVT_CHANGE_CONN_LINK_KEY_COMPLETE 0x09
+#define EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE 3
+#define EVT_MASTER_LINK_KEY_COMPLETE 0x0A
+#define EVT_MASTER_LINK_KEY_COMPLETE_SIZE 4
+#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B
+#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
+#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C
+#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
+#define EVT_QOS_SETUP_COMPLETE 0x0D
+#define EVT_QOS_SETUP_COMPLETE_SIZE (4 + HCI_QOS_CP_SIZE)
+#define EVT_CMD_COMPLETE 0x0E
+#define EVT_CMD_COMPLETE_SIZE 3
+#define EVT_CMD_STATUS 0x0F
+#define EVT_CMD_STATUS_SIZE 4
+#define EVT_HARDWARE_ERROR 0x10
+#define EVT_HARDWARE_ERROR_SIZE 1
+#define EVT_FLUSH_OCCURRED 0x11
+#define EVT_FLUSH_OCCURRED_SIZE 2
+#define EVT_ROLE_CHANGE 0x12
+#define EVT_ROLE_CHANGE_SIZE 8
+#define EVT_NUM_COMP_PKTS 0x13
+#define EVT_NUM_COMP_PKTS_SIZE 1
+#define EVT_MODE_CHANGE 0x14
+#define EVT_MODE_CHANGE_SIZE 6
+#define EVT_RETURN_LINK_KEYS 0x15
+#define EVT_RETURN_LINK_KEYS_SIZE 1
+#define EVT_PIN_CODE_REQ 0x16
+#define EVT_PIN_CODE_REQ_SIZE 6
+#define EVT_LINK_KEY_REQ 0x17
+#define EVT_LINK_KEY_REQ_SIZE 6
+#define EVT_LINK_KEY_NOTIFY 0x18
+#define EVT_LINK_KEY_NOTIFY_SIZE 23
+#define EVT_LOOPBACK_COMMAND 0x19
+#define EVT_DATA_BUFFER_OVERFLOW 0x1A
+#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1
+#define EVT_MAX_SLOTS_CHANGE 0x1B
+#define EVT_MAX_SLOTS_CHANGE_SIZE 3
+#define EVT_READ_CLOCK_OFFSET_COMPLETE 0x1C
+#define EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE 5
+#define EVT_CONN_PTYPE_CHANGED 0x1D
+#define EVT_CONN_PTYPE_CHANGED_SIZE 5
+#define EVT_QOS_VIOLATION 0x1E
+#define EVT_QOS_VIOLATION_SIZE 2
+#define EVT_PSCAN_REP_MODE_CHANGE 0x20
+#define EVT_PSCAN_REP_MODE_CHANGE_SIZE 7
+#define EVT_FLOW_SPEC_COMPLETE 0x21
+#define EVT_FLOW_SPEC_COMPLETE_SIZE (5 + HCI_QOS_CP_SIZE)
+#define EVT_INQUIRY_RESULT_WITH_RSSI 0x22
+#define INQUIRY_INFO_WITH_RSSI_SIZE 14
+#define INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE 15
+#define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE 0x23
+#define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE 13
+#define EVT_SYNC_CONN_COMPLETE 0x2C
+#define EVT_SYNC_CONN_COMPLETE_SIZE 17
+#define EVT_SYNC_CONN_CHANGED 0x2D
+#define EVT_SYNC_CONN_CHANGED_SIZE 9
+#define EVT_SNIFF_SUBRATING 0x2E
+#define EVT_SNIFF_SUBRATING_SIZE 11
+#define EVT_EXTENDED_INQUIRY_RESULT 0x2F
+#define EXTENDED_INQUIRY_INFO_SIZE 254
+#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30
+#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3
+#define EVT_IO_CAPABILITY_REQUEST 0x31
+#define EVT_IO_CAPABILITY_REQUEST_SIZE 6
+#define EVT_IO_CAPABILITY_RESPONSE 0x32
+#define EVT_IO_CAPABILITY_RESPONSE_SIZE 9
+#define EVT_USER_CONFIRM_REQUEST 0x33
+#define EVT_USER_CONFIRM_REQUEST_SIZE 10
+#define EVT_USER_PASSKEY_REQUEST 0x34
+#define EVT_USER_PASSKEY_REQUEST_SIZE 6
+#define EVT_REMOTE_OOB_DATA_REQUEST 0x35
+#define EVT_REMOTE_OOB_DATA_REQUEST_SIZE 6
+#define EVT_SIMPLE_PAIRING_COMPLETE 0x36
+#define EVT_SIMPLE_PAIRING_COMPLETE_SIZE 7
+#define EVT_LINK_SUPERVISION_TIMEOUT_CHANGED 0x38
+#define EVT_LINK_SUPERVISION_TIMEOUT_CHANGED_SIZE 4
+#define EVT_ENHANCED_FLUSH_COMPLETE 0x39
+#define EVT_ENHANCED_FLUSH_COMPLETE_SIZE 2
+#define EVT_USER_PASSKEY_NOTIFY 0x3B
+#define EVT_USER_PASSKEY_NOTIFY_SIZE 10
+#define EVT_KEYPRESS_NOTIFY 0x3C
+#define EVT_KEYPRESS_NOTIFY_SIZE 7
+#define EVT_REMOTE_HOST_FEATURES_NOTIFY 0x3D
+#define EVT_REMOTE_HOST_FEATURES_NOTIFY_SIZE 14
+#define EVT_TESTING 0xFE
+#define EVT_VENDOR 0xFF
+#define EVT_STACK_INTERNAL 0xFD
+#define EVT_STACK_INTERNAL_SIZE 2
+#define EVT_SI_DEVICE 0x01
+#define EVT_SI_DEVICE_SIZE 4
+#define EVT_SI_SECURITY 0x02
+#define HCI_TYPE_LEN 1
+#define HCI_COMMAND_HDR_SIZE 3
+#define HCI_EVENT_HDR_SIZE 2
+#define HCI_ACL_HDR_SIZE 4
+#define HCI_SCO_HDR_SIZE 3
+#define HCI_MSG_HDR_SIZE 6
+#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff) | (ogf << 10))
+#define cmd_opcode_ogf(op) (op >> 10)
+#define cmd_opcode_ocf(op) (op & 0x03ff)
+#define acl_handle_pack(h, f) (uint16_t)((h & 0x0fff) | (f << 12))
+#define acl_handle(h) (h & 0x0fff)
+#define acl_flags(h) (h >> 12)
+#endif
+#define HCI_DATA_DIR 1
+#define HCI_FILTER 2
+#define HCI_TIME_STAMP 3
+#define HCI_CMSG_DIR 0x0001
+#define HCI_CMSG_TSTAMP 0x0002
+#define HCI_DEV_NONE 0xffff
+#define HCI_FLT_TYPE_BITS 31
+#define HCI_FLT_EVENT_BITS 63
+#define HCI_FLT_OGF_BITS 63
+#define HCI_FLT_OCF_BITS 127
+#define IREQ_CACHE_FLUSH 0x0001
+#ifdef __cplusplus
+#endif
+struct hci_dev_stats
+{
+ uint32_t err_rx;
+ uint32_t err_tx;
+ uint32_t cmd_tx;
+ uint32_t evt_rx;
+ uint32_t acl_tx;
+ uint32_t acl_rx;
+ uint32_t sco_tx;
+ uint32_t sco_rx;
+ uint32_t byte_rx;
+ uint32_t byte_tx;
+};
+struct hci_dev_info
+{
+ uint16_t dev_id;
+ char name[8];
+
+ bdaddr_t bdaddr;
+
+ uint32_t flags;
+ uint8_t type;
+
+ uint8_t features[8];
+
+ uint32_t pkt_type;
+ uint32_t link_policy;
+ uint32_t link_mode;
+
+ uint16_t acl_mtu;
+ uint16_t acl_pkts;
+ uint16_t sco_mtu;
+ uint16_t sco_pkts;
+
+ struct hci_dev_stats stat;
+};
+enum
+{
+ HCI_UP,
+ HCI_INIT,
+ HCI_RUNNING,
+
+ HCI_PSCAN,
+ HCI_ISCAN,
+ HCI_AUTH,
+ HCI_ENCRYPT,
+ HCI_INQUIRY,
+
+ HCI_RAW,
+
+ HCI_SECMGR
+};
+struct sockaddr_hci
+{
+ sa_family_t hci_family;
+ unsigned short hci_dev;
+};
+struct hci_conn_info
+{
+ uint16_t handle;
+ bdaddr_t bdaddr;
+ uint8_t type;
+ uint8_t out;
+ uint16_t state;
+ uint32_t link_mode;
+ uint32_t mtu;
+ uint32_t cnt;
+ uint32_t pkts;
+};
+struct hci_conn_list_req
+{
+ uint16_t dev_id;
+ uint16_t conn_num;
+ struct hci_conn_info conn_info[0];
+};
+#endif
diff --git a/external/bluez_bluetooth/inc/bluetooth/hci_lib.h b/external/bluez_bluetooth/inc/bluetooth/hci_lib.h
new file mode 100644
index 000000000..d6886c146
--- /dev/null
+++ b/external/bluez_bluetooth/inc/bluetooth/hci_lib.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Bluez header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to Android. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __HCI_LIB_H
+#define __HCI_LIB_H
+
+#ifdef __cplusplus
+#endif
+#ifdef __cplusplus
+#endif
+static inline int hci_test_bit(int nr, void* addr)
+{
+ return *((uint32_t*)addr + (nr >> 5)) & (1 << (nr & 31));
+}
+#endif
diff --git a/external/bluez_bluetooth/inc/bluetooth/l2cap.h b/external/bluez_bluetooth/inc/bluetooth/l2cap.h
new file mode 100644
index 000000000..514c16eb2
--- /dev/null
+++ b/external/bluez_bluetooth/inc/bluetooth/l2cap.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __L2CAP_H
+#define __L2CAP_H
+
+#ifdef __cplusplus
+#endif
+#include <sys/socket.h>
+#define L2CAP_DEFAULT_MTU 672
+#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
+#define L2CAP_CONN_TIMEOUT (HZ * 40)
+#define L2CAP_OPTIONS 0x01
+#define L2CAP_CONNINFO 0x02
+#define L2CAP_LM 0x03
+#define L2CAP_LM_MASTER 0x0001
+#define L2CAP_LM_AUTH 0x0002
+#define L2CAP_LM_ENCRYPT 0x0004
+#define L2CAP_LM_TRUSTED 0x0008
+#define L2CAP_LM_RELIABLE 0x0010
+#define L2CAP_LM_SECURE 0x0020
+#define L2CAP_LM_FLUSHABLE 0x0040
+#define L2CAP_COMMAND_REJ 0x01
+#define L2CAP_CONN_REQ 0x02
+#define L2CAP_CONN_RSP 0x03
+#define L2CAP_CONF_REQ 0x04
+#define L2CAP_CONF_RSP 0x05
+#define L2CAP_DISCONN_REQ 0x06
+#define L2CAP_DISCONN_RSP 0x07
+#define L2CAP_ECHO_REQ 0x08
+#define L2CAP_ECHO_RSP 0x09
+#define L2CAP_INFO_REQ 0x0a
+#define L2CAP_INFO_RSP 0x0b
+#define L2CAP_HDR_SIZE 4
+#define L2CAP_CMD_HDR_SIZE 4
+#define L2CAP_CMD_REJ_SIZE 2
+#define L2CAP_CONN_REQ_SIZE 4
+#define L2CAP_CONN_RSP_SIZE 8
+#define L2CAP_CR_SUCCESS 0x0000
+#define L2CAP_CR_PEND 0x0001
+#define L2CAP_CR_BAD_PSM 0x0002
+#define L2CAP_CR_SEC_BLOCK 0x0003
+#define L2CAP_CR_NO_MEM 0x0004
+#define L2CAP_CS_NO_INFO 0x0000
+#define L2CAP_CS_AUTHEN_PEND 0x0001
+#define L2CAP_CS_AUTHOR_PEND 0x0002
+#define L2CAP_CONF_REQ_SIZE 4
+#define L2CAP_CONF_RSP_SIZE 6
+#define L2CAP_CONF_SUCCESS 0x0000
+#define L2CAP_CONF_UNACCEPT 0x0001
+#define L2CAP_CONF_REJECT 0x0002
+#define L2CAP_CONF_UNKNOWN 0x0003
+#define L2CAP_CONF_OPT_SIZE 2
+#define L2CAP_CONF_MTU 0x01
+#define L2CAP_CONF_FLUSH_TO 0x02
+#define L2CAP_CONF_QOS 0x03
+#define L2CAP_CONF_RFC 0x04
+#define L2CAP_CONF_RFC_MODE 0x04
+#define L2CAP_CONF_MAX_SIZE 22
+#define L2CAP_MODE_BASIC 0x00
+#define L2CAP_MODE_RETRANS 0x01
+#define L2CAP_MODE_FLOWCTL 0x02
+#define L2CAP_DISCONN_REQ_SIZE 4
+#define L2CAP_DISCONN_RSP_SIZE 4
+#define L2CAP_INFO_REQ_SIZE 2
+#define L2CAP_INFO_RSP_SIZE 4
+#define L2CAP_IT_CL_MTU 0x0001
+#define L2CAP_IT_FEAT_MASK 0x0002
+#define L2CAP_IR_SUCCESS 0x0000
+#define L2CAP_IR_NOTSUPP 0x0001
+#ifdef __cplusplus
+#endif
+struct sockaddr_l2
+{
+ sa_family_t l2_family;
+ unsigned short l2_psm;
+ bdaddr_t l2_bdaddr;
+};
+#endif
diff --git a/external/bluez_bluetooth/inc/bluetooth/rfcomm.h b/external/bluez_bluetooth/inc/bluetooth/rfcomm.h
new file mode 100644
index 000000000..b179717b7
--- /dev/null
+++ b/external/bluez_bluetooth/inc/bluetooth/rfcomm.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Bluez header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to Android. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __RFCOMM_H
+#define __RFCOMM_H
+
+#ifdef __cplusplus
+#endif
+#include <sys/socket.h>
+#define RFCOMM_DEFAULT_MTU 127
+#define RFCOMM_PSM 3
+#define RFCOMM_CONN_TIMEOUT (HZ * 30)
+#define RFCOMM_DISC_TIMEOUT (HZ * 20)
+#define RFCOMM_CONNINFO 0x02
+#define RFCOMM_LM 0x03
+#define RFCOMM_LM_MASTER 0x0001
+#define RFCOMM_LM_AUTH 0x0002
+#define RFCOMM_LM_ENCRYPT 0x0004
+#define RFCOMM_LM_TRUSTED 0x0008
+#define RFCOMM_LM_RELIABLE 0x0010
+#define RFCOMM_LM_SECURE 0x0020
+#define RFCOMM_MAX_DEV 256
+#define RFCOMMCREATEDEV _IOW('R', 200, int)
+#define RFCOMMRELEASEDEV _IOW('R', 201, int)
+#define RFCOMMGETDEVLIST _IOR('R', 210, int)
+#define RFCOMMGETDEVINFO _IOR('R', 211, int)
+#define RFCOMM_REUSE_DLC 0
+#define RFCOMM_RELEASE_ONHUP 1
+#define RFCOMM_HANGUP_NOW 2
+#define RFCOMM_TTY_ATTACHED 3
+#ifdef __cplusplus
+#endif
+struct sockaddr_rc
+{
+ sa_family_t rc_family;
+ bdaddr_t rc_bdaddr;
+ uint8_t rc_channel;
+};
+#endif
diff --git a/external/bluez_bluetooth/inc/bluetooth/sco.h b/external/bluez_bluetooth/inc/bluetooth/sco.h
new file mode 100644
index 000000000..56fe3710a
--- /dev/null
+++ b/external/bluez_bluetooth/inc/bluetooth/sco.h
@@ -0,0 +1,32 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Bluez header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to Android. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __SCO_H
+#define __SCO_H
+
+#ifdef __cplusplus
+#endif
+#define SCO_DEFAULT_MTU 500
+#define SCO_DEFAULT_FLUSH_TO 0xFFFF
+#define SCO_CONN_TIMEOUT (HZ * 40)
+#define SCO_DISCONN_TIMEOUT (HZ * 2)
+#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
+#define SCO_OPTIONS 0x01
+#define SCO_CONNINFO 0x02
+#ifdef __cplusplus
+#endif
+struct sockaddr_sco
+{
+ sa_family_t sco_family;
+ bdaddr_t sco_bdaddr;
+ uint16_t sco_pkt_type;
+};
+#endif
diff --git a/external/boost/Makefile b/external/boost/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/boost/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/boost/Module_boost.mk b/external/boost/Module_boost.mk
new file mode 100644
index 000000000..252bf1c9a
--- /dev/null
+++ b/external/boost/Module_boost.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,boost))
+
+$(eval $(call gb_Module_add_targets,boost,\
+ StaticLibrary_boost_date_time \
+ StaticLibrary_boost_filesystem \
+ StaticLibrary_boost_locale \
+ StaticLibrary_boost_system \
+ StaticLibrary_boost_iostreams \
+ UnpackedTarball_boost \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/boost/README b/external/boost/README
new file mode 100644
index 000000000..7e6426bf9
--- /dev/null
+++ b/external/boost/README
@@ -0,0 +1,4 @@
+From [http://www.boost.org/].
+
+Apart from the spirit parsing framework, LibreOffice currently mostly
+uses the smart pointers, pool memory and binders functionality.
diff --git a/external/boost/StaticLibrary_boost_date_time.mk b/external/boost/StaticLibrary_boost_date_time.mk
new file mode 100644
index 000000000..204524359
--- /dev/null
+++ b/external/boost/StaticLibrary_boost_date_time.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,boost_date_time))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,boost_date_time,boost))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,boost_date_time))
+
+# disable "auto link" "feature" on MSVC
+$(eval $(call gb_StaticLibrary_add_defs,boost_date_time,\
+ -DBOOST_ALL_NO_LIB \
+))
+
+# Needed when building against MSVC in C++17 mode, as
+# workdir/UnpackedTarball/boost/boost/numeric/conversion/detail/converter.hpp uses
+# std::unary_function:
+$(eval $(call gb_StaticLibrary_add_defs,boost_date_time, \
+ -D_HAS_AUTO_PTR_ETC=1 \
+))
+
+$(eval $(call gb_StaticLibrary_use_external,boost_date_time,boost_headers))
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,boost_date_time,cpp))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,boost_date_time,\
+ UnpackedTarball/boost/libs/date_time/src/gregorian/gregorian_types \
+ UnpackedTarball/boost/libs/date_time/src/gregorian/greg_month \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/boost/StaticLibrary_boost_filesystem.mk b/external/boost/StaticLibrary_boost_filesystem.mk
new file mode 100644
index 000000000..23b42d750
--- /dev/null
+++ b/external/boost/StaticLibrary_boost_filesystem.mk
@@ -0,0 +1,43 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,boost_filesystem))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,boost_filesystem,boost))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,boost_filesystem))
+
+# disable "auto link" "feature" on MSVC
+$(eval $(call gb_StaticLibrary_add_defs,boost_filesystem,\
+ -DBOOST_ALL_NO_LIB \
+))
+
+# See workdir/UnpackedTarball/boost/libs/filesystem/build/Jamfile.v2:
+ifeq ($(HAVE_CXX20_ATOMIC_REF),)
+$(eval $(call gb_StaticLibrary_add_defs,boost_filesystem,-DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF))
+endif
+
+$(eval $(call gb_StaticLibrary_use_external,boost_filesystem,boost_headers))
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,boost_filesystem,cpp))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,boost_filesystem,\
+ UnpackedTarball/boost/libs/filesystem/src/codecvt_error_category \
+ UnpackedTarball/boost/libs/filesystem/src/directory \
+ UnpackedTarball/boost/libs/filesystem/src/exception \
+ UnpackedTarball/boost/libs/filesystem/src/operations \
+ UnpackedTarball/boost/libs/filesystem/src/path \
+ UnpackedTarball/boost/libs/filesystem/src/path_traits \
+ UnpackedTarball/boost/libs/filesystem/src/portability \
+ UnpackedTarball/boost/libs/filesystem/src/unique_path \
+ UnpackedTarball/boost/libs/filesystem/src/utf8_codecvt_facet \
+ UnpackedTarball/boost/libs/filesystem/src/windows_file_codecvt \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/boost/StaticLibrary_boost_iostreams.mk b/external/boost/StaticLibrary_boost_iostreams.mk
new file mode 100644
index 000000000..0884a5aee
--- /dev/null
+++ b/external/boost/StaticLibrary_boost_iostreams.mk
@@ -0,0 +1,35 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,boost_iostreams))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,boost_iostreams))
+
+# disable "auto link" "feature" on MSVC
+$(eval $(call gb_StaticLibrary_add_defs,boost_iostreams,\
+ -DBOOST_ALL_NO_LIB \
+))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,boost_iostreams,boost))
+
+
+$(eval $(call gb_StaticLibrary_use_externals,boost_iostreams, \
+ zlib \
+ boost_headers \
+))
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,boost_iostreams,cpp))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,boost_iostreams,\
+ UnpackedTarball/boost/libs/iostreams/src/zlib \
+ UnpackedTarball/boost/libs/iostreams/src/gzip \
+ UnpackedTarball/boost/libs/iostreams/src/file_descriptor \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/boost/StaticLibrary_boost_locale.mk b/external/boost/StaticLibrary_boost_locale.mk
new file mode 100644
index 000000000..c68d63c7d
--- /dev/null
+++ b/external/boost/StaticLibrary_boost_locale.mk
@@ -0,0 +1,59 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,boost_locale))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,boost_locale,boost))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,boost_locale))
+
+# disable "auto link" "feature" on MSVC
+$(eval $(call gb_StaticLibrary_add_defs,boost_locale,\
+ -DBOOST_ALL_NO_LIB -DBOOST_LOCALE_NO_WINAPI_BACKEND -DBOOST_LOCALE_NO_POSIX_BACKEND -DBOOST_USE_WINDOWS_H \
+))
+
+$(eval $(call gb_StaticLibrary_use_external,boost_locale,boost_headers))
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,boost_locale,cpp))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,boost_locale,\
+ UnpackedTarball/boost/libs/locale/src/encoding/codepage \
+ UnpackedTarball/boost/libs/locale/src/shared/date_time \
+ UnpackedTarball/boost/libs/locale/src/shared/format \
+ UnpackedTarball/boost/libs/locale/src/shared/formatting \
+ UnpackedTarball/boost/libs/locale/src/shared/generator \
+ UnpackedTarball/boost/libs/locale/src/shared/ids \
+ UnpackedTarball/boost/libs/locale/src/shared/localization_backend \
+ UnpackedTarball/boost/libs/locale/src/shared/message \
+ UnpackedTarball/boost/libs/locale/src/shared/mo_lambda \
+ UnpackedTarball/boost/libs/locale/src/std/codecvt \
+ UnpackedTarball/boost/libs/locale/src/std/collate \
+ UnpackedTarball/boost/libs/locale/src/std/converter \
+ UnpackedTarball/boost/libs/locale/src/std/numeric \
+ UnpackedTarball/boost/libs/locale/src/std/std_backend \
+ UnpackedTarball/boost/libs/locale/src/util/codecvt_converter \
+ UnpackedTarball/boost/libs/locale/src/util/default_locale \
+ UnpackedTarball/boost/libs/locale/src/util/gregorian \
+ UnpackedTarball/boost/libs/locale/src/util/info \
+ UnpackedTarball/boost/libs/locale/src/util/locale_data \
+))
+
+ifeq ($(OS),WNT)
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,boost_locale,\
+ UnpackedTarball/boost/libs/locale/src/win32/collate \
+ UnpackedTarball/boost/libs/locale/src/win32/converter \
+ UnpackedTarball/boost/libs/locale/src/win32/lcid \
+ UnpackedTarball/boost/libs/locale/src/win32/numeric \
+ UnpackedTarball/boost/libs/locale/src/win32/win_backend \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/boost/StaticLibrary_boost_system.mk b/external/boost/StaticLibrary_boost_system.mk
new file mode 100644
index 000000000..e4b05d7b5
--- /dev/null
+++ b/external/boost/StaticLibrary_boost_system.mk
@@ -0,0 +1,29 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,boost_system))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,boost_system,boost))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,boost_system))
+
+# disable "auto link" "feature" on MSVC
+$(eval $(call gb_StaticLibrary_add_defs,boost_system,\
+ -DBOOST_ALL_NO_LIB \
+))
+
+$(eval $(call gb_StaticLibrary_use_external,boost_system,boost_headers))
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,boost_system,cpp))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,boost_system,\
+ UnpackedTarball/boost/libs/system/src/error_code \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/boost/UnpackedTarball_boost.mk b/external/boost/UnpackedTarball_boost.mk
new file mode 100644
index 000000000..91a0e264a
--- /dev/null
+++ b/external/boost/UnpackedTarball_boost.mk
@@ -0,0 +1,46 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+boost_patches :=
+
+#https://svn.boost.org/trac/boost/ticket/6142
+boost_patches += boost.6142.warnings.patch.1
+
+boost_patches += boost.noiconv.patch
+boost_patches += boost.between.warning.patch
+boost_patches += boost.fallback.encoding.patch
+
+boost_patches += rtti.patch.0
+
+# https://svn.boost.org/trac/boost/ticket/11505
+boost_patches += boost_1_59_0.mpl.config.wundef.patch
+# https://svn.boost.org/trac/boost/ticket/11501
+boost_patches += boost_1_59_0.property_tree.wreturn-type.patch
+
+boost_patches += clang-cl.patch.0
+
+boost_patches += boost_1_63_0.undef.warning.patch.1
+
+boost_patches += windows-no-utf8-locales.patch.0
+
+boost_patches += msvc2017.patch.0
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,boost))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,boost,$(BOOST_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,boost,3))
+
+$(eval $(call gb_UnpackedTarball_add_patches,boost,\
+ $(foreach patch,$(boost_patches),external/boost/$(patch)) \
+ external/boost/boost-emscripten-noshm.patch.0 \
+ external/boost/boost-emscripten-nowasm.patch.0 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/boost/boost-emscripten-noshm.patch.0 b/external/boost/boost-emscripten-noshm.patch.0
new file mode 100644
index 000000000..f9d27b0b6
--- /dev/null
+++ b/external/boost/boost-emscripten-noshm.patch.0
@@ -0,0 +1,11 @@
+--- boost/interprocess/detail/workaround.hpp.orig 2020-12-15 06:31:51.037665526 +0100
++++ boost/interprocess/detail/workaround.hpp 2020-12-15 06:32:39.741281893 +0100
+@@ -31,7 +31,7 @@
+ //////////////////////////////////////////////////////
+ //Check for XSI shared memory objects. They are available in nearly all UNIX platforms
+ //////////////////////////////////////////////////////
+- #if !defined(__QNXNTO__) && !defined(__ANDROID__) && !defined(__HAIKU__) && !(__VXWORKS__)
++ #if !defined(__QNXNTO__) && !defined(__ANDROID__) && !defined(__HAIKU__) && !(__VXWORKS__) && !defined(__EMSCRIPTEN__)
+ #define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
+ #endif
+
diff --git a/external/boost/boost-emscripten-nowasm.patch.0 b/external/boost/boost-emscripten-nowasm.patch.0
new file mode 100644
index 000000000..39723351e
--- /dev/null
+++ b/external/boost/boost-emscripten-nowasm.patch.0
@@ -0,0 +1,11 @@
+--- boost/config/detail/select_platform_config.hpp.orig 2021-11-13 18:32:09.446182220 +0100
++++ boost/config/detail/select_platform_config.hpp 2021-11-13 18:32:57.734041110 +0100
+@@ -89,7 +89,7 @@
+ // Nuxi CloudABI:
+ # define BOOST_PLATFORM_CONFIG "boost/config/platform/cloudabi.hpp"
+
+-#elif defined (__wasm__)
++#elif defined (__wasm__) && !defined (__EMSCRIPTEN__)
+ // Web assembly:
+ # define BOOST_PLATFORM_CONFIG "boost/config/platform/wasm.hpp"
+
diff --git a/external/boost/boost.6142.warnings.patch.1 b/external/boost/boost.6142.warnings.patch.1
new file mode 100644
index 000000000..b38efd90d
--- /dev/null
+++ b/external/boost/boost.6142.warnings.patch.1
@@ -0,0 +1,38 @@
+--- a/boost/mpl/has_xxx.hpp.orig 2011-11-18 13:45:00.000000000 +0100
++++ b/boost/mpl/has_xxx.hpp 2011-11-18 13:47:19.000000000 +0100
+@@ -341,7 +341,7 @@
+ ) \
+ /**/
+
+-# if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
++# if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION) || !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
+ # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
+ template< typename V > \
+ static boost::mpl::aux::no_tag \
+@@ -354,7 +354,7 @@
+ /**/
+ # endif
+
+-# if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
++# if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES) || !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
+ # define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT(z, n, args) \
+ template< typename V > \
+ static boost::mpl::aux::yes_tag \
+@@ -383,7 +383,7 @@
+ /**/
+ # endif
+
+-# if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
++# if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION) || !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
+ # define BOOST_MPL_HAS_MEMBER_TEST(args) \
+ sizeof(BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \
+ == sizeof(boost::mpl::aux::yes_tag) \
+@@ -456,7 +456,7 @@
+ ) \
+ /**/
+
+-# if BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
++# if defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE) && BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
+
+ # if !defined(BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE)
+ # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
diff --git a/external/boost/boost.between.warning.patch b/external/boost/boost.between.warning.patch
new file mode 100644
index 000000000..bb4535708
--- /dev/null
+++ b/external/boost/boost.between.warning.patch
@@ -0,0 +1,13 @@
+diff -ru boost.orig/boost/libs/locale/src/encoding/codepage.cpp boost/boost/libs/locale/src/encoding/codepage.cpp
+--- foo/misc/boost.orig/libs/locale/src/encoding/codepage.cpp
++++ foo/misc/boost/libs/locale/src/encoding/codepage.cpp
+@@ -58,6 +58,9 @@
+ return cvt->convert(begin,end);
+ #endif
+ #endif
++ // ensures we get a sensible warning in boost's gettext results about a real mismatch.
++ if (to_charset && from_charset && !strcmp(to_charset, from_charset))
++ return std::string(begin, end - begin);
+ throw invalid_charset_error(std::string(to_charset) + " or " + from_charset);
+ }
+
diff --git a/external/boost/boost.fallback.encoding.patch b/external/boost/boost.fallback.encoding.patch
new file mode 100644
index 000000000..51ac7fc72
--- /dev/null
+++ b/external/boost/boost.fallback.encoding.patch
@@ -0,0 +1,13 @@
+--- foo/misc/boost.orig/libs/locale/src/util/locale_data.cpp.new 2022-02-17 22:41:27.730549039 +0000
++++ foo/misc/boost/libs/locale/src/util/locale_data.cpp
+@@ -18,8 +18,8 @@
+ language = "C";
+ country.clear();
+ variant.clear();
+- encoding = "us-ascii";
+- utf8=false;
++ encoding = "UTF-8";
++ utf8=true;
+ parse_from_lang(locale_name);
+ }
+
diff --git a/external/boost/boost.noiconv.patch b/external/boost/boost.noiconv.patch
new file mode 100644
index 000000000..1bce0414d
--- /dev/null
+++ b/external/boost/boost.noiconv.patch
@@ -0,0 +1,51 @@
+diff -ru boost.orig/boost/libs/locale/src/encoding/codepage.cpp boost/boost/libs/locale/src/encoding/codepage.cpp
+--- foo/misc/boost.orig/libs/locale/src/encoding/codepage.cpp
++++ foo/misc/boost/libs/locale/src/encoding/codepage.cpp
+@@ -39,6 +39,7 @@
+ char const *from_charset,
+ method_type how)
+ {
++ #if defined(BOOST_LOCALE_WITH_ICONV) || defined(BOOST_LOCALE_WITH_ICU) || defined(BOOST_LOCALE_WITH_WCONV)
+ hold_ptr<converter_between> cvt;
+ #ifdef BOOST_LOCALE_WITH_ICONV
+ cvt.reset(new iconv_between());
+@@ -55,6 +56,7 @@
+ if(cvt->open(to_charset,from_charset,how))
+ return cvt->convert(begin,end);
+ #endif
++ #endif
+ throw invalid_charset_error(std::string(to_charset) + " or " + from_charset);
+ }
+
+@@ -65,6 +67,7 @@
+ char const *charset,
+ method_type how)
+ {
++ #if defined(BOOST_LOCALE_WITH_ICONV) || defined(BOOST_LOCALE_WITH_ICU) || defined(BOOST_LOCALE_WITH_WCONV)
+ hold_ptr<converter_to_utf<CharType> > cvt;
+ #ifdef BOOST_LOCALE_WITH_ICONV
+ cvt.reset(new iconv_to_utf<CharType>());
+@@ -81,6 +84,7 @@
+ if(cvt->open(charset,how))
+ return cvt->convert(begin,end);
+ #endif
++ #endif
+ throw invalid_charset_error(charset);
+ }
+
+@@ -91,6 +95,7 @@
+ char const *charset,
+ method_type how)
+ {
++ #if defined(BOOST_LOCALE_WITH_ICONV) || defined(BOOST_LOCALE_WITH_ICU) || defined(BOOST_LOCALE_WITH_WCONV)
+ hold_ptr<converter_from_utf<CharType> > cvt;
+ #ifdef BOOST_LOCALE_WITH_ICONV
+ cvt.reset(new iconv_from_utf<CharType>());
+@@ -107,6 +112,7 @@
+ if(cvt->open(charset,how))
+ return cvt->convert(begin,end);
+ #endif
++ #endif
+ throw invalid_charset_error(charset);
+ }
+
diff --git a/external/boost/boost_1_59_0.mpl.config.wundef.patch b/external/boost/boost_1_59_0.mpl.config.wundef.patch
new file mode 100644
index 000000000..2826cfc2b
--- /dev/null
+++ b/external/boost/boost_1_59_0.mpl.config.wundef.patch
@@ -0,0 +1,11 @@
+diff -ru boost.orig/boost/mpl/aux_/config/operators.hpp boost/boost/mpl/aux_/config/operators.hpp
+--- foo/misc/boost.orig/boost/mpl/aux_/config/operators.hpp 2015-07-19 11:20:40.015955021 +0200
++++ foo/misc/boost/boost/mpl/aux_/config/operators.hpp 2015-07-19 11:33:14.342946543 +0200
+@@ -24,7 +24,6 @@
+ || BOOST_WORKAROUND(__EDG_VERSION__, <= 245) \
+ || BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0295) \
+ || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \
+- || BOOST_WORKAROUND(__NVCC__, BOOST_TESTED_AT(1)) \
+ )
+
+ # define BOOST_MPL_CFG_USE_OPERATORS_OVERLOADING
diff --git a/external/boost/boost_1_59_0.property_tree.wreturn-type.patch b/external/boost/boost_1_59_0.property_tree.wreturn-type.patch
new file mode 100644
index 000000000..1673e4bd8
--- /dev/null
+++ b/external/boost/boost_1_59_0.property_tree.wreturn-type.patch
@@ -0,0 +1,14 @@
+aka MSVC warning C4715: not all control paths return a value
+
+diff -ru boost.org/boost/property_tree/json_parser/detail/standard_callbacks.hpp boost/boost/property_tree/json_parser/detail/standard_callbacks.hpp
+--- foo/misc/boost.org/boost/property_tree/json_parser/detail/standard_callbacks.hpp 2015-07-07 14:20:48.000000000 +0200
++++ foo/misc/boost/boost/property_tree/json_parser/detail/standard_callbacks.hpp 2015-07-22 08:35:07.764263463 +0200
+@@ -128,7 +128,7 @@
+ }
+ case object:
+ default:
+- BOOST_ASSERT(false); // must start with string, i.e. call new_value
++ std::abort();
+ case key: {
+ l.t->push_back(std::make_pair(key_buffer, Ptree()));
+ l.k = object;
diff --git a/external/boost/boost_1_63_0.undef.warning.patch.1 b/external/boost/boost_1_63_0.undef.warning.patch.1
new file mode 100644
index 000000000..cdf0d820e
--- /dev/null
+++ b/external/boost/boost_1_63_0.undef.warning.patch.1
@@ -0,0 +1,12 @@
+diff -up boost/boost/math/special_functions/fpclassify.hpp.dt boost/boost/math/special_functions/fpclassify.hpp
+--- boost/boost/math/special_functions/fpclassify.hpp.dt 2017-02-03 07:59:18.805415876 +0100
++++ boost/boost/math/special_functions/fpclassify.hpp 2017-02-03 08:00:45.046494362 +0100
+@@ -134,7 +134,7 @@ inline bool is_nan_helper(T, const boost
+ inline bool is_nan_helper(__float128 f, const std::true_type&) { return ::isnanq(f); }
+ inline bool is_nan_helper(__float128 f, const std::false_type&) { return ::isnanq(f); }
+ #elif defined(BOOST_GNU_STDLIB) && BOOST_GNU_STDLIB && \
+- _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
++ _GLIBCXX_USE_C99_MATH && (!defined(_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) || !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC)
+ inline bool is_nan_helper(__float128 f, const std::true_type&) { return std::isnan(static_cast<double>(f)); }
+ inline bool is_nan_helper(__float128 f, const std::false_type&) { return std::isnan(static_cast<double>(f)); }
+ #else
diff --git a/external/boost/clang-cl.patch.0 b/external/boost/clang-cl.patch.0
new file mode 100644
index 000000000..45137f9ff
--- /dev/null
+++ b/external/boost/clang-cl.patch.0
@@ -0,0 +1,20 @@
+--- boost/multi_array/base.hpp
++++ boost/multi_array/base.hpp
+@@ -222,7 +222,7 @@
+ // MSVC 2010 is broken in debug mode: it requires
+ // that an Output Iterator have output_iterator_tag in its iterator_category if
+ // that iterator is not bidirectional_iterator or random_access_iterator.
+-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
++#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600) || defined __clang__
+ struct mutable_iterator_tag
+ : boost::random_access_traversal_tag, std::input_iterator_tag
+ {
+@@ -274,7 +274,7 @@
+ //
+ // iterator support
+ //
+-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
++#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600) || defined __clang__
+ // Deal with VC 2010 output_iterator_tag requirement
+ typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference,
+ mutable_iterator_tag> iterator;
diff --git a/external/boost/include/boost/algorithm/string.hpp b/external/boost/include/boost/algorithm/string.hpp
new file mode 100644
index 000000000..da77bb9a1
--- /dev/null
+++ b/external/boost/include/boost/algorithm/string.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/algorithm/string.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/algorithm/string/predicate.hpp b/external/boost/include/boost/algorithm/string/predicate.hpp
new file mode 100644
index 000000000..b650c15d0
--- /dev/null
+++ b/external/boost/include/boost/algorithm/string/predicate.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/algorithm/string/predicate.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/archive/iterators/base64_from_binary.hpp b/external/boost/include/boost/archive/iterators/base64_from_binary.hpp
new file mode 100644
index 000000000..b5f4f7146
--- /dev/null
+++ b/external/boost/include/boost/archive/iterators/base64_from_binary.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/archive/iterators/base64_from_binary.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/archive/iterators/binary_from_base64.hpp b/external/boost/include/boost/archive/iterators/binary_from_base64.hpp
new file mode 100644
index 000000000..9f4311a6f
--- /dev/null
+++ b/external/boost/include/boost/archive/iterators/binary_from_base64.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/archive/iterators/binary_from_base64.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/archive/iterators/remove_whitespace.hpp b/external/boost/include/boost/archive/iterators/remove_whitespace.hpp
new file mode 100644
index 000000000..e8783de5f
--- /dev/null
+++ b/external/boost/include/boost/archive/iterators/remove_whitespace.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/archive/iterators/remove_whitespace.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/archive/iterators/transform_width.hpp b/external/boost/include/boost/archive/iterators/transform_width.hpp
new file mode 100644
index 000000000..4efa46f64
--- /dev/null
+++ b/external/boost/include/boost/archive/iterators/transform_width.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/archive/iterators/transform_width.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/bind.hpp b/external/boost/include/boost/bind.hpp
new file mode 100644
index 000000000..5e7c69854
--- /dev/null
+++ b/external/boost/include/boost/bind.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/bind.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/cast.hpp b/external/boost/include/boost/cast.hpp
new file mode 100644
index 000000000..513ffd2d3
--- /dev/null
+++ b/external/boost/include/boost/cast.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/cast.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/circular_buffer.hpp b/external/boost/include/boost/circular_buffer.hpp
new file mode 100644
index 000000000..2971bef59
--- /dev/null
+++ b/external/boost/include/boost/circular_buffer.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/circular_buffer.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/cstdint.hpp b/external/boost/include/boost/cstdint.hpp
new file mode 100644
index 000000000..a1200b795
--- /dev/null
+++ b/external/boost/include/boost/cstdint.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/cstdint.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/current_function.hpp b/external/boost/include/boost/current_function.hpp
new file mode 100644
index 000000000..94a8060a2
--- /dev/null
+++ b/external/boost/include/boost/current_function.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/current_function.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/date_time.hpp b/external/boost/include/boost/date_time.hpp
new file mode 100644
index 000000000..ae191390b
--- /dev/null
+++ b/external/boost/include/boost/date_time.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/date_time.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/date_time/posix_time/posix_time.hpp b/external/boost/include/boost/date_time/posix_time/posix_time.hpp
new file mode 100644
index 000000000..23623bfd0
--- /dev/null
+++ b/external/boost/include/boost/date_time/posix_time/posix_time.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/date_time/posix_time/posix_time.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/filesystem.hpp b/external/boost/include/boost/filesystem.hpp
new file mode 100644
index 000000000..3096c1bc7
--- /dev/null
+++ b/external/boost/include/boost/filesystem.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/filesystem.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/filesystem/path.hpp b/external/boost/include/boost/filesystem/path.hpp
new file mode 100644
index 000000000..6a00d52cb
--- /dev/null
+++ b/external/boost/include/boost/filesystem/path.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/filesystem/path.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/functional/hash.hpp b/external/boost/include/boost/functional/hash.hpp
new file mode 100644
index 000000000..b7cf8109d
--- /dev/null
+++ b/external/boost/include/boost/functional/hash.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/functional/hash.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/fusion/adapted/std_pair.hpp b/external/boost/include/boost/fusion/adapted/std_pair.hpp
new file mode 100644
index 000000000..dc53069f2
--- /dev/null
+++ b/external/boost/include/boost/fusion/adapted/std_pair.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/fusion/adapted/std_pair.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/fusion/include/adapt_struct.hpp b/external/boost/include/boost/fusion/include/adapt_struct.hpp
new file mode 100644
index 000000000..45cad2fdc
--- /dev/null
+++ b/external/boost/include/boost/fusion/include/adapt_struct.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/fusion/include/adapt_struct.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/intrusive/circular_list_algorithms.hpp b/external/boost/include/boost/intrusive/circular_list_algorithms.hpp
new file mode 100644
index 000000000..5276879e6
--- /dev/null
+++ b/external/boost/include/boost/intrusive/circular_list_algorithms.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/intrusive/circular_list_algorithms.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/intrusive_ptr.hpp b/external/boost/include/boost/intrusive_ptr.hpp
new file mode 100644
index 000000000..a5672b8ed
--- /dev/null
+++ b/external/boost/include/boost/intrusive_ptr.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/intrusive_ptr.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/io/ios_state.hpp b/external/boost/include/boost/io/ios_state.hpp
new file mode 100644
index 000000000..75f26690b
--- /dev/null
+++ b/external/boost/include/boost/io/ios_state.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/io/ios_state.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/iostreams/filter/gzip.hpp b/external/boost/include/boost/iostreams/filter/gzip.hpp
new file mode 100644
index 000000000..ba684a4c3
--- /dev/null
+++ b/external/boost/include/boost/iostreams/filter/gzip.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/iostreams/filter/gzip.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/iostreams/filtering_stream.hpp b/external/boost/include/boost/iostreams/filtering_stream.hpp
new file mode 100644
index 000000000..17707286c
--- /dev/null
+++ b/external/boost/include/boost/iostreams/filtering_stream.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/iostreams/filtering_stream.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/iterator/iterator_facade.hpp b/external/boost/include/boost/iterator/iterator_facade.hpp
new file mode 100644
index 000000000..dc8aa41e6
--- /dev/null
+++ b/external/boost/include/boost/iterator/iterator_facade.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/iterator/iterator_facade.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/lexical_cast.hpp b/external/boost/include/boost/lexical_cast.hpp
new file mode 100644
index 000000000..56eaf59ef
--- /dev/null
+++ b/external/boost/include/boost/lexical_cast.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/lexical_cast.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/locale.hpp b/external/boost/include/boost/locale.hpp
new file mode 100644
index 000000000..961105150
--- /dev/null
+++ b/external/boost/include/boost/locale.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/locale.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/locale/gnu_gettext.hpp b/external/boost/include/boost/locale/gnu_gettext.hpp
new file mode 100644
index 000000000..979ece267
--- /dev/null
+++ b/external/boost/include/boost/locale/gnu_gettext.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/locale/gnu_gettext.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/make_shared.hpp b/external/boost/include/boost/make_shared.hpp
new file mode 100644
index 000000000..17e1c59e2
--- /dev/null
+++ b/external/boost/include/boost/make_shared.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/make_shared.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/math/common_factor_rt.hpp b/external/boost/include/boost/math/common_factor_rt.hpp
new file mode 100644
index 000000000..72ae2ec67
--- /dev/null
+++ b/external/boost/include/boost/math/common_factor_rt.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/math/common_factor_rt.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/math/special_functions/expm1.hpp b/external/boost/include/boost/math/special_functions/expm1.hpp
new file mode 100644
index 000000000..ac92a5ade
--- /dev/null
+++ b/external/boost/include/boost/math/special_functions/expm1.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/math/special_functions/expm1.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/math/special_functions/sinc.hpp b/external/boost/include/boost/math/special_functions/sinc.hpp
new file mode 100644
index 000000000..262bdf700
--- /dev/null
+++ b/external/boost/include/boost/math/special_functions/sinc.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/math/special_functions/sinc.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/multi_array.hpp b/external/boost/include/boost/multi_array.hpp
new file mode 100644
index 000000000..bbf1ee094
--- /dev/null
+++ b/external/boost/include/boost/multi_array.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/multi_array.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/multi_index/composite_key.hpp b/external/boost/include/boost/multi_index/composite_key.hpp
new file mode 100644
index 000000000..fc71af8a9
--- /dev/null
+++ b/external/boost/include/boost/multi_index/composite_key.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/multi_index/composite_key.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/multi_index/identity.hpp b/external/boost/include/boost/multi_index/identity.hpp
new file mode 100644
index 000000000..95d61fb87
--- /dev/null
+++ b/external/boost/include/boost/multi_index/identity.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/multi_index/identity.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/multi_index/mem_fun.hpp b/external/boost/include/boost/multi_index/mem_fun.hpp
new file mode 100644
index 000000000..cc1c4e16e
--- /dev/null
+++ b/external/boost/include/boost/multi_index/mem_fun.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/multi_index/mem_fun.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/multi_index/ordered_index.hpp b/external/boost/include/boost/multi_index/ordered_index.hpp
new file mode 100644
index 000000000..a617eeb92
--- /dev/null
+++ b/external/boost/include/boost/multi_index/ordered_index.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/multi_index/ordered_index.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/multi_index/random_access_index.hpp b/external/boost/include/boost/multi_index/random_access_index.hpp
new file mode 100644
index 000000000..0af3b51e8
--- /dev/null
+++ b/external/boost/include/boost/multi_index/random_access_index.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/multi_index/random_access_index.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/multi_index_container.hpp b/external/boost/include/boost/multi_index_container.hpp
new file mode 100644
index 000000000..5e0f39701
--- /dev/null
+++ b/external/boost/include/boost/multi_index_container.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/multi_index_container.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/noncopyable.hpp b/external/boost/include/boost/noncopyable.hpp
new file mode 100644
index 000000000..8c57e4df6
--- /dev/null
+++ b/external/boost/include/boost/noncopyable.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/noncopyable.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/none.hpp b/external/boost/include/boost/none.hpp
new file mode 100644
index 000000000..4b49b9806
--- /dev/null
+++ b/external/boost/include/boost/none.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/none.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/numeric/conversion/cast.hpp b/external/boost/include/boost/numeric/conversion/cast.hpp
new file mode 100644
index 000000000..d85f2924e
--- /dev/null
+++ b/external/boost/include/boost/numeric/conversion/cast.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/numeric/conversion/cast.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/operators.hpp b/external/boost/include/boost/operators.hpp
new file mode 100644
index 000000000..716d97934
--- /dev/null
+++ b/external/boost/include/boost/operators.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/operators.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/optional.hpp b/external/boost/include/boost/optional.hpp
new file mode 100644
index 000000000..892970ccd
--- /dev/null
+++ b/external/boost/include/boost/optional.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/optional.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/program_options.hpp b/external/boost/include/boost/program_options.hpp
new file mode 100644
index 000000000..9e39f3dfd
--- /dev/null
+++ b/external/boost/include/boost/program_options.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/program_options.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/property_tree/json_parser.hpp b/external/boost/include/boost/property_tree/json_parser.hpp
new file mode 100644
index 000000000..80808d0eb
--- /dev/null
+++ b/external/boost/include/boost/property_tree/json_parser.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/property_tree/json_parser.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/property_tree/ptree.hpp b/external/boost/include/boost/property_tree/ptree.hpp
new file mode 100644
index 000000000..d000b5b94
--- /dev/null
+++ b/external/boost/include/boost/property_tree/ptree.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/property_tree/ptree.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/property_tree/ptree_fwd.hpp b/external/boost/include/boost/property_tree/ptree_fwd.hpp
new file mode 100644
index 000000000..4088ab20a
--- /dev/null
+++ b/external/boost/include/boost/property_tree/ptree_fwd.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/property_tree/ptree_fwd.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/range/adaptor/reversed.hpp b/external/boost/include/boost/range/adaptor/reversed.hpp
new file mode 100644
index 000000000..5cd97dc3c
--- /dev/null
+++ b/external/boost/include/boost/range/adaptor/reversed.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/range/adaptor/reversed.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/range/iterator_range.hpp b/external/boost/include/boost/range/iterator_range.hpp
new file mode 100644
index 000000000..eaf0570b2
--- /dev/null
+++ b/external/boost/include/boost/range/iterator_range.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/range/iterator_range.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/rational.hpp b/external/boost/include/boost/rational.hpp
new file mode 100644
index 000000000..93cf05cc0
--- /dev/null
+++ b/external/boost/include/boost/rational.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/rational.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/scoped_ptr.hpp b/external/boost/include/boost/scoped_ptr.hpp
new file mode 100644
index 000000000..32aa3486a
--- /dev/null
+++ b/external/boost/include/boost/scoped_ptr.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/scoped_ptr.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/shared_ptr.hpp b/external/boost/include/boost/shared_ptr.hpp
new file mode 100644
index 000000000..946c1ffdf
--- /dev/null
+++ b/external/boost/include/boost/shared_ptr.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/shared_ptr.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/classic.hpp b/external/boost/include/boost/spirit/include/classic.hpp
new file mode 100644
index 000000000..cbce68b6c
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/classic.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/classic.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/classic_core.hpp b/external/boost/include/boost/spirit/include/classic_core.hpp
new file mode 100644
index 000000000..c2c28fec5
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/classic_core.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/classic_core.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/classic_error_handling.hpp b/external/boost/include/boost/spirit/include/classic_error_handling.hpp
new file mode 100644
index 000000000..bc7498777
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/classic_error_handling.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/classic_error_handling.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/classic_file_iterator.hpp b/external/boost/include/boost/spirit/include/classic_file_iterator.hpp
new file mode 100644
index 000000000..b1745d453
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/classic_file_iterator.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/classic_file_iterator.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/classic_utility.hpp b/external/boost/include/boost/spirit/include/classic_utility.hpp
new file mode 100644
index 000000000..e68c37e91
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/classic_utility.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/classic_utility.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/phoenix.hpp b/external/boost/include/boost/spirit/include/phoenix.hpp
new file mode 100644
index 000000000..9b08a6c2c
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/phoenix.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/phoenix.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/qi.hpp b/external/boost/include/boost/spirit/include/qi.hpp
new file mode 100644
index 000000000..04c8d83d1
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/qi.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/qi.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/qi_attr.hpp b/external/boost/include/boost/spirit/include/qi_attr.hpp
new file mode 100644
index 000000000..260082005
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/qi_attr.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/qi_attr.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/qi_lit.hpp b/external/boost/include/boost/spirit/include/qi_lit.hpp
new file mode 100644
index 000000000..d2a768a0d
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/qi_lit.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/qi_lit.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/qi_optional.hpp b/external/boost/include/boost/spirit/include/qi_optional.hpp
new file mode 100644
index 000000000..2ec4204e7
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/qi_optional.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/qi_optional.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/qi_parse_attr.hpp b/external/boost/include/boost/spirit/include/qi_parse_attr.hpp
new file mode 100644
index 000000000..12a3fec4a
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/qi_parse_attr.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/qi_parse_attr.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/qi_sequence.hpp b/external/boost/include/boost/spirit/include/qi_sequence.hpp
new file mode 100644
index 000000000..578e73c5b
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/qi_sequence.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/qi_sequence.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/spirit/include/qi_symbols.hpp b/external/boost/include/boost/spirit/include/qi_symbols.hpp
new file mode 100644
index 000000000..fb60a7f71
--- /dev/null
+++ b/external/boost/include/boost/spirit/include/qi_symbols.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/spirit/include/qi_symbols.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/unordered_map.hpp b/external/boost/include/boost/unordered_map.hpp
new file mode 100644
index 000000000..f626a6a0c
--- /dev/null
+++ b/external/boost/include/boost/unordered_map.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/unordered_map.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/uuid/uuid_generators.hpp b/external/boost/include/boost/uuid/uuid_generators.hpp
new file mode 100644
index 000000000..86e07a639
--- /dev/null
+++ b/external/boost/include/boost/uuid/uuid_generators.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/uuid/uuid_generators.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/uuid/uuid_io.hpp b/external/boost/include/boost/uuid/uuid_io.hpp
new file mode 100644
index 000000000..4da4374bb
--- /dev/null
+++ b/external/boost/include/boost/uuid/uuid_io.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/uuid/uuid_io.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/variant.hpp b/external/boost/include/boost/variant.hpp
new file mode 100644
index 000000000..7019b15c0
--- /dev/null
+++ b/external/boost/include/boost/variant.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/variant.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/variant/recursive_variant.hpp b/external/boost/include/boost/variant/recursive_variant.hpp
new file mode 100644
index 000000000..38f71a0f3
--- /dev/null
+++ b/external/boost/include/boost/variant/recursive_variant.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/variant/recursive_variant.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/include/boost/version.hpp b/external/boost/include/boost/version.hpp
new file mode 100644
index 000000000..4843c225a
--- /dev/null
+++ b/external/boost/include/boost/version.hpp
@@ -0,0 +1,31 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas" /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/version.hpp>
+#pragma GCC diagnostic pop
diff --git a/external/boost/msvc2017.patch.0 b/external/boost/msvc2017.patch.0
new file mode 100644
index 000000000..4b1002a17
--- /dev/null
+++ b/external/boost/msvc2017.patch.0
@@ -0,0 +1,17 @@
+--- boost/iterator.hpp
++++ boost/iterator.hpp
+@@ -13,7 +13,14 @@
+ namespace boost
+ {
+
++#if defined _MSC_VER && !defined __clang__
++#pragma warning(push)
++#pragma warning(disable: 4996)
++#endif
+ using std::iterator;
++#if defined _MSC_VER && !defined __clang__
++#pragma warning(pop)
++#endif
+
+ } // namespace boost
+
diff --git a/external/boost/repack_tarball.sh b/external/boost/repack_tarball.sh
new file mode 100755
index 000000000..ed27875f6
--- /dev/null
+++ b/external/boost/repack_tarball.sh
@@ -0,0 +1,60 @@
+#! /bin/sh
+
+# Repack the boost tarball as xz (much faster to unpack) and remove
+# a lot of needless files such as generated html docs.
+
+tarball="$1"
+
+if test -z "$tarball" -o ! -f "$tarball"; then
+ echo "Usage: $0 <tarball>"
+ exit 1
+fi
+
+tmpdir=$(mktemp -d)
+
+if ! test -d "$tmpdir"; then
+ echo mktemp failed
+ exit 1
+fi
+
+echo Unpacking "$tarball" ...
+tar x -C "$tmpdir" -f "$tarball"
+if test $? -ne 0; then
+ echo tar x failed
+ rm -rf "$tmpdir"
+ exit 1
+fi
+
+echo Removing unnecessary files ...
+find "$tmpdir" \( -name doc -o -name test -o -name example \) -type d -prune -print0 | xargs -0 rm -r
+if test $? -ne 0; then
+ echo file removal failed
+ rm -rf "$tmpdir"
+ exit 1
+fi
+
+name="$(basename "$tarball" | sed 's/\.tar.*$//').tar.xz"
+dir=$(ls "$tmpdir")
+
+echo Creating "$name" ...
+# To make the tarball reproducible, use a timestamp of a file inside the tarball (they all seem to have the same mtime).
+if ! test -f "$tmpdir/$dir/README.md"; then
+ echo timestamp retrieval failed, check the script
+ rm -rf "$tmpdir"
+ exit 1
+fi
+# Many of the options are to make the tarball reproducible.
+LC_ALL=C tar c -C "$tmpdir" --xz -f "$(pwd)/$name" --format=gnu --sort=name --owner=0 --group=0 --mode=go=rX,u=rwX --mtime "$tmpdir/$dir/README.md" "$dir"
+if test $? -ne 0; then
+ echo tar c failed
+ rm -rf "$tmpdir"
+ exit 1
+fi
+
+echo Cleaning up ...
+rm -rf "$tmpdir"
+
+sha256sum "$name"
+
+echo Done.
+exit 0
diff --git a/external/boost/rtti.patch.0 b/external/boost/rtti.patch.0
new file mode 100644
index 000000000..249977a68
--- /dev/null
+++ b/external/boost/rtti.patch.0
@@ -0,0 +1,13 @@
+Visible function type RTTI for Clang -fsanitize=function
+
+--- boost/function/function_base.hpp
++++ boost/function/function_base.hpp
+@@ -159,7 +159,7 @@
+ };
+
+ // The operation type to perform on the given functor/function pointer
+- enum functor_manager_operation_type {
++ enum BOOST_SYMBOL_VISIBLE functor_manager_operation_type {
+ clone_functor_tag,
+ move_functor_tag,
+ destroy_functor_tag,
diff --git a/external/boost/windows-no-utf8-locales.patch.0 b/external/boost/windows-no-utf8-locales.patch.0
new file mode 100644
index 000000000..66038cad7
--- /dev/null
+++ b/external/boost/windows-no-utf8-locales.patch.0
@@ -0,0 +1,20 @@
+Don't ever attempt to initialise a std::locale with a UTF-8 locale on Windows -*- Mode: Diff -*-
+
+--- libs/locale/src/std/std_backend.cpp
++++ libs/locale/src/std/std_backend.cpp
+@@ -109,12 +109,13 @@
+ #endif
+ }
+ else {
++ #if !defined(BOOST_WINDOWS)
+ if(loadable(lid)) {
+ name_ = lid;
+ utf_mode_ = utf8_native_with_wide;
+ }
+- #if defined(BOOST_WINDOWS)
+- else if(loadable(win_name)) {
++ #else
++ if(loadable(win_name)) {
+ name_ = win_name;
+ utf_mode_ = utf8_from_wide;
+ }
diff --git a/external/box2d/Makefile b/external/box2d/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/box2d/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/box2d/Module_box2d.mk b/external/box2d/Module_box2d.mk
new file mode 100644
index 000000000..3986357b3
--- /dev/null
+++ b/external/box2d/Module_box2d.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,box2d))
+
+$(eval $(call gb_Module_add_targets,box2d,\
+ UnpackedTarball_box2d \
+))
+
+$(eval $(call gb_Module_add_targets,box2d,\
+ StaticLibrary_box2d \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/box2d/README b/external/box2d/README
new file mode 100644
index 000000000..d2b46b93b
--- /dev/null
+++ b/external/box2d/README
@@ -0,0 +1,3 @@
+Box2D is a 2D physics engine.
+
+It is available from [https://github.com/erincatto/box2d]
diff --git a/external/box2d/StaticLibrary_box2d.mk b/external/box2d/StaticLibrary_box2d.mk
new file mode 100644
index 000000000..1dfb6f252
--- /dev/null
+++ b/external/box2d/StaticLibrary_box2d.mk
@@ -0,0 +1,72 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,box2d))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,box2d,box2d))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,box2d))
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,box2d,cpp))
+
+$(eval $(call gb_StaticLibrary_set_include,box2d,\
+ -I$(call gb_UnpackedTarball_get_dir,box2d/include/)\
+ -I$(call gb_UnpackedTarball_get_dir,box2d/src/)\
+ $$(INCLUDE)\
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,box2d,\
+ UnpackedTarball/box2d/src/common/b2_timer \
+ UnpackedTarball/box2d/src/common/b2_stack_allocator \
+ UnpackedTarball/box2d/src/common/b2_draw \
+ UnpackedTarball/box2d/src/common/b2_math \
+ UnpackedTarball/box2d/src/common/b2_block_allocator \
+ UnpackedTarball/box2d/src/common/b2_settings \
+ UnpackedTarball/box2d/src/dynamics/b2_body \
+ UnpackedTarball/box2d/src/dynamics/b2_polygon_circle_contact \
+ UnpackedTarball/box2d/src/dynamics/b2_circle_contact \
+ UnpackedTarball/box2d/src/dynamics/b2_contact_solver \
+ UnpackedTarball/box2d/src/dynamics/b2_polygon_contact \
+ UnpackedTarball/box2d/src/dynamics/b2_chain_polygon_contact \
+ UnpackedTarball/box2d/src/dynamics/b2_chain_circle_contact \
+ UnpackedTarball/box2d/src/dynamics/b2_contact \
+ UnpackedTarball/box2d/src/dynamics/b2_edge_polygon_contact \
+ UnpackedTarball/box2d/src/dynamics/b2_edge_circle_contact \
+ UnpackedTarball/box2d/src/dynamics/b2_wheel_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_friction_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_prismatic_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_weld_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_pulley_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_mouse_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_motor_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_distance_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_gear_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_revolute_joint \
+ UnpackedTarball/box2d/src/dynamics/b2_world_callbacks \
+ UnpackedTarball/box2d/src/dynamics/b2_fixture \
+ UnpackedTarball/box2d/src/dynamics/b2_contact_manager \
+ UnpackedTarball/box2d/src/dynamics/b2_island \
+ UnpackedTarball/box2d/src/dynamics/b2_world \
+ UnpackedTarball/box2d/src/rope/b2_rope \
+ UnpackedTarball/box2d/src/collision/b2_time_of_impact \
+ UnpackedTarball/box2d/src/collision/b2_collide_polygon \
+ UnpackedTarball/box2d/src/collision/b2_distance \
+ UnpackedTarball/box2d/src/collision/b2_collision \
+ UnpackedTarball/box2d/src/collision/b2_collide_edge \
+ UnpackedTarball/box2d/src/collision/b2_collide_circle \
+ UnpackedTarball/box2d/src/collision/b2_broad_phase \
+ UnpackedTarball/box2d/src/collision/b2_edge_shape \
+ UnpackedTarball/box2d/src/collision/b2_circle_shape \
+ UnpackedTarball/box2d/src/collision/b2_chain_shape \
+ UnpackedTarball/box2d/src/collision/b2_polygon_shape \
+ UnpackedTarball/box2d/src/collision/b2_dynamic_tree \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/box2d/UnpackedTarball_box2d.mk b/external/box2d/UnpackedTarball_box2d.mk
new file mode 100644
index 000000000..7d7d60e93
--- /dev/null
+++ b/external/box2d/UnpackedTarball_box2d.mk
@@ -0,0 +1,16 @@
+#-*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,box2d))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,box2d,$(BOX2D_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,box2d,1))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/breakpad/0001-Handle-race-between-ExceptionHandler-SignalHandler-a.patch.1 b/external/breakpad/0001-Handle-race-between-ExceptionHandler-SignalHandler-a.patch.1
new file mode 100644
index 000000000..00762650f
--- /dev/null
+++ b/external/breakpad/0001-Handle-race-between-ExceptionHandler-SignalHandler-a.patch.1
@@ -0,0 +1,33 @@
+From caa6f1ea462d0f0c612b871106e3e309fe0290f5 Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman@redhat.com>
+Date: Thu, 16 Aug 2018 09:04:35 +0200
+Subject: [PATCH] Handle race between ExceptionHandler::SignalHandler and
+ ~ExceptionHandler
+
+...where thread A is blocked locking g_handler_stack_mutex_ in SignalHandler
+while thread B executes ~ExceptionHandler and sets g_handler_stack to null, but
+which thread A didn't expect to be null once it acquired the lock.
+---
+ src/client/linux/handler/exception_handler.cc | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
+index b895f6d7..4d58e510 100644
+--- a/src/client/linux/handler/exception_handler.cc
++++ b/src/client/linux/handler/exception_handler.cc
+@@ -372,8 +372,10 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
+ }
+
+ bool handled = false;
+- for (int i = g_handler_stack_->size() - 1; !handled && i >= 0; --i) {
+- handled = (*g_handler_stack_)[i]->HandleSignal(sig, info, uc);
++ if (g_handler_stack_ != NULL) {
++ for (int i = g_handler_stack_->size() - 1; !handled && i >= 0; --i) {
++ handled = (*g_handler_stack_)[i]->HandleSignal(sig, info, uc);
++ }
+ }
+
+ // Upon returning from this signal handler, sig will become unmasked and then
+--
+2.17.1
+
diff --git a/external/breakpad/ExternalProject_breakpad.mk b/external/breakpad/ExternalProject_breakpad.mk
new file mode 100644
index 000000000..a4f124a49
--- /dev/null
+++ b/external/breakpad/ExternalProject_breakpad.mk
@@ -0,0 +1,39 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,breakpad))
+
+$(eval $(call gb_ExternalProject_register_targets,breakpad,\
+ build \
+))
+
+
+ifeq ($(COM),MSC)
+
+$(call gb_ExternalProject_get_state_target,breakpad,build) :
+ $(call gb_Trace_StartRange,breakpad,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ MSBuild.exe src/tools/windows/dump_syms/dump_syms.sln -p:Configuration=Release \
+ /p:PlatformToolset=$(VCTOOLSET) /p:VisualStudioVersion=$(VCVER) /ToolsVersion:Current \
+ )
+ $(call gb_Trace_EndRange,breakpad,EXTERNAL)
+
+else # !ifeq($(COM),MSC)
+
+$(call gb_ExternalProject_get_state_target,breakpad,build) :
+ $(call gb_Trace_StartRange,breakpad,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure CXXFLAGS="-O2 $(gb_VISIBILITY_FLAGS)" \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,breakpad,EXTERNAL)
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/breakpad/Makefile b/external/breakpad/Makefile
new file mode 100644
index 000000000..569ad8a0b
--- /dev/null
+++ b/external/breakpad/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/breakpad/Module_breakpad.mk b/external/breakpad/Module_breakpad.mk
new file mode 100644
index 000000000..f68385ffb
--- /dev/null
+++ b/external/breakpad/Module_breakpad.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,breakpad))
+
+$(eval $(call gb_Module_add_targets,breakpad,\
+ UnpackedTarball_breakpad \
+))
+
+$(eval $(call gb_Module_add_targets,breakpad,\
+ ExternalProject_breakpad \
+))
+ifeq ($(OS),WNT)
+$(eval $(call gb_Module_add_targets,breakpad,\
+ StaticLibrary_breakpad \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/breakpad/README b/external/breakpad/README
new file mode 100644
index 000000000..dfd2bf91c
--- /dev/null
+++ b/external/breakpad/README
@@ -0,0 +1,21 @@
+Google breakpad crash-reporting library
+
+https://chromium.googlesource.com/breakpad/breakpad
+
+When this is enabled and soffice.bin crashes, a "mini-dump" file is written
+as "instdir/crash/*.dmp".
+
+There is an UI to upload the mini-dump to a TDF server but of course
+that only makes sense if the server has symbols available that match
+the build, which is not the case if you have built LO yourself.
+
+If you want to get the backtrace from local mini-dump files:
+
+* with Visual Studio:
+ 1. open the *.dmp file from the Visual Studio IDE File->Open->File
+ 2. then click "Debug Native Only"
+
+* otherwise:
+ 1. run "make symbols" to extract the debuginfo from the binaries
+ 2. run "workdir/UnpackedTarball/breakpad/src/processor/minidump_stackwalk foo.dmp workdir/symbols"
+
diff --git a/external/breakpad/SIGSTKSZ.patch b/external/breakpad/SIGSTKSZ.patch
new file mode 100644
index 000000000..d37c58a2f
--- /dev/null
+++ b/external/breakpad/SIGSTKSZ.patch
@@ -0,0 +1,11 @@
+--- src/client/linux/handler/exception_handler.cc
++++ src/client/linux/handler/exception_handler.cc
+@@ -138,7 +138,7 @@
+ // SIGSTKSZ may be too small to prevent the signal handlers from overrunning
+ // the alternative stack. Ensure that the size of the alternative stack is
+ // large enough.
+- static const unsigned kSigStackSize = std::max(16384, SIGSTKSZ);
++ static const unsigned kSigStackSize = std::max<decltype(SIGSTKSZ)>(16384, SIGSTKSZ);
+
+ // Only set an alternative stack if there isn't already one, or if the current
+ // one is too small.
diff --git a/external/breakpad/StaticLibrary_breakpad.mk b/external/breakpad/StaticLibrary_breakpad.mk
new file mode 100644
index 000000000..fc5d3251f
--- /dev/null
+++ b/external/breakpad/StaticLibrary_breakpad.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,breakpad))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,breakpad))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,breakpad,breakpad))
+
+$(eval $(call gb_StaticLibrary_set_include,breakpad,\
+ -I$(call gb_UnpackedTarball_get_dir,breakpad)/src \
+ -I$(call gb_UnpackedTarball_get_dir,breakpad)/src/client/windows \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_StaticLibrary_add_defs,breakpad,\
+ -DUNICODE \
+))
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,breakpad,cc))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,breakpad,\
+ UnpackedTarball/breakpad/src/common/windows/guid_string \
+ UnpackedTarball/breakpad/src/client/windows/handler/exception_handler \
+ UnpackedTarball/breakpad/src/client/windows/crash_generation/client_info \
+ UnpackedTarball/breakpad/src/client/windows/crash_generation/crash_generation_client \
+ UnpackedTarball/breakpad/src/client/windows/crash_generation/crash_generation_server \
+ UnpackedTarball/breakpad/src/client/windows/crash_generation/minidump_generator \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/breakpad/UnpackedTarball_breakpad.mk b/external/breakpad/UnpackedTarball_breakpad.mk
new file mode 100644
index 000000000..eca3d550d
--- /dev/null
+++ b/external/breakpad/UnpackedTarball_breakpad.mk
@@ -0,0 +1,48 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,breakpad))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,breakpad,0))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,breakpad,$(BREAKPAD_TARBALL)))
+
+# external/breakpad/0001-Handle-race-between-ExceptionHandler-SignalHandler-a.patch upstreamed at
+# <https://chromium-review.googlesource.com/c/breakpad/breakpad/+/1176811> "Handle race between
+# ExceptionHandler::SignalHandler and ~ExceptionHandler";
+# external/breakpad/SIGSTKSZ.patch upstreamed at
+# <https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3226470> "Adpat to SIGSTKSZ type
+# in glibc 2.34":
+$(eval $(call gb_UnpackedTarball_add_patches,breakpad,\
+ external/breakpad/breakpad-use-correct-http-header.patch.1 \
+ external/breakpad/breakpad-wshadow.patch.1 \
+ external/breakpad/breakpad-stackwalk.patch.1 \
+ external/breakpad/0001-Handle-race-between-ExceptionHandler-SignalHandler-a.patch.1 \
+ external/breakpad/c++20-allocator.patch \
+ external/breakpad/breakpad-dump_syms.patch.1 \
+ external/breakpad/breakpad-no-env.patch.1 \
+ external/breakpad/SIGSTKSZ.patch \
+ external/breakpad/sanitizer.patch \
+ external/breakpad/include.patch \
+))
+
+$(eval $(call gb_UnpackedTarball_add_files,breakpad,src/tools/windows/dump_syms,\
+ external/breakpad/dump_syms.vcxproj \
+ external/breakpad/dump_syms.sln \
+))
+
+ifeq ($(COM_IS_CLANG),TRUE)
+ifneq ($(filter -fsanitize=%,$(CC)),)
+$(eval $(call gb_UnpackedTarball_add_patches,breakpad, \
+ external/breakpad/ubsan.patch \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/breakpad/breakpad-dump_syms.patch.1 b/external/breakpad/breakpad-dump_syms.patch.1
new file mode 100644
index 000000000..d895be7ef
--- /dev/null
+++ b/external/breakpad/breakpad-dump_syms.patch.1
@@ -0,0 +1,34 @@
+diff -ur breakpad.org/src/common/windows/pdb_source_line_writer.cc breakpad/src/common/windows/pdb_source_line_writer.cc
+--- breakpad.org/src/common/windows/pdb_source_line_writer.cc 2021-06-11 12:37:22.682324700 +0200
++++ breakpad/src/common/windows/pdb_source_line_writer.cc 2021-06-11 12:44:24.480184800 +0200
+@@ -34,7 +34,7 @@
+ #include <atlbase.h>
+ #include <dia2.h>
+ #include <diacreate.h>
+-#include <ImageHlp.h>
++#include <dbghelp.h>
+ #include <stdio.h>
+
+ #include <algorithm>
+diff -ur breakpad.org/src/common/windows/pe_util.cc breakpad/src/common/windows/pe_util.cc
+--- breakpad.org/src/common/windows/pe_util.cc 2021-06-11 12:37:22.682324700 +0200
++++ breakpad/src/common/windows/pe_util.cc 2021-06-11 12:52:34.542708600 +0200
+@@ -35,6 +35,7 @@
+ #include <ImageHlp.h>
+
+ #include <functional>
++#include <memory>
+
+ #include "common/windows/string_utils-inl.h"
+ #include "common/windows/guid_string.h"
+diff -ur breakpad.org/src/tools/windows/dump_syms/dump_syms.cc breakpad/src/tools/windows/dump_syms/dump_syms.cc
+--- breakpad.org/src/tools/windows/dump_syms/dump_syms.cc 2021-06-11 12:37:20.697959400 +0200
++++ breakpad/src/tools/windows/dump_syms/dump_syms.cc 2021-06-11 12:41:16.922559700 +0200
+@@ -33,6 +33,7 @@
+ #include <stdio.h>
+ #include <wchar.h>
+
++#include <memory>
+ #include <string>
+
+ #include "common/windows/pdb_source_line_writer.h"
diff --git a/external/breakpad/breakpad-no-env.patch.1 b/external/breakpad/breakpad-no-env.patch.1
new file mode 100644
index 000000000..d1b37bd21
--- /dev/null
+++ b/external/breakpad/breakpad-no-env.patch.1
@@ -0,0 +1,13 @@
+diff -ur breakpad.org/src/client/linux/minidump_writer/minidump_writer.cc breakpad/src/client/linux/minidump_writer/minidump_writer.cc
+--- breakpad.org/src/client/linux/minidump_writer/minidump_writer.cc 2021-06-19 15:32:57.258078847 +0200
++++ breakpad/src/client/linux/minidump_writer/minidump_writer.cc 2021-06-19 15:35:07.014082452 +0200
+@@ -289,7 +289,8 @@
+ dir.CopyIndex(dir_index++, &dirent);
+
+ dirent.stream_type = MD_LINUX_ENVIRON;
+- if (!WriteProcFile(&dirent.location, GetCrashThread(), "environ"))
++ // don't include the user's env
++ if (true || !WriteProcFile(&dirent.location, GetCrashThread(), "environ"))
+ NullifyDirectoryEntry(&dirent);
+ dir.CopyIndex(dir_index++, &dirent);
+
diff --git a/external/breakpad/breakpad-stackwalk.patch.1 b/external/breakpad/breakpad-stackwalk.patch.1
new file mode 100644
index 000000000..85362b8fb
--- /dev/null
+++ b/external/breakpad/breakpad-stackwalk.patch.1
@@ -0,0 +1,32 @@
+diff -u -p -d -N -r breakpad.sav/src/processor/stackwalk_common.cc breakpad/src/processor/stackwalk_common.cc
+--- breakpad.sav/src/processor/stackwalk_common.cc 2021-04-07 19:16:35.771272332 +0200
++++ breakpad/src/processor/stackwalk_common.cc 2021-04-07 19:40:46.039940981 +0200
+@@ -750,7 +750,7 @@ static void PrintModules(
+ // one per line, in the following machine-readable pipe-delimited
+ // text format:
+ // Module|{Module Filename}|{Version}|{Debug Filename}|{Debug Identifier}|
+-// {Base Address}|{Max Address}|{Main}
++// {Base Address}|{Max Address}|{Main}|{Code Identifier}
+ static void PrintModulesMachineReadable(const CodeModules* modules) {
+ if (!modules)
+ return;
+@@ -767,7 +767,7 @@ static void PrintModulesMachineReadable(
+ ++module_sequence) {
+ const CodeModule* module = modules->GetModuleAtSequence(module_sequence);
+ uint64_t base_address = module->base_address();
+- printf("Module%c%s%c%s%c%s%c%s%c0x%08" PRIx64 "%c0x%08" PRIx64 "%c%d\n",
++ printf("Module%c%s%c%s%c%s%c%s%c0x%08" PRIx64 "%c0x%08" PRIx64 "%c%d%c%s\n",
+ kOutputSeparator,
+ StripSeparator(PathnameStripper::File(module->code_file())).c_str(),
+ kOutputSeparator, StripSeparator(module->version()).c_str(),
+@@ -778,7 +778,9 @@ static void PrintModulesMachineReadable(
+ kOutputSeparator, base_address,
+ kOutputSeparator, base_address + module->size() - 1,
+ kOutputSeparator,
+- main_module != NULL && base_address == main_address ? 1 : 0);
++ main_module != NULL && base_address == main_address ? 1 : 0,
++ kOutputSeparator,
++ StripSeparator(PathnameStripper::File(module->code_identifier())).c_str());
+ }
+ }
+
diff --git a/external/breakpad/breakpad-use-correct-http-header.patch.1 b/external/breakpad/breakpad-use-correct-http-header.patch.1
new file mode 100644
index 000000000..257d5465b
--- /dev/null
+++ b/external/breakpad/breakpad-use-correct-http-header.patch.1
@@ -0,0 +1,14 @@
+diff -ur breakpad.org/src/tools/linux/symupload/minidump_upload.cc breakpad/src/tools/linux/symupload/minidump_upload.cc
+--- breakpad.org/src/tools/linux/symupload/minidump_upload.cc 2015-11-23 17:37:53.830558138 +0100
++++ breakpad/src/tools/linux/symupload/minidump_upload.cc 2015-11-23 17:38:59.559051874 +0100
+@@ -59,8 +59,8 @@
+ static void Start(Options *options) {
+ std::map<string, string> parameters;
+ // Add parameters
+- parameters["prod"] = options->product;
+- parameters["ver"] = options->version;
++ parameters["ProductName"] = options->product;
++ parameters["Version"] = options->version;
+
+ std::map<string, string> files;
+ files["upload_file_minidump"] = options->minidumpPath;
diff --git a/external/breakpad/breakpad-wshadow.patch.1 b/external/breakpad/breakpad-wshadow.patch.1
new file mode 100644
index 000000000..87010f851
--- /dev/null
+++ b/external/breakpad/breakpad-wshadow.patch.1
@@ -0,0 +1,65 @@
+diff -u -p -d -N -r breakpad.sav/src/client/linux/handler/minidump_descriptor.h breakpad/src/client/linux/handler/minidump_descriptor.h
+--- breakpad.sav/src/client/linux/handler/minidump_descriptor.h 2021-04-07 19:12:50.329462509 +0200
++++ breakpad/src/client/linux/handler/minidump_descriptor.h 2021-04-07 19:29:58.526084027 +0200
+@@ -57,27 +57,27 @@ class MinidumpDescriptor {
+ address_within_principal_mapping_(0),
+ skip_dump_if_principal_mapping_not_referenced_(false) {}
+
+- explicit MinidumpDescriptor(const string& directory)
++ explicit MinidumpDescriptor(const string& dir)
+ : mode_(kWriteMinidumpToFile),
+ fd_(-1),
+- directory_(directory),
++ directory_(dir),
+ c_path_(NULL),
+ size_limit_(-1),
+ address_within_principal_mapping_(0),
+ skip_dump_if_principal_mapping_not_referenced_(false),
+ sanitize_stacks_(false) {
+- assert(!directory.empty());
++ assert(!dir.empty());
+ }
+
+- explicit MinidumpDescriptor(int fd)
++ explicit MinidumpDescriptor(int file_descriptor)
+ : mode_(kWriteMinidumpToFd),
+- fd_(fd),
++ fd_(file_descriptor),
+ c_path_(NULL),
+ size_limit_(-1),
+ address_within_principal_mapping_(0),
+ skip_dump_if_principal_mapping_not_referenced_(false),
+ sanitize_stacks_(false) {
+- assert(fd != -1);
++ assert(file_descriptor != -1);
+ }
+
+ explicit MinidumpDescriptor(const MicrodumpOnConsole&)
+diff -u -p -d -N -r breakpad.sav/src/client/linux/minidump_writer/linux_dumper.h breakpad/src/client/linux/minidump_writer/linux_dumper.h
+--- breakpad.sav/src/client/linux/minidump_writer/linux_dumper.h 2021-04-07 19:12:50.329462509 +0200
++++ breakpad/src/client/linux/minidump_writer/linux_dumper.h 2021-04-07 19:27:50.808928572 +0200
+@@ -176,12 +176,12 @@ class LinuxDumper {
+ void SetCrashInfoFromSigInfo(const siginfo_t& siginfo);
+
+ uintptr_t crash_address() const { return crash_address_; }
+- void set_crash_address(uintptr_t crash_address) {
+- crash_address_ = crash_address;
++ void set_crash_address(uintptr_t crash_addr) {
++ crash_address_ = crash_addr;
+ }
+
+ int crash_signal() const { return crash_signal_; }
+- void set_crash_signal(int crash_signal) { crash_signal_ = crash_signal; }
++ void set_crash_signal(int crash_sig) { crash_signal_ = crash_sig; }
+ const char* GetCrashSignalString() const;
+
+ void set_crash_signal_code(int code) { crash_signal_code_ = code; }
+@@ -196,7 +196,7 @@ class LinuxDumper {
+ }
+
+ pid_t crash_thread() const { return crash_thread_; }
+- void set_crash_thread(pid_t crash_thread) { crash_thread_ = crash_thread; }
++ void set_crash_thread(pid_t thread) { crash_thread_ = thread; }
+
+ // Concatenates the |root_prefix_| and |mapping| path. Writes into |path| and
+ // returns true unless the string is too long.
diff --git a/external/breakpad/c++20-allocator.patch b/external/breakpad/c++20-allocator.patch
new file mode 100644
index 000000000..245fac9e2
--- /dev/null
+++ b/external/breakpad/c++20-allocator.patch
@@ -0,0 +1,12 @@
+diff -u -p -d -N -r breakpad.sav/src/common/memory_allocator.h breakpad/src/common/memory_allocator.h
+--- src/common/memory_allocator.h 2021-04-07 19:12:50.357462734 +0200
++++ src/common/memory_allocator.h 2021-04-07 19:45:05.490291766 +0200
+@@ -161,7 +161,7 @@ class PageAllocator {
+ // Wrapper to use with STL containers
+ template <typename T>
+ struct PageStdAllocator : public std::allocator<T> {
+- typedef typename std::allocator<T>::pointer pointer;
++ typedef T* pointer;
+ typedef typename std::allocator<T>::size_type size_type;
+
+ explicit PageStdAllocator(PageAllocator& allocator) : allocator_(allocator),
diff --git a/external/breakpad/dump_syms.sln b/external/breakpad/dump_syms.sln
new file mode 100644
index 000000000..354b1783c
--- /dev/null
+++ b/external/breakpad/dump_syms.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31229.75
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dump_syms", "dump_syms.vcxproj", "{792E1530-E2C5-4289-992E-317BA30E9D9F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {792E1530-E2C5-4289-992E-317BA30E9D9F}.Debug|x86.ActiveCfg = Debug|Win32
+ {792E1530-E2C5-4289-992E-317BA30E9D9F}.Debug|x86.Build.0 = Debug|Win32
+ {792E1530-E2C5-4289-992E-317BA30E9D9F}.Release|x86.ActiveCfg = Release|Win32
+ {792E1530-E2C5-4289-992E-317BA30E9D9F}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {86FBC9CF-7AF1-4996-BB80-EB24CCFC561A}
+ EndGlobalSection
+EndGlobal
diff --git a/external/breakpad/dump_syms.vcxproj b/external/breakpad/dump_syms.vcxproj
new file mode 100644
index 000000000..9f0fcda9e
--- /dev/null
+++ b/external/breakpad/dump_syms.vcxproj
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{792E1530-E2C5-4289-992E-317BA30E9D9F}</ProjectGuid>
+ <RootNamespace>dumpsyms</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>16.0.31227.257</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>Debug\</OutDir>
+ <IntDir>Debug\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>Release\</OutDir>
+ <IntDir>Release\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>$(VSInstallDir)\DIA SDK\include;..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>$(VSInstallDir)\DIA SDK\lib\diaguids.lib;Dbghelp.lib;imagehlp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(VSInstallDir)\DIA SDK\include;..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>$(VSInstallDir)\DIA SDK\lib\diaguids.lib;Dbghelp.lib;imagehlp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\common\windows\dia_util.h" />
+ <ClInclude Include="..\..\..\common\windows\guid_string.h" />
+ <ClInclude Include="..\..\..\common\windows\omap.h" />
+ <ClInclude Include="..\..\..\common\windows\omap_internal.h" />
+ <ClInclude Include="..\..\..\common\windows\pdb_source_line_writer.h" />
+ <ClInclude Include="..\..\..\common\windows\string_utils-inl.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\common\windows\dia_util.cc" />
+ <ClCompile Include="..\..\..\common\windows\guid_string.cc" />
+ <ClCompile Include="..\..\..\common\windows\omap.cc" />
+ <ClCompile Include="..\..\..\common\windows\pdb_source_line_writer.cc" />
+ <ClCompile Include="..\..\..\common\windows\pe_source_line_writer.cc" />
+ <ClCompile Include="..\..\..\common\windows\pe_util.cc" />
+ <ClCompile Include="..\..\..\common\windows\string_utils.cc" />
+ <ClCompile Include="dump_syms.cc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/external/breakpad/include.patch b/external/breakpad/include.patch
new file mode 100644
index 000000000..e90ae9c11
--- /dev/null
+++ b/external/breakpad/include.patch
@@ -0,0 +1,10 @@
+--- src/client/linux/handler/minidump_descriptor.h
++++ src/client/linux/handler/minidump_descriptor.h
+@@ -31,6 +31,7 @@
+ #define CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_
+
+ #include <assert.h>
++#include <stdint.h>
+ #include <sys/types.h>
+
+ #include <string>
diff --git a/external/breakpad/sanitizer.patch b/external/breakpad/sanitizer.patch
new file mode 100644
index 000000000..5d673103d
--- /dev/null
+++ b/external/breakpad/sanitizer.patch
@@ -0,0 +1,29 @@
+--- src/client/linux/minidump_writer/minidump_writer.cc
++++ src/client/linux/minidump_writer/minidump_writer.cc
+@@ -717,7 +717,7 @@
+ const std::vector<uint64_t> crash_exception_info =
+ dumper_->crash_exception_info();
+ stream->exception_record.number_parameters = crash_exception_info.size();
+- memcpy(stream->exception_record.exception_information,
++ if (!crash_exception_info.empty()) memcpy(stream->exception_record.exception_information,
+ crash_exception_info.data(),
+ sizeof(uint64_t) * crash_exception_info.size());
+ stream->thread_context = crashing_thread_context_;
+@@ -760,7 +760,7 @@
+ // Adjust base address with the virtual address of the PT_LOAD segment
+ // corresponding to offset 0
+ if (ph.p_type == PT_LOAD && ph.p_offset == 0) {
+- base -= ph.p_vaddr;
++ base = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(base) - ph.p_vaddr);
+ }
+ if (ph.p_type == PT_DYNAMIC) {
+ dyn_addr = ph.p_vaddr;
+@@ -769,7 +769,7 @@
+ if (!dyn_addr)
+ return false;
+
+- ElfW(Dyn)* dynamic = reinterpret_cast<ElfW(Dyn)*>(dyn_addr + base);
++ ElfW(Dyn)* dynamic = reinterpret_cast<ElfW(Dyn)*>(dyn_addr + reinterpret_cast<uintptr_t>(base));
+
+ // The dynamic linker makes information available that helps gdb find all
+ // DSOs loaded into the program. If this information is indeed available,
diff --git a/external/breakpad/ubsan.patch b/external/breakpad/ubsan.patch
new file mode 100644
index 000000000..29790b4c0
--- /dev/null
+++ b/external/breakpad/ubsan.patch
@@ -0,0 +1,21 @@
+--- src/client/linux/minidump_writer/directory_reader.h
++++ src/client/linux/minidump_writer/directory_reader.h
+@@ -96,7 +96,7 @@
+ const int fd_;
+ bool hit_eof_;
+ unsigned buf_used_;
+- uint8_t buf_[sizeof(struct kernel_dirent) + NAME_MAX + 1];
++ uint8_t buf_[sizeof(struct kernel_dirent) + NAME_MAX + 1] __attribute__ ((aligned (__BIGGEST_ALIGNMENT__)));
+ };
+
+ } // namespace google_breakpad
+--- src/common/memory_allocator.h
++++ src/common/memory_allocator.h
+@@ -75,6 +75,7 @@
+ if (!bytes)
+ return NULL;
+
++ bytes = (bytes + (__BIGGEST_ALIGNMENT__ - 1)) & ~(__BIGGEST_ALIGNMENT__ - 1);
+ if (current_page_ && page_size_ - page_offset_ >= bytes) {
+ uint8_t* const ret = current_page_ + page_offset_;
+ page_offset_ += bytes;
diff --git a/external/bzip2/ExternalProject_bzip2.mk b/external/bzip2/ExternalProject_bzip2.mk
new file mode 100644
index 000000000..8b37bcd27
--- /dev/null
+++ b/external/bzip2/ExternalProject_bzip2.mk
@@ -0,0 +1,34 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,bzip2))
+
+$(eval $(call gb_ExternalProject_register_targets,bzip2,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_nmake,bzip2,build))
+
+ifeq ($(COM),MSC)
+$(call gb_ExternalProject_get_state_target,bzip2,build):
+ $(call gb_Trace_StartRange,bzip2,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ nmake -nologo -f makefile.msc \
+ )
+ $(call gb_Trace_EndRange,bzip2,EXTERNAL)
+else
+$(call gb_ExternalProject_get_state_target,bzip2,build):
+ $(call gb_Trace_StartRange,bzip2,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,bzip2,EXTERNAL)
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/bzip2/Makefile b/external/bzip2/Makefile
new file mode 100644
index 000000000..569ad8a0b
--- /dev/null
+++ b/external/bzip2/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/bzip2/Module_bzip2.mk b/external/bzip2/Module_bzip2.mk
new file mode 100644
index 000000000..2a59f7a6a
--- /dev/null
+++ b/external/bzip2/Module_bzip2.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,bzip2))
+
+$(eval $(call gb_Module_add_targets,bzip2,\
+ ExternalProject_bzip2 \
+ UnpackedTarball_bzip2 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/bzip2/README b/external/bzip2/README
new file mode 100644
index 000000000..917a9d662
--- /dev/null
+++ b/external/bzip2/README
@@ -0,0 +1 @@
+Data compression library from [http://bzip.org/].
diff --git a/external/bzip2/UnpackedTarball_bzip2.mk b/external/bzip2/UnpackedTarball_bzip2.mk
new file mode 100644
index 000000000..f22ca2b5c
--- /dev/null
+++ b/external/bzip2/UnpackedTarball_bzip2.mk
@@ -0,0 +1,24 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,bzip2))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,bzip2,$(BZIP2_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,bzip2,\
+ blocksort.c \
+ bzlib.c \
+ compress.c \
+ crctable.c \
+ decompress.c \
+ huffman.c \
+ randtable.c \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cairo/ExternalPackage_cairo.mk b/external/cairo/ExternalPackage_cairo.mk
new file mode 100644
index 000000000..116db8a34
--- /dev/null
+++ b/external/cairo/ExternalPackage_cairo.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,cairo,cairo))
+
+$(eval $(call gb_ExternalPackage_use_external_project,cairo,cairo))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+$(eval $(call gb_ExternalPackage_add_file,cairo,$(LIBO_LIB_FOLDER)/libcairo.so.2,src/.libs/libcairo.so.2.1170$(CAIRO_VERSION_MICRO).0))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cairo/ExternalPackage_pixman.mk b/external/cairo/ExternalPackage_pixman.mk
new file mode 100644
index 000000000..85ff062f2
--- /dev/null
+++ b/external/cairo/ExternalPackage_pixman.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,pixman,pixman))
+
+$(eval $(call gb_ExternalPackage_use_external_project,pixman,pixman))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+$(eval $(call gb_ExternalPackage_add_file,pixman,$(LIBO_LIB_FOLDER)/libpixman-1.so.0,pixman/.libs/libpixman-1.so.0.42.2))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cairo/ExternalProject_cairo.mk b/external/cairo/ExternalProject_cairo.mk
new file mode 100644
index 000000000..53a51b5e4
--- /dev/null
+++ b/external/cairo/ExternalProject_cairo.mk
@@ -0,0 +1,84 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,cairo))
+
+$(eval $(call gb_ExternalProject_use_external_project,cairo,pixman))
+
+$(eval $(call gb_ExternalProject_use_externals,cairo,\
+ fontconfig \
+ freetype \
+ libpng \
+ zlib \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,cairo,\
+ build \
+))
+
+# Including -rtlib=compiler-rt in pixman_LIBS is a BAD HACK: At least when compiling with Clang
+# -fsanitize=undefined on Linux x86-64, the generated code references __muloti4, which is an
+# extension provided by libclang_rt.builtins-x86_64.a runtime, but not by GCC's libgcc_s.so.1 (which
+# ultimately boils down to a bug in LLVM, I would say). I am not sure whether it should in general
+# work to mix uses of the (default on Linux, at least) GCC libgcc_s and LLVM's libclang_rt.builtins
+# runtime libraries in one process, but for this specific case of libcairo.so it appears to work
+# well: For one, the only symbol referenced by libcairo.so from the runtime library is __muloti4;
+# for another, at least in my LLVM build, lib/clang/12.0.0/lib/linux/libclang_rt.builtins-x86_64.a
+# is only provided as a static archive; so libcairo.so will only contain a "harmless" copy of
+# __muloti4 and not have a DT_NEEDED of any libclang_rt.builtins dynamic library that it would pull
+# in at runtime.
+# But passing -rtlib=compiler-rt into cairo's configure via the more obvious LDFLAGS would fail at
+# least when building with -fsanitize=address and -fsanitize=undefined, as then the executable
+# compiled by configure when "checking whether the C compiler works" would reference
+# _Unwind_Backtrace etc. that are provided by GCC's libgcc_s.so.1 but not by LLVM's
+# libclang_rt.builtins-x86_64.a (and whatever the reason for that inconsistency). So
+# -rtlib=compiler-rt must be passed just into the linking of libcairo.so, but not generally into
+# cairo's configure. And pixman_LIBS happens to offer that. (The -Wc is necessary so that libtool
+# does not throw away the -rtlib=compiler-rt which it does not understand.)
+
+$(call gb_ExternalProject_get_state_target,cairo,build) :
+ $(call gb_Trace_StartRange,cairo,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure \
+ $(if $(debug),STRIP=" ") \
+ $(if $(filter ANDROID iOS,$(OS)),CFLAGS="$(if $(debug),-g) $(ZLIB_CFLAGS) $(gb_VISIBILITY_FLAGS)") \
+ $(if $(filter EMSCRIPTEN,$(OS)),CFLAGS=" $(ZLIB_CFLAGS) -Wno-enum-conversion $(gb_EMSCRIPTEN_CPPFLAGS)" --enable-pthread=yes PTHREAD_LIBS="") \
+ $(if $(filter-out EMSCRIPTEN ANDROID iOS,$(OS)), \
+ CFLAGS="$(CFLAGS) $(call gb_ExternalProject_get_build_flags,cairo) $(ZLIB_CFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,cairo)" \
+ ) \
+ $(if $(filter ANDROID iOS,$(OS)),PKG_CONFIG=./dummy_pkg_config) \
+ LIBS="$(ZLIB_LIBS)" \
+ $(if $(filter -fsanitize=%,$(LDFLAGS)),LDFLAGS="$(LDFLAGS) -fuse-ld=bfd") \
+ pixman_CFLAGS="-I$(call gb_UnpackedTarball_get_dir,pixman)/pixman -pthread" \
+ pixman_LIBS="-L$(call gb_UnpackedTarball_get_dir,pixman)/pixman/.libs -lpixman-1 \
+ $(if $(filter LINUX,$(OS)),-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\\\$$\$$ORIGIN) \
+ $(if $(filter -fsanitize=%,$(CC)), \
+ $(if $(filter LINUX-X86_64-TRUE,$(OS)-$(CPUNAME)-$(COM_IS_CLANG)), \
+ -Wc$(COMMA)-rtlib=compiler-rt))" \
+ png_REQUIRES="trick_configure_into_using_png_CFLAGS_and_LIBS" \
+ png_CFLAGS="$(LIBPNG_CFLAGS)" png_LIBS="$(LIBPNG_LIBS)" \
+ $(if $(SYSTEM_FREETYPE),,FREETYPE_CFLAGS="-I$(call gb_UnpackedTarball_get_dir,freetype)/include") \
+ $(if $(SYSTEM_FONTCONFIG),,FONTCONFIG_CFLAGS="-I$(call gb_UnpackedTarball_get_dir,fontconfig)") \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),--disable-shared,--disable-static) \
+ $(if $(filter EMSCRIPTEN ANDROID iOS,$(OS)),--disable-xlib --disable-xcb,$(if $(filter TRUE,$(DISABLE_GUI)),--disable-xlib --disable-xcb,--enable-xlib --enable-xcb)) \
+ $(if $(filter iOS,$(OS)),--enable-quartz --enable-quartz-font) \
+ --disable-valgrind \
+ $(if $(filter iOS,$(OS)),--disable-ft,--enable-ft --enable-fc) \
+ --disable-svg --enable-gtk-doc=no --enable-test-surfaces=no \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),$(if $(filter INTEL ARM,$(CPUNAME)),ac_cv_c_bigendian=no ax_cv_c_float_words_bigendian=no)) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ && cd src && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,cairo,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cairo/ExternalProject_pixman.mk b/external/cairo/ExternalProject_pixman.mk
new file mode 100644
index 000000000..9293b9234
--- /dev/null
+++ b/external/cairo/ExternalProject_pixman.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,pixman))
+
+$(eval $(call gb_ExternalProject_register_targets,pixman,\
+ build \
+))
+
+# ANDROID:
+# The pixman-cpu.c code wants to read /proc/<pid>/auxv, but
+# the Android headers don't define Elf32_auxv_t.
+#
+# Maybe we should instead just patch the arm_has_* booleans in
+# pixman-cpu.c to be hardcoded as TRUE and patch out the run-time
+# check?
+$(call gb_ExternalProject_get_state_target,pixman,build) :
+ $(call gb_Trace_StartRange,pixman,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),--disable-shared,--disable-static) \
+ $(if $(filter ANDROID,$(OS)),--disable-arm-simd --disable-arm-neon --disable-arm-a64-neon --disable-arm-iwmmxt) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),$(if $(filter INTEL ARM,$(CPUNAME)),ac_cv_c_bigendian=no)) \
+ $(if $(filter EMSCRIPTEN,$(OS)),CFLAGS="-pthread") \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,pixman,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cairo/Makefile b/external/cairo/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/cairo/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cairo/Module_cairo.mk b/external/cairo/Module_cairo.mk
new file mode 100644
index 000000000..6d8a29add
--- /dev/null
+++ b/external/cairo/Module_cairo.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,cairo))
+
+$(eval $(call gb_Module_add_targets,cairo,\
+ ExternalPackage_cairo \
+ ExternalPackage_pixman \
+ ExternalProject_cairo \
+ ExternalProject_pixman \
+ UnpackedTarball_cairo \
+ UnpackedTarball_pixman \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cairo/README b/external/cairo/README
new file mode 100644
index 000000000..3d955dcd0
--- /dev/null
+++ b/external/cairo/README
@@ -0,0 +1,6 @@
+The graphics library, used for anti-aliasing. From [http://cairographics.org/].
+
+This code is used by default only on Linux, though it is also
+available on Mac. There is a cairo-canvas implementation that is the
+main customer, and it is enabled via 'use hardware acceleration' in
+the general options.
diff --git a/external/cairo/UnpackedTarball_cairo.mk b/external/cairo/UnpackedTarball_cairo.mk
new file mode 100644
index 000000000..e746a4899
--- /dev/null
+++ b/external/cairo/UnpackedTarball_cairo.mk
@@ -0,0 +1,46 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,cairo))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,cairo,$(CAIRO_TARBALL),,cairo))
+
+# cairo >= 1.17.6 was probably created in Fedora where
+# https://salsa.debian.org/mckinstry/libtool/-/commit/26c23f951d049241128e5e04a7bbc263e5b145f1
+# isn't applied, so add that in to avoid: /usr/bin/ld: unrecognized option '--gdb-index'
+
+$(eval $(call gb_UnpackedTarball_add_patches,cairo,\
+ external/cairo/cairo/cairo.buildfix.patch \
+ external/cairo/cairo/cairo.RGB24_888.patch \
+ external/cairo/cairo/cairo-libtool-rpath.patch.1 \
+ external/cairo/cairo/cairo.oldfreetype.patch \
+ external/cairo/cairo/san.patch.0 \
+ external/cairo/cairo/cairo.ofz46165.patch.1 \
+ external/cairo/cairo/0025-libtool-pass-use-ld.patch \
+))
+
+ifeq ($(OS),iOS)
+$(eval $(call gb_UnpackedTarball_add_patches,cairo,\
+ external/cairo/cairo/cairo-1.10.2.no-atsui.patch \
+ external/cairo/cairo/cairo-1.10.2.ios.patch \
+))
+endif
+
+# To be applied only when ENABLE_ANDROID_LOK is not defined
+ifeq ($(OS)$(ENABLE_ANDROID_LOK),ANDROID)
+$(eval $(call gb_UnpackedTarball_add_patches,cairo,\
+ external/cairo/cairo/cairo.GL_RGBA.patch \
+))
+endif
+
+ifneq (,$(filter ANDROID iOS,$(OS)))
+$(eval $(call gb_UnpackedTarball_add_file,cairo,.,external/cairo/cairo/dummy_pkg_config))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cairo/UnpackedTarball_pixman.mk b/external/cairo/UnpackedTarball_pixman.mk
new file mode 100644
index 000000000..3f1f75616
--- /dev/null
+++ b/external/cairo/UnpackedTarball_pixman.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,pixman))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,pixman,$(PIXMAN_TARBALL),,cairo))
+
+$(eval $(call gb_UnpackedTarball_add_patches,pixman,\
+ external/cairo/pixman/pixman-0.24.4.patch \
+ external/cairo/pixman/pixman-ubsan.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cairo/cairo/0025-libtool-pass-use-ld.patch b/external/cairo/cairo/0025-libtool-pass-use-ld.patch
new file mode 100644
index 000000000..c5558ff73
--- /dev/null
+++ b/external/cairo/cairo/0025-libtool-pass-use-ld.patch
@@ -0,0 +1,16 @@
+--- a/cairo/build/ltmain.sh 2022-05-04 16:12:17.409012360 +0100
++++ b/cairo/build/ltmain.sh 2022-05-04 16:12:42.510870063 +0100
+@@ -7273,11 +7273,12 @@
+ # --sysroot=* for sysroot support
+ # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ # -specs=* GCC specs files
++ # -fuse-ld=* Linker select flags for GCC
+ # -stdlib=* select c++ std lib with clang
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+- -specs=*)
++ -specs=*|-fuse-ld=*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ func_append compile_command " $arg"
diff --git a/external/cairo/cairo/cairo-1.10.2.ios.patch b/external/cairo/cairo/cairo-1.10.2.ios.patch
new file mode 100644
index 000000000..c61faf333
--- /dev/null
+++ b/external/cairo/cairo/cairo-1.10.2.ios.patch
@@ -0,0 +1,27 @@
+--- misc/cairo-1.10.2/configure 2011-12-16 10:02:39.626077757 +0100
++++ misc/build/cairo-1.10.2/configure 2011-12-16 10:02:23.518237109 +0100
+@@ -22766,11 +22766,13 @@
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "ApplicationServices/ApplicationServices.h" "ac_cv_header_ApplicationServices_ApplicationServices_h" "$ac_includes_default"
++if false; then
+ if test "x$ac_cv_header_ApplicationServices_ApplicationServices_h" = x""yes; then :
+
+ else
+ use_quartz="no (requires ApplicationServices framework)"
+ fi
++fi
+
+
+ if test "x$use_quartz" != "xyes" ; then
+--- misc/cairo-1.10.2/src/cairo-quartz.h 2011-12-16 10:02:39.639079241 +0100
++++ misc/build/cairo-1.10.2/src/cairo-quartz.h 2011-12-16 10:01:18.404789245 +0100
+@@ -40,7 +40,7 @@
+
+ #if CAIRO_HAS_QUARTZ_SURFACE
+
+-#include <ApplicationServices/ApplicationServices.h>
++#include <CoreGraphics/CoreGraphics.h>
+
+ CAIRO_BEGIN_DECLS
+
diff --git a/external/cairo/cairo/cairo-1.10.2.no-atsui.patch b/external/cairo/cairo/cairo-1.10.2.no-atsui.patch
new file mode 100644
index 000000000..51b98afa5
--- /dev/null
+++ b/external/cairo/cairo/cairo-1.10.2.no-atsui.patch
@@ -0,0 +1,22 @@
+--- misc/cairo-1.10.2/src/cairo-quartz-font.c 2010-12-25 15:21:34.000000000 +0100
++++ misc/build/cairo-1.10.2/src/cairo-quartz-font.c 2011-12-16 09:54:18.672445207 +0100
+@@ -777,7 +777,7 @@
+ return ffont->cgFont;
+ }
+
+-#ifndef __LP64__
++#if 0
+ /*
+ * compat with old ATSUI backend
+ */
+--- misc/cairo-1.10.2/src/cairo-quartz.h 2010-06-18 13:47:13.000000000 +0200
++++ misc/build/cairo-1.10.2/src/cairo-quartz.h 2011-12-16 09:52:53.081501547 +0100
+@@ -66,7 +66,7 @@
+ cairo_public cairo_font_face_t *
+ cairo_quartz_font_face_create_for_cgfont (CGFontRef font);
+
+-#ifndef __LP64__
++#if 0
+ cairo_public cairo_font_face_t *
+ cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id);
+ #endif
diff --git a/external/cairo/cairo/cairo-libtool-rpath.patch.1 b/external/cairo/cairo/cairo-libtool-rpath.patch.1
new file mode 100644
index 000000000..18a3507a9
--- /dev/null
+++ b/external/cairo/cairo/cairo-libtool-rpath.patch.1
@@ -0,0 +1,12 @@
+Prevent libtool from adding annoying stuff to RPATH
+
+--- cairo/configure.orig 2018-10-19 22:20:08.000000000 +0200
++++ cairo/configure 2019-09-04 17:53:00.927539686 +0200
+@@ -10432,6 +10432,7 @@
+ else
+ ld_shlibs=no
+ fi
++hardcode_libdir_flag_spec=
+ ;;
+
+ netbsd*)
diff --git a/external/cairo/cairo/cairo.GL_RGBA.patch b/external/cairo/cairo/cairo.GL_RGBA.patch
new file mode 100644
index 000000000..b1a05feb4
--- /dev/null
+++ b/external/cairo/cairo/cairo.GL_RGBA.patch
@@ -0,0 +1,49 @@
+--- misc/cairo-1.10.2/src/cairo-image-surface.c
++++ misc/cairo-1.10.2/src/cairo-image-surface.c
+@@ -97,11 +97,11 @@
+ return CAIRO_FORMAT_RGBA128F;
+ case PIXMAN_rgb_float:
+ return CAIRO_FORMAT_RGB96F;
+- case PIXMAN_a8r8g8b8:
++ case PIXMAN_a8b8g8r8: //tweaked
+ return CAIRO_FORMAT_ARGB32;
+ case PIXMAN_x2r10g10b10:
+ return CAIRO_FORMAT_RGB30;
+- case PIXMAN_x8r8g8b8:
++ case PIXMAN_x8b8g8r8: //tweaked
+ return CAIRO_FORMAT_RGB24;
+ case PIXMAN_a8:
+ return CAIRO_FORMAT_A8;
+@@ -117,7 +117,7 @@
+ #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,27,2)
+ case PIXMAN_a8r8g8b8_sRGB:
+ #endif
+- case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8:
++ case PIXMAN_a8r8g8b8: case PIXMAN_x8r8g8b8: //tweaked
+ case PIXMAN_b8g8r8: case PIXMAN_b5g6r5:
+ case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5:
+ case PIXMAN_x1b5g5r5: case PIXMAN_a4r4g4b4: case PIXMAN_x4r4g4b4:
+@@ -320,7 +320,7 @@
+ ret = PIXMAN_a8;
+ break;
+ case CAIRO_FORMAT_RGB24:
+- ret = PIXMAN_x8r8g8b8;
++ ret = PIXMAN_x8b8g8r8; //tweaked
+ break;
+ case CAIRO_FORMAT_RGB30:
+ ret = PIXMAN_x2r10g10b10;
+@@ -335,12 +335,12 @@
+ ret = PIXMAN_rgba_float;
+ break;
+ case CAIRO_FORMAT_RGB24_888:
+- ret = PIXMAN_r8g8b8;
++ ret = PIXMAN_b8g8r8; // tweaked
+ break;
+ case CAIRO_FORMAT_ARGB32:
+ case CAIRO_FORMAT_INVALID:
+ default:
+- ret = PIXMAN_a8r8g8b8;
++ ret = PIXMAN_a8b8g8r8; //tweaked
+ break;
+ }
+ return ret;
diff --git a/external/cairo/cairo/cairo.RGB24_888.patch b/external/cairo/cairo/cairo.RGB24_888.patch
new file mode 100644
index 000000000..6b2befabc
--- /dev/null
+++ b/external/cairo/cairo/cairo.RGB24_888.patch
@@ -0,0 +1,105 @@
+diff -ru cairo-1.17.4.orig/src/cairo.h cairo-1.17.4/src/cairo.h
+--- misc/cairo-1.17.4.orig/src/cairo.h 2021-08-29 19:43:26.976435721 +0100
++++ misc/build/cairo-1.17.4/src/cairo.h 2021-08-29 19:47:41.373919330 +0100
+@@ -407,6 +407,8 @@
+ * @CAIRO_FORMAT_RGB30: like RGB24 but with 10bpc. (Since 1.12)
+ * @CAIRO_FORMAT_RGB96F: 3 floats, R, G, B. (Since 1.17.2)
+ * @CAIRO_FORMAT_RGBA128F: 4 floats, R, G, B, A. (Since 1.17.2)
++ * @CAIRO_FORMAT_RGB24_888: each pixel is a 24-bit quantity,
++ * with Red, Green, Blue taking 8-bits each, in that order. (Since 1.1x)
+ *
+ * #cairo_format_t is used to identify the memory format of
+ * image data.
+@@ -424,9 +426,16 @@
+ CAIRO_FORMAT_RGB16_565 = 4,
+ CAIRO_FORMAT_RGB30 = 5,
+ CAIRO_FORMAT_RGB96F = 6,
+- CAIRO_FORMAT_RGBA128F = 7
++ CAIRO_FORMAT_RGBA128F = 7,
++ CAIRO_FORMAT_RGB24_888 = 8
+ } cairo_format_t;
+
++/**
++ * Need this until CAIRO_FORMAT_RGB24_888 is in some official release.
++ * Otherwise we can't reliably check if this is available or we should
++ * convert from 24-bit RGB to 32-bit RGB before passing to Cairo.
++ **/
++#define HAVE_CAIRO_FORMAT_RGB24_888
+
+ /**
+ * cairo_write_func_t:
+diff -ru cairo-1.17.4.orig/src/cairo-image-source.c cairo-1.17.4/src/cairo-image-source.c
+--- misc/cairo-1.17.4.orig/src/cairo-image-source.c 2021-08-29 19:43:26.979435585 +0100
++++ misc/build/cairo-1.17.4/src/cairo-image-source.c 2021-08-29 19:43:47.501506559 +0100
+@@ -509,6 +509,20 @@
+ color.blue = expand_channel(pixel & 0x3fff, 10);
+ return pixman_image_create_solid_fill (&color);
+
++ case CAIRO_FORMAT_RGB24_888:
++ pixel = *(uint32_t *) (image->data + y * image->stride + 3 * x);
++ pixel &= 0x00ffffff; /* ignore next pixel bits */
++ if (pixel == 0)
++ return _pixman_black_image ();
++ if (pixel == 0x00ffffff)
++ return _pixman_white_image ();
++
++ color.alpha = 0xffff;
++ color.red = (pixel >> 16 & 0xff) | (pixel >> 8 & 0xff00);
++ color.green = (pixel >> 8 & 0xff) | (pixel & 0xff00);
++ color.blue = (pixel & 0xff) | (pixel << 8 & 0xff00);
++ return pixman_image_create_solid_fill (&color);
++
+ case CAIRO_FORMAT_ARGB32:
+ case CAIRO_FORMAT_RGB24:
+ pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x);
+diff -ru cairo-1.17.4.orig/src/cairo-image-surface.c cairo-1.17.4/src/cairo-image-surface.c
+--- misc/cairo-1.17.4.orig/src/cairo-image-surface.c 2021-08-29 19:43:26.982435449 +0100
++++ misc/build/cairo-1.17.4/src/cairo-image-surface.c 2021-08-29 19:43:47.501506559 +0100
+@@ -109,13 +109,15 @@
+ return CAIRO_FORMAT_A1;
+ case PIXMAN_r5g6b5:
+ return CAIRO_FORMAT_RGB16_565;
++ case PIXMAN_r8g8b8:
++ return CAIRO_FORMAT_RGB24_888;
+ #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0)
+ case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8:
+ #endif
+ #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,27,2)
+ case PIXMAN_a8r8g8b8_sRGB:
+ #endif
+- case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8:
++ case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8:
+ case PIXMAN_b8g8r8: case PIXMAN_b5g6r5:
+ case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5:
+ case PIXMAN_x1b5g5r5: case PIXMAN_a4r4g4b4: case PIXMAN_x4r4g4b4:
+@@ -332,6 +334,9 @@
+ case CAIRO_FORMAT_RGBA128F:
+ ret = PIXMAN_rgba_float;
+ break;
++ case CAIRO_FORMAT_RGB24_888:
++ ret = PIXMAN_r8g8b8;
++ break;
+ case CAIRO_FORMAT_ARGB32:
+ case CAIRO_FORMAT_INVALID:
+ default:
+@@ -736,6 +741,8 @@
+ case CAIRO_FORMAT_RGB30:
+ case CAIRO_FORMAT_RGB24:
+ return 32;
++ case CAIRO_FORMAT_RGB24_888:
++ return 24;
+ case CAIRO_FORMAT_RGB16_565:
+ return 16;
+ case CAIRO_FORMAT_A8:
+diff -ru cairo-1.17.4.orig/src/cairoint.h cairo-1.17.4/src/cairoint.h
+--- misc/cairo-1.17.4.orig/src/cairoint.h 2021-08-29 19:43:26.973435857 +0100
++++ misc/build/cairo-1.17.4/src/cairoint.h 2021-08-29 19:48:08.396696027 +0100
+@@ -1539,7 +1539,7 @@
+ * in cairo-xlib-surface.c--again see -Wswitch-enum).
+ */
+ #define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 && \
+- (format) <= CAIRO_FORMAT_RGBA128F)
++ (format) <= CAIRO_FORMAT_RGB24_888)
+
+ /* pixman-required stride alignment in bytes. */
+ #define CAIRO_STRIDE_ALIGNMENT (sizeof (uint32_t))
diff --git a/external/cairo/cairo/cairo.buildfix.patch b/external/cairo/cairo/cairo.buildfix.patch
new file mode 100644
index 000000000..5b64dfb59
--- /dev/null
+++ b/external/cairo/cairo/cairo.buildfix.patch
@@ -0,0 +1,122 @@
+diff -ru cairo-1.17.4.orig/build/Makefile.win32.features cairo-1.17.4/build/Makefile.win32.features
+--- misc/cairo-1.17.4.orig/build/Makefile.win32.features 2021-08-29 19:43:27.093430425 +0100
++++ misc/build/cairo-1.17.4/build/Makefile.win32.features 2021-08-29 19:43:47.496506785 +0100
+@@ -30,7 +30,7 @@
+ CAIRO_HAS_FC_FONT=0
+ CAIRO_HAS_PS_SURFACE=1
+ CAIRO_HAS_PDF_SURFACE=1
+-CAIRO_HAS_SVG_SURFACE=1
++CAIRO_HAS_SVG_SURFACE=0
+ CAIRO_HAS_TEST_SURFACES=0
+ CAIRO_HAS_TEE_SURFACE=0
+ CAIRO_HAS_XML_SURFACE=0
+diff -ru cairo-1.17.4.orig/configure cairo-1.17.4/configure
+--- misc/cairo-1.17.4.orig/configure 2021-08-29 19:43:26.966436173 +0100
++++ misc/build/cairo-1.17.4/configure 2021-08-29 19:43:47.500506604 +0100
+@@ -17149,61 +17149,12 @@
+ rm -f confcache
+
+
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5
+-$as_echo_n "checking for compress in -lz... " >&6; }
+-if ${ac_cv_lib_z_compress+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lz $LIBS"
+-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-/* Override any GCC internal prototype to avoid an error.
+- Use char because int might match the return type of a GCC
+- builtin and then its argument prototype would still apply. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-char compress ();
+-int
+-main ()
+-{
+-return compress ();
+- ;
+- return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+- ac_cv_lib_z_compress=yes
+-else
+- ac_cv_lib_z_compress=no
+-fi
+-rm -f core conftest.err conftest.$ac_objext \
+- conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
+-fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5
+-$as_echo "$ac_cv_lib_z_compress" >&6; }
+-if test "x$ac_cv_lib_z_compress" = xyes; then :
+- ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+-if test "x$ac_cv_header_zlib_h" = xyes; then :
+
+ have_libz=yes
+
+ $as_echo "#define HAVE_ZLIB 1" >>confdefs.h
+
+
+-else
+- have_libz="no (requires zlib http://www.gzip.org/zlib/)"
+-fi
+-
+-
+-else
+- have_libz="no (requires zlib http://www.gzip.org/zlib/)"
+-fi
+-
+-
+ save_LIBS="$LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzo2a_decompress in -llzo2" >&5
+ $as_echo_n "checking for lzo2a_decompress in -llzo2... " >&6; }
+@@ -24319,7 +24270,7 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FREETYPE_VERSION - OK" >&5
+ $as_echo "$FREETYPE_VERSION - OK" >&6; }
+ ft_NONPKGCONFIG_CFLAGS=`$FREETYPE_CONFIG --cflags`
+- ft_NONPKGCONFIG_LIBS=`$FREETYPE_CONFIG --libs`
++ ft_NONPKGCONFIG_LIBS=`$FREETYPE_CONFIG --libs | $SED -e 's/-lz//g'`
+ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FREETYPE_VERSION - Too old" >&5
+ $as_echo "$FREETYPE_VERSION - Too old" >&6; }
+ use_ft="no ($FREETYPE_VERSION found; version $FREETYPE_MIN_VERSION from release $FREETYPE_MIN_RELEASE required)"
+@@ -24329,7 +24280,7 @@
+ fi
+
+ ft_CFLAGS="$FREETYPE_CFLAGS"
+- ft_LIBS="$FREETYPE_LIBS"
++ ft_LIBS=`echo "$FREETYPE_LIBS" | $SED -e 's/-lz//g'`
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cairo's FreeType font backend feature could be enabled" >&5
+@@ -24962,7 +24913,7 @@
+
+ # The ps backend requires zlib.
+ use_ps=$have_libz
+- ps_NONPKGCONFIG_LIBS=-lz
++ ps_NONPKGCONFIG_LIBS=$ZLIB3RDLIB
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cairo's PostScript surface backend feature could be enabled" >&5
+@@ -25355,7 +25306,7 @@
+
+ # The pdf backend requires zlib.
+ use_pdf=$have_libz
+- pdf_NONPKGCONFIG_LIBS=-lz
++ pdf_NONPKGCONFIG_LIBS=$ZLIB3RDLIB
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cairo's PDF surface backend feature could be enabled" >&5
+@@ -27218,7 +27169,7 @@
+ use_xml="no (requires --enable-png)"
+ else
+ use_xml=$have_libz
+- xml_NONPKGCONFIG_LIBS=-lz
++ xml_NONPKGCONFIG_LIBS=$ZLIB3RDLIB
+ fi
+
+
diff --git a/external/cairo/cairo/cairo.ofz46165.patch.1 b/external/cairo/cairo/cairo.ofz46165.patch.1
new file mode 100644
index 000000000..948313c2a
--- /dev/null
+++ b/external/cairo/cairo/cairo.ofz46165.patch.1
@@ -0,0 +1,16 @@
+--- a/src/cairo-pen.c 2022-03-30 09:48:14.702456922 +0100
++++ b/src/cairo-pen.c 2022-03-30 09:50:40.011793460 +0100
+@@ -289,7 +289,12 @@
+ } else if (tolerance >= major_axis) {
+ num_vertices = 4;
+ } else {
+- num_vertices = ceil (2*M_PI / acos (1 - tolerance / major_axis));
++ double divisor = acos (1 - tolerance / major_axis);
++
++ if (divisor == 0.0)
++ return 4;
++
++ num_vertices = ceil (2*M_PI / divisor);
+
+ /* number of vertices must be even */
+ if (num_vertices % 2)
diff --git a/external/cairo/cairo/cairo.oldfreetype.patch b/external/cairo/cairo/cairo.oldfreetype.patch
new file mode 100644
index 000000000..a25c8bbdd
--- /dev/null
+++ b/external/cairo/cairo/cairo.oldfreetype.patch
@@ -0,0 +1,42 @@
+--- a/cairo/src/cairo-ft-font.c 2020-09-23 15:27:09.114619562 +0200
++++ b/cairo/src/cairo-ft-font.c 2020-09-23 15:27:22.602808705 +0200
+@@ -2838,7 +2838,7 @@
+ goto cleanup;
+ }
+
+-#if FREETYPE_MAJOR > 2 || ( FREETYPE_MAJOR == 2 && FREETYPE_MINOR >= 8)
++#if 0
+ /* If FT_Get_Var_Blend_Coordinates() is available, we can check if the
+ * current design coordinates are the default coordinates. In this case
+ * the current outlines match the font tables.
+--- a/cairo/src/cairo-ft-font.c 2020-09-24 10:35:25.391941702 +0200
++++ b/cairo/src/cairo-ft-font.c 2020-09-24 10:35:39.900126419 +0200
+@@ -451,7 +451,7 @@
+ unscaled->have_color = FT_HAS_COLOR (face) != 0;
+ unscaled->have_color_set = TRUE;
+
+-#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES
++#if 0
+ {
+ FT_MM_Var *ft_mm_var;
+ if (0 == FT_Get_MM_Var (face, &ft_mm_var))
+@@ -2377,7 +2377,7 @@
+ }
+
+ current_coords = malloc (sizeof (FT_Fixed) * ft_mm_var->num_axis);
+-#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES
++#if 0
+ ret = FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, current_coords);
+ if (ret == 0) {
+ for (i = 0; i < ft_mm_var->num_axis; i++) {
+--- a/cairo/test/font-variations.c 2020-09-24 10:36:01.592402635 +0200
++++ b/cairo/test/font-variations.c 2020-09-24 10:36:08.728493510 +0200
+@@ -117,7 +117,7 @@
+ return CAIRO_TEST_FAILURE;
+ }
+
+-#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES
++#if 0
+ ret = FT_Get_Var_Design_Coordinates (ft_face, 20, coords);
+ if (ret != 0) {
+ cairo_test_log (ctx, "Failed to get coords");
diff --git a/external/cairo/cairo/dummy_pkg_config b/external/cairo/cairo/dummy_pkg_config
new file mode 100755
index 000000000..829303ea5
--- /dev/null
+++ b/external/cairo/cairo/dummy_pkg_config
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+
diff --git a/external/cairo/cairo/san.patch.0 b/external/cairo/cairo/san.patch.0
new file mode 100644
index 000000000..272fef628
--- /dev/null
+++ b/external/cairo/cairo/san.patch.0
@@ -0,0 +1,103 @@
+--- src/cairo-fixed-private.h
++++ src/cairo-fixed-private.h
+@@ -61,7 +61,7 @@
+ static inline cairo_fixed_t
+ _cairo_fixed_from_int (int i)
+ {
+- return i << CAIRO_FIXED_FRAC_BITS;
++ return (unsigned)i << CAIRO_FIXED_FRAC_BITS;
+ }
+
+ /* This is the "magic number" approach to converting a double into fixed
+@@ -249,7 +249,7 @@
+ } else if ((f >> CAIRO_FIXED_FRAC_BITS) > INT16_MAX) {
+ x = INT32_MAX;
+ } else {
+- x = f << (16 - CAIRO_FIXED_FRAC_BITS);
++ x = (uint32_t)f << (16 - CAIRO_FIXED_FRAC_BITS);
+ }
+
+ return x;
+--- src/cairo-gstate.c
++++ src/cairo-gstate.c
+@@ -2297,7 +2297,7 @@
+ if (!drop || KEEP_GLYPH (transformed_glyphs[j]))
+ j++;
+ }
+- memcpy (transformed_clusters, clusters,
++ if (num_clusters != 0) memcpy (transformed_clusters, clusters,
+ num_clusters * sizeof (cairo_text_cluster_t));
+ } else {
+ const cairo_glyph_t *cur_glyph;
+@@ -2352,7 +2352,7 @@
+ if (! drop || KEEP_GLYPH (transformed_glyphs[j]))
+ j++;
+ }
+- memcpy (transformed_clusters, clusters,
++ if (num_clusters != 0) memcpy (transformed_clusters, clusters,
+ num_clusters * sizeof (cairo_text_cluster_t));
+ } else {
+ const cairo_glyph_t *cur_glyph;
+--- src/cairo-image-source.c
++++ src/cairo-image-source.c
+@@ -509,7 +509,7 @@
+ return pixman_image_create_solid_fill (&color);
+
+ case CAIRO_FORMAT_RGB24_888:
+- pixel = *(uint32_t *) (image->data + y * image->stride + 3 * x);
++ pixel = (uint32_t)(image->data + y * image->stride + 3 * x)[0] | ((uint32_t)(image->data + y * image->stride + 3 * x)[1] << 8) | ((uint32_t)(image->data + y * image->stride + 3 * x)[2] << 16);
+ pixel &= 0x00ffffff; /* ignore next pixel bits */
+ if (pixel == 0)
+ return _pixman_black_image ();
+--- src/cairo-surface.c
++++ src/cairo-surface.c
+@@ -2849,7 +2849,7 @@
+
+ if (_cairo_scaled_font_has_color_glyphs (scaled_font)) {
+ utf8_copy = malloc (sizeof (char) * utf8_len);
+- memcpy (utf8_copy, utf8, sizeof (char) * utf8_len);
++ if (utf8_len != 0) memcpy (utf8_copy, utf8, sizeof (char) * utf8_len);
+ utf8 = utf8_copy;
+
+ status = composite_color_glyphs (surface, op,
+--- src/cairo-tor-scan-converter.c
++++ src/cairo-tor-scan-converter.c
+@@ -253,7 +253,7 @@
+ #elif GRID_XY == 15
+ # define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c))
+ #elif GRID_XY == 2*256*15
+-# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9)
++# define GRID_AREA_TO_ALPHA(c) (((c) + ((uint32_t)(c)<<4) + 256) >> 9)
+ #else
+ # define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY)
+ #endif
+--- src/cairo-xlib-render-compositor.c
++++ src/cairo-xlib-render-compositor.c
+@@ -1849,8 +1849,8 @@
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
+
+- dx = -dst_x << 16;
+- dy = -dst_y << 16;
++ dx = (unsigned)-dst_x << 16;
++ dy = (unsigned)-dst_y << 16;
+ for (i = 0; i < traps->num_traps; i++) {
+ cairo_trapezoid_t *t = &traps->traps[i];
+
+--- src/cairo-xlib-surface-shm.c
++++ src/cairo-xlib-surface-shm.c
+@@ -1152,9 +1152,11 @@
+ cairo_surface_t *surface;
+
+ surface = NULL;
+- if (has_shm (other))
+- surface = &_cairo_xlib_shm_surface_create (other, format, width, height,
+- FALSE, has_shm_pixmaps (other))->image.base;
++ if (has_shm (other)) {
++ cairo_xlib_shm_surface_t * shm_surface = _cairo_xlib_shm_surface_create (other, format, width, height,
++ FALSE, has_shm_pixmaps (other));
++ if (shm_surface) surface = &shm_surface->image.base;
++ }
+
+ return surface;
+ }
diff --git a/external/cairo/pixman/pixman-0.24.4.patch b/external/cairo/pixman/pixman-0.24.4.patch
new file mode 100644
index 000000000..a5d32f88f
--- /dev/null
+++ b/external/cairo/pixman/pixman-0.24.4.patch
@@ -0,0 +1,91 @@
+--- misc/pixman-0.24.4/Makefile.in 2011-11-06 22:11:25.000000000 +0100
++++ misc/build/pixman-0.24.4/Makefile.in 2011-12-16 09:06:45.317211035 +0100
+@@ -385,7 +385,7 @@
+ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+-SUBDIRS = pixman demos test
++SUBDIRS = pixman
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = pixman-1.pc
+ GPGKEY = 3892336E
+--- misc/pixman-0.24.4/pixman/pixman-utils.c
++++ misc/build/pixman-0.24.4/pixman/pixman-utils.c
+@@ -27,6 +27,7 @@
+ #endif
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <limits.h>
+
+ #include "pixman-private.h"
+
+--- misc/pixman-0.24.4/pixman/pixman-glyph.c 2015-06-30 05:48:31.000000000 -0400
++++ misc/build/pixman-0.24.4/pixman/pixman-glyph.c 2017-11-25 13:26:33.075558418 -0500
+@@ -38,6 +38,7 @@
+
+ /* XXX: These numbers are arbitrary---we've never done any measurements.
+ */
++#define N_PIXELS_HIGH_WATER (4 * 1024 * 1024)
+ #define N_GLYPHS_HIGH_WATER (16384)
+ #define N_GLYPHS_LOW_WATER (8192)
+ #define HASH_SIZE (2 * N_GLYPHS_HIGH_WATER)
+@@ -58,6 +59,7 @@
+ int n_glyphs;
+ int n_tombstones;
+ int freeze_count;
++ long n_pixels;
+ pixman_list_t mru;
+ glyph_t * glyphs[HASH_SIZE];
+ };
+@@ -133,6 +135,7 @@
+ if (*loc == TOMBSTONE)
+ cache->n_tombstones--;
+ cache->n_glyphs++;
++ cache->n_pixels += glyph->image->bits.width * glyph->image->bits.height;
+
+ *loc = glyph;
+ }
+@@ -150,6 +153,7 @@
+ cache->glyphs[idx & HASH_MASK] = TOMBSTONE;
+ cache->n_tombstones++;
+ cache->n_glyphs--;
++ cache->n_pixels -= glyph->image->bits.width * glyph->image->bits.height;
+
+ /* Eliminate tombstones if possible */
+ if (cache->glyphs[(idx + 1) & HASH_MASK] == NULL)
+@@ -180,6 +184,7 @@
+
+ cache->n_glyphs = 0;
+ cache->n_tombstones = 0;
++ cache->n_pixels = 0;
+ }
+
+ PIXMAN_EXPORT pixman_glyph_cache_t *
+@@ -194,6 +199,7 @@
+ cache->n_glyphs = 0;
+ cache->n_tombstones = 0;
+ cache->freeze_count = 0;
++ cache->n_pixels = 0;
+
+ pixman_list_init (&cache->mru);
+
+@@ -220,9 +226,9 @@
+ pixman_glyph_cache_thaw (pixman_glyph_cache_t *cache)
+ {
+ if (--cache->freeze_count == 0 &&
+- cache->n_glyphs + cache->n_tombstones > N_GLYPHS_HIGH_WATER)
++ (cache->n_glyphs + cache->n_tombstones > N_GLYPHS_HIGH_WATER || cache->n_pixels > N_PIXELS_HIGH_WATER))
+ {
+- if (cache->n_tombstones > N_GLYPHS_HIGH_WATER)
++ if (cache->n_tombstones > N_GLYPHS_LOW_WATER)
+ {
+ /* More than half the entries are
+ * tombstones. Just dump the whole table.
+@@ -230,7 +236,7 @@
+ clear_table (cache);
+ }
+
+- while (cache->n_glyphs > N_GLYPHS_LOW_WATER)
++ while (cache->n_glyphs > N_GLYPHS_LOW_WATER || cache->n_pixels > N_PIXELS_HIGH_WATER)
+ {
+ glyph_t *glyph = CONTAINER_OF (glyph_t, mru_link, cache->mru.tail);
diff --git a/external/cairo/pixman/pixman-ubsan.patch b/external/cairo/pixman/pixman-ubsan.patch
new file mode 100644
index 000000000..64e5778ee
--- /dev/null
+++ b/external/cairo/pixman/pixman-ubsan.patch
@@ -0,0 +1,76 @@
+diff -ru pixman-0.42.2.orig/pixman/pixman-bits-image.c pixman-0.42.2/pixman/pixman-bits-image.c
+--- misc/pixman-0.42.2.orig/pixman/pixman-bits-image.c 2022-11-03 02:25:48.000000000 +0900
++++ misc/build/pixman-0.42.2/pixman/pixman-bits-image.c 2022-11-28 21:35:25.896969126 +0900
+@@ -351,8 +351,8 @@
+ * positioned relative to a particular phase (and not relative to whatever
+ * exact fraction we happen to get here).
+ */
+- x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
+- y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
++ x = ((uint32_t)(x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
++ y = ((uint32_t)(y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
+
+ px = (x & 0xffff) >> x_phase_shift;
+ py = (y & 0xffff) >> y_phase_shift;
+diff -ru pixman-0.42.2.orig/pixman/pixman-combine32.c pixman-0.42.2/pixman/pixman-combine32.c
+--- misc/pixman-0.42.2.orig/pixman/pixman-combine32.c 2022-02-02 05:51:25.000000000 +0900
++++ misc/build/pixman-0.42.2/pixman/pixman-combine32.c 2022-11-28 21:38:48.226968594 +0900
+@@ -589,7 +589,7 @@
+ rg = DIV_ONE_UN8 (rg); \
+ rb = DIV_ONE_UN8 (rb); \
+ \
+- *(dest + i) = ra << 24 | rr << 16 | rg << 8 | rb; \
++ *(dest + i) = (uint32_t)ra << 24 | rr << 16 | rg << 8 | rb; \
+ } \
+ } \
+ \
+diff -ru pixman-0.42.2.orig/pixman/pixman-fast-path.c pixman-0.42.2/pixman/pixman-fast-path.c
+--- misc/pixman-0.42.2.orig/pixman/pixman-fast-path.c 2022-10-18 02:47:42.000000000 +0900
++++ misc/build/pixman-0.42.2/pixman/pixman-fast-path.c 2022-11-28 21:53:12.596963317 +0900
+@@ -2758,8 +2758,8 @@
+ * positioned relative to a particular phase (and not relative to whatever
+ * exact fraction we happen to get here).
+ */
+- x = ((vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
+- y = ((vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
++ x = ((uint32_t)(vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1);
++ y = ((uint32_t)(vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1);
+
+ px = (x & 0xffff) >> x_phase_shift;
+ py = (y & 0xffff) >> y_phase_shift;
+@@ -2837,9 +2837,9 @@
+ sbtot = CLIP (sbtot, 0, 0xff);
+
+ #ifdef WORDS_BIGENDIAN
+- buffer[k] = (satot << 0) | (srtot << 8) | (sgtot << 16) | (sbtot << 24);
++ buffer[k] = (satot << 0) | (srtot << 8) | (sgtot << 16) | ((uint32_t)sbtot << 24);
+ #else
+- buffer[k] = (satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot << 0);
++ buffer[k] = ((uint32_t)satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot << 0);
+ #endif
+
+ next:
+diff -ru pixman-0.42.2.orig/pixman/pixman-sse2.c pixman-0.42.2/pixman/pixman-sse2.c
+--- misc/pixman-0.42.2/pixman/pixman-sse2.c 2022-02-02 05:51:25.000000000 +0900
++++ misc/build/pixman-0.42.2/pixman/pixman-sse2.c 2022-11-28 22:11:19.276969466 +0900
+@@ -3345,7 +3345,7 @@
+
+ b = filler & 0xff;
+ w = (b << 8) | b;
+- filler = (w << 16) | w;
++ filler = ((uint32_t)w << 16) | w;
+ }
+ else if (bpp == 16)
+ {
+diff -ru pixman-0.42.2.orig/pixman/pixman-utils.c pixman-0.42.2/pixman/pixman-utils.c
+--- misc/pixman-0.42.2.orig/pixman/pixman-utils.c 2022-02-02 05:51:25.000000000 +0900
++++ misc/build/pixman-0.42.2/pixman/pixman-utils.c 2022-11-28 21:55:44.196964912 +0900
+@@ -213,7 +213,7 @@
+ g = float_to_unorm (src[i].g, 8);
+ b = float_to_unorm (src[i].b, 8);
+
+- dst[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
++ dst[i] = ((uint32_t)a << 24) | (r << 16) | (g << 8) | (b << 0);
+ }
+ }
+
diff --git a/external/clew/Library_clew.mk b/external/clew/Library_clew.mk
new file mode 100644
index 000000000..9e664fed5
--- /dev/null
+++ b/external/clew/Library_clew.mk
@@ -0,0 +1,41 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,clew))
+
+$(eval $(call gb_Library_add_defs,clew,\
+ -DCLEW_BUILD \
+))
+
+ifeq ($(OS),LINUX)
+$(eval $(call gb_Library_add_libs,clew,\
+ -ldl \
+ -lrt \
+))
+endif
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_Library_add_libs,clew,\
+ -framework OpenCL \
+))
+endif
+
+$(eval $(call gb_Library_add_cobjects,clew,\
+ external/clew/source/clew \
+))
+
+$(eval $(call gb_Library_set_include,clew, \
+ -I$(SRCDIR)/external/clew/source/include \
+ $$(INCLUDE) \
+))
+
+# This is required for module-deps.pl to produce correct dependencies.
+$(eval $(call gb_Library_use_libraries,clew,))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/clew/Makefile b/external/clew/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/clew/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/clew/Module_clew.mk b/external/clew/Module_clew.mk
new file mode 100644
index 000000000..51f174b78
--- /dev/null
+++ b/external/clew/Module_clew.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,clew))
+
+$(eval $(call gb_Module_add_targets,clew,\
+ Library_clew \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/clew/README b/external/clew/README
new file mode 100644
index 000000000..7a0d65293
--- /dev/null
+++ b/external/clew/README
@@ -0,0 +1,5 @@
+CLEW is the OpenCL Extension Wrangler - similar to GLEW but for OpenCL
+
+This project doesn't appear to have an obvious upstream, so
+the source files are in our git repo and there is no option
+to use a system library.
diff --git a/external/clew/source/clew.c b/external/clew/source/clew.c
new file mode 100644
index 000000000..4ed80035d
--- /dev/null
+++ b/external/clew/source/clew.c
@@ -0,0 +1,325 @@
+//////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2009-2011 Organic Vectory B.V.
+// Written by George van Venrooij
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file license.txt)
+//////////////////////////////////////////////////////////////////////////
+
+#include "clew/clew.h"
+
+//! \file clew.c
+//! \brief OpenCL run-time loader source
+
+#ifndef CLCC_GENERATE_DOCUMENTATION
+ #ifdef _WIN32
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+
+ typedef HMODULE CLCC_DYNLIB_HANDLE;
+
+ #define CLCC_DYNLIB_OPEN LoadLibrary
+ #define CLCC_DYNLIB_CLOSE FreeLibrary
+ #define CLCC_DYNLIB_IMPORT GetProcAddress
+ #else
+ #include <dlfcn.h>
+
+ typedef void* CLCC_DYNLIB_HANDLE;
+
+ #define CLCC_DYNLIB_OPEN(path) dlopen(path, RTLD_NOW | RTLD_GLOBAL)
+ #define CLCC_DYNLIB_CLOSE dlclose
+ #define CLCC_DYNLIB_IMPORT dlsym
+ #endif
+#else
+ //typedef implementation_defined CLCC_DYNLIB_HANDLE;
+ //#define CLCC_DYNLIB_OPEN(path) implementation_defined
+ //#define CLCC_DYNLIB_CLOSE implementation_defined
+ //#define CLCC_DYNLIB_IMPORT implementation_defined
+#endif
+
+#include <stdlib.h>
+
+//! \brief module handle
+static CLCC_DYNLIB_HANDLE module = NULL;
+
+// Variables holding function entry points
+#ifndef CLCC_GENERATE_DOCUMENTATION
+PFNCLGETPLATFORMIDS __clewGetPlatformIDs = NULL;
+PFNCLGETPLATFORMINFO __clewGetPlatformInfo = NULL;
+PFNCLGETDEVICEIDS __clewGetDeviceIDs = NULL;
+PFNCLGETDEVICEINFO __clewGetDeviceInfo = NULL;
+PFNCLCREATECONTEXT __clewCreateContext = NULL;
+PFNCLCREATECONTEXTFROMTYPE __clewCreateContextFromType = NULL;
+PFNCLRETAINCONTEXT __clewRetainContext = NULL;
+PFNCLRELEASECONTEXT __clewReleaseContext = NULL;
+PFNCLGETCONTEXTINFO __clewGetContextInfo = NULL;
+PFNCLCREATECOMMANDQUEUE __clewCreateCommandQueue = NULL;
+PFNCLRETAINCOMMANDQUEUE __clewRetainCommandQueue = NULL;
+PFNCLRELEASECOMMANDQUEUE __clewReleaseCommandQueue = NULL;
+PFNCLGETCOMMANDQUEUEINFO __clewGetCommandQueueInfo = NULL;
+PFNCLSETCOMMANDQUEUEPROPERTY __clewSetCommandQueueProperty = NULL;
+PFNCLCREATEBUFFER __clewCreateBuffer = NULL;
+PFNCLCREATEIMAGE2D __clewCreateImage2D = NULL;
+PFNCLCREATEIMAGE3D __clewCreateImage3D = NULL;
+PFNCLRETAINMEMOBJECT __clewRetainMemObject = NULL;
+PFNCLRELEASEMEMOBJECT __clewReleaseMemObject = NULL;
+PFNCLGETSUPPORTEDIMAGEFORMATS __clewGetSupportedImageFormats = NULL;
+PFNCLGETMEMOBJECTINFO __clewGetMemObjectInfo = NULL;
+PFNCLGETIMAGEINFO __clewGetImageInfo = NULL;
+PFNCLCREATESAMPLER __clewCreateSampler = NULL;
+PFNCLRETAINSAMPLER __clewRetainSampler = NULL;
+PFNCLRELEASESAMPLER __clewReleaseSampler = NULL;
+PFNCLGETSAMPLERINFO __clewGetSamplerInfo = NULL;
+PFNCLCREATEPROGRAMWITHSOURCE __clewCreateProgramWithSource = NULL;
+PFNCLCREATEPROGRAMWITHBINARY __clewCreateProgramWithBinary = NULL;
+PFNCLRETAINPROGRAM __clewRetainProgram = NULL;
+PFNCLRELEASEPROGRAM __clewReleaseProgram = NULL;
+PFNCLBUILDPROGRAM __clewBuildProgram = NULL;
+PFNCLUNLOADCOMPILER __clewUnloadCompiler = NULL;
+PFNCLGETPROGRAMINFO __clewGetProgramInfo = NULL;
+PFNCLGETPROGRAMBUILDINFO __clewGetProgramBuildInfo = NULL;
+PFNCLCREATEKERNEL __clewCreateKernel = NULL;
+PFNCLCREATEKERNELSINPROGRAM __clewCreateKernelsInProgram = NULL;
+PFNCLRETAINKERNEL __clewRetainKernel = NULL;
+PFNCLRELEASEKERNEL __clewReleaseKernel = NULL;
+PFNCLSETKERNELARG __clewSetKernelArg = NULL;
+PFNCLGETKERNELINFO __clewGetKernelInfo = NULL;
+PFNCLGETKERNELWORKGROUPINFO __clewGetKernelWorkGroupInfo = NULL;
+PFNCLWAITFOREVENTS __clewWaitForEvents = NULL;
+PFNCLGETEVENTINFO __clewGetEventInfo = NULL;
+PFNCLRETAINEVENT __clewRetainEvent = NULL;
+PFNCLRELEASEEVENT __clewReleaseEvent = NULL;
+PFNCLGETEVENTPROFILINGINFO __clewGetEventProfilingInfo = NULL;
+PFNCLFLUSH __clewFlush = NULL;
+PFNCLFINISH __clewFinish = NULL;
+PFNCLENQUEUEREADBUFFER __clewEnqueueReadBuffer = NULL;
+PFNCLENQUEUEWRITEBUFFER __clewEnqueueWriteBuffer = NULL;
+PFNCLENQUEUECOPYBUFFER __clewEnqueueCopyBuffer = NULL;
+PFNCLENQUEUEREADIMAGE __clewEnqueueReadImage = NULL;
+PFNCLENQUEUEWRITEIMAGE __clewEnqueueWriteImage = NULL;
+PFNCLENQUEUECOPYIMAGE __clewEnqueueCopyImage = NULL;
+PFNCLENQUEUECOPYIMAGETOBUFFER __clewEnqueueCopyImageToBuffer = NULL;
+PFNCLENQUEUECOPYBUFFERTOIMAGE __clewEnqueueCopyBufferToImage = NULL;
+PFNCLENQUEUEMAPBUFFER __clewEnqueueMapBuffer = NULL;
+PFNCLENQUEUEMAPIMAGE __clewEnqueueMapImage = NULL;
+PFNCLENQUEUEUNMAPMEMOBJECT __clewEnqueueUnmapMemObject = NULL;
+PFNCLENQUEUENDRANGEKERNEL __clewEnqueueNDRangeKernel = NULL;
+PFNCLENQUEUETASK __clewEnqueueTask = NULL;
+PFNCLENQUEUENATIVEKERNEL __clewEnqueueNativeKernel = NULL;
+PFNCLENQUEUEMARKER __clewEnqueueMarker = NULL;
+PFNCLENQUEUEWAITFOREVENTS __clewEnqueueWaitForEvents = NULL;
+PFNCLENQUEUEBARRIER __clewEnqueueBarrier = NULL;
+PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress = NULL;
+#endif // CLCC_GENERATE_DOCUMENTATION
+
+
+//! \brief Unloads OpenCL dynamic library, should not be called directly
+static void clewExit(void)
+{
+ if (module != NULL)
+ {
+ // Ignore errors
+ CLCC_DYNLIB_CLOSE(module);
+ module = NULL;
+ }
+}
+
+#define CLEW_CHECK_FUNCTION(f) \
+ if ((f) == NULL) \
+ { \
+ CLCC_DYNLIB_CLOSE(module); \
+ module = NULL; \
+ return CLEW_ERROR_IMPORT_FAILED; \
+ } \
+
+//! \param path path to dynamic library to load
+//! \return CLEW_ERROR_OPEN_FAILED if the library could not be opened
+//! CLEW_ERROR_ATEXIT_FAILED if atexit(clewExit) failed
+//! CLEW_SUCCESS when the library was successfully loaded
+int clewInit(const char* path)
+{
+ int error = 0;
+
+ // Check if already initialized
+ if (module != NULL)
+ {
+ return CLEW_SUCCESS;
+ }
+
+ // Load library
+ module = CLCC_DYNLIB_OPEN(path);
+
+ // Check for errors
+ if (module == NULL)
+ {
+ return CLEW_ERROR_OPEN_FAILED;
+ }
+
+ // Set unloading
+ error = atexit(clewExit);
+
+ if (error)
+ {
+ // Failure queueing atexit, shutdown with error
+ CLCC_DYNLIB_CLOSE(module);
+ module = NULL;
+
+ return CLEW_ERROR_ATEXIT_FAILED;
+ }
+
+ // Determine function entry-points
+ CLEW_CHECK_FUNCTION(__clewGetPlatformIDs = (PFNCLGETPLATFORMIDS )CLCC_DYNLIB_IMPORT(module, "clGetPlatformIDs"));
+ CLEW_CHECK_FUNCTION(__clewGetPlatformInfo = (PFNCLGETPLATFORMINFO )CLCC_DYNLIB_IMPORT(module, "clGetPlatformInfo"));
+ CLEW_CHECK_FUNCTION(__clewGetDeviceIDs = (PFNCLGETDEVICEIDS )CLCC_DYNLIB_IMPORT(module, "clGetDeviceIDs"));
+ CLEW_CHECK_FUNCTION(__clewGetDeviceInfo = (PFNCLGETDEVICEINFO )CLCC_DYNLIB_IMPORT(module, "clGetDeviceInfo"));
+ CLEW_CHECK_FUNCTION(__clewCreateContext = (PFNCLCREATECONTEXT )CLCC_DYNLIB_IMPORT(module, "clCreateContext"));
+ CLEW_CHECK_FUNCTION(__clewCreateContextFromType = (PFNCLCREATECONTEXTFROMTYPE )CLCC_DYNLIB_IMPORT(module, "clCreateContextFromType"));
+ CLEW_CHECK_FUNCTION(__clewRetainContext = (PFNCLRETAINCONTEXT )CLCC_DYNLIB_IMPORT(module, "clRetainContext"));
+ CLEW_CHECK_FUNCTION(__clewReleaseContext = (PFNCLRELEASECONTEXT )CLCC_DYNLIB_IMPORT(module, "clReleaseContext"));
+ CLEW_CHECK_FUNCTION(__clewGetContextInfo = (PFNCLGETCONTEXTINFO )CLCC_DYNLIB_IMPORT(module, "clGetContextInfo"));
+ CLEW_CHECK_FUNCTION(__clewCreateCommandQueue = (PFNCLCREATECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clCreateCommandQueue"));
+ CLEW_CHECK_FUNCTION(__clewRetainCommandQueue = (PFNCLRETAINCOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clRetainCommandQueue"));
+ CLEW_CHECK_FUNCTION(__clewReleaseCommandQueue = (PFNCLRELEASECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clReleaseCommandQueue"));
+ CLEW_CHECK_FUNCTION(__clewGetCommandQueueInfo = (PFNCLGETCOMMANDQUEUEINFO )CLCC_DYNLIB_IMPORT(module, "clGetCommandQueueInfo"));
+ CLEW_CHECK_FUNCTION(__clewSetCommandQueueProperty = (PFNCLSETCOMMANDQUEUEPROPERTY )CLCC_DYNLIB_IMPORT(module, "clSetCommandQueueProperty"));
+ CLEW_CHECK_FUNCTION(__clewCreateBuffer = (PFNCLCREATEBUFFER )CLCC_DYNLIB_IMPORT(module, "clCreateBuffer"));
+ CLEW_CHECK_FUNCTION(__clewCreateImage2D = (PFNCLCREATEIMAGE2D )CLCC_DYNLIB_IMPORT(module, "clCreateImage2D"));
+ CLEW_CHECK_FUNCTION(__clewCreateImage3D = (PFNCLCREATEIMAGE3D )CLCC_DYNLIB_IMPORT(module, "clCreateImage3D"));
+ CLEW_CHECK_FUNCTION(__clewRetainMemObject = (PFNCLRETAINMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clRetainMemObject"));
+ CLEW_CHECK_FUNCTION(__clewReleaseMemObject = (PFNCLRELEASEMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clReleaseMemObject"));
+ CLEW_CHECK_FUNCTION(__clewGetSupportedImageFormats = (PFNCLGETSUPPORTEDIMAGEFORMATS )CLCC_DYNLIB_IMPORT(module, "clGetSupportedImageFormats"));
+ CLEW_CHECK_FUNCTION(__clewGetMemObjectInfo = (PFNCLGETMEMOBJECTINFO )CLCC_DYNLIB_IMPORT(module, "clGetMemObjectInfo"));
+ CLEW_CHECK_FUNCTION(__clewGetImageInfo = (PFNCLGETIMAGEINFO )CLCC_DYNLIB_IMPORT(module, "clGetImageInfo"));
+ CLEW_CHECK_FUNCTION(__clewCreateSampler = (PFNCLCREATESAMPLER )CLCC_DYNLIB_IMPORT(module, "clCreateSampler"));
+ CLEW_CHECK_FUNCTION(__clewRetainSampler = (PFNCLRETAINSAMPLER )CLCC_DYNLIB_IMPORT(module, "clRetainSampler"));
+ CLEW_CHECK_FUNCTION(__clewReleaseSampler = (PFNCLRELEASESAMPLER )CLCC_DYNLIB_IMPORT(module, "clReleaseSampler"));
+ CLEW_CHECK_FUNCTION(__clewGetSamplerInfo = (PFNCLGETSAMPLERINFO )CLCC_DYNLIB_IMPORT(module, "clGetSamplerInfo"));
+ CLEW_CHECK_FUNCTION(__clewCreateProgramWithSource = (PFNCLCREATEPROGRAMWITHSOURCE )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithSource"));
+ CLEW_CHECK_FUNCTION(__clewCreateProgramWithBinary = (PFNCLCREATEPROGRAMWITHBINARY )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithBinary"));
+ CLEW_CHECK_FUNCTION(__clewRetainProgram = (PFNCLRETAINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clRetainProgram"));
+ CLEW_CHECK_FUNCTION(__clewReleaseProgram = (PFNCLRELEASEPROGRAM )CLCC_DYNLIB_IMPORT(module, "clReleaseProgram"));
+ CLEW_CHECK_FUNCTION(__clewBuildProgram = (PFNCLBUILDPROGRAM )CLCC_DYNLIB_IMPORT(module, "clBuildProgram"));
+ CLEW_CHECK_FUNCTION(__clewUnloadCompiler = (PFNCLUNLOADCOMPILER )CLCC_DYNLIB_IMPORT(module, "clUnloadCompiler"));
+ CLEW_CHECK_FUNCTION(__clewGetProgramInfo = (PFNCLGETPROGRAMINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramInfo"));
+ CLEW_CHECK_FUNCTION(__clewGetProgramBuildInfo = (PFNCLGETPROGRAMBUILDINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramBuildInfo"));
+ CLEW_CHECK_FUNCTION(__clewCreateKernel = (PFNCLCREATEKERNEL )CLCC_DYNLIB_IMPORT(module, "clCreateKernel"));
+ CLEW_CHECK_FUNCTION(__clewCreateKernelsInProgram = (PFNCLCREATEKERNELSINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clCreateKernelsInProgram"));
+ CLEW_CHECK_FUNCTION(__clewRetainKernel = (PFNCLRETAINKERNEL )CLCC_DYNLIB_IMPORT(module, "clRetainKernel"));
+ CLEW_CHECK_FUNCTION(__clewReleaseKernel = (PFNCLRELEASEKERNEL )CLCC_DYNLIB_IMPORT(module, "clReleaseKernel"));
+ CLEW_CHECK_FUNCTION(__clewSetKernelArg = (PFNCLSETKERNELARG )CLCC_DYNLIB_IMPORT(module, "clSetKernelArg"));
+ CLEW_CHECK_FUNCTION(__clewGetKernelInfo = (PFNCLGETKERNELINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelInfo"));
+ CLEW_CHECK_FUNCTION(__clewGetKernelWorkGroupInfo = (PFNCLGETKERNELWORKGROUPINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelWorkGroupInfo"));
+ CLEW_CHECK_FUNCTION(__clewWaitForEvents = (PFNCLWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clWaitForEvents"));
+ CLEW_CHECK_FUNCTION(__clewGetEventInfo = (PFNCLGETEVENTINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventInfo"));
+ CLEW_CHECK_FUNCTION(__clewRetainEvent = (PFNCLRETAINEVENT )CLCC_DYNLIB_IMPORT(module, "clRetainEvent"));
+ CLEW_CHECK_FUNCTION(__clewReleaseEvent = (PFNCLRELEASEEVENT )CLCC_DYNLIB_IMPORT(module, "clReleaseEvent"));
+ CLEW_CHECK_FUNCTION(__clewGetEventProfilingInfo = (PFNCLGETEVENTPROFILINGINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventProfilingInfo"));
+ CLEW_CHECK_FUNCTION(__clewFlush = (PFNCLFLUSH )CLCC_DYNLIB_IMPORT(module, "clFlush"));
+ CLEW_CHECK_FUNCTION(__clewFinish = (PFNCLFINISH )CLCC_DYNLIB_IMPORT(module, "clFinish"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueReadBuffer = (PFNCLENQUEUEREADBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadBuffer"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueWriteBuffer = (PFNCLENQUEUEWRITEBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteBuffer"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueCopyBuffer = (PFNCLENQUEUECOPYBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBuffer"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueReadImage = (PFNCLENQUEUEREADIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadImage"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueWriteImage = (PFNCLENQUEUEWRITEIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteImage"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueCopyImage = (PFNCLENQUEUECOPYIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImage"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueCopyImageToBuffer = (PFNCLENQUEUECOPYIMAGETOBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImageToBuffer"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueCopyBufferToImage = (PFNCLENQUEUECOPYBUFFERTOIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBufferToImage"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueMapBuffer = (PFNCLENQUEUEMAPBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapBuffer"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueMapImage = (PFNCLENQUEUEMAPIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapImage"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueUnmapMemObject = (PFNCLENQUEUEUNMAPMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clEnqueueUnmapMemObject"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueNDRangeKernel = (PFNCLENQUEUENDRANGEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNDRangeKernel"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueTask = (PFNCLENQUEUETASK )CLCC_DYNLIB_IMPORT(module, "clEnqueueTask"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueNativeKernel = (PFNCLENQUEUENATIVEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNativeKernel"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueMarker = (PFNCLENQUEUEMARKER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMarker"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueWaitForEvents = (PFNCLENQUEUEWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clEnqueueWaitForEvents"));
+ CLEW_CHECK_FUNCTION(__clewEnqueueBarrier = (PFNCLENQUEUEBARRIER )CLCC_DYNLIB_IMPORT(module, "clEnqueueBarrier"));
+ CLEW_CHECK_FUNCTION(__clewGetExtensionFunctionAddress = (PFNCLGETEXTENSIONFUNCTIONADDRESS )CLCC_DYNLIB_IMPORT(module, "clGetExtensionFunctionAddress"));
+
+ return CLEW_SUCCESS;
+}
+
+//! \param error CL error code
+//! \return a string representation of the error code
+const char* clewErrorString(cl_int error)
+{
+ static const char* strings[] =
+ {
+ // Error Codes
+ "CL_SUCCESS" // 0
+ , "CL_DEVICE_NOT_FOUND" // -1
+ , "CL_DEVICE_NOT_AVAILABLE" // -2
+ , "CL_COMPILER_NOT_AVAILABLE" // -3
+ , "CL_MEM_OBJECT_ALLOCATION_FAILURE" // -4
+ , "CL_OUT_OF_RESOURCES" // -5
+ , "CL_OUT_OF_HOST_MEMORY" // -6
+ , "CL_PROFILING_INFO_NOT_AVAILABLE" // -7
+ , "CL_MEM_COPY_OVERLAP" // -8
+ , "CL_IMAGE_FORMAT_MISMATCH" // -9
+ , "CL_IMAGE_FORMAT_NOT_SUPPORTED" // -10
+ , "CL_BUILD_PROGRAM_FAILURE" // -11
+ , "CL_MAP_FAILURE" // -12
+
+ , "" // -13
+ , "" // -14
+ , "" // -15
+ , "" // -16
+ , "" // -17
+ , "" // -18
+ , "" // -19
+
+ , "" // -20
+ , "" // -21
+ , "" // -22
+ , "" // -23
+ , "" // -24
+ , "" // -25
+ , "" // -26
+ , "" // -27
+ , "" // -28
+ , "" // -29
+
+ , "CL_INVALID_VALUE" // -30
+ , "CL_INVALID_DEVICE_TYPE" // -31
+ , "CL_INVALID_PLATFORM" // -32
+ , "CL_INVALID_DEVICE" // -33
+ , "CL_INVALID_CONTEXT" // -34
+ , "CL_INVALID_QUEUE_PROPERTIES" // -35
+ , "CL_INVALID_COMMAND_QUEUE" // -36
+ , "CL_INVALID_HOST_PTR" // -37
+ , "CL_INVALID_MEM_OBJECT" // -38
+ , "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR" // -39
+ , "CL_INVALID_IMAGE_SIZE" // -40
+ , "CL_INVALID_SAMPLER" // -41
+ , "CL_INVALID_BINARY" // -42
+ , "CL_INVALID_BUILD_OPTIONS" // -43
+ , "CL_INVALID_PROGRAM" // -44
+ , "CL_INVALID_PROGRAM_EXECUTABLE" // -45
+ , "CL_INVALID_KERNEL_NAME" // -46
+ , "CL_INVALID_KERNEL_DEFINITION" // -47
+ , "CL_INVALID_KERNEL" // -48
+ , "CL_INVALID_ARG_INDEX" // -49
+ , "CL_INVALID_ARG_VALUE" // -50
+ , "CL_INVALID_ARG_SIZE" // -51
+ , "CL_INVALID_KERNEL_ARGS" // -52
+ , "CL_INVALID_WORK_DIMENSION" // -53
+ , "CL_INVALID_WORK_GROUP_SIZE" // -54
+ , "CL_INVALID_WORK_ITEM_SIZE" // -55
+ , "CL_INVALID_GLOBAL_OFFSET" // -56
+ , "CL_INVALID_EVENT_WAIT_LIST" // -57
+ , "CL_INVALID_EVENT" // -58
+ , "CL_INVALID_OPERATION" // -59
+ , "CL_INVALID_GL_OBJECT" // -60
+ , "CL_INVALID_BUFFER_SIZE" // -61
+ , "CL_INVALID_MIP_LEVEL" // -62
+ , "CL_INVALID_GLOBAL_WORK_SIZE" // -63
+ };
+
+ if ( (error > 0)
+ || (error < -63)
+ )
+ {
+ return "unknown error code (no OpenCL driver?)";
+ }
+
+ return strings[-error];
+}
diff --git a/external/clew/source/include/clew/clew.h b/external/clew/source/include/clew/clew.h
new file mode 100644
index 000000000..a722b68bb
--- /dev/null
+++ b/external/clew/source/include/clew/clew.h
@@ -0,0 +1,1187 @@
+#ifndef CLEW_CLEW_H_INCLUDED
+#define CLEW_CLEW_H_INCLUDED
+
+//////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2009-2011 Organic Vectory B.V.
+// Written by George van Venrooij
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file license.txt)
+//////////////////////////////////////////////////////////////////////////
+
+//! \file clew.h
+//! \brief OpenCL run-time loader header
+//!
+//! This file contains a copy of the contents of CL.H and CL_PLATFORM.H from the
+//! official OpenCL spec. The purpose of this code is to load the OpenCL dynamic
+//! library at run-time and thus allow the executable to function on many
+//! platforms regardless of the vendor of the OpenCL driver actually installed.
+//! Some of the techniques used here were inspired by work done in the GLEW
+//! library (http://glew.sourceforge.net/)
+
+// Run-time dynamic linking functionality based on concepts used in GLEW
+#ifdef __OPENCL_CL_H
+#error cl.h included before clew.h
+#endif
+
+#ifdef __OPENCL_CL_PLATFORM_H
+#error cl_platform.h included before clew.h
+#endif
+
+#ifndef CLCC_GENERATE_DOCUMENTATION
+// Prevent cl.h inclusion
+#define __OPENCL_CL_H
+// Prevent cl_platform.h inclusion
+#define __CL_PLATFORM_H
+#endif // CLCC_GENERATE_DOCUMENTATION
+
+/*******************************************************************************
+* Copyright (c) 2008-2009 The Khronos Group Inc.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and/or associated documentation files (the
+* "Materials"), to deal in the Materials without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Materials, and to
+* permit persons to whom the Materials are furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Materials.
+*
+* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+******************************************************************************/
+#ifdef __APPLE__
+/* Contains #defines for AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER below */
+#include <AvailabilityMacros.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CLCC_GENERATE_DOCUMENTATION
+
+#if defined(_WIN32)
+#define CL_API_ENTRY
+#define CL_API_CALL __stdcall
+#else
+#define CL_API_ENTRY
+#define CL_API_CALL
+#endif
+
+#if defined(__APPLE__)
+#define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
+#define CL_EXTENSION_WEAK_LINK __attribute__((weak_import))
+#else
+#define CL_API_SUFFIX__VERSION_1_0
+#define CL_EXTENSION_WEAK_LINK
+#endif
+
+#include <stdint.h>
+
+#if defined(_WIN32) && defined(_MSC_VER)
+
+/* scalar types */
+typedef signed __int8 cl_char;
+typedef unsigned __int8 cl_uchar;
+typedef signed __int16 cl_short;
+typedef unsigned __int16 cl_ushort;
+typedef signed __int32 cl_int;
+typedef unsigned __int32 cl_uint;
+typedef signed __int64 cl_long;
+typedef unsigned __int64 cl_ulong;
+
+typedef unsigned __int16 cl_half;
+typedef float cl_float;
+typedef double cl_double;
+
+
+/*
+* Vector types
+*
+* Note: OpenCL requires that all types be naturally aligned.
+* This means that vector types must be naturally aligned.
+* For example, a vector of four floats must be aligned to
+* a 16 byte boundary (calculated as 4 * the natural 4-byte
+* alignment of the float). The alignment qualifiers here
+* will only function properly if your compiler supports them
+* and if you don't actively work to defeat them. For example,
+* in order for a cl_float4 to be 16 byte aligned in a struct,
+* the start of the struct must itself be 16-byte aligned.
+*
+* Maintaining proper alignment is the user's responsibility.
+*/
+typedef signed __int8 cl_char2[2];
+typedef signed __int8 cl_char4[4];
+typedef signed __int8 cl_char8[8];
+typedef signed __int8 cl_char16[16];
+typedef unsigned __int8 cl_uchar2[2];
+typedef unsigned __int8 cl_uchar4[4];
+typedef unsigned __int8 cl_uchar8[8];
+typedef unsigned __int8 cl_uchar16[16];
+
+typedef signed __int16 cl_short2[2];
+typedef signed __int16 cl_short4[4];
+typedef signed __int16 cl_short8[8];
+typedef signed __int16 cl_short16[16];
+typedef unsigned __int16 cl_ushort2[2];
+typedef unsigned __int16 cl_ushort4[4];
+typedef unsigned __int16 cl_ushort8[8];
+typedef unsigned __int16 cl_ushort16[16];
+
+typedef signed __int32 cl_int2[2];
+typedef signed __int32 cl_int4[4];
+typedef signed __int32 cl_int8[8];
+typedef signed __int32 cl_int16[16];
+typedef unsigned __int32 cl_uint2[2];
+typedef unsigned __int32 cl_uint4[4];
+typedef unsigned __int32 cl_uint8[8];
+typedef unsigned __int32 cl_uint16[16];
+
+typedef signed __int64 cl_long2[2];
+typedef signed __int64 cl_long4[4];
+typedef signed __int64 cl_long8[8];
+typedef signed __int64 cl_long16[16];
+typedef unsigned __int64 cl_ulong2[2];
+typedef unsigned __int64 cl_ulong4[4];
+typedef unsigned __int64 cl_ulong8[8];
+typedef unsigned __int64 cl_ulong16[16];
+
+typedef float cl_float2[2];
+typedef float cl_float4[4];
+typedef float cl_float8[8];
+typedef float cl_float16[16];
+
+typedef double cl_double2[2];
+typedef double cl_double4[4];
+typedef double cl_double8[8];
+typedef double cl_double16[16];
+/* There are no vector types for half */
+
+#else
+
+/* scalar types */
+typedef int8_t cl_char;
+typedef uint8_t cl_uchar;
+typedef int16_t cl_short __attribute__((aligned(2)));
+typedef uint16_t cl_ushort __attribute__((aligned(2)));
+typedef int32_t cl_int __attribute__((aligned(4)));
+typedef uint32_t cl_uint __attribute__((aligned(4)));
+typedef int64_t cl_long __attribute__((aligned(8)));
+typedef uint64_t cl_ulong __attribute__((aligned(8)));
+
+typedef uint16_t cl_half __attribute__((aligned(2)));
+typedef float cl_float __attribute__((aligned(4)));
+typedef double cl_double __attribute__((aligned(8)));
+
+/*
+* Vector types
+*
+* Note: OpenCL requires that all types be naturally aligned.
+* This means that vector types must be naturally aligned.
+* For example, a vector of four floats must be aligned to
+* a 16 byte boundary (calculated as 4 * the natural 4-byte
+* alignment of the float). The alignment qualifiers here
+* will only function properly if your compiler supports them
+* and if you don't actively work to defeat them. For example,
+* in order for a cl_float4 to be 16 byte aligned in a struct,
+* the start of the struct must itself be 16-byte aligned.
+*
+* Maintaining proper alignment is the user's responsibility.
+*/
+typedef int8_t cl_char2[2] __attribute__((aligned(2)));
+typedef int8_t cl_char4[4] __attribute__((aligned(4)));
+typedef int8_t cl_char8[8] __attribute__((aligned(8)));
+typedef int8_t cl_char16[16] __attribute__((aligned(16)));
+typedef uint8_t cl_uchar2[2] __attribute__((aligned(2)));
+typedef uint8_t cl_uchar4[4] __attribute__((aligned(4)));
+typedef uint8_t cl_uchar8[8] __attribute__((aligned(8)));
+typedef uint8_t cl_uchar16[16] __attribute__((aligned(16)));
+
+typedef int16_t cl_short2[2] __attribute__((aligned(4)));
+typedef int16_t cl_short4[4] __attribute__((aligned(8)));
+typedef int16_t cl_short8[8] __attribute__((aligned(16)));
+typedef int16_t cl_short16[16] __attribute__((aligned(32)));
+typedef uint16_t cl_ushort2[2] __attribute__((aligned(4)));
+typedef uint16_t cl_ushort4[4] __attribute__((aligned(8)));
+typedef uint16_t cl_ushort8[8] __attribute__((aligned(16)));
+typedef uint16_t cl_ushort16[16] __attribute__((aligned(32)));
+
+typedef int32_t cl_int2[2] __attribute__((aligned(8)));
+typedef int32_t cl_int4[4] __attribute__((aligned(16)));
+typedef int32_t cl_int8[8] __attribute__((aligned(32)));
+typedef int32_t cl_int16[16] __attribute__((aligned(64)));
+typedef uint32_t cl_uint2[2] __attribute__((aligned(8)));
+typedef uint32_t cl_uint4[4] __attribute__((aligned(16)));
+typedef uint32_t cl_uint8[8] __attribute__((aligned(32)));
+typedef uint32_t cl_uint16[16] __attribute__((aligned(64)));
+
+typedef int64_t cl_long2[2] __attribute__((aligned(16)));
+typedef int64_t cl_long4[4] __attribute__((aligned(32)));
+typedef int64_t cl_long8[8] __attribute__((aligned(64)));
+typedef int64_t cl_long16[16] __attribute__((aligned(128)));
+typedef uint64_t cl_ulong2[2] __attribute__((aligned(16)));
+typedef uint64_t cl_ulong4[4] __attribute__((aligned(32)));
+typedef uint64_t cl_ulong8[8] __attribute__((aligned(64)));
+typedef uint64_t cl_ulong16[16] __attribute__((aligned(128)));
+
+typedef float cl_float2[2] __attribute__((aligned(8)));
+typedef float cl_float4[4] __attribute__((aligned(16)));
+typedef float cl_float8[8] __attribute__((aligned(32)));
+typedef float cl_float16[16] __attribute__((aligned(64)));
+
+typedef double cl_double2[2] __attribute__((aligned(16)));
+typedef double cl_double4[4] __attribute__((aligned(32)));
+typedef double cl_double8[8] __attribute__((aligned(64)));
+typedef double cl_double16[16] __attribute__((aligned(128)));
+
+/* There are no vector types for half */
+
+#endif
+
+/******************************************************************************/
+
+// Macro names and corresponding values defined by OpenCL
+
+#define CL_SCHAR_MAX 127
+#define CL_SCHAR_MIN (-127-1)
+#define CL_SHRT_MIN (-32767-1)
+#define CL_INT_MIN (-2147483647-1)
+#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL)
+#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL)
+#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL)
+
+#define CL_FLT_MAX_10_EXP +38
+#define CL_FLT_MAX_EXP +128
+#define CL_FLT_MIN_10_EXP -37
+#define CL_FLT_MIN_EXP -125
+#if defined(_MSC_VER)
+// MSVC doesn't understand hex floats
+#define CL_FLT_MAX 3.402823466e+38F
+#define CL_FLT_MIN 1.175494351e-38F
+#define CL_FLT_EPSILON 1.192092896e-07F
+#else
+#define CL_FLT_MAX 0x1.fffffep127f
+#define CL_FLT_MIN 0x1.0p-126f
+#define CL_FLT_EPSILON 0x1.0p-23f
+#endif
+
+#define CL_DBL_MAX_10_EXP +308
+#define CL_DBL_MAX_EXP +1024
+#define CL_DBL_MIN_10_EXP -307
+#define CL_DBL_MIN_EXP -1021
+#if defined(_MSC_VER)
+// MSVC doesn't understand hex floats
+#define CL_DBL_MAX 1.7976931348623158e+308
+#define CL_DBL_MIN 2.2250738585072014e-308
+#define CL_DBL_EPSILON 2.2204460492503131e-016
+#else
+#define CL_DBL_MAX 0x1.fffffffffffffp1023
+#define CL_DBL_MIN 0x1.0p-1022
+#define CL_DBL_EPSILON 0x1.0p-52
+#endif
+
+#include <stddef.h>
+
+
+// CL.h contents
+/******************************************************************************/
+
+typedef struct _cl_platform_id * cl_platform_id;
+typedef struct _cl_device_id * cl_device_id;
+typedef struct _cl_context * cl_context;
+typedef struct _cl_command_queue * cl_command_queue;
+typedef struct _cl_mem * cl_mem;
+typedef struct _cl_program * cl_program;
+typedef struct _cl_kernel * cl_kernel;
+typedef struct _cl_event * cl_event;
+typedef struct _cl_sampler * cl_sampler;
+
+typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */
+typedef cl_ulong cl_bitfield;
+typedef cl_bitfield cl_device_type;
+typedef cl_uint cl_platform_info;
+typedef cl_uint cl_device_info;
+typedef cl_bitfield cl_device_address_info;
+typedef cl_bitfield cl_device_fp_config;
+typedef cl_uint cl_device_mem_cache_type;
+typedef cl_uint cl_device_local_mem_type;
+typedef cl_bitfield cl_device_exec_capabilities;
+typedef cl_bitfield cl_command_queue_properties;
+
+typedef intptr_t cl_context_properties;
+typedef cl_uint cl_context_info;
+typedef cl_uint cl_command_queue_info;
+typedef cl_uint cl_channel_order;
+typedef cl_uint cl_channel_type;
+typedef cl_bitfield cl_mem_flags;
+typedef cl_uint cl_mem_object_type;
+typedef cl_uint cl_mem_info;
+typedef cl_uint cl_image_info;
+typedef cl_uint cl_addressing_mode;
+typedef cl_uint cl_filter_mode;
+typedef cl_uint cl_sampler_info;
+typedef cl_bitfield cl_map_flags;
+typedef cl_uint cl_program_info;
+typedef cl_uint cl_program_build_info;
+typedef cl_int cl_build_status;
+typedef cl_uint cl_kernel_info;
+typedef cl_uint cl_kernel_work_group_info;
+typedef cl_uint cl_event_info;
+typedef cl_uint cl_command_type;
+typedef cl_uint cl_profiling_info;
+
+typedef struct {
+ cl_channel_order image_channel_order;
+ cl_channel_type image_channel_data_type;
+} cl_image_format;
+
+
+
+/******************************************************************************/
+
+// Error Codes
+#define CL_SUCCESS 0
+#define CL_DEVICE_NOT_FOUND -1
+#define CL_DEVICE_NOT_AVAILABLE -2
+#define CL_COMPILER_NOT_AVAILABLE -3
+#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4
+#define CL_OUT_OF_RESOURCES -5
+#define CL_OUT_OF_HOST_MEMORY -6
+#define CL_PROFILING_INFO_NOT_AVAILABLE -7
+#define CL_MEM_COPY_OVERLAP -8
+#define CL_IMAGE_FORMAT_MISMATCH -9
+#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10
+#define CL_BUILD_PROGRAM_FAILURE -11
+#define CL_MAP_FAILURE -12
+
+#define CL_INVALID_VALUE -30
+#define CL_INVALID_DEVICE_TYPE -31
+#define CL_INVALID_PLATFORM -32
+#define CL_INVALID_DEVICE -33
+#define CL_INVALID_CONTEXT -34
+#define CL_INVALID_QUEUE_PROPERTIES -35
+#define CL_INVALID_COMMAND_QUEUE -36
+#define CL_INVALID_HOST_PTR -37
+#define CL_INVALID_MEM_OBJECT -38
+#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39
+#define CL_INVALID_IMAGE_SIZE -40
+#define CL_INVALID_SAMPLER -41
+#define CL_INVALID_BINARY -42
+#define CL_INVALID_BUILD_OPTIONS -43
+#define CL_INVALID_PROGRAM -44
+#define CL_INVALID_PROGRAM_EXECUTABLE -45
+#define CL_INVALID_KERNEL_NAME -46
+#define CL_INVALID_KERNEL_DEFINITION -47
+#define CL_INVALID_KERNEL -48
+#define CL_INVALID_ARG_INDEX -49
+#define CL_INVALID_ARG_VALUE -50
+#define CL_INVALID_ARG_SIZE -51
+#define CL_INVALID_KERNEL_ARGS -52
+#define CL_INVALID_WORK_DIMENSION -53
+#define CL_INVALID_WORK_GROUP_SIZE -54
+#define CL_INVALID_WORK_ITEM_SIZE -55
+#define CL_INVALID_GLOBAL_OFFSET -56
+#define CL_INVALID_EVENT_WAIT_LIST -57
+#define CL_INVALID_EVENT -58
+#define CL_INVALID_OPERATION -59
+#define CL_INVALID_GL_OBJECT -60
+#define CL_INVALID_BUFFER_SIZE -61
+#define CL_INVALID_MIP_LEVEL -62
+#define CL_INVALID_GLOBAL_WORK_SIZE -63
+
+// cl_bool
+#define CL_TRUE 1
+
+// cl_platform_info
+#define CL_PLATFORM_PROFILE 0x0900
+#define CL_PLATFORM_VERSION 0x0901
+#define CL_PLATFORM_NAME 0x0902
+#define CL_PLATFORM_VENDOR 0x0903
+#define CL_PLATFORM_EXTENSIONS 0x0904
+
+// cl_device_type - bitfield
+#define CL_DEVICE_TYPE_DEFAULT (1 << 0)
+#define CL_DEVICE_TYPE_CPU (1 << 1)
+#define CL_DEVICE_TYPE_GPU (1 << 2)
+#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3)
+#define CL_DEVICE_TYPE_CUSTOM (1 << 4)
+#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF
+
+// cl_device_info
+#define CL_DEVICE_TYPE 0x1000
+#define CL_DEVICE_VENDOR_ID 0x1001
+#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002
+#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003
+#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004
+#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005
+#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006
+#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007
+#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008
+#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009
+#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A
+#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B
+#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C
+#define CL_DEVICE_ADDRESS_BITS 0x100D
+#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E
+#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F
+#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010
+#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011
+#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012
+#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013
+#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014
+#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015
+#define CL_DEVICE_IMAGE_SUPPORT 0x1016
+#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017
+#define CL_DEVICE_MAX_SAMPLERS 0x1018
+#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019
+#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A
+#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B
+#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C
+#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D
+#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E
+#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F
+#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020
+#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021
+#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022
+#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023
+#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024
+#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025
+#define CL_DEVICE_ENDIAN_LITTLE 0x1026
+#define CL_DEVICE_AVAILABLE 0x1027
+#define CL_DEVICE_COMPILER_AVAILABLE 0x1028
+#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029
+#define CL_DEVICE_QUEUE_PROPERTIES 0x102A
+#define CL_DEVICE_NAME 0x102B
+#define CL_DEVICE_VENDOR 0x102C
+#define CL_DRIVER_VERSION 0x102D
+#define CL_DEVICE_PROFILE 0x102E
+#define CL_DEVICE_VERSION 0x102F
+#define CL_DEVICE_EXTENSIONS 0x1030
+#define CL_DEVICE_PLATFORM 0x1031
+#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032
+/* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG */
+#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034
+#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035
+#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036
+#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037
+#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038
+#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039
+#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A
+#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B
+#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C
+#define CL_DEVICE_OPENCL_C_VERSION 0x103D
+#define CL_DEVICE_LINKER_AVAILABLE 0x103E
+#define CL_DEVICE_BUILT_IN_KERNELS 0x103F
+#define CL_DEVICE_IMAGE_MAX_BUFFER_SIZE 0x1040
+#define CL_DEVICE_IMAGE_MAX_ARRAY_SIZE 0x1041
+#define CL_DEVICE_PARENT_DEVICE 0x1042
+#define CL_DEVICE_PARTITION_MAX_SUB_DEVICES 0x1043
+#define CL_DEVICE_PARTITION_PROPERTIES 0x1044
+#define CL_DEVICE_PARTITION_AFFINITY_DOMAIN 0x1045
+#define CL_DEVICE_PARTITION_TYPE 0x1046
+#define CL_DEVICE_REFERENCE_COUNT 0x1047
+#define CL_DEVICE_PREFERRED_INTEROP_USER_SYNC 0x1048
+#define CL_DEVICE_PRINTF_BUFFER_SIZE 0x1049
+#define CL_DEVICE_IMAGE_PITCH_ALIGNMENT 0x104A
+#define CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 0x104B
+
+// cl_device_fp_config - bitfield
+#define CL_FP_DENORM (1 << 0)
+#define CL_FP_INF_NAN (1 << 1)
+#define CL_FP_ROUND_TO_NEAREST (1 << 2)
+#define CL_FP_ROUND_TO_ZERO (1 << 3)
+#define CL_FP_ROUND_TO_INF (1 << 4)
+#define CL_FP_FMA (1 << 5)
+
+// cl_device_exec_capabilities - bitfield
+#define CL_EXEC_KERNEL (1 << 0)
+#define CL_EXEC_NATIVE_KERNEL (1 << 1)
+
+// cl_command_queue_properties - bitfield
+#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0)
+#define CL_QUEUE_PROFILING_ENABLE (1 << 1)
+
+// cl_context_info
+#define CL_CONTEXT_DEVICES 0x1081
+
+// cl_context_properties
+#define CL_CONTEXT_PLATFORM 0x1084
+
+// cl_mem_flags - bitfield
+#define CL_MEM_READ_WRITE (1 << 0)
+#define CL_MEM_WRITE_ONLY (1 << 1)
+#define CL_MEM_READ_ONLY (1 << 2)
+#define CL_MEM_USE_HOST_PTR (1 << 3)
+#define CL_MEM_ALLOC_HOST_PTR (1 << 4)
+#define CL_MEM_COPY_HOST_PTR (1 << 5)
+
+// cl_map_flags - bitfield
+#define CL_MAP_READ (1 << 0)
+#define CL_MAP_WRITE (1 << 1)
+
+// cl_program_info
+#define CL_PROGRAM_NUM_DEVICES 0x1162
+#define CL_PROGRAM_DEVICES 0x1163
+#define CL_PROGRAM_BINARY_SIZES 0x1165
+#define CL_PROGRAM_BINARIES 0x1166
+
+// cl_program_build_info
+#define CL_PROGRAM_BUILD_STATUS 0x1181
+#define CL_PROGRAM_BUILD_LOG 0x1183
+
+// cl_build_status
+#define CL_BUILD_NONE -1
+#define CL_BUILD_ERROR -2
+#define CL_BUILD_IN_PROGRESS -3
+
+/********************************************************************************************************/
+
+/********************************************************************************************************/
+
+// Function signature typedef's
+
+// Platform API
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETPLATFORMIDS)(cl_uint /* num_entries */,
+ cl_platform_id * /* platforms */,
+ cl_uint * /* num_platforms */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETPLATFORMINFO)(cl_platform_id /* platform */,
+ cl_platform_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+// Device APIs
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETDEVICEIDS)(cl_platform_id /* platform */,
+ cl_device_type /* device_type */,
+ cl_uint /* num_entries */,
+ cl_device_id * /* devices */,
+ cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETDEVICEINFO)(cl_device_id /* device */,
+ cl_device_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+// Context APIs
+typedef CL_API_ENTRY cl_context (CL_API_CALL *
+PFNCLCREATECONTEXT)(const cl_context_properties * /* properties */,
+ cl_uint /* num_devices */,
+ const cl_device_id * /* devices */,
+ void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */,
+ void * /* user_data */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_context (CL_API_CALL *
+PFNCLCREATECONTEXTFROMTYPE)(const cl_context_properties * /* properties */,
+ cl_device_type /* device_type */,
+ void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */,
+ void * /* user_data */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRETAINCONTEXT)(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRELEASECONTEXT)(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETCONTEXTINFO)(cl_context /* context */,
+ cl_context_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+// Command Queue APIs
+typedef CL_API_ENTRY cl_command_queue (CL_API_CALL *
+PFNCLCREATECOMMANDQUEUE)(cl_context /* context */,
+ cl_device_id /* device */,
+ cl_command_queue_properties /* properties */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRETAINCOMMANDQUEUE)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRELEASECOMMANDQUEUE)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETCOMMANDQUEUEINFO)(cl_command_queue /* command_queue */,
+ cl_command_queue_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLSETCOMMANDQUEUEPROPERTY)(cl_command_queue /* command_queue */,
+ cl_command_queue_properties /* properties */,
+ cl_bool /* enable */,
+ cl_command_queue_properties * /* old_properties */) CL_API_SUFFIX__VERSION_1_0;
+
+// Memory Object APIs
+typedef CL_API_ENTRY cl_mem (CL_API_CALL *
+PFNCLCREATEBUFFER)(cl_context /* context */,
+ cl_mem_flags /* flags */,
+ size_t /* size */,
+ void * /* host_ptr */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_mem (CL_API_CALL *
+PFNCLCREATEIMAGE2D)(cl_context /* context */,
+ cl_mem_flags /* flags */,
+ const cl_image_format * /* image_format */,
+ size_t /* image_width */,
+ size_t /* image_height */,
+ size_t /* image_row_pitch */,
+ void * /* host_ptr */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_mem (CL_API_CALL *
+PFNCLCREATEIMAGE3D)(cl_context /* context */,
+ cl_mem_flags /* flags */,
+ const cl_image_format * /* image_format */,
+ size_t /* image_width */,
+ size_t /* image_height */,
+ size_t /* image_depth */,
+ size_t /* image_row_pitch */,
+ size_t /* image_slice_pitch */,
+ void * /* host_ptr */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRETAINMEMOBJECT)(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRELEASEMEMOBJECT)(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETSUPPORTEDIMAGEFORMATS)(cl_context /* context */,
+ cl_mem_flags /* flags */,
+ cl_mem_object_type /* image_type */,
+ cl_uint /* num_entries */,
+ cl_image_format * /* image_formats */,
+ cl_uint * /* num_image_formats */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETMEMOBJECTINFO)(cl_mem /* memobj */,
+ cl_mem_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETIMAGEINFO)(cl_mem /* image */,
+ cl_image_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+// Sampler APIs
+typedef CL_API_ENTRY cl_sampler (CL_API_CALL *
+PFNCLCREATESAMPLER)(cl_context /* context */,
+ cl_bool /* normalized_coords */,
+ cl_addressing_mode /* addressing_mode */,
+ cl_filter_mode /* filter_mode */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRETAINSAMPLER)(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRELEASESAMPLER)(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETSAMPLERINFO)(cl_sampler /* sampler */,
+ cl_sampler_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+// Program Object APIs
+typedef CL_API_ENTRY cl_program (CL_API_CALL *
+PFNCLCREATEPROGRAMWITHSOURCE)(cl_context /* context */,
+ cl_uint /* count */,
+ const char ** /* strings */,
+ const size_t * /* lengths */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_program (CL_API_CALL *
+PFNCLCREATEPROGRAMWITHBINARY)(cl_context /* context */,
+ cl_uint /* num_devices */,
+ const cl_device_id * /* device_list */,
+ const size_t * /* lengths */,
+ const unsigned char ** /* binaries */,
+ cl_int * /* binary_status */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRETAINPROGRAM)(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRELEASEPROGRAM)(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLBUILDPROGRAM)(cl_program /* program */,
+ cl_uint /* num_devices */,
+ const cl_device_id * /* device_list */,
+ const char * /* options */,
+ void (*pfn_notify)(cl_program /* program */, void * /* user_data */),
+ void * /* user_data */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLUNLOADCOMPILER)(void) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETPROGRAMINFO)(cl_program /* program */,
+ cl_program_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETPROGRAMBUILDINFO)(cl_program /* program */,
+ cl_device_id /* device */,
+ cl_program_build_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+// Kernel Object APIs
+typedef CL_API_ENTRY cl_kernel (CL_API_CALL *
+PFNCLCREATEKERNEL)(cl_program /* program */,
+ const char * /* kernel_name */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLCREATEKERNELSINPROGRAM)(cl_program /* program */,
+ cl_uint /* num_kernels */,
+ cl_kernel * /* kernels */,
+ cl_uint * /* num_kernels_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRETAINKERNEL)(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRELEASEKERNEL)(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLSETKERNELARG)(cl_kernel /* kernel */,
+ cl_uint /* arg_index */,
+ size_t /* arg_size */,
+ const void * /* arg_value */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETKERNELINFO)(cl_kernel /* kernel */,
+ cl_kernel_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETKERNELWORKGROUPINFO)(cl_kernel /* kernel */,
+ cl_device_id /* device */,
+ cl_kernel_work_group_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+// Event Object APIs
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLWAITFOREVENTS)(cl_uint /* num_events */,
+ const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETEVENTINFO)(cl_event /* event */,
+ cl_event_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRETAINEVENT)(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLRELEASEEVENT)(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+// Profiling APIs
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLGETEVENTPROFILINGINFO)(cl_event /* event */,
+ cl_profiling_info /* param_name */,
+ size_t /* param_value_size */,
+ void * /* param_value */,
+ size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+// Flush and Finish APIs
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLFLUSH)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLFINISH)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
+
+// Enqueued Commands APIs
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUEREADBUFFER)(cl_command_queue /* command_queue */,
+ cl_mem /* buffer */,
+ cl_bool /* blocking_read */,
+ size_t /* offset */,
+ size_t /* cb */,
+ void * /* ptr */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUEWRITEBUFFER)(cl_command_queue /* command_queue */,
+ cl_mem /* buffer */,
+ cl_bool /* blocking_write */,
+ size_t /* offset */,
+ size_t /* cb */,
+ const void * /* ptr */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUECOPYBUFFER)(cl_command_queue /* command_queue */,
+ cl_mem /* src_buffer */,
+ cl_mem /* dst_buffer */,
+ size_t /* src_offset */,
+ size_t /* dst_offset */,
+ size_t /* cb */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUEREADIMAGE)(cl_command_queue /* command_queue */,
+ cl_mem /* image */,
+ cl_bool /* blocking_read */,
+ const size_t * /* origin[3] */,
+ const size_t * /* region[3] */,
+ size_t /* row_pitch */,
+ size_t /* slice_pitch */,
+ void * /* ptr */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUEWRITEIMAGE)(cl_command_queue /* command_queue */,
+ cl_mem /* image */,
+ cl_bool /* blocking_write */,
+ const size_t * /* origin[3] */,
+ const size_t * /* region[3] */,
+ size_t /* input_row_pitch */,
+ size_t /* input_slice_pitch */,
+ const void * /* ptr */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUECOPYIMAGE)(cl_command_queue /* command_queue */,
+ cl_mem /* src_image */,
+ cl_mem /* dst_image */,
+ const size_t * /* src_origin[3] */,
+ const size_t * /* dst_origin[3] */,
+ const size_t * /* region[3] */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUECOPYIMAGETOBUFFER)(cl_command_queue /* command_queue */,
+ cl_mem /* src_image */,
+ cl_mem /* dst_buffer */,
+ const size_t * /* src_origin[3] */,
+ const size_t * /* region[3] */,
+ size_t /* dst_offset */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUECOPYBUFFERTOIMAGE)(cl_command_queue /* command_queue */,
+ cl_mem /* src_buffer */,
+ cl_mem /* dst_image */,
+ size_t /* src_offset */,
+ const size_t * /* dst_origin[3] */,
+ const size_t * /* region[3] */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY void * (CL_API_CALL *
+PFNCLENQUEUEMAPBUFFER)(cl_command_queue /* command_queue */,
+ cl_mem /* buffer */,
+ cl_bool /* blocking_map */,
+ cl_map_flags /* map_flags */,
+ size_t /* offset */,
+ size_t /* cb */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY void * (CL_API_CALL *
+PFNCLENQUEUEMAPIMAGE)(cl_command_queue /* command_queue */,
+ cl_mem /* image */,
+ cl_bool /* blocking_map */,
+ cl_map_flags /* map_flags */,
+ const size_t * /* origin[3] */,
+ const size_t * /* region[3] */,
+ size_t * /* image_row_pitch */,
+ size_t * /* image_slice_pitch */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */,
+ cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUEUNMAPMEMOBJECT)(cl_command_queue /* command_queue */,
+ cl_mem /* memobj */,
+ void * /* mapped_ptr */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUENDRANGEKERNEL)(cl_command_queue /* command_queue */,
+ cl_kernel /* kernel */,
+ cl_uint /* work_dim */,
+ const size_t * /* global_work_offset */,
+ const size_t * /* global_work_size */,
+ const size_t * /* local_work_size */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUETASK)(cl_command_queue /* command_queue */,
+ cl_kernel /* kernel */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUENATIVEKERNEL)(cl_command_queue /* command_queue */,
+ void (*user_func)(void *),
+ void * /* args */,
+ size_t /* cb_args */,
+ cl_uint /* num_mem_objects */,
+ const cl_mem * /* mem_list */,
+ const void ** /* args_mem_loc */,
+ cl_uint /* num_events_in_wait_list */,
+ const cl_event * /* event_wait_list */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUEMARKER)(cl_command_queue /* command_queue */,
+ cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUEWAITFOREVENTS)(cl_command_queue /* command_queue */,
+ cl_uint /* num_events */,
+ const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0;
+
+typedef CL_API_ENTRY cl_int (CL_API_CALL *
+PFNCLENQUEUEBARRIER)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0;
+
+// Extension function access
+//
+// Returns the extension function address for the given function name,
+// or NULL if a valid function can not be found. The client must
+// check to make sure the address is not NULL, before using or
+// calling the returned function address.
+//
+typedef CL_API_ENTRY void * (CL_API_CALL * PFNCLGETEXTENSIONFUNCTIONADDRESS)(const char * /* func_name */) CL_API_SUFFIX__VERSION_1_0;
+
+#ifdef CLEW_STATIC
+# define CLEWAPI extern
+#else
+# ifdef CLEW_BUILD
+# if defined(_WIN32)
+# define CLEWAPI extern __declspec(dllexport)
+# else
+# define CLEWAPI extern __attribute__ ((visibility("default")))
+# endif
+# else
+# if defined(_WIN32)
+# define CLEWAPI extern __declspec(dllimport)
+# else
+# define CLEWAPI extern
+# endif
+# endif
+#endif
+
+#define CLEW_FUN_EXPORT CLEWAPI
+
+#define CLEW_GET_FUN(x) x
+
+
+// Variables holding function entry points
+CLEW_FUN_EXPORT PFNCLGETPLATFORMIDS __clewGetPlatformIDs ;
+CLEW_FUN_EXPORT PFNCLGETPLATFORMINFO __clewGetPlatformInfo ;
+CLEW_FUN_EXPORT PFNCLGETDEVICEIDS __clewGetDeviceIDs ;
+CLEW_FUN_EXPORT PFNCLGETDEVICEINFO __clewGetDeviceInfo ;
+CLEW_FUN_EXPORT PFNCLCREATECONTEXT __clewCreateContext ;
+CLEW_FUN_EXPORT PFNCLCREATECONTEXTFROMTYPE __clewCreateContextFromType ;
+CLEW_FUN_EXPORT PFNCLRETAINCONTEXT __clewRetainContext ;
+CLEW_FUN_EXPORT PFNCLRELEASECONTEXT __clewReleaseContext ;
+CLEW_FUN_EXPORT PFNCLGETCONTEXTINFO __clewGetContextInfo ;
+CLEW_FUN_EXPORT PFNCLCREATECOMMANDQUEUE __clewCreateCommandQueue ;
+CLEW_FUN_EXPORT PFNCLRETAINCOMMANDQUEUE __clewRetainCommandQueue ;
+CLEW_FUN_EXPORT PFNCLRELEASECOMMANDQUEUE __clewReleaseCommandQueue ;
+CLEW_FUN_EXPORT PFNCLGETCOMMANDQUEUEINFO __clewGetCommandQueueInfo ;
+CLEW_FUN_EXPORT PFNCLSETCOMMANDQUEUEPROPERTY __clewSetCommandQueueProperty ;
+CLEW_FUN_EXPORT PFNCLCREATEBUFFER __clewCreateBuffer ;
+CLEW_FUN_EXPORT PFNCLCREATEIMAGE2D __clewCreateImage2D ;
+CLEW_FUN_EXPORT PFNCLCREATEIMAGE3D __clewCreateImage3D ;
+CLEW_FUN_EXPORT PFNCLRETAINMEMOBJECT __clewRetainMemObject ;
+CLEW_FUN_EXPORT PFNCLRELEASEMEMOBJECT __clewReleaseMemObject ;
+CLEW_FUN_EXPORT PFNCLGETSUPPORTEDIMAGEFORMATS __clewGetSupportedImageFormats ;
+CLEW_FUN_EXPORT PFNCLGETMEMOBJECTINFO __clewGetMemObjectInfo ;
+CLEW_FUN_EXPORT PFNCLGETIMAGEINFO __clewGetImageInfo ;
+CLEW_FUN_EXPORT PFNCLCREATESAMPLER __clewCreateSampler ;
+CLEW_FUN_EXPORT PFNCLRETAINSAMPLER __clewRetainSampler ;
+CLEW_FUN_EXPORT PFNCLRELEASESAMPLER __clewReleaseSampler ;
+CLEW_FUN_EXPORT PFNCLGETSAMPLERINFO __clewGetSamplerInfo ;
+CLEW_FUN_EXPORT PFNCLCREATEPROGRAMWITHSOURCE __clewCreateProgramWithSource ;
+CLEW_FUN_EXPORT PFNCLCREATEPROGRAMWITHBINARY __clewCreateProgramWithBinary ;
+CLEW_FUN_EXPORT PFNCLRETAINPROGRAM __clewRetainProgram ;
+CLEW_FUN_EXPORT PFNCLRELEASEPROGRAM __clewReleaseProgram ;
+CLEW_FUN_EXPORT PFNCLBUILDPROGRAM __clewBuildProgram ;
+CLEW_FUN_EXPORT PFNCLUNLOADCOMPILER __clewUnloadCompiler ;
+CLEW_FUN_EXPORT PFNCLGETPROGRAMINFO __clewGetProgramInfo ;
+CLEW_FUN_EXPORT PFNCLGETPROGRAMBUILDINFO __clewGetProgramBuildInfo ;
+CLEW_FUN_EXPORT PFNCLCREATEKERNEL __clewCreateKernel ;
+CLEW_FUN_EXPORT PFNCLCREATEKERNELSINPROGRAM __clewCreateKernelsInProgram ;
+CLEW_FUN_EXPORT PFNCLRETAINKERNEL __clewRetainKernel ;
+CLEW_FUN_EXPORT PFNCLRELEASEKERNEL __clewReleaseKernel ;
+CLEW_FUN_EXPORT PFNCLSETKERNELARG __clewSetKernelArg ;
+CLEW_FUN_EXPORT PFNCLGETKERNELINFO __clewGetKernelInfo ;
+CLEW_FUN_EXPORT PFNCLGETKERNELWORKGROUPINFO __clewGetKernelWorkGroupInfo ;
+CLEW_FUN_EXPORT PFNCLWAITFOREVENTS __clewWaitForEvents ;
+CLEW_FUN_EXPORT PFNCLGETEVENTINFO __clewGetEventInfo ;
+CLEW_FUN_EXPORT PFNCLRETAINEVENT __clewRetainEvent ;
+CLEW_FUN_EXPORT PFNCLRELEASEEVENT __clewReleaseEvent ;
+CLEW_FUN_EXPORT PFNCLGETEVENTPROFILINGINFO __clewGetEventProfilingInfo ;
+CLEW_FUN_EXPORT PFNCLFLUSH __clewFlush ;
+CLEW_FUN_EXPORT PFNCLFINISH __clewFinish ;
+CLEW_FUN_EXPORT PFNCLENQUEUEREADBUFFER __clewEnqueueReadBuffer ;
+CLEW_FUN_EXPORT PFNCLENQUEUEWRITEBUFFER __clewEnqueueWriteBuffer ;
+CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFER __clewEnqueueCopyBuffer ;
+CLEW_FUN_EXPORT PFNCLENQUEUEREADIMAGE __clewEnqueueReadImage ;
+CLEW_FUN_EXPORT PFNCLENQUEUEWRITEIMAGE __clewEnqueueWriteImage ;
+CLEW_FUN_EXPORT PFNCLENQUEUECOPYIMAGE __clewEnqueueCopyImage ;
+CLEW_FUN_EXPORT PFNCLENQUEUECOPYIMAGETOBUFFER __clewEnqueueCopyImageToBuffer ;
+CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFERTOIMAGE __clewEnqueueCopyBufferToImage ;
+CLEW_FUN_EXPORT PFNCLENQUEUEMAPBUFFER __clewEnqueueMapBuffer ;
+CLEW_FUN_EXPORT PFNCLENQUEUEMAPIMAGE __clewEnqueueMapImage ;
+CLEW_FUN_EXPORT PFNCLENQUEUEUNMAPMEMOBJECT __clewEnqueueUnmapMemObject ;
+CLEW_FUN_EXPORT PFNCLENQUEUENDRANGEKERNEL __clewEnqueueNDRangeKernel ;
+CLEW_FUN_EXPORT PFNCLENQUEUETASK __clewEnqueueTask ;
+CLEW_FUN_EXPORT PFNCLENQUEUENATIVEKERNEL __clewEnqueueNativeKernel ;
+CLEW_FUN_EXPORT PFNCLENQUEUEMARKER __clewEnqueueMarker ;
+CLEW_FUN_EXPORT PFNCLENQUEUEWAITFOREVENTS __clewEnqueueWaitForEvents ;
+CLEW_FUN_EXPORT PFNCLENQUEUEBARRIER __clewEnqueueBarrier ;
+CLEW_FUN_EXPORT PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress ;
+
+
+#define clGetPlatformIDs CLEW_GET_FUN(__clewGetPlatformIDs )
+#define clGetPlatformInfo CLEW_GET_FUN(__clewGetPlatformInfo )
+#define clGetDeviceIDs CLEW_GET_FUN(__clewGetDeviceIDs )
+#define clGetDeviceInfo CLEW_GET_FUN(__clewGetDeviceInfo )
+#define clCreateContext CLEW_GET_FUN(__clewCreateContext )
+#define clCreateContextFromType CLEW_GET_FUN(__clewCreateContextFromType )
+#define clRetainContext CLEW_GET_FUN(__clewRetainContext )
+#define clReleaseContext CLEW_GET_FUN(__clewReleaseContext )
+#define clGetContextInfo CLEW_GET_FUN(__clewGetContextInfo )
+#define clCreateCommandQueue CLEW_GET_FUN(__clewCreateCommandQueue )
+#define clRetainCommandQueue CLEW_GET_FUN(__clewRetainCommandQueue )
+#define clReleaseCommandQueue CLEW_GET_FUN(__clewReleaseCommandQueue )
+#define clGetCommandQueueInfo CLEW_GET_FUN(__clewGetCommandQueueInfo )
+#define clSetCommandQueueProperty CLEW_GET_FUN(__clewSetCommandQueueProperty )
+#define clCreateBuffer CLEW_GET_FUN(__clewCreateBuffer )
+#define clCreateImage2D CLEW_GET_FUN(__clewCreateImage2D )
+#define clCreateImage3D CLEW_GET_FUN(__clewCreateImage3D )
+#define clRetainMemObject CLEW_GET_FUN(__clewRetainMemObject )
+#define clReleaseMemObject CLEW_GET_FUN(__clewReleaseMemObject )
+#define clGetSupportedImageFormats CLEW_GET_FUN(__clewGetSupportedImageFormats )
+#define clGetMemObjectInfo CLEW_GET_FUN(__clewGetMemObjectInfo )
+#define clGetImageInfo CLEW_GET_FUN(__clewGetImageInfo )
+#define clCreateSampler CLEW_GET_FUN(__clewCreateSampler )
+#define clRetainSampler CLEW_GET_FUN(__clewRetainSampler )
+#define clReleaseSampler CLEW_GET_FUN(__clewReleaseSampler )
+#define clGetSamplerInfo CLEW_GET_FUN(__clewGetSamplerInfo )
+#define clCreateProgramWithSource CLEW_GET_FUN(__clewCreateProgramWithSource )
+#define clCreateProgramWithBinary CLEW_GET_FUN(__clewCreateProgramWithBinary )
+#define clRetainProgram CLEW_GET_FUN(__clewRetainProgram )
+#define clReleaseProgram CLEW_GET_FUN(__clewReleaseProgram )
+#define clBuildProgram CLEW_GET_FUN(__clewBuildProgram )
+#define clUnloadCompiler CLEW_GET_FUN(__clewUnloadCompiler )
+#define clGetProgramInfo CLEW_GET_FUN(__clewGetProgramInfo )
+#define clGetProgramBuildInfo CLEW_GET_FUN(__clewGetProgramBuildInfo )
+#define clCreateKernel CLEW_GET_FUN(__clewCreateKernel )
+#define clCreateKernelsInProgram CLEW_GET_FUN(__clewCreateKernelsInProgram )
+#define clRetainKernel CLEW_GET_FUN(__clewRetainKernel )
+#define clReleaseKernel CLEW_GET_FUN(__clewReleaseKernel )
+#define clSetKernelArg CLEW_GET_FUN(__clewSetKernelArg )
+#define clGetKernelInfo CLEW_GET_FUN(__clewGetKernelInfo )
+#define clGetKernelWorkGroupInfo CLEW_GET_FUN(__clewGetKernelWorkGroupInfo )
+#define clWaitForEvents CLEW_GET_FUN(__clewWaitForEvents )
+#define clGetEventInfo CLEW_GET_FUN(__clewGetEventInfo )
+#define clRetainEvent CLEW_GET_FUN(__clewRetainEvent )
+#define clReleaseEvent CLEW_GET_FUN(__clewReleaseEvent )
+#define clGetEventProfilingInfo CLEW_GET_FUN(__clewGetEventProfilingInfo )
+#define clFlush CLEW_GET_FUN(__clewFlush )
+#define clFinish CLEW_GET_FUN(__clewFinish )
+#define clEnqueueReadBuffer CLEW_GET_FUN(__clewEnqueueReadBuffer )
+#define clEnqueueWriteBuffer CLEW_GET_FUN(__clewEnqueueWriteBuffer )
+#define clEnqueueCopyBuffer CLEW_GET_FUN(__clewEnqueueCopyBuffer )
+#define clEnqueueReadImage CLEW_GET_FUN(__clewEnqueueReadImage )
+#define clEnqueueWriteImage CLEW_GET_FUN(__clewEnqueueWriteImage )
+#define clEnqueueCopyImage CLEW_GET_FUN(__clewEnqueueCopyImage )
+#define clEnqueueCopyImageToBuffer CLEW_GET_FUN(__clewEnqueueCopyImageToBuffer )
+#define clEnqueueCopyBufferToImage CLEW_GET_FUN(__clewEnqueueCopyBufferToImage )
+#define clEnqueueMapBuffer CLEW_GET_FUN(__clewEnqueueMapBuffer )
+#define clEnqueueMapImage CLEW_GET_FUN(__clewEnqueueMapImage )
+#define clEnqueueUnmapMemObject CLEW_GET_FUN(__clewEnqueueUnmapMemObject )
+#define clEnqueueNDRangeKernel CLEW_GET_FUN(__clewEnqueueNDRangeKernel )
+#define clEnqueueTask CLEW_GET_FUN(__clewEnqueueTask )
+#define clEnqueueNativeKernel CLEW_GET_FUN(__clewEnqueueNativeKernel )
+#define clEnqueueMarker CLEW_GET_FUN(__clewEnqueueMarker )
+#define clEnqueueWaitForEvents CLEW_GET_FUN(__clewEnqueueWaitForEvents )
+#define clEnqueueBarrier CLEW_GET_FUN(__clewEnqueueBarrier )
+#define clGetExtensionFunctionAddress CLEW_GET_FUN(__clewGetExtensionFunctionAddress )
+
+#endif // CLCC_GENERATE_DOCUMENTATION
+
+#define CLEW_SUCCESS 0 //!< Success error code
+#define CLEW_ERROR_OPEN_FAILED -1 //!< Error code for failing to open the dynamic library
+#define CLEW_ERROR_ATEXIT_FAILED -2 //!< Error code for failing to queue the closing of the dynamic library to atexit()
+#define CLEW_ERROR_IMPORT_FAILED -3 //!< Error code for failing to import a named function from the dll
+
+//! \brief Load OpenCL dynamic library and set function entry points
+CLEW_FUN_EXPORT int clewInit (const char*);
+//! \brief Convert an OpenCL error code to its string equivalent
+CLEW_FUN_EXPORT const char* clewErrorString (cl_int error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CLEW_CLEW_H_INCLUDED
diff --git a/external/clucene/Library_clucene.mk b/external/clucene/Library_clucene.mk
new file mode 100644
index 000000000..c6f289550
--- /dev/null
+++ b/external/clucene/Library_clucene.mk
@@ -0,0 +1,234 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,clucene))
+
+$(eval $(call gb_Library_use_external,clucene,zlib))
+
+$(eval $(call gb_Library_use_unpacked,clucene,clucene))
+
+$(eval $(call gb_Library_set_warnings_disabled,clucene))
+
+$(eval $(call gb_Library_set_include,clucene,\
+ -I$(call gb_UnpackedTarball_get_dir,clucene)/inc/internal \
+ -I$(call gb_UnpackedTarball_get_dir,clucene)/src/core \
+ -I$(call gb_UnpackedTarball_get_dir,clucene)/src/contribs-lib \
+ -I$(call gb_UnpackedTarball_get_dir,clucene)/src/shared \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_set_precompiled_header,clucene,external/clucene/inc/pch/precompiled_clucene))
+
+$(eval $(call gb_Library_add_defs,clucene,\
+ -Dclucene_shared_EXPORTS \
+ -Dclucene_core_EXPORTS \
+ -Dclucene_contribs_lib_EXPORTS \
+))
+
+# Needed when building against MSVC in C++17 mode, as
+# workdir/UnpackedTarball/clucene/src/core/CLucene/util/Equators.h uses std::binary_function:
+$(eval $(call gb_Library_add_defs,clucene, \
+ -D_HAS_AUTO_PTR_ETC=1 \
+))
+
+ifeq ($(OS),LINUX)
+$(eval $(call gb_Library_add_libs,clucene,\
+ -lm \
+ -ldl \
+ -pthread \
+))
+endif
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,clucene,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,clucene,\
+ UnpackedTarball/clucene/src/shared/CLucene/SharedHeader \
+ UnpackedTarball/clucene/src/shared/CLucene/config/gunichartables \
+ UnpackedTarball/clucene/src/shared/CLucene/config/repl_tcslwr \
+ UnpackedTarball/clucene/src/shared/CLucene/config/repl_tcstoll \
+ UnpackedTarball/clucene/src/shared/CLucene/config/repl_tcscasecmp \
+ UnpackedTarball/clucene/src/shared/CLucene/config/repl_tprintf \
+ UnpackedTarball/clucene/src/shared/CLucene/config/repl_lltot \
+ UnpackedTarball/clucene/src/shared/CLucene/config/repl_tcstod \
+ UnpackedTarball/clucene/src/shared/CLucene/config/utf8 \
+ UnpackedTarball/clucene/src/shared/CLucene/config/threads \
+ UnpackedTarball/clucene/src/shared/CLucene/debug/condition \
+ UnpackedTarball/clucene/src/shared/CLucene/util/StringBuffer \
+ UnpackedTarball/clucene/src/shared/CLucene/util/Misc \
+ UnpackedTarball/clucene/src/shared/CLucene/util/dirent \
+ UnpackedTarball/clucene/src/core/CLucene/StdHeader \
+ UnpackedTarball/clucene/src/core/CLucene/debug/error \
+ UnpackedTarball/clucene/src/core/CLucene/util/ThreadLocal \
+ UnpackedTarball/clucene/src/core/CLucene/util/Reader \
+ UnpackedTarball/clucene/src/core/CLucene/util/Equators \
+ UnpackedTarball/clucene/src/core/CLucene/util/FastCharStream \
+ UnpackedTarball/clucene/src/core/CLucene/util/MD5Digester \
+ UnpackedTarball/clucene/src/core/CLucene/util/StringIntern \
+ UnpackedTarball/clucene/src/core/CLucene/util/BitSet \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/FastCharStream \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/MultiFieldQueryParser \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/QueryParser \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/QueryParserTokenManager \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/QueryToken \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/legacy/Lexer \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/legacy/MultiFieldQueryParser \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/legacy/QueryParser \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/legacy/QueryParserBase \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/legacy/QueryToken \
+ UnpackedTarball/clucene/src/core/CLucene/queryParser/legacy/TokenList \
+ UnpackedTarball/clucene/src/core/CLucene/analysis/standard/StandardAnalyzer \
+ UnpackedTarball/clucene/src/core/CLucene/analysis/standard/StandardFilter \
+ UnpackedTarball/clucene/src/core/CLucene/analysis/standard/StandardTokenizer \
+ UnpackedTarball/clucene/src/core/CLucene/analysis/Analyzers \
+ UnpackedTarball/clucene/src/core/CLucene/analysis/AnalysisHeader \
+ UnpackedTarball/clucene/src/core/CLucene/store/MMapInput \
+ UnpackedTarball/clucene/src/core/CLucene/store/IndexInput \
+ UnpackedTarball/clucene/src/core/CLucene/store/Lock \
+ UnpackedTarball/clucene/src/core/CLucene/store/LockFactory \
+ UnpackedTarball/clucene/src/core/CLucene/store/IndexOutput \
+ UnpackedTarball/clucene/src/core/CLucene/store/Directory \
+ UnpackedTarball/clucene/src/core/CLucene/store/FSDirectory \
+ UnpackedTarball/clucene/src/core/CLucene/store/RAMDirectory \
+ UnpackedTarball/clucene/src/core/CLucene/document/Document \
+ UnpackedTarball/clucene/src/core/CLucene/document/DateField \
+ UnpackedTarball/clucene/src/core/CLucene/document/DateTools \
+ UnpackedTarball/clucene/src/core/CLucene/document/Field \
+ UnpackedTarball/clucene/src/core/CLucene/document/FieldSelector \
+ UnpackedTarball/clucene/src/core/CLucene/document/NumberTools \
+ UnpackedTarball/clucene/src/core/CLucene/index/IndexFileNames \
+ UnpackedTarball/clucene/src/core/CLucene/index/IndexFileNameFilter \
+ UnpackedTarball/clucene/src/core/CLucene/index/IndexDeletionPolicy \
+ UnpackedTarball/clucene/src/core/CLucene/index/SegmentMergeInfo \
+ UnpackedTarball/clucene/src/core/CLucene/index/SegmentInfos \
+ UnpackedTarball/clucene/src/core/CLucene/index/MergeScheduler \
+ UnpackedTarball/clucene/src/core/CLucene/index/SegmentTermDocs \
+ UnpackedTarball/clucene/src/core/CLucene/index/FieldsWriter \
+ UnpackedTarball/clucene/src/core/CLucene/index/TermInfosWriter \
+ UnpackedTarball/clucene/src/core/CLucene/index/Term \
+ UnpackedTarball/clucene/src/core/CLucene/index/Terms \
+ UnpackedTarball/clucene/src/core/CLucene/index/MergePolicy \
+ UnpackedTarball/clucene/src/core/CLucene/index/DocumentsWriter \
+ UnpackedTarball/clucene/src/core/CLucene/index/DocumentsWriterThreadState \
+ UnpackedTarball/clucene/src/core/CLucene/index/SegmentTermVector \
+ UnpackedTarball/clucene/src/core/CLucene/index/TermVectorReader \
+ UnpackedTarball/clucene/src/core/CLucene/index/FieldInfos \
+ UnpackedTarball/clucene/src/core/CLucene/index/CompoundFile \
+ UnpackedTarball/clucene/src/core/CLucene/index/SkipListReader \
+ UnpackedTarball/clucene/src/core/CLucene/index/SkipListWriter \
+ UnpackedTarball/clucene/src/core/CLucene/index/IndexFileDeleter \
+ UnpackedTarball/clucene/src/core/CLucene/index/SegmentReader \
+ UnpackedTarball/clucene/src/core/CLucene/index/DirectoryIndexReader \
+ UnpackedTarball/clucene/src/core/CLucene/index/TermVectorWriter \
+ UnpackedTarball/clucene/src/core/CLucene/index/IndexReader \
+ UnpackedTarball/clucene/src/core/CLucene/index/SegmentTermPositions \
+ UnpackedTarball/clucene/src/core/CLucene/index/SegmentMerger \
+ UnpackedTarball/clucene/src/core/CLucene/index/IndexWriter \
+ UnpackedTarball/clucene/src/core/CLucene/index/MultiReader \
+ UnpackedTarball/clucene/src/core/CLucene/index/MultiSegmentReader \
+ UnpackedTarball/clucene/src/core/CLucene/index/Payload \
+ UnpackedTarball/clucene/src/core/CLucene/index/SegmentTermEnum \
+ UnpackedTarball/clucene/src/core/CLucene/index/TermInfo \
+ UnpackedTarball/clucene/src/core/CLucene/index/IndexModifier \
+ UnpackedTarball/clucene/src/core/CLucene/index/SegmentMergeQueue \
+ UnpackedTarball/clucene/src/core/CLucene/index/FieldsReader \
+ UnpackedTarball/clucene/src/core/CLucene/index/TermInfosReader \
+ UnpackedTarball/clucene/src/core/CLucene/index/MultipleTermPositions \
+ UnpackedTarball/clucene/src/core/CLucene/search/Compare \
+ UnpackedTarball/clucene/src/core/CLucene/search/Scorer \
+ UnpackedTarball/clucene/src/core/CLucene/search/ScorerDocQueue \
+ UnpackedTarball/clucene/src/core/CLucene/search/PhraseScorer \
+ UnpackedTarball/clucene/src/core/CLucene/search/SloppyPhraseScorer \
+ UnpackedTarball/clucene/src/core/CLucene/search/DisjunctionSumScorer \
+ UnpackedTarball/clucene/src/core/CLucene/search/ConjunctionScorer \
+ UnpackedTarball/clucene/src/core/CLucene/search/PhraseQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/PrefixQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/ExactPhraseScorer \
+ UnpackedTarball/clucene/src/core/CLucene/search/TermScorer \
+ UnpackedTarball/clucene/src/core/CLucene/search/Similarity \
+ UnpackedTarball/clucene/src/core/CLucene/search/BooleanScorer \
+ UnpackedTarball/clucene/src/core/CLucene/search/BooleanScorer2 \
+ UnpackedTarball/clucene/src/core/CLucene/search/HitQueue \
+ UnpackedTarball/clucene/src/core/CLucene/search/FieldCacheImpl \
+ UnpackedTarball/clucene/src/core/CLucene/search/ChainedFilter \
+ UnpackedTarball/clucene/src/core/CLucene/search/RangeFilter \
+ UnpackedTarball/clucene/src/core/CLucene/search/CachingWrapperFilter \
+ UnpackedTarball/clucene/src/core/CLucene/search/QueryFilter \
+ UnpackedTarball/clucene/src/core/CLucene/search/TermQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/FuzzyQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/SearchHeader \
+ UnpackedTarball/clucene/src/core/CLucene/search/RangeQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/IndexSearcher \
+ UnpackedTarball/clucene/src/core/CLucene/search/Sort \
+ UnpackedTarball/clucene/src/core/CLucene/search/PhrasePositions \
+ UnpackedTarball/clucene/src/core/CLucene/search/FieldDocSortedHitQueue \
+ UnpackedTarball/clucene/src/core/CLucene/search/WildcardTermEnum \
+ UnpackedTarball/clucene/src/core/CLucene/search/MultiSearcher \
+ UnpackedTarball/clucene/src/core/CLucene/search/Hits \
+ UnpackedTarball/clucene/src/core/CLucene/search/MultiTermQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/FilteredTermEnum \
+ UnpackedTarball/clucene/src/core/CLucene/search/FieldSortedHitQueue \
+ UnpackedTarball/clucene/src/core/CLucene/search/WildcardQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/Explanation \
+ UnpackedTarball/clucene/src/core/CLucene/search/BooleanQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/FieldCache \
+ UnpackedTarball/clucene/src/core/CLucene/search/DateFilter \
+ UnpackedTarball/clucene/src/core/CLucene/search/MatchAllDocsQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/MultiPhraseQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/ConstantScoreQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/CachingSpanFilter \
+ UnpackedTarball/clucene/src/core/CLucene/search/SpanQueryFilter \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/NearSpansOrdered \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/NearSpansUnordered \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/SpanFirstQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/SpanNearQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/SpanNotQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/SpanOrQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/SpanScorer \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/SpanTermQuery \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/SpanWeight \
+ UnpackedTarball/clucene/src/core/CLucene/search/spans/TermSpans \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/analysis/LanguageBasedAnalyzer \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/analysis/PorterStemmer \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/Snowball \
+))
+
+$(eval $(call gb_Library_add_generated_cobjects,clucene,\
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/libstemmer/libstemmer \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_danish \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_dutch \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_english \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_finnish \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_french \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_german \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_italian \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_norwegian \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_porter \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_portuguese \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_spanish \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_swedish \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_KOI8_R_russian \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_danish \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_dutch \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_english \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_finnish \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_french \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_german \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_italian \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_norwegian \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_porter \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_portuguese \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_russian \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_spanish \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_swedish \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/runtime/utilities \
+ UnpackedTarball/clucene/src/contribs-lib/CLucene/snowball/runtime/api \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/clucene/Makefile b/external/clucene/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/clucene/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/clucene/Module_clucene.mk b/external/clucene/Module_clucene.mk
new file mode 100644
index 000000000..d74fc441f
--- /dev/null
+++ b/external/clucene/Module_clucene.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,clucene))
+
+$(eval $(call gb_Module_add_targets,clucene,\
+ Library_clucene \
+ UnpackedTarball_clucene \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/clucene/README b/external/clucene/README
new file mode 100644
index 000000000..bedae920f
--- /dev/null
+++ b/external/clucene/README
@@ -0,0 +1,4 @@
+External package containing clucene from [http://clucene.sourceforge.net/].
+
+This is used to index our downloadable help packages, and allow them
+to be searched efficiently at run-time. \ No newline at end of file
diff --git a/external/clucene/UnpackedTarball_clucene.mk b/external/clucene/UnpackedTarball_clucene.mk
new file mode 100644
index 000000000..c3928d335
--- /dev/null
+++ b/external/clucene/UnpackedTarball_clucene.mk
@@ -0,0 +1,81 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,clucene))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,clucene,$(CLUCENE_TARBALL)))
+
+ifneq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_set_post_action,clucene,\
+ mkdir -p inc/internal/CLucene/util && \
+ mv src/shared/CLucene/util/dirent.h inc/internal/CLucene/util \
+))
+endif
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,clucene,0))
+
+# clucene-multimap-put.patch was proposed upstream, see
+# http://sourceforge.net/mailarchive/message.php?msg_id=29143260
+# clucene-mutex.patch was proposed upstream, see
+# http://sourceforge.net/mailarchive/message.php?msg_id=32314782
+# clucene-asan.patch was proposed upstream, see
+# http://sourceforge.net/mailarchive/message.php?msg_id=32367781
+# see msvc14.0 error report on:
+# https://connect.microsoft.com/VisualStudio/feedback/details/1424082/vs2015-rc-c-compiler-mixes-up-template-parameter-with-identical-named-inherited-typedef
+# ostream-wchar_t.patch was proposed upstream, see
+# <https://sourceforge.net/p/clucene/mailman/message/36989348/>
+# heap-buffer-overflow.patch was proposed upstream, see
+# <https://sourceforge.net/p/clucene/mailman/message/36991067/>
+# c++20.patch was proposed upstream, see
+# <https://sourceforge.net/p/clucene/mailman/message/37040362/>
+# nullstring.patch was proposed upstream, see
+# <https://sourceforge.net/p/clucene/mailman/message/37338234/>
+$(eval $(call gb_UnpackedTarball_add_patches,clucene,\
+ external/clucene/patches/clucene-debug.patch \
+ external/clucene/patches/clucene-multimap-put.patch \
+ external/clucene/patches/clucene-narrowing-conversions.patch \
+ external/clucene/patches/clucene-nullptr.patch \
+ external/clucene/patches/clucene-warnings.patch \
+ external/clucene/patches/clucene-aix.patch \
+ external/clucene/patches/clucene-git1-win64.patch \
+ external/clucene/patches/clucene-ub.patch \
+ external/clucene/patches/clucene-mutex.patch \
+ external/clucene/patches/clucene-asan.patch \
+ external/clucene/patches/clucene-mixes-uptemplate-parameter-msvc-14.patch \
+ external/clucene/patches/ostream-wchar_t.patch \
+ external/clucene/patches/heap-buffer-overflow.patch \
+ external/clucene/patches/c++20.patch \
+ external/clucene/patches/write-strings.patch \
+ external/clucene/patches/nullstring.patch \
+ external/clucene/patches/binary_function.patch \
+))
+
+ifneq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,clucene,\
+ external/clucene/patches/clucene-libcpp.patch \
+))
+endif
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_file,clucene,src/shared/CLucene/_clucene-config.h,external/clucene/configs/_clucene-config-MSVC.h))
+$(eval $(call gb_UnpackedTarball_add_file,clucene,src/shared/CLucene/clucene-config.h,external/clucene/configs/clucene-config-MSVC.h))
+else # ! $(OS),WNT
+ifeq ($(HAVE_GCC_BUILTIN_ATOMIC),TRUE)
+$(eval $(call gb_UnpackedTarball_add_file,clucene,src/shared/CLucene/clucene-config.h,external/clucene/configs/clucene-config-GCC-atomic.h))
+else
+$(eval $(call gb_UnpackedTarball_add_file,clucene,src/shared/CLucene/clucene-config.h,external/clucene/configs/clucene-config-generic.h))
+endif
+ifeq ($(OS),LINUX)
+$(eval $(call gb_UnpackedTarball_add_file,clucene,src/shared/CLucene/_clucene-config.h,external/clucene/configs/_clucene-config-LINUX.h))
+else
+$(eval $(call gb_UnpackedTarball_add_file,clucene,src/shared/CLucene/_clucene-config.h,external/clucene/configs/_clucene-config-generic.h))
+endif
+endif # $(OS),WNT
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/clucene/configs/_clucene-config-LINUX.h b/external/clucene/configs/_clucene-config-LINUX.h
new file mode 100644
index 000000000..2b425b6b2
--- /dev/null
+++ b/external/clucene/configs/_clucene-config-LINUX.h
@@ -0,0 +1,114 @@
+#ifndef _SRC_CLUCENE_INTERNAL_CLUCENE_CONFIG_H
+#define _SRC_CLUCENE_INTERNAL_CLUCENE_CONFIG_H 1
+
+/* src/shared/CLucene/_clucene-config.h.
+* Normally generated automatically at end of cmake,
+* but here in LibreOffice this actually is a copy of
+* clucene/configs/_clucene-config-LINUX.h.
+* These are internal definitions, and this file does not need to be distributed
+*/
+
+/* CMake will look for these functions: */
+/* #undef _CL_HAVE_FUNCTION__VSNWPRINTF */
+/* #undef _CL_HAVE_FUNCTION__SNWPRINTF */
+#define _CL_HAVE_FUNCTION_WCSCASECMP
+#define _CL_HAVE_FUNCTION_WCSCAT 1
+#define _CL_HAVE_FUNCTION_WCSCHR 1
+#define _CL_HAVE_FUNCTION_WCSCMP 1
+#define _CL_HAVE_FUNCTION_WCSCPY 1
+#define _CL_HAVE_FUNCTION_WCSCSPN 1
+/* #undef _CL_HAVE_FUNCTION_WCSICMP */
+#define _CL_HAVE_FUNCTION_WCSLEN 1
+#define _CL_HAVE_FUNCTION_WCSNCMP 1
+#define _CL_HAVE_FUNCTION_WCSNCPY 1
+#define _CL_HAVE_FUNCTION_WCSSTR 1
+#define _CL_HAVE_FUNCTION_WCSTOD 1
+#define _CL_HAVE_FUNCTION_WCSDUP 1
+#define _CL_HAVE_FUNCTION_WCSTOLL 1
+/* #undef _CL_HAVE_FUNCTION_WCSUPR */
+#define _CL_HAVE_FUNCTION_GETTIMEOFDAY 1
+/* #undef _CL_HAVE_FUNCTION_MAPVIEWOFFILE */
+
+/* #undef _CL_HAVE_FUNCTION_LLTOA */
+/* #undef _CL_HAVE_FUNCTION_LLTOW */
+#define _CL_HAVE_FUNCTION_PRINTF 1
+#define _CL_HAVE_FUNCTION_SNPRINTF 1
+#define _CL_HAVE_FUNCTION_MMAP 1
+/* #undef _CL_HAVE_FUNCTION_STRLWR */
+#define _CL_HAVE_FUNCTION_STRTOLL 1
+/* #undef _CL_HAVE_FUNCTION_STRUPR */
+/* #undef _CL_HAVE_FUNCTION_GETPAGESIZE */
+#define _CL_HAVE_FUNCTION_USLEEP 1
+/* #undef _CL_HAVE_FUNCTION_SLEEP */
+
+#define CL_MAX_PATH 4096
+//this is the max filename... for now its just the same,
+//but this could change, so we use a different name
+#define CL_MAX_NAME CL_MAX_PATH
+//this used to be CL_MAX_NAME * 32, but as Alex Hudson points out, this could come to be 128kb.
+//the above logic for CL_MAX_NAME should be correct enough to handle all file names
+#define CL_MAX_DIR CL_MAX_PATH
+
+#define _O_RANDOM 0
+#define _O_BINARY 0
+#define _S_IREAD S_IREAD
+#define _S_IWRITE S_IWRITE
+#define _timeb timeb
+
+#define _ILONG(x) x ## L
+#define _ILONGLONG(x) x ## LL
+
+#define fileStat stat64
+#define cl_stat_t stat64
+#define fileSize CL_NS(util)::Misc::filelength
+#define fileSeek lseek64
+#define fileTell(fhandle) fileSeek(fhandle, 0, SEEK_CUR)
+#define fileHandleStat fstat64
+#define _realpath realpath
+#define _rename rename
+#define _close close
+#define _read read
+#define _cl_open open
+#define _write write
+#define _snprintf snprintf
+#define _mkdir(x) mkdir(x,0777)
+#define _unlink unlink
+#define _ftime ftime
+#define SLEEPFUNCTION usleep
+
+/* CMake will determine these specifics. Things like bugs, etc */
+
+/* Does not support new float byte<->float conversions */
+/* #undef _CL_HAVE_NO_FLOAT_BYTE */
+
+/* Define if recursive pthread mutexes are available */
+#define _CL_HAVE_PTHREAD_MUTEX_RECURSIVE 1
+
+/** define if you would like to force clucene to use the internal
+* character functions.
+* Tests may display unpredictable behaviour if this is not defined.
+*/
+#ifndef LUCENE_USE_INTERNAL_CHAR_FUNCTIONS
+ #define LUCENE_USE_INTERNAL_CHAR_FUNCTIONS 1
+#endif
+
+/** fix ansi for loop scope */
+#if 1==0
+ #define for if (0); else for
+#endif
+
+
+/* Compiler oddities */
+
+//not sure why, but cygwin reports _S_IREAD, but doesn't actually work...
+//TODO: make this work properly (this bit shouldn't be necessary)
+#ifdef __CYGWIN__
+ #define _S_IREAD 0333
+ #define _S_IWRITE 0333
+#endif
+
+#ifdef __BORLANDC__ //borland compiler
+ #define O_RANDOM 0
+#endif
+
+#endif
diff --git a/external/clucene/configs/_clucene-config-MSVC.h b/external/clucene/configs/_clucene-config-MSVC.h
new file mode 100644
index 000000000..09ef41cb6
--- /dev/null
+++ b/external/clucene/configs/_clucene-config-MSVC.h
@@ -0,0 +1,114 @@
+#ifndef _SRC_CLUCENE_INTERNAL_CLUCENE_CONFIG_H
+#define _SRC_CLUCENE_INTERNAL_CLUCENE_CONFIG_H 1
+
+/* src/shared/CLucene/_clucene-config.h.
+* Normally generated automatically at end of cmake,
+* but here in LibreOffice this actually is a copy of
+* clucene/configs/_clucene-config-MSVC.h.
+* These are internal definitions, and this file does not need to be distributed
+*/
+
+/* CMake will look for these functions: */
+#define _CL_HAVE_FUNCTION__VSNWPRINTF
+#define _CL_HAVE_FUNCTION__SNWPRINTF
+/* #undef _CL_HAVE_FUNCTION_WCSCASECMP */
+#define _CL_HAVE_FUNCTION_WCSCAT 1
+#define _CL_HAVE_FUNCTION_WCSCHR 1
+#define _CL_HAVE_FUNCTION_WCSCMP 1
+#define _CL_HAVE_FUNCTION_WCSCPY 1
+#define _CL_HAVE_FUNCTION_WCSCSPN 1
+#define _CL_HAVE_FUNCTION_WCSICMP
+#define _CL_HAVE_FUNCTION_WCSLEN 1
+#define _CL_HAVE_FUNCTION_WCSNCMP 1
+#define _CL_HAVE_FUNCTION_WCSNCPY 1
+#define _CL_HAVE_FUNCTION_WCSSTR 1
+#define _CL_HAVE_FUNCTION_WCSTOD 1
+#define _CL_HAVE_FUNCTION_WCSDUP 1
+/* #undef _CL_HAVE_FUNCTION_WCSTOLL */
+#define _CL_HAVE_FUNCTION_WCSUPR 1
+/* #undef _CL_HAVE_FUNCTION_GETTIMEOFDAY */
+#define _CL_HAVE_FUNCTION_MAPVIEWOFFILE 1
+
+/* #undef _CL_HAVE_FUNCTION_LLTOA */
+/* #undef _CL_HAVE_FUNCTION_LLTOW */
+#define _CL_HAVE_FUNCTION_PRINTF 1
+/* #undef _CL_HAVE_FUNCTION_SNPRINTF */
+/* #undef _CL_HAVE_FUNCTION_MMAP */
+#define _CL_HAVE_FUNCTION_STRLWR 1
+/* #undef _CL_HAVE_FUNCTION_STRTOLL */
+#define _CL_HAVE_FUNCTION_STRUPR 1
+/* #undef _CL_HAVE_FUNCTION_GETPAGESIZE */
+/* #undef _CL_HAVE_FUNCTION_USLEEP */
+#define _CL_HAVE_FUNCTION_SLEEP 1
+
+#define CL_MAX_PATH 4096
+//this is the max filename... for now its just the same,
+//but this could change, so we use a different name
+#define CL_MAX_NAME CL_MAX_PATH
+//this used to be CL_MAX_NAME * 32, but as Alex Hudson points out, this could come to be 128kb.
+//the above logic for CL_MAX_NAME should be correct enough to handle all file names
+#define CL_MAX_DIR CL_MAX_PATH
+
+/* undef _O_RANDOM _O_RANDOM */
+/* undef _O_BINARY _O_BINARY */
+/* undef _S_IREAD _S_IREAD */
+/* undef _S_IWRITE _S_IWRITE */
+/* #undef _timeb */
+
+#define _ILONG(x) x ## L
+#define _ILONGLONG(x) x ## LL
+
+#define fileStat _stati64
+#define cl_stat_t _stati64
+#define fileSize _filelengthi64
+#define fileSeek _lseeki64
+#define fileTell _telli64
+#define fileHandleStat _fstati64
+#define _realpath(rel,abs) ::_fullpath(abs,rel,CL_MAX_PATH)
+#define _rename rename
+/* undef _close _close */
+/* undef _read _read */
+#define _cl_open _open
+/* undef _write _write */
+/* undef _snprintf _snprintf */
+/* undef _mkdir _mkdir */
+/* undef _unlink _unlink */
+/* undef _ftime _ftime */
+#define SLEEPFUNCTION Sleep
+
+/* CMake will determine these specifics. Things like bugs, etc */
+
+/* Does not support new float byte<->float conversions */
+/* #undef _CL_HAVE_NO_FLOAT_BYTE */
+
+/* Define if recursive pthread mutexes are available */
+/* #undef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE */
+
+/** define if you would like to force clucene to use the internal
+* character functions.
+* Tests may display unpredictable behaviour if this is not defined.
+*/
+#ifndef LUCENE_USE_INTERNAL_CHAR_FUNCTIONS
+ #define LUCENE_USE_INTERNAL_CHAR_FUNCTIONS 1
+#endif
+
+/** fix ansi for loop scope */
+#if 1==0
+ #define for if (0); else for
+#endif
+
+
+/* Compiler oddities */
+
+//not sure why, but cygwin reports _S_IREAD, but doesn't actually work...
+//TODO: make this work properly (this bit shouldn't be necessary)
+#ifdef __CYGWIN__
+ #define _S_IREAD 0333
+ #define _S_IWRITE 0333
+#endif
+
+#ifdef __BORLANDC__ //borland compiler
+ #define O_RANDOM 0
+#endif
+
+#endif
diff --git a/external/clucene/configs/_clucene-config-generic.h b/external/clucene/configs/_clucene-config-generic.h
new file mode 100644
index 000000000..42cf27c7f
--- /dev/null
+++ b/external/clucene/configs/_clucene-config-generic.h
@@ -0,0 +1,114 @@
+#ifndef _SRC_CLUCENE_INTERNAL_CLUCENE_CONFIG_H
+#define _SRC_CLUCENE_INTERNAL_CLUCENE_CONFIG_H 1
+
+/* src/shared/CLucene/_clucene-config.h.
+* Normally generated automatically at end of cmake,
+* but here in LibreOffice this actually is a copy of
+* clucene/configs/_clucene-config-generic.h.
+* These are internal definitions, and this file does not need to be distributed
+*/
+
+/* CMake will look for these functions: */
+/* #undef _CL_HAVE_FUNCTION__VSNWPRINTF */
+/* #undef _CL_HAVE_FUNCTION__SNWPRINTF */
+#define _CL_HAVE_FUNCTION_WCSCASECMP
+#define _CL_HAVE_FUNCTION_WCSCAT 1
+#define _CL_HAVE_FUNCTION_WCSCHR 1
+#define _CL_HAVE_FUNCTION_WCSCMP 1
+#define _CL_HAVE_FUNCTION_WCSCPY 1
+#define _CL_HAVE_FUNCTION_WCSCSPN 1
+/* #undef _CL_HAVE_FUNCTION_WCSICMP */
+#define _CL_HAVE_FUNCTION_WCSLEN 1
+#define _CL_HAVE_FUNCTION_WCSNCMP 1
+#define _CL_HAVE_FUNCTION_WCSNCPY 1
+#define _CL_HAVE_FUNCTION_WCSSTR 1
+#define _CL_HAVE_FUNCTION_WCSTOD 1
+/* #undef _CL_HAVE_FUNCTION_WCSDUP 1 */
+#define _CL_HAVE_FUNCTION_WCSTOLL 1
+/* #undef _CL_HAVE_FUNCTION_WCSUPR */
+#define _CL_HAVE_FUNCTION_GETTIMEOFDAY 1
+/* #undef _CL_HAVE_FUNCTION_MAPVIEWOFFILE */
+
+/* #undef _CL_HAVE_FUNCTION_LLTOA */
+/* #undef _CL_HAVE_FUNCTION_LLTOW */
+#define _CL_HAVE_FUNCTION_PRINTF 1
+#define _CL_HAVE_FUNCTION_SNPRINTF 1
+#define _CL_HAVE_FUNCTION_MMAP 1
+/* #undef _CL_HAVE_FUNCTION_STRLWR */
+#define _CL_HAVE_FUNCTION_STRTOLL 1
+/* #undef _CL_HAVE_FUNCTION_STRUPR */
+/* #undef _CL_HAVE_FUNCTION_GETPAGESIZE */
+#define _CL_HAVE_FUNCTION_USLEEP 1
+/* #undef _CL_HAVE_FUNCTION_SLEEP */
+
+#define CL_MAX_PATH 4096
+//this is the max filename... for now its just the same,
+//but this could change, so we use a different name
+#define CL_MAX_NAME CL_MAX_PATH
+//this used to be CL_MAX_NAME * 32, but as Alex Hudson points out, this could come to be 128kb.
+//the above logic for CL_MAX_NAME should be correct enough to handle all file names
+#define CL_MAX_DIR CL_MAX_PATH
+
+#define _O_RANDOM 0
+#define _O_BINARY 0
+#define _S_IREAD S_IREAD
+#define _S_IWRITE S_IWRITE
+#define _timeb timeb
+
+#define _ILONG(x) x ## L
+#define _ILONGLONG(x) x ## LL
+
+#define fileStat stat
+#define cl_stat_t stat
+#define fileSize CL_NS(util)::Misc::filelength
+#define fileSeek lseek
+#define fileTell(fhandle) fileSeek(fhandle, 0, SEEK_CUR)
+#define fileHandleStat fstat
+#define _realpath realpath
+#define _rename rename
+#define _close close
+#define _read read
+#define _cl_open open
+#define _write write
+#define _snprintf snprintf
+#define _mkdir(x) mkdir(x,0777)
+#define _unlink unlink
+#define _ftime ftime
+#define SLEEPFUNCTION usleep
+
+/* CMake will determine these specifics. Things like bugs, etc */
+
+/* Does not support new float byte<->float conversions */
+/* #undef _CL_HAVE_NO_FLOAT_BYTE */
+
+/* Define if recursive pthread mutexes are available */
+#define _CL_HAVE_PTHREAD_MUTEX_RECURSIVE 1
+
+/** define if you would like to force clucene to use the internal
+* character functions.
+* Tests may display unpredictable behaviour if this is not defined.
+*/
+#ifndef LUCENE_USE_INTERNAL_CHAR_FUNCTIONS
+ #define LUCENE_USE_INTERNAL_CHAR_FUNCTIONS 1
+#endif
+
+/** fix ansi for loop scope */
+#if 1==0
+ #define for if (0); else for
+#endif
+
+
+/* Compiler oddities */
+
+//not sure why, but cygwin reports _S_IREAD, but doesn't actually work...
+//TODO: make this work properly (this bit shouldn't be necessary)
+#ifdef __CYGWIN__
+ #define _S_IREAD 0333
+ #define _S_IWRITE 0333
+#endif
+
+#ifdef __BORLANDC__ //borland compiler
+ #define O_RANDOM 0
+#endif
+
+#endif
diff --git a/external/clucene/configs/clucene-config-GCC-atomic.h b/external/clucene/configs/clucene-config-GCC-atomic.h
new file mode 100644
index 000000000..3c034a1da
--- /dev/null
+++ b/external/clucene/configs/clucene-config-GCC-atomic.h
@@ -0,0 +1,150 @@
+#ifndef _SRC_CLUCENE_CLUCENE_CONFIG_H
+#define _SRC_CLUCENE_CLUCENE_CONFIG_H 1
+
+/* src/shared/CLucene/clucene-config.h.
+* Normally generated automatically at end of cmake,
+* but here in LibreOffice this actually is a copy of
+* clucene/configs/clucene-config-GCC-atomic.h.
+*/
+
+/* CMake will look for these headers: */
+#define _CL_HAVE_STRING_H 1
+#define _CL_HAVE_MEMORY_H 1
+#define _CL_HAVE_UNISTD_H 1
+/* #undef _CL_HAVE_IO_H */
+/* #undef _CL_HAVE_DIRECT_H */
+#define _CL_HAVE_DIRENT_H 1
+#define _CL_HAVE_SYS_DIR_H
+/* #undef _CL_HAVE_SYS_NDIR_H */
+#define _CL_HAVE_ERRNO_H 1
+#define _CL_HAVE_WCHAR_H 1
+#define _CL_HAVE_WCTYPE_H
+#define _CL_HAVE_CTYPE_H 1
+/* #undef _CL_HAVE_WINDOWS_H */
+/* #undef _CL_HAVE_WINDEF_H */
+#define _CL_HAVE_SYS_TYPES_H 1
+/* #undef _CL_HAVE_DLFCN_H */
+#define _CL_HAVE_EXT_HASH_MAP 1
+/* #undef _CL_HAVE_EXT_HASH_SET */
+#define _CL_HAVE_TR1_UNORDERED_MAP 1
+#define _CL_HAVE_TR1_UNORDERED_SET 1
+#define _CL_HAVE_HASH_MAP
+#define _CL_HAVE_HASH_SET
+/* #undef _CL_HAVE_NDIR_H */
+#define _CL_HAVE_SYS_STAT_H 1
+#define _CL_HAVE_SYS_TIMEB_H 1
+#define _CL_HAVE_SYS_TIME_H 1
+/* #undef _CL_HAVE_TCHAR_H */
+#define _CL_HAVE_SYS_MMAN_H 1
+/* #undef _CL_HAVE_WINERROR_H */
+#define _CL_HAVE_STDINT_H 1
+
+// our needed types
+/* undef int8_t int8_t */
+/* undef uint8_t uint8_t */
+/* undef int16_t int16_t */
+/* undef uint16_t uint16_t */
+/* undef int32_t int32_t */
+/* undef uint32_t uint32_t */
+/* undef int64_t int64_t */
+/* undef uint64_t uint64_t */
+
+/* undef float_t*/
+
+/* undef size_t size_t */
+
+/* tchar & _T definitions... */
+typedef wchar_t TCHAR;
+#define _T(x) L ## x
+
+/* CMake will determine these specifics. Things like bugs, etc */
+
+/* if we can't support the map/set hashing */
+/* #undef LUCENE_DISABLE_HASHING */
+
+/* Define if you have POSIX threads libraries and header files. */
+#define _CL_HAVE_PTHREAD 1
+
+/* Define if you have Win32 threads libraries and header files. */
+/* #undef _CL_HAVE_WIN32_THREADS */
+
+/* Define if we have gcc atomic functions */
+#define _CL_HAVE_GCC_ATOMIC_FUNCTIONS 1
+
+/* Define what eval method is required for float_t to be defined (for GCC). */
+/* #undef _FLT_EVAL_METHOD */
+
+/* If we use hashmaps, which namespace do we use: */
+#define CL_NS_HASHING(func) std::tr1::func
+/* If we use hashmaps, which classes do we use: */
+#define _CL_HASH_MAP unordered_map
+#define _CL_HASH_SET unordered_set
+
+/* define if the compiler implements namespaces */
+#define _CL_HAVE_NAMESPACES
+
+/* Defined if the snprintf overflow test fails */
+/* #undef _CL_HAVE_SNPRINTF_BUG */
+
+/* Defined if the swprintf test fails */
+/* #undef _CL_HAVE_SNWPRINTF_BUG */
+
+/* How to define a static const in a class */
+#define LUCENE_STATIC_CONSTANT(type, assignment) static const type assignment
+
+/* Define to the necessary symbol if this constant uses a non-standard name on
+ your system. */
+//todo: not checked
+/* #undef _CL_PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+//todo: not being checked for...
+/* #undef _CL_STAT_MACROS_BROKEN */
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+//not actually used for anything...
+//#define _CL_TIME_WITH_SYS_TIME 1
+
+/* Define that we will be using -fvisibility=hidden, and
+ * make public classes visible using __attribute__ ((visibility("default")))
+ */
+#define _CL_HAVE_GCCVISIBILITYPATCH 1
+
+
+/* Versions, etc */
+
+/* Name of package */
+#define _CL_PACKAGE "clucene-core"
+
+/* Version number of package */
+#define _CL_VERSION "2.3.3.4"
+
+/* So-Version number of package */
+#define _CL_SOVERSION "1"
+
+/* A comparable version number */
+#define _CL_INT_VERSION 2030304
+
+/* Configured options (from command line) */
+
+/* Forces into Ascii mode */
+/* #undef _ASCII */
+
+/* Conditional Debugging */
+/* #undef _CL__CND_DEBUG */
+
+/* debuging option */
+/* #undef _DEBUG */
+
+/* Disable multithreading */
+/* #undef _CL_DISABLE_MULTITHREADING */
+
+
+#ifdef __BORLANDC__ //borland compiler
+ //todo: bcc incorrectly detects this... fix this in cmake
+ #undef LUCENE_STATIC_CONSTANT
+ #define LUCENE_STATIC_CONSTANT(type, assignment) enum { assignment }
+#endif
+
+
+#endif
diff --git a/external/clucene/configs/clucene-config-MSVC.h b/external/clucene/configs/clucene-config-MSVC.h
new file mode 100644
index 000000000..5e22e7a7e
--- /dev/null
+++ b/external/clucene/configs/clucene-config-MSVC.h
@@ -0,0 +1,149 @@
+#ifndef _SRC_CLUCENE_CLUCENE_CONFIG_H
+#define _SRC_CLUCENE_CLUCENE_CONFIG_H 1
+
+/* src/shared/CLucene/clucene-config.h.
+* Normally generated automatically at end of cmake,
+* but here in LibreOffice this actually is a copy of
+* clucene/configs/clucene-config-MSVC.h.
+*/
+
+/* CMake will look for these headers: */
+#define _CL_HAVE_STRING_H 1
+#define _CL_HAVE_MEMORY_H 1
+/* #undef _CL_HAVE_UNISTD_H */
+#define _CL_HAVE_IO_H 1
+#define _CL_HAVE_DIRECT_H 1
+/* #undef _CL_HAVE_DIRENT_H */
+/* #undef _CL_HAVE_SYS_DIR_H */
+/* #undef _CL_HAVE_SYS_NDIR_H */
+#define _CL_HAVE_ERRNO_H 1
+#define _CL_HAVE_WCHAR_H 1
+#define _CL_HAVE_WCTYPE_H
+#define _CL_HAVE_CTYPE_H 1
+#define _CL_HAVE_WINDOWS_H 1
+/* #undef _CL_HAVE_WINDEF_H */
+#define _CL_HAVE_SYS_TYPES_H 1
+/* #undef _CL_HAVE_DLFCN_H */
+/* #undef _CL_HAVE_EXT_HASH_MAP */
+/* #undef _CL_HAVE_EXT_HASH_SET */
+/* #undef _CL_HAVE_TR1_UNORDERED_MAP */
+/* #undef _CL_HAVE_TR1_UNORDERED_SET */
+/* #undef _CL_HAVE_HASH_MAP */
+/* #undef _CL_HAVE_HASH_SET */
+/* #undef _CL_HAVE_NDIR_H */
+#define _CL_HAVE_SYS_STAT_H 1
+#define _CL_HAVE_SYS_TIMEB_H 1
+/* #undef _CL_HAVE_SYS_TIME_H */
+#define _CL_HAVE_TCHAR_H 1
+/* #undef _CL_HAVE_SYS_MMAN_H */
+#define _CL_HAVE_WINERROR_H 1
+/* #undef _CL_HAVE_STDINT_H */
+
+// our needed types
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+
+typedef unsigned long _cl_dword_t;
+/* undef size_t size_t */
+
+/* tchar & _T definitions... */
+/* undef TCHAR TCHAR */
+/* #undef _T */
+
+/* CMake will determine these specifics. Things like bugs, etc */
+
+/* if we can't support the map/set hashing */
+/* #undef LUCENE_DISABLE_HASHING */
+
+/* Define if you have POSIX threads libraries and header files. */
+/* #undef _CL_HAVE_PTHREAD */
+
+/* Define if you have Win32 threads libraries and header files. */
+#define _CL_HAVE_WIN32_THREADS 1
+
+/* Define if we have gcc atomic functions */
+/* #undef _CL_HAVE_GCC_ATOMIC_FUNCTIONS */
+
+/* Define what eval method is required for float_t to be defined (for GCC). */
+/* #undef _FLT_EVAL_METHOD */
+
+/* If we use hashmaps, which namespace do we use: */
+#define CL_NS_HASHING(func)
+/* If we use hashmaps, which classes do we use: */
+#define _CL_HASH_MAP
+#define _CL_HASH_SET
+
+/* define if the compiler implements namespaces */
+#define _CL_HAVE_NAMESPACES
+
+/* Defined if the snprintf overflow test fails */
+/* #undef _CL_HAVE_SNPRINTF_BUG */
+
+/* Defined if the swprintf test fails */
+/* #undef _CL_HAVE_SNWPRINTF_BUG */
+
+/* How to define a static const in a class */
+#define LUCENE_STATIC_CONSTANT(type, assignment) static const type assignment
+
+/* Define to the necessary symbol if this constant uses a non-standard name on
+ your system. */
+//todo: not checked
+/* #undef _CL_PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+//todo: not being checked for...
+/* #undef _CL_STAT_MACROS_BROKEN */
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+//not actually used for anything...
+/* #undef _CL_TIME_WITH_SYS_TIME */
+
+/* Define that we will be using -fvisibility=hidden, and
+ * make public classes visible using __attribute__ ((visibility("default")))
+ */
+/* #undef _CL_HAVE_GCCVISIBILITYPATCH */
+
+
+/* Versions, etc */
+
+/* Name of package */
+#define _CL_PACKAGE "clucene-core"
+
+/* Version number of package */
+#define _CL_VERSION "2.3.3.4"
+
+/* So-Version number of package */
+#define _CL_SOVERSION "1"
+
+/* A comparable version number */
+#define _CL_INT_VERSION 2030304
+
+/* Configured options (from command line) */
+
+/* Forces into Ascii mode */
+/* #undef _ASCII */
+
+/* Conditional Debugging */
+/* #undef _CL__CND_DEBUG */
+
+/* debuging option */
+/* #undef _DEBUG */
+
+/* Disable multithreading */
+/* #undef _CL_DISABLE_MULTITHREADING */
+
+
+#ifdef __BORLANDC__ //borland compiler
+ //todo: bcc incorrectly detects this... fix this in cmake
+ #undef LUCENE_STATIC_CONSTANT
+ #define LUCENE_STATIC_CONSTANT(type, assignment) enum { assignment }
+#endif
+
+
+#endif
diff --git a/external/clucene/configs/clucene-config-generic.h b/external/clucene/configs/clucene-config-generic.h
new file mode 100644
index 000000000..b84dd4bc0
--- /dev/null
+++ b/external/clucene/configs/clucene-config-generic.h
@@ -0,0 +1,150 @@
+#ifndef _SRC_CLUCENE_CLUCENE_CONFIG_H
+#define _SRC_CLUCENE_CLUCENE_CONFIG_H 1
+
+/* src/shared/CLucene/clucene-config.h.
+* Normally generated automatically at end of cmake,
+* but here in LibreOffice this actually is a copy of
+* clucene/configs/clucene-config-generic.h.
+*/
+
+/* CMake will look for these headers: */
+#define _CL_HAVE_STRING_H 1
+#define _CL_HAVE_MEMORY_H 1
+#define _CL_HAVE_UNISTD_H 1
+/* #undef _CL_HAVE_IO_H */
+/* #undef _CL_HAVE_DIRECT_H */
+#define _CL_HAVE_DIRENT_H 1
+#define _CL_HAVE_SYS_DIR_H
+/* #undef _CL_HAVE_SYS_NDIR_H */
+#define _CL_HAVE_ERRNO_H 1
+#define _CL_HAVE_WCHAR_H 1
+#define _CL_HAVE_WCTYPE_H
+#define _CL_HAVE_CTYPE_H 1
+/* #undef _CL_HAVE_WINDOWS_H */
+/* #undef _CL_HAVE_WINDEF_H */
+#define _CL_HAVE_SYS_TYPES_H 1
+/* #undef _CL_HAVE_DLFCN_H */
+#define _CL_HAVE_EXT_HASH_MAP 1
+/* #undef _CL_HAVE_EXT_HASH_SET */
+#define _CL_HAVE_TR1_UNORDERED_MAP 1
+#define _CL_HAVE_TR1_UNORDERED_SET 1
+#define _CL_HAVE_HASH_MAP
+#define _CL_HAVE_HASH_SET
+/* #undef _CL_HAVE_NDIR_H */
+#define _CL_HAVE_SYS_STAT_H 1
+#define _CL_HAVE_SYS_TIMEB_H 1
+#define _CL_HAVE_SYS_TIME_H 1
+/* #undef _CL_HAVE_TCHAR_H */
+#define _CL_HAVE_SYS_MMAN_H 1
+/* #undef _CL_HAVE_WINERROR_H */
+#define _CL_HAVE_STDINT_H 1
+
+// our needed types
+/* undef int8_t int8_t */
+/* undef uint8_t uint8_t */
+/* undef int16_t int16_t */
+/* undef uint16_t uint16_t */
+/* undef int32_t int32_t */
+/* undef uint32_t uint32_t */
+/* undef int64_t int64_t */
+/* undef uint64_t uint64_t */
+
+/* undef float_t*/
+
+/* undef size_t size_t */
+
+/* tchar & _T definitions... */
+typedef wchar_t TCHAR;
+#define _T(x) L ## x
+
+/* CMake will determine these specifics. Things like bugs, etc */
+
+/* if we can't support the map/set hashing */
+/* #undef LUCENE_DISABLE_HASHING */
+
+/* Define if you have POSIX threads libraries and header files. */
+#define _CL_HAVE_PTHREAD 1
+
+/* Define if you have Win32 threads libraries and header files. */
+/* #undef _CL_HAVE_WIN32_THREADS */
+
+/* Define if we have gcc atomic functions */
+/* #undef _CL_HAVE_GCC_ATOMIC_FUNCTIONS */
+
+/* Define what eval method is required for float_t to be defined (for GCC). */
+/* #undef _FLT_EVAL_METHOD */
+
+/* If we use hashmaps, which namespace do we use: */
+#define CL_NS_HASHING(func) std::tr1::func
+/* If we use hashmaps, which classes do we use: */
+#define _CL_HASH_MAP unordered_map
+#define _CL_HASH_SET unordered_set
+
+/* define if the compiler implements namespaces */
+#define _CL_HAVE_NAMESPACES
+
+/* Defined if the snprintf overflow test fails */
+/* #undef _CL_HAVE_SNPRINTF_BUG */
+
+/* Defined if the swprintf test fails */
+/* #undef _CL_HAVE_SNWPRINTF_BUG */
+
+/* How to define a static const in a class */
+#define LUCENE_STATIC_CONSTANT(type, assignment) static const type assignment
+
+/* Define to the necessary symbol if this constant uses a non-standard name on
+ your system. */
+//todo: not checked
+/* #undef _CL_PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+//todo: not being checked for...
+/* #undef _CL_STAT_MACROS_BROKEN */
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+//not actually used for anything...
+//#define _CL_TIME_WITH_SYS_TIME 1
+
+/* Define that we will be using -fvisibility=hidden, and
+ * make public classes visible using __attribute__ ((visibility("default")))
+ */
+#define _CL_HAVE_GCCVISIBILITYPATCH 1
+
+
+/* Versions, etc */
+
+/* Name of package */
+#define _CL_PACKAGE "clucene-core"
+
+/* Version number of package */
+#define _CL_VERSION "2.3.3.4"
+
+/* So-Version number of package */
+#define _CL_SOVERSION "1"
+
+/* A comparable version number */
+#define _CL_INT_VERSION 2030304
+
+/* Configured options (from command line) */
+
+/* Forces into Ascii mode */
+/* #undef _ASCII */
+
+/* Conditional Debugging */
+/* #undef _CL__CND_DEBUG */
+
+/* debuging option */
+/* #undef _DEBUG */
+
+/* Disable multithreading */
+/* #undef _CL_DISABLE_MULTITHREADING */
+
+
+#ifdef __BORLANDC__ //borland compiler
+ //todo: bcc incorrectly detects this... fix this in cmake
+ #undef LUCENE_STATIC_CONSTANT
+ #define LUCENE_STATIC_CONSTANT(type, assignment) enum { assignment }
+#endif
+
+
+#endif
diff --git a/external/clucene/inc/pch/precompiled_clucene.cxx b/external/clucene/inc/pch/precompiled_clucene.cxx
new file mode 100644
index 000000000..98e81ca8e
--- /dev/null
+++ b/external/clucene/inc/pch/precompiled_clucene.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_clucene.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/clucene/inc/pch/precompiled_clucene.hxx b/external/clucene/inc/pch/precompiled_clucene.hxx
new file mode 100644
index 000000000..f68f71e87
--- /dev/null
+++ b/external/clucene/inc/pch/precompiled_clucene.hxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2019-10-13 10:16:55 using:
+ ./bin/update_pch external/clucene clucene --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/clucene/inc/pch/precompiled_clucene.hxx "make external/clucene.build" --find-conflicts
+*/
+
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <assert.h>
+#include <cctype>
+#include <climits>
+#include <errno.h>
+#include <fcntl.h>
+#include <iostream>
+#include <limits.h>
+#include <map>
+#include <sstream>
+#include <zlib.h>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <CLucene/_ApiHeader.h>
+#include <CLucene/_SharedHeader.h>
+#include <CLucene/analysis/AnalysisHeader.h>
+#include <CLucene/analysis/Analyzers.h>
+#include <CLucene/analysis/cjk/CJKAnalyzer.h>
+#include <CLucene/analysis/standard/StandardFilter.h>
+#include <CLucene/analysis/standard/StandardTokenizer.h>
+#include <CLucene/document/DateField.h>
+#include <CLucene/document/DateTools.h>
+#include <CLucene/document/Document.h>
+#include <CLucene/document/Field.h>
+#include <CLucene/document/FieldSelector.h>
+#include <CLucene/index/IndexReader.h>
+#include <CLucene/index/IndexWriter.h>
+#include <CLucene/index/MergePolicy.h>
+#include <CLucene/index/MultipleTermPositions.h>
+#include <CLucene/index/Term.h>
+#include <CLucene/index/TermVector.h>
+#include <CLucene/index/Terms.h>
+#include <CLucene/index/_IndexFileNameFilter.h>
+#include <CLucene/index/_IndexFileNames.h>
+#include <CLucene/index/_Term.h>
+#include <CLucene/search/BooleanClause.h>
+#include <CLucene/search/BooleanQuery.h>
+#include <CLucene/search/ConstantScoreQuery.h>
+#include <CLucene/search/Explanation.h>
+#include <CLucene/search/FieldCache.h>
+#include <CLucene/search/FieldSortedHitQueue.h>
+#include <CLucene/search/FuzzyQuery.h>
+#include <CLucene/search/IndexSearcher.h>
+#include <CLucene/search/MatchAllDocsQuery.h>
+#include <CLucene/search/MultiPhraseQuery.h>
+#include <CLucene/search/PhraseQuery.h>
+#include <CLucene/search/PrefixQuery.h>
+#include <CLucene/search/Query.h>
+#include <CLucene/search/RangeQuery.h>
+#include <CLucene/search/Scorer.h>
+#include <CLucene/search/SearchHeader.h>
+#include <CLucene/search/Similarity.h>
+#include <CLucene/search/Sort.h>
+#include <CLucene/search/TermQuery.h>
+#include <CLucene/search/WildcardQuery.h>
+#include <CLucene/search/spans/Spans.h>
+#include <CLucene/snowball/SnowballFilter.h>
+#include <CLucene/store/Directory.h>
+#include <CLucene/store/FSDirectory.h>
+#include <CLucene/store/IndexInput.h>
+#include <CLucene/store/IndexOutput.h>
+#include <CLucene/store/Lock.h>
+#include <CLucene/store/LockFactory.h>
+#include <CLucene/store/_Lock.h>
+#include <CLucene/store/_RAMDirectory.h>
+#include <CLucene/util/Array.h>
+#include <CLucene/util/BitSet.h>
+#include <CLucene/util/CLStreams.h>
+#include <CLucene/util/Misc.h>
+#include <CLucene/util/PriorityQueue.h>
+#include <CLucene/util/StringBuffer.h>
+#include <CLucene/util/VoidList.h>
+#include <CLucene/util/_Arrays.h>
+#include <CLucene/util/_FastCharStream.h>
+#include <CLucene/util/_MD5Digester.h>
+#include <CLucene/util/_StringIntern.h>
+#include <CLucene/util/_ThreadLocal.h>
+#include <CLucene/util/dirent.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/clucene/patches/binary_function.patch b/external/clucene/patches/binary_function.patch
new file mode 100644
index 000000000..5b6f8ece9
--- /dev/null
+++ b/external/clucene/patches/binary_function.patch
@@ -0,0 +1,34 @@
+--- src/core/CLucene/util/Equators.h
++++ src/core/CLucene/util/Equators.h
+@@ -22,19 +22,19 @@
+ /** @internal */
+ class CLUCENE_INLINE_EXPORT Equals{
+ public:
+- class CLUCENE_INLINE_EXPORT Int32:public CL_NS_STD(binary_function)<const int32_t*,const int32_t*,bool>
++ class CLUCENE_INLINE_EXPORT Int32
+ {
+ public:
+ bool operator()( const int32_t val1, const int32_t val2 ) const;
+ };
+
+- class CLUCENE_INLINE_EXPORT Char:public CL_NS_STD(binary_function)<const char*,const char*,bool>
++ class CLUCENE_INLINE_EXPORT Char
+ {
+ public:
+ bool operator()( const char* val1, const char* val2 ) const;
+ };
+ #ifdef _UCS2
+- class CLUCENE_INLINE_EXPORT WChar: public CL_NS_STD(binary_function)<const wchar_t*,const wchar_t*,bool>
++ class CLUCENE_INLINE_EXPORT WChar
+ {
+ public:
+ bool operator()( const wchar_t* val1, const wchar_t* val2 ) const;
+@@ -48,7 +48,7 @@
+
+
+ template<typename _cl>
+- class CLUCENE_INLINE_EXPORT Void:public CL_NS_STD(binary_function)<const void*,const void*,bool>
++ class CLUCENE_INLINE_EXPORT Void
+ {
+ public:
+ bool operator()( _cl* val1, _cl* val2 ) const{
diff --git a/external/clucene/patches/c++20.patch b/external/clucene/patches/c++20.patch
new file mode 100644
index 000000000..c982e861e
--- /dev/null
+++ b/external/clucene/patches/c++20.patch
@@ -0,0 +1,11 @@
+--- src/core/CLucene/util/_bufferedstream.h
++++ src/core/CLucene/util/_bufferedstream.h
+@@ -68,7 +68,7 @@
+ void setMinBufSize(int32_t s) {
+ buffer.makeSpace(s);
+ }
+- BufferedStreamImpl<T>();
++ BufferedStreamImpl();
+ public:
+ int32_t read(const T*& start, int32_t min, int32_t max);
+ int64_t reset(int64_t pos);
diff --git a/external/clucene/patches/clucene-aix.patch b/external/clucene/patches/clucene-aix.patch
new file mode 100644
index 000000000..2b796fa45
--- /dev/null
+++ b/external/clucene/patches/clucene-aix.patch
@@ -0,0 +1,40 @@
+diff -rc clucene.orig/src/core/CLucene/store/MMapInput.cpp clucene/src/core/CLucene/store/MMapInput.cpp
+*** src/core/CLucene/store/MMapInput.cpp Wed Apr 10 10:57:37 2013
+--- src/core/CLucene/store/MMapInput.cpp Wed Apr 10 10:58:30 2013
+***************
+*** 115,121 ****
+ {
+ }
+
+! bool MMapIndexInput::open(const char* path, IndexInput*& ret, CLuceneError& error, int32_t __bufferSize ) {
+
+ //Func - Constructor.
+ // Opens the file named path
+--- 115,121 ----
+ {
+ }
+
+! bool MMapIndexInput::Open(const char* path, IndexInput*& ret, CLuceneError& error, int32_t __bufferSize ) {
+
+ //Func - Constructor.
+ // Opens the file named path
+diff -rc clucene.orig/src/core/CLucene/store/_MMapIndexInput.h clucene/src/core/CLucene/store/_MMapIndexInput.h
+*** src/core/CLucene/store/_MMapIndexInput.h Wed Apr 10 10:57:37 2013
+--- src/core/CLucene/store/_MMapIndexInput.h Wed Apr 10 10:58:53 2013
+***************
+*** 18,24 ****
+ MMapIndexInput(const MMapIndexInput& clone);
+ MMapIndexInput(Internal* _internal);
+ public:
+! static bool open(const char* path, IndexInput*& ret, CLuceneError& error, int32_t __bufferSize);
+
+ ~MMapIndexInput();
+ IndexInput* clone() const;
+--- 18,24 ----
+ MMapIndexInput(const MMapIndexInput& clone);
+ MMapIndexInput(Internal* _internal);
+ public:
+! static bool Open(const char* path, IndexInput*& ret, CLuceneError& error, int32_t __bufferSize);
+
+ ~MMapIndexInput();
+ IndexInput* clone() const;
diff --git a/external/clucene/patches/clucene-asan.patch b/external/clucene/patches/clucene-asan.patch
new file mode 100644
index 000000000..51adfad4a
--- /dev/null
+++ b/external/clucene/patches/clucene-asan.patch
@@ -0,0 +1,26 @@
+--- src/core/CLucene/index/IndexWriter.cpp
++++ src/core/CLucene/index/IndexWriter.cpp
+@@ -53,7 +53,6 @@
+
+ DEFINE_MUTEX(IndexWriter::MESSAGE_ID_LOCK)
+ int32_t IndexWriter::MESSAGE_ID = 0;
+-const int32_t IndexWriter::MAX_TERM_LENGTH = DocumentsWriter::MAX_TERM_LENGTH;
+
+ class IndexWriter::Internal{
+ public:
+--- src/core/CLucene/index/IndexWriter.h
++++ src/core/CLucene/index/IndexWriter.h
+@@ -384,13 +384,6 @@
+ */
+ static const int32_t DEFAULT_MAX_MERGE_DOCS;
+
+- /**
+- * Absolute hard maximum length for a term. If a term
+- * arrives from the analyzer longer than this length, it
+- * is skipped and a message is printed to infoStream, if
+- * set (see {@link #setInfoStream}).
+- */
+- static const int32_t MAX_TERM_LENGTH;
+
+
+ /* Determines how often segment indices are merged by addDocument(). With
diff --git a/external/clucene/patches/clucene-debug.patch b/external/clucene/patches/clucene-debug.patch
new file mode 100644
index 000000000..640454e2f
--- /dev/null
+++ b/external/clucene/patches/clucene-debug.patch
@@ -0,0 +1,11 @@
+--- src/core/CLucene/index/TermInfosReader.cpp
++++ src/core/CLucene/index/TermInfosReader.cpp
+@@ -111,7 +111,7 @@
+ //destroy their elements
+ #ifdef _DEBUG
+ for ( int32_t i=0; i<indexTermsLength;++i ){
+- indexTerms[i].__cl_refcount--;
++ indexTerms[i].__cl_decref();
+ }
+ #endif
+ //Delete the arrays
diff --git a/external/clucene/patches/clucene-git1-win64.patch b/external/clucene/patches/clucene-git1-win64.patch
new file mode 100644
index 000000000..dc07d380b
--- /dev/null
+++ b/external/clucene/patches/clucene-git1-win64.patch
@@ -0,0 +1,45 @@
+--- src/shared/CLucene/config/threads.cpp 2013-06-06 16:25:23.014622397 +0200
++++ src/shared/CLucene/config/threads.cpp 2013-06-06 16:33:35.326048842 +0200
+@@ -63,14 +63,14 @@
+ }
+
+ int32_t mutex_thread::atomic_increment(_LUCENE_ATOMIC_INT *theInteger){
+-#ifdef _M_X64
++#ifdef _WIN64
+ return _InterlockedIncrement64(theInteger);
+ #else
+ return InterlockedIncrement(theInteger);
+ #endif
+ }
+ int32_t mutex_thread::atomic_decrement(_LUCENE_ATOMIC_INT *theInteger){
+-#ifdef _M_X64
++#ifdef _WIN64
+ return _InterlockedDecrement64(theInteger);
+ #else
+ return InterlockedDecrement(theInteger);
+--- src/shared/CLucene/config/_threads.h 2013-06-06 16:25:23.013622420 +0200
++++ src/shared/CLucene/config/_threads.h 2013-06-06 16:29:39.152601408 +0200
+@@ -34,9 +34,9 @@
+
+ __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
+
+-#ifdef _M_X64
+- __declspec(dllimport) long long __stdcall _InterlockedIncrement64(__inout long long volatile*);
+- __declspec(dllimport) long long __stdcall _InterlockedDecrement64(__inout long long volatile*);
++#ifdef _WIN64
++ long long __stdcall _InterlockedIncrement64(long long volatile*);
++ long long __stdcall _InterlockedDecrement64(long long volatile*);
+ #else
+ __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile*);
+ __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile*);
+--- src/shared/CLucene/LuceneThreads.h 2013-06-06 16:25:23.014622397 +0200
++++ src/shared/CLucene/LuceneThreads.h 2013-06-06 16:37:45.490166481 +0200
+@@ -101,7 +101,7 @@
+
+ #define _LUCENE_ATOMIC_INC(theInteger) CL_NS(util)::mutex_thread::atomic_increment(theInteger)
+ #define _LUCENE_ATOMIC_DEC(theInteger) CL_NS(util)::mutex_thread::atomic_decrement(theInteger)
+-#ifdef _M_X64
++#ifdef _WIN64
+ #define _LUCENE_ATOMIC_INT long long
+ #else
+ #define _LUCENE_ATOMIC_INT long
diff --git a/external/clucene/patches/clucene-libcpp.patch b/external/clucene/patches/clucene-libcpp.patch
new file mode 100644
index 000000000..35235212c
--- /dev/null
+++ b/external/clucene/patches/clucene-libcpp.patch
@@ -0,0 +1,42 @@
+--- src/shared/CLucene/LuceneThreads.h
++++ src/shared/CLucene/LuceneThreads.h
+@@ -7,6 +7,7 @@
+ #ifndef _LuceneThreads_h
+ #define _LuceneThreads_h
+
++#include "CLucene/config/_threads.h"
+
+ CL_NS_DEF(util)
+ class CLuceneThreadIdCompare;
+--- src/core/CLucene/util/VoidMap.h
++++ src/core/CLucene/util/VoidMap.h
+@@ -11,8 +11,13 @@
+ #include "CLucene/LuceneThreads.h"
+
+ #if defined(_CL_HAVE_TR1_UNORDERED_MAP) && defined(_CL_HAVE_TR1_UNORDERED_SET)
++#ifdef _LIBCPP_VERSION
++ #include <unordered_map>
++ #include <unordered_set>
++#else
+ #include <tr1/unordered_map>
+ #include <tr1/unordered_set>
++#endif
+ #elif defined(_CL_HAVE_HASH_MAP) && defined(_CL_HAVE_HASH_SET)
+ //hashing is all or nothing!
+ #include <hash_map>
+--- src/shared/CLucene/config/repl_tchar.h
++++ src/shared/CLucene/config/repl_tchar.h
+@@ -36,8 +36,13 @@
+ #define _tcsncpy wcsncpy //copy a specified amount of one string to another string.
+ #define _tcscat wcscat //copy a string onto the end of the other string
+ #define _tcsncat wcsncat
++#if defined(_LIBCPP_VERSION) && defined(__APPLE__)
++ #define _tcschr ::wcschr //find location of one character
++ #define _tcsstr ::wcsstr //find location of a string
++#else
+ #define _tcschr wcschr //find location of one character
+ #define _tcsstr wcsstr //find location of a string
++#endif
+ #define _tcslen wcslen //get length of a string
+ #define _tcscmp wcscmp //case sensitive compare two strings
+ #define _tcsncmp wcsncmp //case sensitive compare two strings
diff --git a/external/clucene/patches/clucene-mixes-uptemplate-parameter-msvc-14.patch b/external/clucene/patches/clucene-mixes-uptemplate-parameter-msvc-14.patch
new file mode 100644
index 000000000..0c9cd0a1f
--- /dev/null
+++ b/external/clucene/patches/clucene-mixes-uptemplate-parameter-msvc-14.patch
@@ -0,0 +1,53 @@
+diff -ru clucene.org/src/core/CLucene/util/VoidMap.h clucene/src/core/CLucene/util/VoidMap.h
+--- src/core/CLucene/util/VoidMap.h 2015-07-24 20:11:28.892997236 +0200
++++ src/core/CLucene/util/VoidMap.h 2015-07-24 20:21:17.290990623 +0200
+@@ -154,16 +154,16 @@
+
+ //a CLSet with CLHashMap traits
+ template<typename _kt, typename _vt,
+- typename _Compare,
++ typename Compare,
+ typename _EqualDummy,
+ typename _KeyDeletor=CL_NS(util)::Deletor::Dummy,
+ typename _ValueDeletor=CL_NS(util)::Deletor::Dummy>
+ class CLUCENE_INLINE_EXPORT CLHashMap:public __CLMap<_kt,_vt,
+- CL_NS_STD(map)<_kt,_vt, _Compare>,
++ CL_NS_STD(map)<_kt,_vt, Compare>,
+ _KeyDeletor,_ValueDeletor>
+ {
+- typedef typename CL_NS_STD(map)<_kt,_vt,_Compare> _base;
+- typedef __CLMap<_kt, _vt, CL_NS_STD(map)<_kt,_vt, _Compare>,
++ typedef typename CL_NS_STD(map)<_kt,_vt,Compare> _base;
++ typedef __CLMap<_kt, _vt, CL_NS_STD(map)<_kt,_vt, Compare>,
+ _KeyDeletor,_ValueDeletor> _this;
+ public:
+ CLHashMap ( const bool deleteKey=false, const bool deleteValue=false )
+@@ -260,15 +260,15 @@
+ //A collection that contains no duplicates
+ //does not guarantee that the order will remain constant over time
+ template<typename _kt, typename _vt,
+- typename _Compare,
++ typename Compare,
+ typename _KeyDeletor=CL_NS(util)::Deletor::Dummy,
+ typename _ValueDeletor=CL_NS(util)::Deletor::Dummy>
+ class CLUCENE_INLINE_EXPORT CLSet:public __CLMap<_kt,_vt,
+- CL_NS_STD(map)<_kt,_vt, _Compare>,
++ CL_NS_STD(map)<_kt,_vt, Compare>,
+ _KeyDeletor,_ValueDeletor>
+ {
+- typedef typename CL_NS_STD(map)<_kt,_vt,_Compare> _base;
+- typedef __CLMap<_kt, _vt, CL_NS_STD(map)<_kt,_vt, _Compare>,
++ typedef typename CL_NS_STD(map)<_kt,_vt,Compare> _base;
++ typedef __CLMap<_kt, _vt, CL_NS_STD(map)<_kt,_vt, Compare>,
+ _KeyDeletor,_ValueDeletor> _this;
+ public:
+ CLSet ( const bool deleteKey=false, const bool deleteValue=false )
+@@ -294,7 +294,7 @@
+
+ //A collection that can contains duplicates
+ template<typename _kt, typename _vt,
+- typename _Compare,
++ typename Compare,
+ typename _KeyDeletor=CL_NS(util)::Deletor::Dummy,
+ typename _ValueDeletor=CL_NS(util)::Deletor::Dummy>
+ class CLUCENE_INLINE_EXPORT CLMultiMap:public __CLMap<_kt,_vt,
diff --git a/external/clucene/patches/clucene-multimap-put.patch b/external/clucene/patches/clucene-multimap-put.patch
new file mode 100644
index 000000000..bfff31a87
--- /dev/null
+++ b/external/clucene/patches/clucene-multimap-put.patch
@@ -0,0 +1,9 @@
+--- src/core/CLucene/util/VoidMap.h
++++ src/core/CLucene/util/VoidMap.h
+@@ -316,6 +316,7 @@ public:
+ if ( _this::dk || _this::dv )
+ _this::remove(k);
+
++ (*this)[k] = v;
+ }
+ };
diff --git a/external/clucene/patches/clucene-mutex.patch b/external/clucene/patches/clucene-mutex.patch
new file mode 100644
index 000000000..2a6b7d2d3
--- /dev/null
+++ b/external/clucene/patches/clucene-mutex.patch
@@ -0,0 +1,13 @@
+--- src/core/CLucene/store/FSDirectory.cpp
++++ src/core/CLucene/store/FSDirectory.cpp
+@@ -219,9 +219,8 @@
+ _CLDECDELETE(handle);
+
+ //printf("handle=%d\n", handle->__cl_refcount);
+- if ( dounlock ){
+ mutex->unlock();
+- }else{
++ if ( !dounlock ){
+ delete mutex;
+ }
+ }
diff --git a/external/clucene/patches/clucene-narrowing-conversions.patch b/external/clucene/patches/clucene-narrowing-conversions.patch
new file mode 100644
index 000000000..64065acb1
--- /dev/null
+++ b/external/clucene/patches/clucene-narrowing-conversions.patch
@@ -0,0 +1,36 @@
+--- src/core/CLucene/queryParser/QueryParser.cpp.sav 2011-03-17 01:21:07.000000000 +0100
++++ src/core/CLucene/queryParser/QueryParser.cpp 2012-03-09 18:20:58.000000000 +0100
+@@ -79,7 +79,7 @@
+ _T("<RANGEEX_GOOP>")
+ };
+
+-const int32_t QueryParser::jj_la1_0[] = {0x180,0x180,0xe00,0xe00,0x1f69f80,0x48000,0x10000,0x1f69000,0x1348000,0x80000,0x80000,0x10000,0x18000000,0x2000000,0x18000000,0x10000,0x80000000,0x20000000,0x80000000,0x10000,0x80000,0x10000,0x1f68000};
++const int32_t QueryParser::jj_la1_0[] = {0x180,0x180,0xe00,0xe00,0x1f69f80,0x48000,0x10000,0x1f69000,0x1348000,0x80000,0x80000,0x10000,0x18000000,0x2000000,0x18000000,0x10000,int32_t(0x80000000),0x20000000,int32_t(0x80000000),0x10000,0x80000,0x10000,0x1f68000};
+ const int32_t QueryParser::jj_la1_1[] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x1,0x0,0x0,0x0,0x0};
+
+ struct QueryParser::JJCalls {
+--- src/core/CLucene/queryParser/QueryParserTokenManager.cpp.sav 2011-03-17 01:21:07.000000000 +0100
++++ src/core/CLucene/queryParser/QueryParserTokenManager.cpp 2012-03-09 18:20:24.000000000 +0100
+@@ -15,9 +15,9 @@
+
+ CL_NS_DEF(queryParser)
+
+-const int64_t QueryParserTokenManager::jjbitVec2[]={0x0L, 0x0L, _ILONGLONG(0xffffffffffffffff), _ILONGLONG(0xffffffffffffffff)};
++const int64_t QueryParserTokenManager::jjbitVec2[]={0x0L, 0x0L, int64_t(_ILONGLONG(0xffffffffffffffff)), int64_t(_ILONGLONG(0xffffffffffffffff))};
+ const int64_t QueryParserTokenManager::jjbitVec0[] = {
+- _ILONGLONG(0xfffffffffffffffe), _ILONGLONG(0xffffffffffffffff), _ILONGLONG(0xffffffffffffffff), _ILONGLONG(0xffffffffffffffff)
++ int64_t(_ILONGLONG(0xfffffffffffffffe)), int64_t(_ILONGLONG(0xffffffffffffffff)), int64_t(_ILONGLONG(0xffffffffffffffff)), int64_t(_ILONGLONG(0xffffffffffffffff))
+ };
+ const int32_t QueryParserTokenManager::jjnextStates[]={
+ 15, 17, 18, 29, 32, 23, 33, 30, 20, 21, 32, 23, 33, 31, 34, 27,
+--- src/core/CLucene/queryParser/legacy/Lexer.cpp.sav 2013-03-01 09:25:18.000000000 +0100
++++ src/core/CLucene/queryParser/legacy/Lexer.cpp 09:25:12.000000000 +0100
+@@ -117,7 +117,7 @@ bool Lexer::GetNextToken(QueryToken* tok
+ if( _istspace(ch)!=0 ) {
+ continue;
+ }
+- TCHAR buf[2] = {ch,'\0'};
++ TCHAR buf[2] = {TCHAR(ch),'\0'};
+ switch(ch) {
+ case '+':
+ token->set(buf, QueryToken::PLUS);
diff --git a/external/clucene/patches/clucene-nullptr.patch b/external/clucene/patches/clucene-nullptr.patch
new file mode 100644
index 000000000..a32ddb870
--- /dev/null
+++ b/external/clucene/patches/clucene-nullptr.patch
@@ -0,0 +1,22 @@
+--- src/core/CLucene/index/DocumentsWriter.cpp 2011-03-16 20:21:07.000000000 -0400
++++ src/core/CLucene/index/DocumentsWriter.cpp 2012-07-31 18:52:09.000000000 -0400
+@@ -125,7 +125,7 @@
+ if (this->postingsFreeListDW.values){
+ if (this->postingsFreeCountDW < this->postingsFreeListDW.length) {
+ memset(this->postingsFreeListDW.values + this->postingsFreeCountDW
+- , NULL
++ , 0
+ , sizeof(Posting*));
+ }
+ postingsFreeListDW.deleteUntilNULL();
+--- src/core/CLucene/util/VoidMap.h 2012-07-31 18:13:08.000000000 -0400
++++ src/core/CLucene/util/VoidMap.h 2012-07-31 18:42:54.000000000 -0400
+@@ -83,7 +83,7 @@
+ _vt get( _kt k) const {
+ const_iterator itr = base::find(k);
+ if ( itr==base::end() )
+- return (_vt)NULL;
++ return static_cast<_vt>(0);
+ else
+ return itr->second;
+ }
diff --git a/external/clucene/patches/clucene-ub.patch b/external/clucene/patches/clucene-ub.patch
new file mode 100644
index 000000000..e1ca3131f
--- /dev/null
+++ b/external/clucene/patches/clucene-ub.patch
@@ -0,0 +1,33 @@
+--- src/core/CLucene/index/DocumentsWriterThreadState.cpp
++++ src/core/CLucene/index/DocumentsWriterThreadState.cpp
+@@ -994,7 +994,7 @@
+ const TCHAR* tokenText = token->termBuffer();
+ const int32_t tokenTextLen = token->termLength();
+
+- int32_t code = 0;
++ uint32_t code = 0;
+
+ // Compute hashcode
+ int32_t downto = tokenTextLen;
+@@ -1203,7 +1203,7 @@
+ const int32_t newMask = newSize-1;
+
+ ValueArray<Posting*> newHash(newSize);
+- int32_t hashPos, code;
++ int32_t hashPos; uint32_t code;
+ const TCHAR* pos = NULL;
+ const TCHAR* start = NULL;
+ Posting* p0;
+--- src/core/CLucene/store/IndexInput.cpp
++++ src/core/CLucene/store/IndexInput.cpp
+@@ -41,8 +41,8 @@
+ }
+
+ int64_t IndexInput::readLong() {
+- int64_t i = ((int64_t)readInt() << 32);
+- return (i | ((int64_t)readInt() & 0xFFFFFFFFL));
++ uint64_t i = ((uint64_t)readInt() << 32);
++ return (i | ((uint64_t)readInt() & 0xFFFFFFFFL));
+ }
+
+ int64_t IndexInput::readVLong() {
diff --git a/external/clucene/patches/clucene-warnings.patch b/external/clucene/patches/clucene-warnings.patch
new file mode 100644
index 000000000..6326f6c35
--- /dev/null
+++ b/external/clucene/patches/clucene-warnings.patch
@@ -0,0 +1,124 @@
+--- src/core/CLucene/analysis/AnalysisHeader.h 2012-02-22 12:37:22.531637934 +0000
++++ src/core/CLucene/analysis/AnalysisHeader.h 2012-02-22 12:39:15.369916728 +0000
+@@ -7,6 +7,11 @@
+ #ifndef _lucene_analysis_AnalysisHeader_
+ #define _lucene_analysis_AnalysisHeader_
+
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic push
++# pragma GCC diagnostic ignored "-Woverloaded-virtual"
++#endif
++
+ #include "CLucene/index/Payload.h"
+ #include "CLucene/util/VoidList.h"
+ #include "CLucene/LuceneThreads.h"
+@@ -361,4 +361,8 @@
+ };
+
+ CL_NS_END
++
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic pop
++#endif
+ #endif
+--- src/core/CLucene/search/Searchable.h 2012-02-22 12:37:22.513637729 +0000
++++ src/core/CLucene/search/Searchable.h 2012-02-22 12:38:51.073641550 +0000
+@@ -7,6 +7,11 @@
+ #ifndef _lucene_search_Searcher_
+ #define _lucene_search_Searcher_
+
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic push
++# pragma GCC diagnostic ignored "-Woverloaded-virtual"
++#endif
++
+
+ //#include "CLucene/index/IndexReader.h"
+ CL_CLASS_DEF(index,Term)
+@@ -180,4 +180,8 @@
+ };
+
+ CL_NS_END
++
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic pop
++#endif
+ #endif
+--- src/core/CLucene/store/IndexInput.h 2012-02-22 12:37:22.508637673 +0000
++++ src/core/CLucene/store/IndexInput.h 2012-02-22 12:39:00.465747935 +0000
+@@ -7,6 +7,11 @@
+ #ifndef _lucene_store_IndexInput_
+ #define _lucene_store_IndexInput_
+
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic push
++# pragma GCC diagnostic ignored "-Woverloaded-virtual"
++#endif
++
+ #include "CLucene/LuceneThreads.h"
+ #include "CLucene/util/Equators.h"
+
+@@ -195,4 +195,8 @@
+ virtual void seekInternal(const int64_t pos) = 0;
+ };
+ CL_NS_END
++
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic pop
++#endif
+ #endif
+--- src/core/CLucene/util/Array.h 2012-02-22 12:37:22.510637696 +0000
++++ src/core/CLucene/util/Array.h 2012-02-22 12:38:33.714444884 +0000
+@@ -7,6 +7,20 @@
+ #ifndef _lucene_util_Array_
+ #define _lucene_util_Array_
+
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic push
++# pragma GCC diagnostic ignored "-Wshadow"
++# pragma GCC diagnostic ignored "-Wunused-parameter"
++#if defined __clang__
++#if __has_warning("-Wmisleading-indentation")
++#pragma GCC diagnostic ignored "-Wmisleading-indentation"
++#endif
++#else
++# pragma GCC diagnostic ignored "-Wpragmas"
++# pragma GCC diagnostic ignored "-Wmisleading-indentation"
++#endif
++#endif
++
+ #include <stdlib.h>
+ #include <string.h>
+
+@@ -338,4 +338,8 @@
+
+
+ CL_NS_END
++
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic pop
++#endif
+ #endif
+--- src/core/CLucene/util/PriorityQueue.h 2012-02-22 12:37:22.510637696 +0000
++++ src/core/CLucene/util/PriorityQueue.h 2012-02-22 12:38:40.316519685 +0000
+@@ -7,6 +7,11 @@
+ #ifndef _lucene_util_PriorityQueue_
+ #define _lucene_util_PriorityQueue_
+
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic push
++# pragma GCC diagnostic ignored "-Wshadow"
++#endif
++
+ #include <stdlib.h>
+
+ CL_NS_DEF(util)
+@@ -199,4 +199,8 @@
+ };
+
+ CL_NS_END
++
++#if defined(__GNUC__) || defined __clang__
++# pragma GCC diagnostic pop
++#endif
+ #endif
diff --git a/external/clucene/patches/contribs-lib-makefile.patch b/external/clucene/patches/contribs-lib-makefile.patch
new file mode 100644
index 000000000..8cc05aea4
--- /dev/null
+++ b/external/clucene/patches/contribs-lib-makefile.patch
@@ -0,0 +1,23 @@
+--- src/contribs-lib/CMakeLists.txt 2012-05-24 22:38:20.002443317 +0200
++++ src/contribs-lib/CMakeLists.txt 2012-05-24 22:38:05.218443899 +0200
+@@ -113,3 +113,20 @@
+ COMPILE_DEFINITIONS_DEBUG _DEBUG
+ )
+
++#install lib
++install(TARGETS clucene-contribs-lib
++ DESTINATION ${LIB_DESTINATION}
++ COMPONENT runtime )
++
++#install public headers.
++FOREACH(file ${HEADERS})
++ get_filename_component(apath ${file} PATH)
++ get_filename_component(aname ${file} NAME)
++ file(RELATIVE_PATH relpath ${CMAKE_SOURCE_DIR}/src/contribs-lib ${apath})
++ IF ( NOT aname MATCHES "^_.*" )
++ install(FILES ${file}
++ DESTINATION include/${relpath}
++ COMPONENT development)
++ ENDIF ( NOT aname MATCHES "^_.*" )
++ENDFOREACH(file)
++
diff --git a/external/clucene/patches/heap-buffer-overflow.patch b/external/clucene/patches/heap-buffer-overflow.patch
new file mode 100644
index 000000000..7421db854
--- /dev/null
+++ b/external/clucene/patches/heap-buffer-overflow.patch
@@ -0,0 +1,11 @@
+--- src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.cpp
++++ src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.cpp
+@@ -66,7 +66,7 @@
+ //ucs4(c variable). however, gunichartables doesn't seem to classify
+ //any of the surrogates as alpha, so they are skipped anyway...
+ //so for now we just convert to ucs4 so that we dont corrupt the input.
+- if ( c >= 0xd800 || c <= 0xdfff ){
++ if ( (c >= 0xd800 || c <= 0xdfff) && bufferIndex != dataLen ){
+ clunichar c2 = ioBuffer[bufferIndex];
+ if ( c2 >= 0xdc00 && c2 <= 0xdfff ){
+ bufferIndex++;
diff --git a/external/clucene/patches/nullstring.patch b/external/clucene/patches/nullstring.patch
new file mode 100644
index 000000000..6043e9f00
--- /dev/null
+++ b/external/clucene/patches/nullstring.patch
@@ -0,0 +1,11 @@
+--- src/core/CLucene/index/SegmentInfos.cpp
++++ src/core/CLucene/index/SegmentInfos.cpp
+@@ -358,7 +358,7 @@
+ if (delGen == NO) {
+ // In this case we know there is no deletion filename
+ // against this segment
+- return NULL;
++ return {};
+ } else {
+ // If delGen is CHECK_DIR, it's the pre-lockless-commit file format
+ return IndexFileNames::fileNameFromGeneration(name.c_str(), (string(".") + IndexFileNames::DELETES_EXTENSION).c_str(), delGen);
diff --git a/external/clucene/patches/ostream-wchar_t.patch b/external/clucene/patches/ostream-wchar_t.patch
new file mode 100644
index 000000000..63c9e1481
--- /dev/null
+++ b/external/clucene/patches/ostream-wchar_t.patch
@@ -0,0 +1,29 @@
+--- src/core/CLucene/index/DocumentsWriterThreadState.cpp
++++ src/core/CLucene/index/DocumentsWriterThreadState.cpp
+@@ -484,7 +484,7 @@
+ last->next = fp->next;
+
+ if (_parent->infoStream != NULL)
+- (*_parent->infoStream) << " remove field=" << fp->fieldInfo->name << "\n";
++ (*_parent->infoStream) << " remove field\n";
+
+ _CLDELETE(fp);
+ } else {
+@@ -557,7 +557,7 @@
+ fieldDataArray[i]->processField(analyzer);
+
+ if (maxTermPrefix != NULL && _parent->infoStream != NULL)
+- (*_parent->infoStream) << "WARNING: document contains at least one immense term (longer than the max length " << MAX_TERM_LENGTH << "), all of which were skipped. Please correct the analyzer to not produce such terms. The prefix of the first immense term is: '" << maxTermPrefix << "...'\n";
++ (*_parent->infoStream) << "WARNING: document contains at least one immense term (longer than the max length " << MAX_TERM_LENGTH << "), all of which were skipped. Please correct the analyzer to not produce such terms.\n";
+
+ if (_parent->ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH
+ && _parent->numBytesUsed > 0.95 * _parent->ramBufferSize)
+@@ -910,7 +910,7 @@
+ // truncate the token stream after maxFieldLength tokens.
+ if ( length >= maxFieldLength) {
+ if (_parent->infoStream != NULL)
+- (*_parent->infoStream) << "maxFieldLength " << maxFieldLength << " reached for field " << fieldInfo->name << ", ignoring following tokens\n";
++ (*_parent->infoStream) << "maxFieldLength " << maxFieldLength << " reached for field, ignoring following tokens\n";
+ break;
+ }
+ } else if (length > IndexWriter::DEFAULT_MAX_FIELD_LENGTH) {
diff --git a/external/clucene/patches/write-strings.patch b/external/clucene/patches/write-strings.patch
new file mode 100644
index 000000000..d1661ee72
--- /dev/null
+++ b/external/clucene/patches/write-strings.patch
@@ -0,0 +1,22 @@
+--- src/contribs-lib/CLucene/analysis/PorterStemmer.cpp
++++ src/contribs-lib/CLucene/analysis/PorterStemmer.cpp
+@@ -94,7 +94,7 @@
+ return true;
+ }
+
+- bool PorterStemmer::ends(TCHAR *s) {
++ bool PorterStemmer::ends(const TCHAR *s) {
+ size_t l = _tcslen(s);
+ size_t o = k-l+1;
+ if (o < k0)
+--- src/contribs-lib/CLucene/analysis/PorterStemmer.h
++++ src/contribs-lib/CLucene/analysis/PorterStemmer.h
+@@ -68,7 +68,7 @@
+ */
+ bool cvc(size_t i);
+
+- bool ends(TCHAR *s);
++ bool ends(const TCHAR *s);
+
+ /* setto(s) sets (j+1),...k to the characters in the string s, readjusting
+ k. */
diff --git a/external/coinmp/ExternalPackage_coinmp.mk b/external/coinmp/ExternalPackage_coinmp.mk
new file mode 100644
index 000000000..23fbb10b8
--- /dev/null
+++ b/external/coinmp/ExternalPackage_coinmp.mk
@@ -0,0 +1,41 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,coinmp,coinmp))
+
+$(eval $(call gb_ExternalPackage_use_external_project,coinmp,coinmp))
+
+ifeq ($(OS),WNT)
+ifeq ($(CPUNAME),X86_64)
+coinmp_arch_subdir=x64/
+endif
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/CoinMP.dll,CoinMP/MSVisualStudio/v9/$(coinmp_arch_subdir)$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release)/CoinMP.dll))
+else ifneq ($(DISABLE_DYNLOADING),)
+# Just use the static archives from workdir. See bin/lo-all-static-libs
+else ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCbc.3.dylib,Cbc/src/.libs/libCbc.3.8.8.dylib))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCbcSolver.3.dylib,Cbc/src/.libs/libCbcSolver.3.8.8.dylib))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCgl.1.dylib,Cgl/src/.libs/libCgl.1.8.5.dylib))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libClp.1.dylib,Clp/src/.libs/libClp.1.12.6.dylib))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libOsiClp.1.dylib,Clp/src/OsiClp/.libs/libOsiClp.1.12.6.dylib))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCoinMP.1.dylib,CoinMP/src/.libs/libCoinMP.1.7.6.dylib))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCoinUtils.3.dylib,CoinUtils/src/.libs/libCoinUtils.3.9.11.dylib))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libOsi.1.dylib,Osi/src/Osi/.libs/libOsi.1.11.5.dylib))
+else
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCbc.so.3,Cbc/src/.libs/libCbc.so.3.8.8))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCbcSolver.so.3,Cbc/src/.libs/libCbcSolver.so.3.8.8))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCgl.so.1,Cgl/src/.libs/libCgl.so.1.8.5))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libClp.so.1,Clp/src/.libs/libClp.so.1.12.6))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libOsiClp.so.1,Clp/src/OsiClp/.libs/libOsiClp.so.1.12.6))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCoinMP.so.1,CoinMP/src/.libs/libCoinMP.so.1.7.6))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libCoinUtils.so.3,CoinUtils/src/.libs/libCoinUtils.so.3.9.11))
+$(eval $(call gb_ExternalPackage_add_file,coinmp,$(LIBO_LIB_FOLDER)/libOsi.so.1,Osi/src/Osi/.libs/libOsi.so.1.11.5))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/coinmp/ExternalProject_coinmp.mk b/external/coinmp/ExternalProject_coinmp.mk
new file mode 100644
index 000000000..0a9c44c5e
--- /dev/null
+++ b/external/coinmp/ExternalProject_coinmp.mk
@@ -0,0 +1,59 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,coinmp))
+
+$(eval $(call gb_ExternalProject_register_targets,coinmp,\
+ build \
+))
+
+ifeq ($(COM),MSC)
+$(call gb_ExternalProject_get_state_target,coinmp,build) :
+ $(call gb_Trace_StartRange,coinmp,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ MSBuild.exe CoinMP.sln /t:Build \
+ /p:Configuration=$(if $(MSVC_USE_DEBUG_RUNTIME),Debug,Release) \
+ /p:Platform=$(if $(filter INTEL,$(CPUNAME)),Win32,x64) \
+ /p:PlatformToolset=$(VCTOOLSET) /p:VisualStudioVersion=$(VCVER) /ToolsVersion:Current \
+ $(if $(filter 10,$(WINDOWS_SDK_VERSION)),/p:WindowsTargetPlatformVersion=$(UCRTVERSION)) \
+ ,CoinMP/MSVisualStudio/v9)
+ $(call gb_Trace_EndRange,coinmp,EXTERNAL)
+
+else
+$(call gb_ExternalProject_get_state_target,coinmp,build) :
+ $(call gb_Trace_StartRange,coinmp,EXTERNAL)
+ +$(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure COIN_SKIP_PROJECTS="Data/Sample" \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(DISABLE_DYNLOADING),--disable-shared) \
+ --disable-bzlib \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ --without-glpk \
+ --enable-dependency-linking F77=unavailable \
+ $(if $(filter LINUX,$(OS)), \
+ 'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN') \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),&& $(PERL) \
+ $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/Cbc/src/.libs/libCbc.3.8.8.dylib \
+ $(EXTERNAL_WORKDIR)/Cbc/src/.libs/libCbcSolver.3.8.8.dylib \
+ $(EXTERNAL_WORKDIR)/Cgl/src/.libs/libCgl.1.8.5.dylib \
+ $(EXTERNAL_WORKDIR)/Clp/src/.libs/libClp.1.12.6.dylib \
+ $(EXTERNAL_WORKDIR)/Clp/src/OsiClp/.libs/libOsiClp.1.12.6.dylib \
+ $(EXTERNAL_WORKDIR)/CoinMP/src/.libs/libCoinMP.1.7.6.dylib \
+ $(EXTERNAL_WORKDIR)/CoinUtils/src/.libs/libCoinUtils.3.9.11.dylib \
+ $(EXTERNAL_WORKDIR)/Osi/src/Osi/.libs/libOsi.1.11.5.dylib) \
+ )
+ $(call gb_Trace_EndRange,coinmp,EXTERNAL)
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/coinmp/Makefile b/external/coinmp/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/coinmp/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/coinmp/Module_coinmp.mk b/external/coinmp/Module_coinmp.mk
new file mode 100644
index 000000000..30d9d7585
--- /dev/null
+++ b/external/coinmp/Module_coinmp.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,coinmp))
+
+$(eval $(call gb_Module_add_targets,coinmp,\
+ ExternalPackage_coinmp \
+ ExternalProject_coinmp \
+ UnpackedTarball_coinmp \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/coinmp/README b/external/coinmp/README
new file mode 100644
index 000000000..0e155d10f
--- /dev/null
+++ b/external/coinmp/README
@@ -0,0 +1,5 @@
+CoinMP is a C-API library that supports most of the functionality of CLP (Coin LP),
+CBC (Coin Branch-and-Cut), and CGL (Cut Generation Library) projects.
+
+Info [https://projects.coin-or.org/CoinMP].
+From [http://www.coin-or.org/download/source/CoinMP/].
diff --git a/external/coinmp/UnpackedTarball_coinmp.mk b/external/coinmp/UnpackedTarball_coinmp.mk
new file mode 100644
index 000000000..0764d428a
--- /dev/null
+++ b/external/coinmp/UnpackedTarball_coinmp.mk
@@ -0,0 +1,52 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,coinmp))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,coinmp,$(COINMP_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,coinmp,\
+ CoinMP/MSVisualStudio/v9/CoinMP.sln \
+))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,coinmp,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,coinmp))
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,coinmp,\
+ BuildTools \
+ Cbc \
+ Cgl \
+ Clp \
+ CoinMP \
+ CoinUtils \
+ Data/Sample \
+ Osi \
+))
+
+# * external/coinmp/Wnon-c-typedef-for-linkage.patch upstream at
+# <https://list.coin-or.org/pipermail/coin-discuss/2020-February/003972.html> "[Coin-discuss]
+# Small patch to fix Clang -Wnon-c-typedef-for-linkage in Clp":
+$(eval $(call gb_UnpackedTarball_add_patches,coinmp,\
+ external/coinmp/osi_cuts_iterator.patch.0 \
+ external/coinmp/no-binaries.patch.1 \
+ external/coinmp/werror-format-security.patch.0 \
+ external/coinmp/werror-undef.patch.0 \
+ external/coinmp/coinmp-msvc-disable-sse2.patch.1 \
+ $(if $(filter MSC,$(COM)),external/coinmp/windows.build.patch.1) \
+ external/coinmp/werror-format-pedantic.patch.0 \
+ external/coinmp/ubsan.patch.0 \
+ external/coinmp/rpath.patch \
+ external/coinmp/libtool.patch \
+ external/coinmp/Wnon-c-typedef-for-linkage.patch \
+ external/coinmp/register.patch \
+ external/coinmp/configure-exit.patch \
+ external/coinmp/pedantic-errors.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/coinmp/Wnon-c-typedef-for-linkage.patch b/external/coinmp/Wnon-c-typedef-for-linkage.patch
new file mode 100644
index 000000000..ace749d23
--- /dev/null
+++ b/external/coinmp/Wnon-c-typedef-for-linkage.patch
@@ -0,0 +1,14 @@
+--- Clp/src/Clp_C_Interface.h
++++ Clp/src/Clp_C_Interface.h
+@@ -12,9 +12,9 @@
+ #include "Coin_C_defines.h"
+
+ #if defined (CLP_EXTERN_C)
+-typedef struct {
++struct Clp_Solve {
+ ClpSolve options;
+-} Clp_Solve;
++};
+ #else
+ typedef void Clp_Solve;
+ #endif
diff --git a/external/coinmp/coinmp-msvc-disable-sse2.patch.1 b/external/coinmp/coinmp-msvc-disable-sse2.patch.1
new file mode 100644
index 000000000..0f518d6e3
--- /dev/null
+++ b/external/coinmp/coinmp-msvc-disable-sse2.patch.1
@@ -0,0 +1,10 @@
+--- coinmp/BuildTools/MSVisualStudio/v10/Release.props.orig 2014-10-02 14:22:21.497268171 +0200
++++ coinmp/BuildTools/MSVisualStudio/v10/Release.props 2014-10-02 14:22:30.193267497 +0200
+@@ -6,6 +6,7 @@
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <StringPooling>true</StringPooling>
++ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup />
diff --git a/external/coinmp/configure-exit.patch b/external/coinmp/configure-exit.patch
new file mode 100644
index 000000000..0a81b8073
--- /dev/null
+++ b/external/coinmp/configure-exit.patch
@@ -0,0 +1,33 @@
+--- Cgl/configure
++++ Cgl/configure
+@@ -3501,8 +3501,6 @@
+ fi
+ for ac_declaration in \
+ '' \
+- 'extern "C" void std::exit (int) throw (); using std::exit;' \
+- 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+--- Clp/configure
++++ Clp/configure
+@@ -3528,8 +3528,6 @@
+ fi
+ for ac_declaration in \
+ '' \
+- 'extern "C" void std::exit (int) throw (); using std::exit;' \
+- 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+--- CoinUtils/configure
++++ CoinUtils/configure
+@@ -3527,8 +3527,6 @@
+ fi
+ for ac_declaration in \
+ '' \
+- 'extern "C" void std::exit (int) throw (); using std::exit;' \
+- 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
diff --git a/external/coinmp/libtool.patch b/external/coinmp/libtool.patch
new file mode 100644
index 000000000..ca1716f5f
--- /dev/null
+++ b/external/coinmp/libtool.patch
@@ -0,0 +1,162 @@
+--- Cbc/ltmain.sh
++++ Cbc/ltmain.sh
+@@ -1254,6 +1254,12 @@
+ prev=
+ continue
+ ;;
++ mllvm)
++ # Clang does not use LLVM to link, so we can simply discard any
++ # '-mllvm $arg' options when doing the link step.
++ prev=
++ continue
++ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+@@ -1607,6 +1613,11 @@
+ continue
+ ;;
+
++ -mllvm)
++ prev=mllvm
++ continue
++ ;;
++
+ -module)
+ module=yes
+ continue
+--- Cgl/ltmain.sh
++++ Cgl/ltmain.sh
+@@ -1254,6 +1254,12 @@
+ prev=
+ continue
+ ;;
++ mllvm)
++ # Clang does not use LLVM to link, so we can simply discard any
++ # '-mllvm $arg' options when doing the link step.
++ prev=
++ continue
++ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+@@ -1607,6 +1613,11 @@
+ continue
+ ;;
+
++ -mllvm)
++ prev=mllvm
++ continue
++ ;;
++
+ -module)
+ module=yes
+ continue
+--- Clp/ltmain.sh
++++ Clp/ltmain.sh
+@@ -1254,6 +1254,12 @@
+ prev=
+ continue
+ ;;
++ mllvm)
++ # Clang does not use LLVM to link, so we can simply discard any
++ # '-mllvm $arg' options when doing the link step.
++ prev=
++ continue
++ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+@@ -1607,6 +1613,11 @@
+ continue
+ ;;
+
++ -mllvm)
++ prev=mllvm
++ continue
++ ;;
++
+ -module)
+ module=yes
+ continue
+--- CoinMP/ltmain.sh
++++ CoinMP/ltmain.sh
+@@ -1254,6 +1254,12 @@
+ prev=
+ continue
+ ;;
++ mllvm)
++ # Clang does not use LLVM to link, so we can simply discard any
++ # '-mllvm $arg' options when doing the link step.
++ prev=
++ continue
++ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+@@ -1607,6 +1613,11 @@
+ continue
+ ;;
+
++ -mllvm)
++ prev=mllvm
++ continue
++ ;;
++
+ -module)
+ module=yes
+ continue
+--- CoinUtils/ltmain.sh
++++ CoinUtils/ltmain.sh
+@@ -1254,6 +1254,12 @@
+ prev=
+ continue
+ ;;
++ mllvm)
++ # Clang does not use LLVM to link, so we can simply discard any
++ # '-mllvm $arg' options when doing the link step.
++ prev=
++ continue
++ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+@@ -1607,6 +1613,11 @@
+ continue
+ ;;
+
++ -mllvm)
++ prev=mllvm
++ continue
++ ;;
++
+ -module)
+ module=yes
+ continue
+--- Osi/ltmain.sh
++++ Osi/ltmain.sh
+@@ -1254,6 +1254,12 @@
+ prev=
+ continue
+ ;;
++ mllvm)
++ # Clang does not use LLVM to link, so we can simply discard any
++ # '-mllvm $arg' options when doing the link step.
++ prev=
++ continue
++ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+@@ -1607,6 +1613,11 @@
+ continue
+ ;;
+
++ -mllvm)
++ prev=mllvm
++ continue
++ ;;
++
+ -module)
+ module=yes
+ continue
diff --git a/external/coinmp/no-binaries.patch.1 b/external/coinmp/no-binaries.patch.1
new file mode 100644
index 000000000..0c36950c1
--- /dev/null
+++ b/external/coinmp/no-binaries.patch.1
@@ -0,0 +1,25 @@
+# -*- Mode: Diff -*-
+# Patch to avoid building any programs for CoinMP
+#
+--- coinmp/Clp/src/Makefile.in
++++ coinmp/Clp/src/Makefile.in
+@@ -95,7 +95,7 @@
+ @COIN_HAS_AMD_FALSE@@COIN_HAS_CHOLMOD_FALSE@@COIN_HAS_GLPK_TRUE@am__append_4 = ClpCholeskyUfl.cpp ClpCholeskyUfl.hpp
+ @COIN_HAS_MUMPS_TRUE@am__append_5 = ClpCholeskyMumps.cpp ClpCholeskyMumps.hpp
+ @COIN_HAS_WSMP_TRUE@am__append_6 = ClpCholeskyWssmp.cpp ClpCholeskyWssmp.hpp ClpCholeskyWssmpKKT.cpp ClpCholeskyWssmpKKT.hpp
+-bin_PROGRAMS = clp$(EXEEXT)
++bin_PROGRAMS =
+ @COIN_HAS_CHOLMOD_TRUE@am__append_7 = -I`$(CYGPATH_W) $(CHOLMODINCDIR)`
+ @COIN_HAS_AMD_TRUE@am__append_8 = -I`$(CYGPATH_W) $(AMDINCDIR)`
+ @COIN_HAS_ABC_TRUE@am__append_9 = AbcSimplex.hpp CoinAbcCommon.hpp AbcCommon.hpp
+--- coinmp/Cbc/src/Makefile.in
++++ coinmp/Cbc/src/Makefile.in
+@@ -44,7 +44,7 @@
+ POST_UNINSTALL = :
+ build_triplet = @build@
+ host_triplet = @host@
+-bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)
++bin_PROGRAMS =
+
+ ########################################################################
+ # cbc program #
diff --git a/external/coinmp/osi_cuts_iterator.patch.0 b/external/coinmp/osi_cuts_iterator.patch.0
new file mode 100644
index 000000000..42ed5afdc
--- /dev/null
+++ b/external/coinmp/osi_cuts_iterator.patch.0
@@ -0,0 +1,12 @@
+diff -ru coinmp.orig/Osi/src/Osi/OsiCuts.hpp coinmp/Osi/src/Osi/OsiCuts.hpp
+--- Osi/src/Osi/OsiCuts.hpp 2011-06-13 17:08:11.000000000 +0200
++++ Osi/src/Osi/OsiCuts.hpp 2016-03-03 22:21:04.669838200 +0100
+@@ -74,7 +74,7 @@
+ class const_iterator {
+ friend class OsiCuts;
+ public:
+- typedef std::bidirectional_iterator_tag iterator_category;
++ typedef std::forward_iterator_tag iterator_category;
+ typedef OsiCut* value_type;
+ typedef size_t difference_type;
+ typedef OsiCut ** pointer;
diff --git a/external/coinmp/pedantic-errors.patch b/external/coinmp/pedantic-errors.patch
new file mode 100644
index 000000000..2cf86b7e0
--- /dev/null
+++ b/external/coinmp/pedantic-errors.patch
@@ -0,0 +1,11 @@
+--- Clp/src/ClpSimplex.cpp
++++ Clp/src/ClpSimplex.cpp
+@@ -6035,7 +6035,7 @@
+ assert (!doKKT);
+ ClpCholeskyTaucs * cholesky = new ClpCholeskyTaucs();
+ barrier.setCholesky(cholesky);
+-#elifdef COIN_HAS_MUMPS
++#elif defined COIN_HAS_MUMPS
+ if (!doKKT) {
+ ClpCholeskyMumps * cholesky = new ClpCholeskyMumps();
+ barrier.setCholesky(cholesky);
diff --git a/external/coinmp/register.patch b/external/coinmp/register.patch
new file mode 100644
index 000000000..cf4ca4d06
--- /dev/null
+++ b/external/coinmp/register.patch
@@ -0,0 +1,369 @@
+--- CoinUtils/src/CoinHelperFunctions.hpp
++++ CoinUtils/src/CoinHelperFunctions.hpp
+@@ -41,7 +41,7 @@
+ handled correctly. */
+
+ template <class T> inline void
+-CoinCopyN(register const T* from, const int size, register T* to)
++CoinCopyN(const T* from, const int size, T* to)
+ {
+ if (size == 0 || from == to)
+ return;
+@@ -52,10 +52,10 @@
+ "CoinCopyN", "");
+ #endif
+
+- register int n = (size + 7) / 8;
++ int n = (size + 7) / 8;
+ if (to > from) {
+- register const T* downfrom = from + size;
+- register T* downto = to + size;
++ const T* downfrom = from + size;
++ T* downto = to + size;
+ // Use Duff's device to copy
+ switch (size % 8) {
+ case 0: do{ *--downto = *--downfrom;
+@@ -99,7 +99,7 @@
+ the difference down to int. -- lh, 100823 --
+ */
+ template <class T> inline void
+-CoinCopy(register const T* first, register const T* last, register T* to)
++CoinCopy(const T* first, const T* last, T* to)
+ {
+ CoinCopyN(first, static_cast<int>(last-first), to);
+ }
+@@ -114,7 +114,7 @@
+ Note JJF - the speed claim seems to be false on IA32 so I have added
+ CoinMemcpyN which can be used for atomic data */
+ template <class T> inline void
+-CoinDisjointCopyN(register const T* from, const int size, register T* to)
++CoinDisjointCopyN(const T* from, const int size, T* to)
+ {
+ #ifndef _MSC_VER
+ if (size == 0 || from == to)
+@@ -135,7 +135,7 @@
+ throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
+ #endif
+
+- for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
++ for (int n = size / 8; n > 0; --n, from += 8, to += 8) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+@@ -167,8 +167,8 @@
+ are copied at a time. The source array is given by its first and "after
+ last" entry; the target array is given by its first entry. */
+ template <class T> inline void
+-CoinDisjointCopy(register const T* first, register const T* last,
+- register T* to)
++CoinDisjointCopy(const T* first, const T* last,
++ T* to)
+ {
+ CoinDisjointCopyN(first, static_cast<int>(last - first), to);
+ }
+@@ -256,7 +256,7 @@
+ alternative coding if USE_MEMCPY defined*/
+ #ifndef COIN_USE_RESTRICT
+ template <class T> inline void
+-CoinMemcpyN(register const T* from, const int size, register T* to)
++CoinMemcpyN(const T* from, const int size, T* to)
+ {
+ #ifndef _MSC_VER
+ #ifdef USE_MEMCPY
+@@ -296,7 +296,7 @@
+ throw CoinError("overlapping arrays", "CoinMemcpyN", "");
+ #endif
+
+- for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
++ for (int n = size / 8; n > 0; --n, from += 8, to += 8) {
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+@@ -343,8 +343,8 @@
+ are copied at a time. The source array is given by its first and "after
+ last" entry; the target array is given by its first entry. */
+ template <class T> inline void
+-CoinMemcpy(register const T* first, register const T* last,
+- register T* to)
++CoinMemcpy(const T* first, const T* last,
++ T* to)
+ {
+ CoinMemcpyN(first, static_cast<int>(last - first), to);
+ }
+@@ -358,7 +358,7 @@
+ Note JJF - the speed claim seems to be false on IA32 so I have added
+ CoinZero to allow for memset. */
+ template <class T> inline void
+-CoinFillN(register T* to, const int size, register const T value)
++CoinFillN(T* to, const int size, const T value)
+ {
+ if (size == 0)
+ return;
+@@ -369,7 +369,7 @@
+ "CoinFillN", "");
+ #endif
+ #if 1
+- for (register int n = size / 8; n > 0; --n, to += 8) {
++ for (int n = size / 8; n > 0; --n, to += 8) {
+ to[0] = value;
+ to[1] = value;
+ to[2] = value;
+@@ -413,7 +413,7 @@
+ entries are filled at a time. The array is given by its first and "after
+ last" entry. */
+ template <class T> inline void
+-CoinFill(register T* first, register T* last, const T value)
++CoinFill(T* first, T* last, const T value)
+ {
+ CoinFillN(first, last - first, value);
+ }
+@@ -427,7 +427,7 @@
+ Note JJF - the speed claim seems to be false on IA32 so I have allowed
+ for memset as an alternative */
+ template <class T> inline void
+-CoinZeroN(register T* to, const int size)
++CoinZeroN(T* to, const int size)
+ {
+ #ifdef USE_MEMCPY
+ // Use memset - seems faster on Intel with gcc
+@@ -448,7 +448,7 @@
+ "CoinZeroN", "");
+ #endif
+ #if 1
+- for (register int n = size / 8; n > 0; --n, to += 8) {
++ for (int n = size / 8; n > 0; --n, to += 8) {
+ to[0] = 0;
+ to[1] = 0;
+ to[2] = 0;
+@@ -519,7 +519,7 @@
+ entries are filled at a time. The array is given by its first and "after
+ last" entry. */
+ template <class T> inline void
+-CoinZero(register T* first, register T* last)
++CoinZero(T* first, T* last)
+ {
+ CoinZeroN(first, last - first);
+ }
+@@ -545,7 +545,7 @@
+ This function was introduced because for some reason compiler tend to
+ handle the <code>max()</code> function differently. */
+ template <class T> inline T
+-CoinMax(register const T x1, register const T x2)
++CoinMax(const T x1, const T x2)
+ {
+ return (x1 > x2) ? x1 : x2;
+ }
+@@ -556,7 +556,7 @@
+ This function was introduced because for some reason compiler tend to
+ handle the min() function differently. */
+ template <class T> inline T
+-CoinMin(register const T x1, register const T x2)
++CoinMin(const T x1, const T x2)
+ {
+ return (x1 < x2) ? x1 : x2;
+ }
+@@ -578,7 +578,7 @@
+ according to operator<. The array is given by a pointer to its first entry
+ and by its size. */
+ template <class T> inline bool
+-CoinIsSorted(register const T* first, const int size)
++CoinIsSorted(const T* first, const int size)
+ {
+ if (size == 0)
+ return true;
+@@ -590,7 +590,7 @@
+ #if 1
+ // size1 is the number of comparisons to be made
+ const int size1 = size - 1;
+- for (register int n = size1 / 8; n > 0; --n, first += 8) {
++ for (int n = size1 / 8; n > 0; --n, first += 8) {
+ if (first[8] < first[7]) return false;
+ if (first[7] < first[6]) return false;
+ if (first[6] < first[5]) return false;
+@@ -627,7 +627,7 @@
+ according to operator<. The array is given by its first and "after
+ last" entry. */
+ template <class T> inline bool
+-CoinIsSorted(register const T* first, register const T* last)
++CoinIsSorted(const T* first, const T* last)
+ {
+ return CoinIsSorted(first, static_cast<int>(last - first));
+ }
+@@ -638,7 +638,7 @@
+ etc. For speed 8 entries are filled at a time. The array is given by a
+ pointer to its first entry and its size. */
+ template <class T> inline void
+-CoinIotaN(register T* first, const int size, register T init)
++CoinIotaN(T* first, const int size, T init)
+ {
+ if (size == 0)
+ return;
+@@ -648,7 +648,7 @@
+ throw CoinError("negative number of entries", "CoinIotaN", "");
+ #endif
+ #if 1
+- for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
++ for (int n = size / 8; n > 0; --n, first += 8, init += 8) {
+ first[0] = init;
+ first[1] = init + 1;
+ first[2] = init + 2;
+@@ -706,7 +706,7 @@
+ integer array specified by the last two arguments (again, first and "after
+ last" entry). */
+ template <class T> inline T *
+-CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
++CoinDeleteEntriesFromArray(T * arrayFirst, T * arrayLast,
+ const int * firstDelPos, const int * lastDelPos)
+ {
+ int delNum = static_cast<int>(lastDelPos - firstDelPos);
+--- CoinUtils/src/CoinModelUseful2.cpp
++++ CoinUtils/src/CoinModelUseful2.cpp
+@@ -917,8 +917,8 @@
+
+ int position=0;
+ int nEof=0; // Number of time send of string
+- register int yystate;
+- register int yyn;
++ int yystate;
++ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+@@ -936,12 +936,12 @@
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+- register short *yyssp;
++ short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+- register YYSTYPE *yyvsp;
++ YYSTYPE *yyvsp;
+
+
+
+--- CoinUtils/src/CoinOslC.h
++++ CoinUtils/src/CoinOslC.h
+@@ -34,30 +34,30 @@
+ extern "C"{
+ #endif
+
+-int c_ekkbtrn( register const EKKfactinfo *fact,
++int c_ekkbtrn( const EKKfactinfo *fact,
+ double *dwork1,
+ int * mpt,int first_nonzero);
+-int c_ekkbtrn_ipivrw( register const EKKfactinfo *fact,
++int c_ekkbtrn_ipivrw( const EKKfactinfo *fact,
+ double *dwork1,
+ int * mpt, int ipivrw,int * spare);
+
+-int c_ekketsj( register /*const*/ EKKfactinfo *fact,
++int c_ekketsj( /*const*/ EKKfactinfo *fact,
+ double *dwork1,
+ int *mpt2, double dalpha, int orig_nincol,
+ int npivot, int *nuspikp,
+ const int ipivrw, int * spare);
+-int c_ekkftrn( register const EKKfactinfo *fact,
++int c_ekkftrn( const EKKfactinfo *fact,
+ double *dwork1,
+ double * dpermu,int * mpt, int numberNonZero);
+
+-int c_ekkftrn_ft( register EKKfactinfo *fact,
++int c_ekkftrn_ft( EKKfactinfo *fact,
+ double *dwork1, int *mpt, int *nincolp);
+-void c_ekkftrn2( register EKKfactinfo *fact, double *dwork1,
++void c_ekkftrn2( EKKfactinfo *fact, double *dwork1,
+ double * dpermu1,int * mpt1, int *nincolp,
+ double *dwork1_ft, int *mpt_ft, int *nincolp_ft);
+
+-int c_ekklfct( register EKKfactinfo *fact);
+-int c_ekkslcf( register const EKKfactinfo *fact);
++int c_ekklfct( EKKfactinfo *fact);
++int c_ekkslcf( const EKKfactinfo *fact);
+ inline void c_ekkscpy(int n, const int *marr1,int *marr2)
+ { CoinMemcpyN(marr1,n,marr2);}
+ inline void c_ekkdcpy(int n, const double *marr1,double *marr2)
+--- CoinUtils/src/CoinOslFactorization2.cpp
++++ CoinUtils/src/CoinOslFactorization2.cpp
+@@ -20,9 +20,9 @@
+ extern int ets_count;
+ extern int ets_check;
+ #endif
+-#define COIN_REGISTER register
++#define COIN_REGISTER
+ #define COIN_REGISTER2
+-#define COIN_REGISTER3 register
++#define COIN_REGISTER3
+ #ifdef COIN_USE_RESTRICT
+ # define COIN_RESTRICT2 __restrict
+ #else
+--- CoinUtils/src/CoinOslFactorization3.cpp
++++ CoinUtils/src/CoinOslFactorization3.cpp
+@@ -1378,7 +1378,7 @@
+ }
+ }
+ } /* c_ekkmltf */
+-int c_ekklfct( register EKKfactinfo *fact)
++int c_ekklfct( EKKfactinfo *fact)
+ {
+ const int nrow = fact->nrow;
+ int ninbas = fact->xcsadr[nrow+1]-1;
+@@ -2607,7 +2607,7 @@
+ }
+ }
+ } /* c_ekkclcp */
+-int c_ekkslcf( register const EKKfactinfo *fact)
++int c_ekkslcf( const EKKfactinfo *fact)
+ {
+ int * hrow = fact->xeradr;
+ int * hcol = fact->xecadr;
+--- CoinUtils/src/CoinPackedVectorBase.cpp
++++ CoinUtils/src/CoinPackedVectorBase.cpp
+@@ -194,8 +194,8 @@
+ double
+ CoinPackedVectorBase::oneNorm() const
+ {
+- register double norm = 0.0;
+- register const double* elements = getElements();
++ double norm = 0.0;
++ const double* elements = getElements();
+ for (int i = getNumElements() - 1; i >= 0; --i) {
+ norm += fabs(elements[i]);
+ }
+@@ -224,8 +224,8 @@
+ double
+ CoinPackedVectorBase::infNorm() const
+ {
+- register double norm = 0.0;
+- register const double* elements = getElements();
++ double norm = 0.0;
++ const double* elements = getElements();
+ for (int i = getNumElements() - 1; i >= 0; --i) {
+ norm = CoinMax(norm, fabs(elements[i]));
+ }
+--- CoinUtils/src/CoinSearchTree.hpp
++++ CoinUtils/src/CoinSearchTree.hpp
+@@ -153,8 +153,8 @@
+ static inline const char* name() { return "CoinSearchTreeComparePreferred"; }
+ inline bool operator()(const CoinTreeSiblings* x,
+ const CoinTreeSiblings* y) const {
+- register const CoinTreeNode* xNode = x->currentNode();
+- register const CoinTreeNode* yNode = y->currentNode();
++ const CoinTreeNode* xNode = x->currentNode();
++ const CoinTreeNode* yNode = y->currentNode();
+ const BitVector128 xPref = xNode->getPreferred();
+ const BitVector128 yPref = yNode->getPreferred();
+ bool retval = true;
+--- CoinUtils/src/CoinSimpFactorization.cpp
++++ CoinUtils/src/CoinSimpFactorization.cpp
+@@ -2440,7 +2440,7 @@
+ const int row=secRowOfU_[i];
+ const int column=colOfU_[i];
+ if ( denseVector_[column]==0.0 ) continue;
+- register const double multiplier=denseVector_[column]*invOfPivots_[row];
++ const double multiplier=denseVector_[column]*invOfPivots_[row];
+ denseVector_[column]=0.0;
+ const int rowBeg=UrowStarts_[row];
+ const int rowEnd=rowBeg+UrowLengths_[row];
diff --git a/external/coinmp/rpath.patch b/external/coinmp/rpath.patch
new file mode 100644
index 000000000..50a2acde2
--- /dev/null
+++ b/external/coinmp/rpath.patch
@@ -0,0 +1,60 @@
+--- Cbc/configure
++++ Cbc/configure
+@@ -12484,6 +12484,7 @@
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+ lynxos*)
+ # FIXME: insert proper C++ library support
+--- Cgl/configure
++++ Cgl/configure
+@@ -12455,6 +12455,7 @@
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+ lynxos*)
+ # FIXME: insert proper C++ library support
+--- Clp/configure
++++ Clp/configure
+@@ -12482,6 +12482,7 @@
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+ lynxos*)
+ # FIXME: insert proper C++ library support
+--- CoinMP/configure
++++ CoinMP/configure
+@@ -12424,6 +12424,7 @@
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+ lynxos*)
+ # FIXME: insert proper C++ library support
+--- CoinUtils/configure
++++ CoinUtils/configure
+@@ -13939,6 +13939,7 @@
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+ lynxos*)
+ # FIXME: insert proper C++ library support
+--- Osi/configure
++++ Osi/configure
+@@ -12453,6 +12453,7 @@
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+ lynxos*)
+ # FIXME: insert proper C++ library support
diff --git a/external/coinmp/ubsan.patch.0 b/external/coinmp/ubsan.patch.0
new file mode 100644
index 000000000..157332986
--- /dev/null
+++ b/external/coinmp/ubsan.patch.0
@@ -0,0 +1,11 @@
+--- Clp/src/ClpParameters.hpp
++++ Clp/src/ClpParameters.hpp
+@@ -81,7 +81,7 @@
+ template <class T> inline void
+ ClpDisjointCopyN( const T * array, const int size, T * newArray)
+ {
+- memcpy(reinterpret_cast<void *> (newArray), array, size * sizeof(T));
++ if (size != 0) memcpy(reinterpret_cast<void *> (newArray), array, size * sizeof(T));
+ }
+ /// And set
+ template <class T> inline void
diff --git a/external/coinmp/werror-format-pedantic.patch.0 b/external/coinmp/werror-format-pedantic.patch.0
new file mode 100644
index 000000000..a604c4354
--- /dev/null
+++ b/external/coinmp/werror-format-pedantic.patch.0
@@ -0,0 +1,10 @@
+--- Cbc/configure
++++ Cbc/configure
+@@ -3780,7 +3780,6 @@
+ *-darwin*)
+ ;;
+ *)
+- coin_warn_cxxflags="-pedantic-errors $coin_warn_cxxflags"
+ ;;
+ esac
+ esac
diff --git a/external/coinmp/werror-format-security.patch.0 b/external/coinmp/werror-format-security.patch.0
new file mode 100644
index 000000000..90c116b5b
--- /dev/null
+++ b/external/coinmp/werror-format-security.patch.0
@@ -0,0 +1,12 @@
+diff -ur coinmp.org/CoinUtils/src/CoinMessageHandler.cpp coinmp/CoinUtils/src/CoinMessageHandler.cpp
+--- CoinUtils/src/CoinMessageHandler.cpp 2014-05-21 23:14:01.384874167 +0200
++++ CoinUtils/src/CoinMessageHandler.cpp 2014-05-21 23:14:47.708874712 +0200
+@@ -820,7 +820,7 @@
+ sprintf(messageOut_,g_format_,doublevalue);
+ if (next != format_+2) {
+ messageOut_+=strlen(messageOut_);
+- sprintf(messageOut_,format_+2);
++ sprintf(messageOut_,"%s",format_+2);
+ }
+ }
+ messageOut_+=strlen(messageOut_);
diff --git a/external/coinmp/werror-undef.patch.0 b/external/coinmp/werror-undef.patch.0
new file mode 100644
index 000000000..a9b80f280
--- /dev/null
+++ b/external/coinmp/werror-undef.patch.0
@@ -0,0 +1,11 @@
+--- CoinUtils/src/config_coinutils_default.h 2014-06-06 14:28:06.872113540 +0100
++++ CoinUtils/src/config_coinutils_default.h 2014-06-06 14:28:29.400294129 +0100
+@@ -26,7 +26,7 @@
+ all of this inside the guard for MSC_VER >= 1200. If you're reading this
+ and have been developing in MSVS long enough to know, fix it. -- lh, 100915 --
+ */
+-#if _MSC_VER >= 1200
++#if defined _MSC_VER && _MSC_VER >= 1200
+ # include <BaseTsd.h>
+ # define COIN_INT64_T INT64
+ # define COIN_UINT64_T UINT64
diff --git a/external/coinmp/windows.build.patch.1 b/external/coinmp/windows.build.patch.1
new file mode 100644
index 000000000..2bd0526ac
--- /dev/null
+++ b/external/coinmp/windows.build.patch.1
@@ -0,0 +1,3241 @@
+diff -urN coinmp.org/Cbc/MSVisualStudio/v9/libCbc/libCbc.vcxproj coinmp/Cbc/MSVisualStudio/v9/libCbc/libCbc.vcxproj
+--- coinmp.org/Cbc/MSVisualStudio/v9/libCbc/libCbc.vcxproj 1970-01-01 01:00:00.000000000 +0100
++++ coinmp/Cbc/MSVisualStudio/v9/libCbc/libCbc.vcxproj 2014-02-28 15:32:36.548600694 +0100
+@@ -0,0 +1,506 @@
++<?xml version="1.0" encoding="utf-8"?>
++<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
++ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|Win32">
++ <Configuration>Debug</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|x64">
++ <Configuration>Debug</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|Win32">
++ <Configuration>Release</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|x64">
++ <Configuration>Release</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ </ItemGroup>
++ <PropertyGroup Label="Globals">
++ <ProjectGuid>{363BA154-FEC9-4E1E-BC23-93CEC58AB785}</ProjectGuid>
++ <RootNamespace>libCbc</RootNamespace>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
++ <ImportGroup Label="ExtensionSettings">
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <PropertyGroup Label="UserMacros" />
++ <PropertyGroup>
++ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\Cbc\src\;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CBC_BUILD;_DEBUG;WIN32;_LIB;USE_CBCCONFIG;COIN_NO_CLP_MESSAGE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ <ShowIncludes>false</ShowIncludes>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\Cbc\src\;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CBC_BUILD;NDEBUG;WIN32;_LIB;USE_CBCCONFIG;COIN_NO_CLP_MESSAGE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\Cbc\src\;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CBC_BUILD;_DEBUG;WIN32;_LIB;USE_CBCCONFIG;COIN_NO_CLP_MESSAGE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ <ShowIncludes>false</ShowIncludes>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\Cbc\src\;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CBC_BUILD;NDEBUG;WIN32;_LIB;USE_CBCCONFIG;COIN_NO_CLP_MESSAGE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemGroup>
++ <ClCompile Include="..\..\..\src\CbcBranchAllDifferent.cpp" />
++ <ClCompile Include="..\..\..\src\CbcBranchCut.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcBranchDecision.cpp" />
++ <ClCompile Include="..\..\..\src\CbcBranchDefaultDecision.cpp" />
++ <ClCompile Include="..\..\..\src\CbcBranchDynamic.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcBranchingObject.cpp" />
++ <ClCompile Include="..\..\..\src\CbcBranchLotsize.cpp" />
++ <ClCompile Include="..\..\..\src\CbcBranchToFixLots.cpp" />
++ <ClCompile Include="..\..\..\src\CbcClique.cpp" />
++ <ClCompile Include="..\..\..\src\CbcCompareDefault.cpp" />
++ <ClCompile Include="..\..\..\src\CbcCompareDepth.cpp" />
++ <ClCompile Include="..\..\..\src\CbcCompareEstimate.cpp" />
++ <ClCompile Include="..\..\..\src\CbcCompareObjective.cpp" />
++ <ClCompile Include="..\..\..\src\CbcConsequence.cpp" />
++ <ClCompile Include="..\..\..\src\CbcCountRowCut.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcCutGenerator.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcCutModifier.cpp" />
++ <ClCompile Include="..\..\..\src\CbcCutSubsetModifier.cpp" />
++ <ClCompile Include="..\..\..\src\CbcDummyBranchingObject.cpp" />
++ <ClCompile Include="..\..\..\src\CbcEventHandler.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcFathom.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcFathomDynamicProgramming.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcFixVariable.cpp" />
++ <ClCompile Include="..\..\..\src\CbcFollowOn.cpp" />
++ <ClCompile Include="..\..\..\src\CbcFullNodeInfo.cpp" />
++ <ClCompile Include="..\..\..\src\CbcGeneral.cpp" />
++ <ClCompile Include="..\..\..\src\CbcGeneralDepth.cpp" />
++ <ClCompile Include="..\..\..\src\CbcHeuristic.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicDINS.cpp" />
++ <ClCompile Include="..\..\..\src\CbcHeuristicDive.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicDiveCoefficient.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicDiveFractional.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicDiveGuided.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicDiveLineSearch.cpp" />
++ <ClCompile Include="..\..\..\src\CbcHeuristicDivePseudoCost.cpp" />
++ <ClCompile Include="..\..\..\src\CbcHeuristicDiveVectorLength.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicFPump.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicGreedy.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicLocal.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicPivotAndFix.cpp" />
++ <ClCompile Include="..\..\..\src\CbcHeuristicRandRound.cpp" />
++ <ClCompile Include="..\..\..\src\CbcHeuristicRENS.cpp" />
++ <ClCompile Include="..\..\..\src\CbcHeuristicRINS.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcHeuristicVND.cpp" />
++ <ClCompile Include="..\..\..\src\CbcMessage.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcModel.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcNode.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcNodeInfo.cpp" />
++ <ClCompile Include="..\..\..\src\CbcNWay.cpp" />
++ <ClCompile Include="..\..\..\src\CbcObject.cpp" />
++ <ClCompile Include="..\..\..\src\CbcObjectUpdateData.cpp" />
++ <ClCompile Include="..\..\..\src\CbcParam.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcPartialNodeInfo.cpp" />
++ <ClCompile Include="..\..\..\src\CbcSimpleInteger.cpp" />
++ <ClCompile Include="..\..\..\src\CbcSimpleIntegerDynamicPseudoCost.cpp" />
++ <ClCompile Include="..\..\..\src\CbcSimpleIntegerPseudoCost.cpp" />
++ <ClCompile Include="..\..\..\src\CbcSOS.cpp" />
++ <ClCompile Include="..\..\..\src\CbcStatistics.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcStrategy.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcSubProblem.cpp" />
++ <ClCompile Include="..\..\..\src\CbcThread.cpp" />
++ <ClCompile Include="..\..\..\src\CbcTree.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CbcTreeLocal.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ </ItemGroup>
++ <ItemGroup>
++ <ClInclude Include="..\..\..\src\CbcBranchActual.hpp" />
++ <ClInclude Include="..\..\..\src\CbcBranchAllDifferent.hpp" />
++ <ClInclude Include="..\..\..\src\CbcBranchBase.hpp" />
++ <ClInclude Include="..\..\..\src\CbcBranchCut.hpp" />
++ <ClInclude Include="..\..\..\src\CbcBranchDecision.hpp" />
++ <ClInclude Include="..\..\..\src\CbcBranchDefaultDecision.hpp" />
++ <ClInclude Include="..\..\..\src\CbcBranchDynamic.hpp" />
++ <ClInclude Include="..\..\..\src\CbcBranchingObject.hpp" />
++ <ClInclude Include="..\..\..\src\CbcBranchLotsize.hpp" />
++ <ClInclude Include="..\..\..\src\CbcBranchToFixLots.hpp" />
++ <ClInclude Include="..\..\..\src\CbcChooseVariable.hpp" />
++ <ClInclude Include="..\..\..\src\CbcClique.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCompare.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCompareActual.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCompareBase.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCompareDefault.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCompareDepth.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCompareEstimate.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCompareObjective.hpp" />
++ <ClInclude Include="..\..\..\src\CbcConfig.h" />
++ <ClInclude Include="..\..\..\src\CbcConsequence.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCountRowCut.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCutGenerator.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCutModifier.hpp" />
++ <ClInclude Include="..\..\..\src\CbcCutSubsetModifier.hpp" />
++ <ClInclude Include="..\..\..\src\CbcDummyBranchingObject.hpp" />
++ <ClInclude Include="..\..\..\src\CbcEventHandler.hpp" />
++ <ClInclude Include="..\..\..\src\CbcFathom.hpp" />
++ <ClInclude Include="..\..\..\src\CbcFathomDynamicProgramming.hpp" />
++ <ClInclude Include="..\..\..\src\CbcFeasibilityBase.hpp" />
++ <ClInclude Include="..\..\..\src\CbcFixVariable.hpp" />
++ <ClInclude Include="..\..\..\src\CbcFollowOn.hpp" />
++ <ClInclude Include="..\..\..\src\CbcFullNodeInfo.hpp" />
++ <ClInclude Include="..\..\..\src\CbcGeneral.hpp" />
++ <ClInclude Include="..\..\..\src\CbcGeneralDepth.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristic.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicDINS.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicDive.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicDiveCoefficient.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicDiveFractional.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicDiveGuided.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicDiveLineSearch.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicDivePseudoCost.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicDiveVectorLength.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicFPump.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicGreedy.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicLocal.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicPivotAndFix.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicRandRound.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicRENS.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicRINS.hpp" />
++ <ClInclude Include="..\..\..\src\CbcHeuristicVND.hpp" />
++ <ClInclude Include="..\..\..\src\CbcMessage.hpp" />
++ <ClInclude Include="..\..\..\src\CbcModel.hpp" />
++ <ClInclude Include="..\..\..\src\CbcNode.hpp" />
++ <ClInclude Include="..\..\..\src\CbcNodeInfo.hpp" />
++ <ClInclude Include="..\..\..\src\CbcNWay.hpp" />
++ <ClInclude Include="..\..\..\src\CbcObject.hpp" />
++ <ClInclude Include="..\..\..\src\CbcObjectUpdateData.hpp" />
++ <ClInclude Include="..\..\..\..\Clp\src\CbcOrClpParam.hpp" />
++ <ClInclude Include="..\..\..\src\CbcParam.hpp" />
++ <ClInclude Include="..\..\..\src\CbcPartialNodeInfo.hpp" />
++ <ClInclude Include="..\..\..\src\CbcSimpleInteger.hpp" />
++ <ClInclude Include="..\..\..\src\CbcSimpleIntegerDynamicPseudoCost.hpp" />
++ <ClInclude Include="..\..\..\src\CbcSimpleIntegerPseudoCost.hpp" />
++ <ClInclude Include="..\..\..\src\CbcSOS.hpp" />
++ <ClInclude Include="..\..\..\src\CbcStatistics.hpp" />
++ <ClInclude Include="..\..\..\src\CbcStrategy.hpp" />
++ <ClInclude Include="..\..\..\src\CbcSubProblem.hpp" />
++ <ClInclude Include="..\..\..\src\CbcThread.hpp" />
++ <ClInclude Include="..\..\..\src\CbcTree.hpp" />
++ <ClInclude Include="..\..\..\src\CbcTreeLocal.hpp" />
++ </ItemGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
++ <ImportGroup Label="ExtensionTargets">
++ </ImportGroup>
++</Project>
+\ No newline at end of file
+diff -urN coinmp.org/Cbc/MSVisualStudio/v9/libCbcSolver/libCbcSolver.vcxproj coinmp/Cbc/MSVisualStudio/v9/libCbcSolver/libCbcSolver.vcxproj
+--- coinmp.org/Cbc/MSVisualStudio/v9/libCbcSolver/libCbcSolver.vcxproj 1970-01-01 01:00:00.000000000 +0100
++++ coinmp/Cbc/MSVisualStudio/v9/libCbcSolver/libCbcSolver.vcxproj 2014-02-28 15:32:36.548600694 +0100
+@@ -0,0 +1,172 @@
++<?xml version="1.0" encoding="utf-8"?>
++<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
++ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|Win32">
++ <Configuration>Debug</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|x64">
++ <Configuration>Debug</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|Win32">
++ <Configuration>Release</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|x64">
++ <Configuration>Release</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ </ItemGroup>
++ <PropertyGroup Label="Globals">
++ <ProjectGuid>{71DA4595-E8A7-4B21-A00A-D96D29D11E3E}</ProjectGuid>
++ <RootNamespace>libCbcSolver</RootNamespace>
++ <Keyword>ManagedCProj</Keyword>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ <CLRSupport>false</CLRSupport>
++ <WholeProgramOptimization>false</WholeProgramOptimization>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ <CLRSupport>false</CLRSupport>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ <CLRSupport>false</CLRSupport>
++ <WholeProgramOptimization>false</WholeProgramOptimization>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ <CLRSupport>false</CLRSupport>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
++ <ImportGroup Label="ExtensionSettings">
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <PropertyGroup Label="UserMacros" />
++ <PropertyGroup>
++ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\src;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglRedSplit2;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CBC_BUILD;WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ </ClCompile>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <ClCompile>
++ <AdditionalIncludeDirectories>..\..\..\src;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglRedSplit2;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CBC_BUILD;WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ </ClCompile>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\src;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglRedSplit2;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CBC_BUILD;WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ </ClCompile>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <AdditionalIncludeDirectories>..\..\..\src;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglRedSplit2;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ </ClCompile>
++ </ItemDefinitionGroup>
++ <ItemGroup>
++ <Reference Include="System">
++ <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
++ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
++ </Reference>
++ <Reference Include="System.Data">
++ <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
++ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
++ </Reference>
++ <Reference Include="System.Xml">
++ <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
++ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
++ </Reference>
++ </ItemGroup>
++ <ItemGroup>
++ <ClCompile Include="..\..\..\src\CbcCbcParam.cpp" />
++ <ClCompile Include="..\..\..\src\CbcLinked.cpp" />
++ <ClCompile Include="..\..\..\src\CbcLinkedUtils.cpp" />
++ <ClCompile Include="..\..\..\src\CbcMipStartIO.cpp" />
++ <ClCompile Include="..\..\..\src\CbcSolver.cpp" />
++ <ClCompile Include="..\..\..\src\CbcSolverAnalyze.cpp" />
++ <ClCompile Include="..\..\..\src\CbcSolverExpandKnapsack.cpp" />
++ <ClCompile Include="..\..\..\src\CbcSolverHeuristics.cpp" />
++ <ClCompile Include="..\..\..\src\unitTestClp.cpp" />
++ </ItemGroup>
++ <ItemGroup>
++ <ClInclude Include="..\..\..\src\CbcLinked.hpp" />
++ <ClInclude Include="..\..\..\src\CbcMipStartIO.hpp" />
++ <ClInclude Include="..\..\..\src\CbcSolver.hpp" />
++ <ClInclude Include="..\..\..\src\CbcSolverAnalyze.hpp" />
++ <ClInclude Include="..\..\..\src\CbcSolverExpandKnapsack.hpp" />
++ <ClInclude Include="..\..\..\src\CbcSolverHeuristics.hpp" />
++ </ItemGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
++ <ImportGroup Label="ExtensionTargets">
++ </ImportGroup>
++</Project>
+\ No newline at end of file
+diff -urN coinmp.org/Cgl/MSVisualStudio/v9/libCgl/libCgl.vcxproj coinmp/Cgl/MSVisualStudio/v9/libCgl/libCgl.vcxproj
+--- coinmp.org/Cgl/MSVisualStudio/v9/libCgl/libCgl.vcxproj 1970-01-01 01:00:00.000000000 +0100
++++ coinmp/Cgl/MSVisualStudio/v9/libCgl/libCgl.vcxproj 2014-02-28 15:32:36.552600694 +0100
+@@ -0,0 +1,397 @@
++<?xml version="1.0" encoding="utf-8"?>
++<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
++ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|Win32">
++ <Configuration>Debug</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|x64">
++ <Configuration>Debug</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|Win32">
++ <Configuration>Release</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|x64">
++ <Configuration>Release</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ </ItemGroup>
++ <PropertyGroup Label="Globals">
++ <ProjectGuid>{DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}</ProjectGuid>
++ <RootNamespace>libCgl</RootNamespace>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
++ <ImportGroup Label="ExtensionSettings">
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <PropertyGroup Label="UserMacros" />
++ <PropertyGroup>
++ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\src;..\..\..\src\CglClique;..\..\..\src\CglDuplicateRow;..\..\..\src\CglFlowCover;..\..\..\src\CglGomory;..\..\..\src\CglKnapsackCover;..\..\..\src\CglMixedIntegerRounding;..\..\..\src\CglMixedIntegerRounding2;..\..\..\src\CglOddHole;..\..\..\src\CglPreProcess;..\..\..\src\CglProbing;..\..\..\src\CglRedSplit;..\..\..\src\CglResidualCapacity;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\src;..\..\..\src\CglClique;..\..\..\src\CglDuplicateRow;..\..\..\src\CglFlowCover;..\..\..\src\CglGomory;..\..\..\src\CglKnapsackCover;..\..\..\src\CglMixedIntegerRounding;..\..\..\src\CglMixedIntegerRounding2;..\..\..\src\CglOddHole;..\..\..\src\CglPreProcess;..\..\..\src\CglProbing;..\..\..\src\CglRedSplit;..\..\..\src\CglResidualCapacity;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\src;..\..\..\src\CglClique;..\..\..\src\CglDuplicateRow;..\..\..\src\CglFlowCover;..\..\..\src\CglGomory;..\..\..\src\CglKnapsackCover;..\..\..\src\CglMixedIntegerRounding;..\..\..\src\CglMixedIntegerRounding2;..\..\..\src\CglOddHole;..\..\..\src\CglPreProcess;..\..\..\src\CglProbing;..\..\..\src\CglRedSplit;..\..\..\src\CglResidualCapacity;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\src;..\..\..\src\CglClique;..\..\..\src\CglDuplicateRow;..\..\..\src\CglFlowCover;..\..\..\src\CglGomory;..\..\..\src\CglKnapsackCover;..\..\..\src\CglMixedIntegerRounding;..\..\..\src\CglMixedIntegerRounding2;..\..\..\src\CglOddHole;..\..\..\src\CglPreProcess;..\..\..\src\CglProbing;..\..\..\src\CglRedSplit;..\..\..\src\CglResidualCapacity;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemGroup>
++ <ClCompile Include="..\..\..\src\CglZeroHalf\Cgl012cut.cpp" />
++ <ClCompile Include="..\..\..\src\CglAllDifferent\CglAllDifferent.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglClique\CglClique.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglClique\CglCliqueHelper.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglCutGenerator.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglDuplicateRow\CglDuplicateRow.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglFlowCover\CglFlowCover.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglGMI\CglGMI.cpp" />
++ <ClCompile Include="..\..\..\src\CglGMI\CglGMIParam.cpp" />
++ <ClCompile Include="..\..\..\src\CglGomory\CglGomory.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglKnapsackCover\CglKnapsackCover.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglLandP\CglLandP.cpp" />
++ <ClCompile Include="..\..\..\src\CglLandP\CglLandPMessages.cpp" />
++ <ClCompile Include="..\..\..\src\CglLandP\CglLandPSimplex.cpp" />
++ <ClCompile Include="..\..\..\src\CglLandP\CglLandPTabRow.cpp" />
++ <ClCompile Include="..\..\..\src\CglLandP\CglLandPUtils.cpp" />
++ <ClCompile Include="..\..\..\src\CglLandP\CglLandPValidator.cpp" />
++ <ClCompile Include="..\..\..\src\CglLiftAndProject\CglLiftAndProject.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglMessage.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglMixedIntegerRounding\CglMixedIntegerRounding.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglMixedIntegerRounding2\CglMixedIntegerRounding2.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglOddHole\CglOddHole.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglParam.cpp" />
++ <ClCompile Include="..\..\..\src\CglPreProcess\CglPreProcess.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglProbing\CglProbing.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglRedSplit\CglRedSplit.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglRedSplit2\CglRedSplit2.cpp" />
++ <ClCompile Include="..\..\..\src\CglRedSplit2\CglRedSplit2Param.cpp" />
++ <ClCompile Include="..\..\..\src\CglRedSplit\CglRedSplitParam.cpp" />
++ <ClCompile Include="..\..\..\src\CglResidualCapacity\CglResidualCapacity.cpp" />
++ <ClCompile Include="..\..\..\src\CglSimpleRounding\CglSimpleRounding.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglStored.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglTreeInfo.cpp" />
++ <ClCompile Include="..\..\..\src\CglTwomir\CglTwomir.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CglZeroHalf\CglZeroHalf.cpp" />
++ </ItemGroup>
++ <ItemGroup>
++ <ClInclude Include="..\..\..\src\CglZeroHalf\Cgl012cut.hpp" />
++ <ClInclude Include="..\..\..\src\CglAllDifferent\CglAllDifferent.hpp" />
++ <ClInclude Include="..\..\..\src\CglClique\CglClique.hpp" />
++ <ClInclude Include="..\..\..\src\CglConfig.h" />
++ <ClInclude Include="..\..\..\src\CglCutGenerator.hpp" />
++ <ClInclude Include="..\..\..\src\CglDuplicateRow\CglDuplicateRow.hpp" />
++ <ClInclude Include="..\..\..\src\CglFlowCover\CglFlowCover.hpp" />
++ <ClInclude Include="..\..\..\src\CglGMI\CglGMI.hpp" />
++ <ClInclude Include="..\..\..\src\CglGMI\CglGMIParam.hpp" />
++ <ClInclude Include="..\..\..\src\CglGomory\CglGomory.hpp" />
++ <ClInclude Include="..\..\..\src\CglKnapsackCover\CglKnapsackCover.hpp" />
++ <ClInclude Include="..\..\..\src\CglLandP\CglLandP.hpp" />
++ <ClInclude Include="..\..\..\src\CglLandP\CglLandPMessages.hpp" />
++ <ClInclude Include="..\..\..\src\CglLandP\CglLandPSimplex.hpp" />
++ <ClInclude Include="..\..\..\src\CglLandP\CglLandPTabRow.hpp" />
++ <ClInclude Include="..\..\..\src\CglLandP\CglLandPUtils.hpp" />
++ <ClInclude Include="..\..\..\src\CglLandP\CglLandPValidator.hpp" />
++ <ClInclude Include="..\..\..\src\CglLiftAndProject\CglLiftAndProject.hpp" />
++ <ClInclude Include="..\..\..\src\CglMessage.hpp" />
++ <ClInclude Include="..\..\..\src\CglMixedIntegerRounding\CglMixedIntegerRounding.hpp" />
++ <ClInclude Include="..\..\..\src\CglMixedIntegerRounding2\CglMixedIntegerRounding2.hpp" />
++ <ClInclude Include="..\..\..\src\CglOddHole\CglOddHole.hpp" />
++ <ClInclude Include="..\..\..\src\CglParam.hpp" />
++ <ClInclude Include="..\..\..\src\CglPreProcess\CglPreProcess.hpp" />
++ <ClInclude Include="..\..\..\src\CglProbing\CglProbing.hpp" />
++ <ClInclude Include="..\..\..\src\CglRedSplit\CglRedSplit.hpp" />
++ <ClInclude Include="..\..\..\src\CglRedSplit2\CglRedSplit2.hpp" />
++ <ClInclude Include="..\..\..\src\CglRedSplit2\CglRedSplit2Param.hpp" />
++ <ClInclude Include="..\..\..\src\CglRedSplit\CglRedSplitParam.hpp" />
++ <ClInclude Include="..\..\..\src\CglResidualCapacity\CglResidualCapacity.hpp" />
++ <ClInclude Include="..\..\..\src\CglSimpleRounding\CglSimpleRounding.hpp" />
++ <ClInclude Include="..\..\..\src\CglStored.hpp" />
++ <ClInclude Include="..\..\..\src\CglTreeInfo.hpp" />
++ <ClInclude Include="..\..\..\src\CglTwomir\CglTwomir.hpp" />
++ <ClInclude Include="..\..\..\src\CglZeroHalf\CglZeroHalf.hpp" />
++ </ItemGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
++ <ImportGroup Label="ExtensionTargets">
++ </ImportGroup>
++</Project>
+\ No newline at end of file
+diff -urN coinmp.org/Clp/MSVisualStudio/v9/libClp/libClp.vcxproj coinmp/Clp/MSVisualStudio/v9/libClp/libClp.vcxproj
+--- coinmp.org/Clp/MSVisualStudio/v9/libClp/libClp.vcxproj 1970-01-01 01:00:00.000000000 +0100
++++ coinmp/Clp/MSVisualStudio/v9/libClp/libClp.vcxproj 2014-02-28 15:32:36.556600694 +0100
+@@ -0,0 +1,579 @@
++<?xml version="1.0" encoding="utf-8"?>
++<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
++ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|Win32">
++ <Configuration>Debug</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|x64">
++ <Configuration>Debug</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|Win32">
++ <Configuration>Release</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|x64">
++ <Configuration>Release</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ </ItemGroup>
++ <PropertyGroup Label="Globals">
++ <ProjectGuid>{4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}</ProjectGuid>
++ <RootNamespace>libClp</RootNamespace>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
++ <ImportGroup Label="ExtensionSettings">
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <PropertyGroup Label="UserMacros" />
++ <PropertyGroup>
++ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CLP_BUILD;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CLP_BUILD;WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CLP_BUILD;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>CLP_BUILD;WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemGroup>
++ <ClCompile Include="..\..\..\src\Clp_C_Interface.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpCholeskyBase.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpCholeskyDense.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpCholeskyWssmp.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpCholeskyWssmpKKT.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpConstraint.cpp" />
++ <ClCompile Include="..\..\..\src\ClpConstraintLinear.cpp" />
++ <ClCompile Include="..\..\..\src\ClpConstraintQuadratic.cpp" />
++ <ClCompile Include="..\..\..\src\ClpDualRowDantzig.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpDualRowPivot.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpDualRowSteepest.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpDummyMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpDynamicExampleMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpDynamicMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpEventHandler.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpFactorization.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpGubDynamicMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpGubMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpHelperFunctions.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpInterior.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpLinearObjective.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpLsqr.cpp" />
++ <ClCompile Include="..\..\..\src\ClpMatrixBase.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpMessage.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpModel.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpNetworkBasis.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpNetworkMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpNode.cpp" />
++ <ClCompile Include="..\..\..\src\ClpNonLinearCost.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpObjective.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpPackedMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpPdco.cpp" />
++ <ClCompile Include="..\..\..\src\ClpPdcoBase.cpp" />
++ <ClCompile Include="..\..\..\src\ClpPlusMinusOneMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpPredictorCorrector.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpPresolve.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpPrimalColumnDantzig.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpPrimalColumnPivot.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpPrimalColumnSteepest.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpQuadraticObjective.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpSimplex.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpSimplexDual.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpSimplexNonlinear.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpSimplexOther.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpSimplexPrimal.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\ClpSolve.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\Idiot.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\IdiSolve.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ </ItemGroup>
++ <ItemGroup>
++ <ClInclude Include="..\..\..\src\Clp_C_Interface.h" />
++ <ClInclude Include="..\..\..\src\ClpCholeskyBase.hpp" />
++ <ClInclude Include="..\..\..\src\ClpCholeskyDense.hpp" />
++ <ClInclude Include="..\..\..\src\ClpCholeskyMumps.hpp" />
++ <ClInclude Include="..\..\..\src\ClpCholeskyUfl.hpp" />
++ <ClInclude Include="..\..\..\src\ClpCholeskyWssmp.hpp" />
++ <ClInclude Include="..\..\..\src\ClpConfig.h" />
++ <ClInclude Include="..\..\..\src\ClpConstraint.hpp" />
++ <ClInclude Include="..\..\..\src\ClpConstraintLinear.hpp" />
++ <ClInclude Include="..\..\..\src\ClpConstraintQuadratic.hpp" />
++ <ClInclude Include="..\..\..\src\ClpDualRowDantzig.hpp" />
++ <ClInclude Include="..\..\..\src\ClpDualRowPivot.hpp" />
++ <ClInclude Include="..\..\..\src\ClpDualRowSteepest.hpp" />
++ <ClInclude Include="..\..\..\src\ClpDummyMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\ClpDynamicExampleMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\ClpDynamicMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\ClpEventHandler.hpp" />
++ <ClInclude Include="..\..\..\src\ClpFactorization.hpp" />
++ <ClInclude Include="..\..\..\src\ClpGubDynamicMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\ClpGubMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\ClpHelperFunctions.hpp" />
++ <ClInclude Include="..\..\..\src\ClpInterior.hpp" />
++ <ClInclude Include="..\..\..\src\ClpLinearObjective.hpp" />
++ <ClInclude Include="..\..\..\src\ClpLsqr.hpp" />
++ <ClInclude Include="..\..\..\src\ClpMatrixBase.hpp" />
++ <ClInclude Include="..\..\..\src\ClpMessage.hpp" />
++ <ClInclude Include="..\..\..\src\ClpModel.hpp" />
++ <ClInclude Include="..\..\..\src\ClpNetworkBasis.hpp" />
++ <ClInclude Include="..\..\..\src\ClpNetworkMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\ClpNode.hpp" />
++ <ClInclude Include="..\..\..\src\ClpNonLinearCost.hpp" />
++ <ClInclude Include="..\..\..\src\ClpObjective.hpp" />
++ <ClInclude Include="..\..\..\src\ClpPackedMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\ClpParameters.hpp" />
++ <ClInclude Include="..\..\..\src\ClpPdco.hpp" />
++ <ClInclude Include="..\..\..\src\ClpPdcoBase.hpp" />
++ <ClInclude Include="..\..\..\src\ClpPlusMinusOneMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\ClpPredictorCorrector.hpp" />
++ <ClInclude Include="..\..\..\src\ClpPresolve.hpp" />
++ <ClInclude Include="..\..\..\src\ClpPrimalColumnDantzig.hpp" />
++ <ClInclude Include="..\..\..\src\ClpPrimalColumnPivot.hpp" />
++ <ClInclude Include="..\..\..\src\ClpPrimalColumnSteepest.hpp" />
++ <ClInclude Include="..\..\..\src\ClpQuadraticObjective.hpp" />
++ <ClInclude Include="..\..\..\src\ClpSimplex.hpp" />
++ <ClInclude Include="..\..\..\src\ClpSimplexDual.hpp" />
++ <ClInclude Include="..\..\..\src\ClpSimplexNonlinear.hpp" />
++ <ClInclude Include="..\..\..\src\ClpSimplexOther.hpp" />
++ <ClInclude Include="..\..\..\src\ClpSimplexPrimal.hpp" />
++ <ClInclude Include="..\..\..\src\ClpSolve.hpp" />
++ <ClInclude Include="..\..\..\src\Idiot.hpp" />
++ </ItemGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
++ <ImportGroup Label="ExtensionTargets">
++ </ImportGroup>
++</Project>
+\ No newline at end of file
+diff -urN coinmp.org/Clp/MSVisualStudio/v9/libOsiClp/libOsiClp.vcxproj coinmp/Clp/MSVisualStudio/v9/libOsiClp/libOsiClp.vcxproj
+--- coinmp.org/Clp/MSVisualStudio/v9/libOsiClp/libOsiClp.vcxproj 1970-01-01 01:00:00.000000000 +0100
++++ coinmp/Clp/MSVisualStudio/v9/libOsiClp/libOsiClp.vcxproj 2014-02-28 15:32:36.556600694 +0100
+@@ -0,0 +1,181 @@
++<?xml version="1.0" encoding="utf-8"?>
++<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
++ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|Win32">
++ <Configuration>Debug</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|x64">
++ <Configuration>Debug</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|Win32">
++ <Configuration>Release</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|x64">
++ <Configuration>Release</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ </ItemGroup>
++ <PropertyGroup Label="Globals">
++ <ProjectGuid>{02D45875-A8CF-41B9-990B-3699C0ECFE10}</ProjectGuid>
++ <RootNamespace>libOsiClp</RootNamespace>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
++ <ImportGroup Label="ExtensionSettings">
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <PropertyGroup Label="UserMacros" />
++ <PropertyGroup>
++ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src;..\..\..\..\Osi\src\Osi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src;..\..\..\..\Osi\src\Osi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src;..\..\..\..\Osi\src\Osi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src;..\..\..\..\Osi\src\Osi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ </ItemDefinitionGroup>
++ <ItemGroup>
++ <ClCompile Include="..\..\..\src\OsiClp\OsiClpSolverInterface.cpp" />
++ </ItemGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
++ <ImportGroup Label="ExtensionTargets">
++ </ImportGroup>
++</Project>
+\ No newline at end of file
+diff -urN coinmp.org/CoinMP/MSVisualStudio/v9/CoinMP/CoinMP.vcxproj coinmp/CoinMP/MSVisualStudio/v9/CoinMP/CoinMP.vcxproj
+--- coinmp.org/CoinMP/MSVisualStudio/v9/CoinMP/CoinMP.vcxproj 1970-01-01 01:00:00.000000000 +0100
++++ coinmp/CoinMP/MSVisualStudio/v9/CoinMP/CoinMP.vcxproj 2014-02-28 15:32:36.560600694 +0100
+@@ -0,0 +1,237 @@
++<?xml version="1.0" encoding="utf-8"?>
++<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
++ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|Win32">
++ <Configuration>Debug</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|x64">
++ <Configuration>Debug</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|Win32">
++ <Configuration>Release</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|x64">
++ <Configuration>Release</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ </ItemGroup>
++ <PropertyGroup Label="Globals">
++ <ProjectGuid>{175F0674-F0B9-479C-9C9D-76969C06D794}</ProjectGuid>
++ <RootNamespace>CoinMP</RootNamespace>
++ <Keyword>Win32Proj</Keyword>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
++ <ImportGroup Label="ExtensionSettings">
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <PropertyGroup Label="UserMacros" />
++ <PropertyGroup>
++ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ <LinkIncremental>true</LinkIncremental>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ <LinkIncremental>true</LinkIncremental>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ </PropertyGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\Clp\src;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cbc\src;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglLiftAndProject;..\..\..\..\Cgl\src\CglSimpleRounding;..\..\..\..\Clp\src\OsiClp;..\..\..\..\BuildTools\headers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;COINMP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
++ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
++ </ClCompile>
++ <Link>
++ <ModuleDefinitionFile>..\..\..\..\CoinMP\src\CoinMP.def</ModuleDefinitionFile>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Windows</SubSystem>
++ <RandomizedBaseAddress>true</RandomizedBaseAddress>
++ <DataExecutionPrevention />
++ <TargetMachine>MachineX86</TargetMachine>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <ClCompile>
++ <AdditionalIncludeDirectories>..\..\..\..\Clp\src;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cbc\src;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglLiftAndProject;..\..\..\..\Cgl\src\CglSimpleRounding;..\..\..\..\Clp\src\OsiClp;..\..\..\..\BuildTools\headers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;COINMP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
++ </ClCompile>
++ <Link>
++ <ModuleDefinitionFile>..\..\..\src\CoinMP.def</ModuleDefinitionFile>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Windows</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ <RandomizedBaseAddress>true</RandomizedBaseAddress>
++ <DataExecutionPrevention />
++ <TargetMachine>MachineX86</TargetMachine>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\Clp\src;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cbc\src;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglLiftAndProject;..\..\..\..\Cgl\src\CglSimpleRounding;..\..\..\..\Clp\src\OsiClp;..\..\..\..\BuildTools\headers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;COINMP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
++ </ClCompile>
++ <Link>
++ <ModuleDefinitionFile>..\..\..\..\CoinMP\src\CoinMP.def</ModuleDefinitionFile>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Windows</SubSystem>
++ <RandomizedBaseAddress>true</RandomizedBaseAddress>
++ <DataExecutionPrevention />
++ <TargetMachine>MachineX64</TargetMachine>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <AdditionalIncludeDirectories>..\..\..\..\Clp\src;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Cbc\src;..\..\..\..\Cgl\src;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglLiftAndProject;..\..\..\..\Cgl\src\CglSimpleRounding;..\..\..\..\Clp\src\OsiClp;..\..\..\..\BuildTools\headers;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;COINMP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
++ </ClCompile>
++ <Link>
++ <ModuleDefinitionFile>..\..\..\src\CoinMP.def</ModuleDefinitionFile>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Windows</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ <RandomizedBaseAddress>true</RandomizedBaseAddress>
++ <DataExecutionPrevention />
++ <TargetMachine>MachineX64</TargetMachine>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemGroup>
++ <ClCompile Include="..\..\..\src\CoinCbc.cpp" />
++ <ClCompile Include="..\..\..\src\CoinMP.cpp" />
++ <ClCompile Include="..\..\..\src\CoinOption.c" />
++ <ClCompile Include="..\..\..\src\CoinProblem.c" />
++ <ClCompile Include="..\..\..\src\CoinResult.c" />
++ <ClCompile Include="..\..\..\src\CoinSolver.c" />
++ </ItemGroup>
++ <ItemGroup>
++ <None Include="..\..\..\src\CoinMP.def" />
++ </ItemGroup>
++ <ItemGroup>
++ <ClInclude Include="..\..\..\..\Cbc\src\CbcSolver.hpp" />
++ <ClInclude Include="..\..\..\src\CoinCbc.h" />
++ <ClInclude Include="..\..\..\src\CoinMP.h" />
++ <ClInclude Include="..\..\..\src\CoinOption.h" />
++ <ClInclude Include="..\..\..\src\CoinProblem.h" />
++ <ClInclude Include="..\..\..\src\CoinResult.h" />
++ <ClInclude Include="..\..\..\src\CoinSolver.h" />
++ <ClInclude Include="resource.h" />
++ </ItemGroup>
++ <ItemGroup>
++ <ResourceCompile Include="CoinMP.rc" />
++ </ItemGroup>
++ <ItemGroup>
++ <ProjectReference Include="..\..\..\..\Cbc\MSVisualStudio\v9\libCbcSolver\libCbcSolver.vcxproj">
++ <Project>{71da4595-e8a7-4b21-a00a-d96d29d11e3e}</Project>
++ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
++ </ProjectReference>
++ <ProjectReference Include="..\..\..\..\Cbc\MSVisualStudio\v9\libCbc\libCbc.vcxproj">
++ <Project>{363ba154-fec9-4e1e-bc23-93cec58ab785}</Project>
++ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
++ </ProjectReference>
++ <ProjectReference Include="..\..\..\..\Cgl\MSVisualStudio\v9\libCgl\libCgl.vcxproj">
++ <Project>{dbea3904-f0b8-408a-9e1a-6497febe8c42}</Project>
++ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
++ </ProjectReference>
++ <ProjectReference Include="..\..\..\..\Clp\MSVisualStudio\v9\libClp\libClp.vcxproj">
++ <Project>{4f8f7d1c-3a9e-444d-8ee9-77f33fa05994}</Project>
++ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
++ </ProjectReference>
++ <ProjectReference Include="..\..\..\..\Clp\MSVisualStudio\v9\libOsiClp\libOsiClp.vcxproj">
++ <Project>{02d45875-a8cf-41b9-990b-3699c0ecfe10}</Project>
++ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
++ </ProjectReference>
++ <ProjectReference Include="..\..\..\..\CoinUtils\MSVisualStudio\v9\libCoinUtils\libCoinUtils.vcxproj">
++ <Project>{c4867f15-438d-4ff8-8388-62fbaaa9786c}</Project>
++ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
++ </ProjectReference>
++ <ProjectReference Include="..\..\..\..\Osi\MSVisualStudio\v9\libOsi\libOsi.vcxproj">
++ <Project>{7d98e2cb-876e-4f75-9f71-77d3fe87e149}</Project>
++ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
++ </ProjectReference>
++ </ItemGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
++ <ImportGroup Label="ExtensionTargets">
++ </ImportGroup>
++</Project>
+\ No newline at end of file
+diff -urN coinmp.org/CoinMP/MSVisualStudio/v9/CoinMP.sln coinmp/CoinMP/MSVisualStudio/v9/CoinMP.sln
+--- coinmp.org/CoinMP/MSVisualStudio/v9/CoinMP.sln 2014-02-28 15:32:23.168600537 +0100
++++ coinmp/CoinMP/MSVisualStudio/v9/CoinMP.sln 2014-02-28 15:32:36.580600695 +0100
+@@ -1,35 +1,23 @@
+ 
+-Microsoft Visual Studio Solution File, Format Version 10.00
+-# Visual Studio 2008
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libClp", "..\..\..\Clp\MSVisualStudio\v9\libClp\libClp.vcproj", "{4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}"
++Microsoft Visual Studio Solution File, Format Version 12.00
++# Visual Studio Express 2012 for Windows Desktop
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libClp", "..\..\..\Clp\MSVisualStudio\v9\libClp\libClp.vcxproj", "{4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCoinUtils", "..\..\..\CoinUtils\MSVisualStudio\v9\libCoinUtils\libCoinUtils.vcproj", "{C4867F15-438D-4FF8-8388-62FBAAA9786C}"
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCoinUtils", "..\..\..\CoinUtils\MSVisualStudio\v9\libCoinUtils\libCoinUtils.vcxproj", "{C4867F15-438D-4FF8-8388-62FBAAA9786C}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCgl", "..\..\..\Cgl\MSVisualStudio\v9\libCgl\libCgl.vcproj", "{DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}"
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCgl", "..\..\..\Cgl\MSVisualStudio\v9\libCgl\libCgl.vcxproj", "{DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCbc", "..\..\..\Cbc\MSVisualStudio\v9\libCbc\libCbc.vcproj", "{363BA154-FEC9-4E1E-BC23-93CEC58AB785}"
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCbc", "..\..\..\Cbc\MSVisualStudio\v9\libCbc\libCbc.vcxproj", "{363BA154-FEC9-4E1E-BC23-93CEC58AB785}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsi", "..\..\..\Osi\MSVisualStudio\v9\libOsi\libOsi.vcproj", "{7D98E2CB-876E-4F75-9F71-77D3FE87E149}"
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsi", "..\..\..\Osi\MSVisualStudio\v9\libOsi\libOsi.vcxproj", "{7D98E2CB-876E-4F75-9F71-77D3FE87E149}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsiClp", "..\..\..\Clp\MSVisualStudio\v9\libOsiClp\libOsiClp.vcproj", "{02D45875-A8CF-41B9-990B-3699C0ECFE10}"
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsiClp", "..\..\..\Clp\MSVisualStudio\v9\libOsiClp\libOsiClp.vcxproj", "{02D45875-A8CF-41B9-990B-3699C0ECFE10}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoinMP", "CoinMP\CoinMP.vcproj", "{175F0674-F0B9-479C-9C9D-76969C06D794}"
+- ProjectSection(ProjectDependencies) = postProject
+- {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42} = {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}
+- {C4867F15-438D-4FF8-8388-62FBAAA9786C} = {C4867F15-438D-4FF8-8388-62FBAAA9786C}
+- {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994} = {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}
+- {363BA154-FEC9-4E1E-BC23-93CEC58AB785} = {363BA154-FEC9-4E1E-BC23-93CEC58AB785}
+- {02D45875-A8CF-41B9-990B-3699C0ECFE10} = {02D45875-A8CF-41B9-990B-3699C0ECFE10}
+- {71DA4595-E8A7-4B21-A00A-D96D29D11E3E} = {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}
+- {7D98E2CB-876E-4F75-9F71-77D3FE87E149} = {7D98E2CB-876E-4F75-9F71-77D3FE87E149}
+- EndProjectSection
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoinMP", "CoinMP\CoinMP.vcxproj", "{175F0674-F0B9-479C-9C9D-76969C06D794}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unitTest", "unitTest\unitTest.vcproj", "{9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}"
+- ProjectSection(ProjectDependencies) = postProject
+- {175F0674-F0B9-479C-9C9D-76969C06D794} = {175F0674-F0B9-479C-9C9D-76969C06D794}
+- EndProjectSection
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unitTest", "unitTest\unitTest.vcxproj", "{9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCbcSolver", "..\..\..\Cbc\MSVisualStudio\v9\libCbcSolver\libCbcSolver.vcproj", "{71DA4595-E8A7-4B21-A00A-D96D29D11E3E}"
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCbcSolver", "..\..\..\Cbc\MSVisualStudio\v9\libCbcSolver\libCbcSolver.vcxproj", "{71DA4595-E8A7-4B21-A00A-D96D29D11E3E}"
+ EndProject
+ Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+@@ -121,6 +123,7 @@
+ {175F0674-F0B9-479C-9C9D-76969C06D794}.Debug|Win32.ActiveCfg = Debug|Win32
+ {175F0674-F0B9-479C-9C9D-76969C06D794}.Debug|Win32.Build.0 = Debug|Win32
+ {175F0674-F0B9-479C-9C9D-76969C06D794}.Debug|x64.ActiveCfg = Debug|x64
++ {175F0674-F0B9-479C-9C9D-76969C06D794}.Debug|x64.Build.0 = Debug|x64
+ {175F0674-F0B9-479C-9C9D-76969C06D794}.Release|Any CPU.ActiveCfg = Release|Win32
+ {175F0674-F0B9-479C-9C9D-76969C06D794}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {175F0674-F0B9-479C-9C9D-76969C06D794}.Release|Mixed Platforms.Build.0 = Release|Win32
+@@ -134,6 +137,7 @@
+ {9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}.Debug|Win32.Build.0 = Debug|Win32
+ {9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}.Debug|x64.ActiveCfg = Debug|x64
++ {9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}.Debug|x64.Build.0 = Debug|x64
+ {9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}.Release|Any CPU.ActiveCfg = Release|Win32
+ {9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}.Release|Mixed Platforms.Build.0 = Release|Win32
+diff -urN coinmp.org/CoinMP/MSVisualStudio/v9/unitTest/unitTest.vcxproj coinmp/CoinMP/MSVisualStudio/v9/unitTest/unitTest.vcxproj
+--- coinmp.org/CoinMP/MSVisualStudio/v9/unitTest/unitTest.vcxproj 1970-01-01 01:00:00.000000000 +0100
++++ coinmp/CoinMP/MSVisualStudio/v9/unitTest/unitTest.vcxproj 2014-02-28 15:32:36.564600694 +0100
+@@ -0,0 +1,188 @@
++<?xml version="1.0" encoding="utf-8"?>
++<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
++ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|Win32">
++ <Configuration>Debug</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|x64">
++ <Configuration>Debug</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|Win32">
++ <Configuration>Release</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|x64">
++ <Configuration>Release</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ </ItemGroup>
++ <PropertyGroup Label="Globals">
++ <ProjectGuid>{9F2D36EA-6D9E-42CB-A648-BCC0CB3E68E6}</ProjectGuid>
++ <RootNamespace>unitTest</RootNamespace>
++ <Keyword>Win32Proj</Keyword>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <CharacterSet>Unicode</CharacterSet>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
++ <ImportGroup Label="ExtensionSettings">
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ </ImportGroup>
++ <PropertyGroup Label="UserMacros" />
++ <PropertyGroup>
++ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ <LinkIncremental>true</LinkIncremental>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ <LinkIncremental>true</LinkIncremental>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ </PropertyGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\CoinMP\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
++ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <RandomizedBaseAddress>true</RandomizedBaseAddress>
++ <DataExecutionPrevention />
++ <TargetMachine>MachineX86</TargetMachine>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <ClCompile>
++ <AdditionalIncludeDirectories>..\..\..\..\CoinMP\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ <RandomizedBaseAddress>true</RandomizedBaseAddress>
++ <DataExecutionPrevention />
++ <TargetMachine>MachineX86</TargetMachine>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\CoinMP\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <RandomizedBaseAddress>true</RandomizedBaseAddress>
++ <DataExecutionPrevention />
++ <TargetMachine>MachineX64</TargetMachine>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <AdditionalIncludeDirectories>..\..\..\..\CoinMP\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ <RandomizedBaseAddress>true</RandomizedBaseAddress>
++ <DataExecutionPrevention />
++ <TargetMachine>MachineX64</TargetMachine>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemGroup>
++ <ClCompile Include="..\..\..\test\unitTest.cpp" />
++ </ItemGroup>
++ <ItemGroup>
++ <ProjectReference Include="..\CoinMP\CoinMP.vcxproj">
++ <Project>{175f0674-f0b9-479c-9c9d-76969c06d794}</Project>
++ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
++ </ProjectReference>
++ </ItemGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
++ <ImportGroup Label="ExtensionTargets">
++ </ImportGroup>
++</Project>
+\ No newline at end of file
+diff -urN coinmp.org/CoinUtils/MSVisualStudio/v9/libCoinUtils/libCoinUtils.vcxproj coinmp/CoinUtils/MSVisualStudio/v9/libCoinUtils/libCoinUtils.vcxproj
+--- coinmp.org/CoinUtils/MSVisualStudio/v9/libCoinUtils/libCoinUtils.vcxproj 1970-01-01 01:00:00.000000000 +0100
++++ coinmp/CoinUtils/MSVisualStudio/v9/libCoinUtils/libCoinUtils.vcxproj 2014-02-28 15:32:36.564600694 +0100
+@@ -0,0 +1,650 @@
++<?xml version="1.0" encoding="utf-8"?>
++<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
++ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|Win32">
++ <Configuration>Debug</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|x64">
++ <Configuration>Debug</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|Win32">
++ <Configuration>Release</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|x64">
++ <Configuration>Release</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ </ItemGroup>
++ <PropertyGroup Label="Globals">
++ <ProjectGuid>{C4867F15-438D-4FF8-8388-62FBAAA9786C}</ProjectGuid>
++ <RootNamespace>libCoinUtils</RootNamespace>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
++ <ImportGroup Label="ExtensionSettings">
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <PropertyGroup Label="UserMacros" />
++ <PropertyGroup>
++ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemGroup>
++ <ClCompile Include="..\..\..\src\CoinAlloc.cpp" />
++ <ClCompile Include="..\..\..\src\CoinBuild.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinDenseFactorization.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinDenseVector.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinError.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinFactorization1.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinFactorization2.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinFactorization3.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinFactorization4.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinFileIO.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinFinite.cpp" />
++ <ClCompile Include="..\..\..\src\CoinIndexedVector.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinLpIO.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinMessage.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinMessageHandler.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinModel.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinModelUseful.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinModelUseful2.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinMpsIO.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinOslFactorization.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinOslFactorization2.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinOslFactorization3.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPackedMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPackedVector.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPackedVectorBase.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinParam.cpp" />
++ <ClCompile Include="..\..\..\src\CoinParamUtils.cpp" />
++ <ClCompile Include="..\..\..\src\CoinPostsolveMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPrePostsolveMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveDoubleton.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveDual.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveDupcol.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveEmpty.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveFixed.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveForcing.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveHelperFunctions.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveImpliedFree.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveIsolated.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveMatrix.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolvePsdebug.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveSingleton.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveSubst.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveTighten.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveTripleton.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveUseless.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinPresolveZeros.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinSearchTree.cpp" />
++ <ClCompile Include="..\..\..\src\CoinShallowPackedVector.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinSimpFactorization.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinSnapshot.cpp" />
++ <ClCompile Include="..\..\..\src\CoinStructuredModel.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinWarmStartBasis.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinWarmStartDual.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinWarmStartPrimalDual.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ <ClCompile Include="..\..\..\src\CoinWarmStartVector.cpp">
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
++ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
++ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
++ </ClCompile>
++ </ItemGroup>
++ <ItemGroup>
++ <ClInclude Include="..\..\..\src\Coin_C_defines.h" />
++ <ClInclude Include="..\..\..\src\CoinAlloc.hpp" />
++ <ClInclude Include="..\..\..\src\CoinBuild.hpp" />
++ <ClInclude Include="..\..\..\src\CoinDenseFactorization.hpp" />
++ <ClInclude Include="..\..\..\src\CoinDenseVector.hpp" />
++ <ClInclude Include="..\..\..\src\CoinDistance.hpp" />
++ <ClInclude Include="..\..\..\src\CoinError.hpp" />
++ <ClInclude Include="..\..\..\src\CoinFactorization.hpp" />
++ <ClInclude Include="..\..\..\src\CoinFileIO.hpp" />
++ <ClInclude Include="..\..\..\src\CoinFinite.hpp" />
++ <ClInclude Include="..\..\..\src\CoinFloatEqual.hpp" />
++ <ClInclude Include="..\..\..\src\CoinHelperFunctions.hpp" />
++ <ClInclude Include="..\..\..\src\CoinIndexedVector.hpp" />
++ <ClInclude Include="..\..\..\src\CoinLpIO.hpp" />
++ <ClInclude Include="..\..\..\src\CoinMessage.hpp" />
++ <ClInclude Include="..\..\..\src\CoinMessageHandler.hpp" />
++ <ClInclude Include="..\..\..\src\CoinModel.hpp" />
++ <ClInclude Include="..\..\..\src\CoinModelUseful.hpp" />
++ <ClInclude Include="..\..\..\src\CoinMpsIO.hpp" />
++ <ClInclude Include="..\..\..\src\CoinOslC.h" />
++ <ClInclude Include="..\..\..\src\CoinOslFactorization.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPackedMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPackedVector.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPackedVectorBase.hpp" />
++ <ClInclude Include="..\..\..\src\CoinParam.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPragma.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveDoubleton.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveDual.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveDupcol.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveEmpty.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveFixed.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveForcing.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveImpliedFree.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveIsolated.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveMatrix.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolvePsdebug.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveSingleton.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveSubst.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveTighten.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveTripleton.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveUseless.hpp" />
++ <ClInclude Include="..\..\..\src\CoinPresolveZeros.hpp" />
++ <ClInclude Include="..\..\..\src\CoinSearchTree.hpp" />
++ <ClInclude Include="..\..\..\src\CoinShallowPackedVector.hpp" />
++ <ClInclude Include="..\..\..\src\CoinSimpFactorization.hpp" />
++ <ClInclude Include="..\..\..\src\CoinSort.hpp" />
++ <ClInclude Include="..\..\..\src\CoinStructuredModel.hpp" />
++ <ClInclude Include="..\..\..\src\CoinTime.hpp" />
++ <ClInclude Include="..\..\..\src\CoinTypes.hpp" />
++ <ClInclude Include="..\..\..\src\CoinUtilsAutomake.hpp" />
++ <ClInclude Include="..\..\..\src\CoinUtilsConfig.h" />
++ <ClInclude Include="..\..\..\src\CoinWarmStart.hpp" />
++ <ClInclude Include="..\..\..\src\CoinWarmStartBasis.hpp" />
++ <ClInclude Include="..\..\..\src\CoinWarmStartDual.hpp" />
++ <ClInclude Include="..\..\..\src\CoinWarmStartPrimalDual.hpp" />
++ <ClInclude Include="..\..\..\src\CoinWarmStartVector.hpp" />
++ <ClInclude Include="..\..\..\..\BuildTools\headers\configall_system.h" />
++ <ClInclude Include="..\..\..\..\BuildTools\headers\configall_system_msc.h" />
++ </ItemGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
++ <ImportGroup Label="ExtensionTargets">
++ </ImportGroup>
++</Project>
+\ No newline at end of file
+diff -urN coinmp.org/Osi/MSVisualStudio/v9/libOsi/libOsi.vcxproj coinmp/Osi/MSVisualStudio/v9/libOsi/libOsi.vcxproj
+--- coinmp.org/Osi/MSVisualStudio/v9/libOsi/libOsi.vcxproj 1970-01-01 01:00:00.000000000 +0100
++++ coinmp/Osi/MSVisualStudio/v9/libOsi/libOsi.vcxproj 2014-02-28 15:32:36.568600695 +0100
+@@ -0,0 +1,220 @@
++<?xml version="1.0" encoding="utf-8"?>
++<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
++ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|Win32">
++ <Configuration>Debug</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|x64">
++ <Configuration>Debug</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|Win32">
++ <Configuration>Release</Configuration>
++ <Platform>Win32</Platform>
++ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|x64">
++ <Configuration>Release</Configuration>
++ <Platform>x64</Platform>
++ </ProjectConfiguration>
++ </ItemGroup>
++ <PropertyGroup Label="Globals">
++ <ProjectGuid>{7D98E2CB-876E-4F75-9F71-77D3FE87E149}</ProjectGuid>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <PlatformToolset>v110</PlatformToolset>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
++ <ImportGroup Label="ExtensionSettings">
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
++ </ImportGroup>
++ <PropertyGroup Label="UserMacros" />
++ <PropertyGroup>
++ <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
++ <IntDir>$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
++ <IntDir>$(Platform)\$(Configuration)\</IntDir>
++ </PropertyGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\Osi\src\Osi;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>..\..\..\..\Osi\src\Osi;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <MinimalRebuild>true</MinimalRebuild>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\Osi\src\Osi;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
++ <Midl>
++ <TargetEnvironment>X64</TargetEnvironment>
++ </Midl>
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <AdditionalIncludeDirectories>..\..\..\..\Osi\src\Osi;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\inc;..\..\..\..\CoinUtils\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <StringPooling>true</StringPooling>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <PrecompiledHeader />
++ <WarningLevel>Level3</WarningLevel>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ <ResourceCompile>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <Culture>0x0409</Culture>
++ </ResourceCompile>
++ <Lib>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ </Lib>
++ </ItemDefinitionGroup>
++ <ItemGroup>
++ <ClCompile Include="..\..\..\src\Osi\OsiAuxInfo.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiBranchingObject.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiChooseVariable.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiColCut.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiCut.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiCuts.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiNames.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiPresolve.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiRowCut.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiRowCutDebugger.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiSolverBranch.cpp" />
++ <ClCompile Include="..\..\..\src\Osi\OsiSolverInterface.cpp" />
++ </ItemGroup>
++ <ItemGroup>
++ <ClInclude Include="..\..\..\src\OsiAuxInfo.hpp" />
++ <ClInclude Include="..\..\..\src\OsiBranchingObject.hpp" />
++ <ClInclude Include="..\..\..\src\OsiChooseVariable.hpp" />
++ <ClInclude Include="..\..\..\src\OsiColCut.hpp" />
++ <ClInclude Include="..\..\..\src\OsiCollections.hpp" />
++ <ClInclude Include="..\..\..\src\OsiConfig.h" />
++ <ClInclude Include="..\..\..\src\OsiCut.hpp" />
++ <ClInclude Include="..\..\..\src\OsiCuts.hpp" />
++ <ClInclude Include="..\..\..\src\OsiOpbdpSolve.hpp" />
++ <ClInclude Include="..\..\..\src\OsiPresolve.hpp" />
++ <ClInclude Include="..\..\..\src\OsiRowCut.hpp" />
++ <ClInclude Include="..\..\..\src\OsiRowCutDebugger.hpp" />
++ <ClInclude Include="..\..\..\src\OsiSolverBranch.hpp" />
++ <ClInclude Include="..\..\..\src\OsiSolverInterface.hpp" />
++ <ClInclude Include="..\..\..\src\OsiSolverParameters.hpp" />
++ </ItemGroup>
++ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
++ <ImportGroup Label="ExtensionTargets">
++ </ImportGroup>
++</Project>
+\ No newline at end of file
diff --git a/external/cppunit/CPPUNIT_PLUGIN_EXPORT.patch.0 b/external/cppunit/CPPUNIT_PLUGIN_EXPORT.patch.0
new file mode 100644
index 000000000..a764be95a
--- /dev/null
+++ b/external/cppunit/CPPUNIT_PLUGIN_EXPORT.patch.0
@@ -0,0 +1,11 @@
+--- include/cppunit/plugin/TestPlugIn.h
++++ include/cppunit/plugin/TestPlugIn.h
+@@ -111,7 +111,7 @@
+ /*! \brief Type of the function exported by a plug-in.
+ * \ingroup WritingTestPlugIn
+ */
+-typedef CppUnitTestPlugIn *(*TestPlugInSignature)();
++extern "C" { typedef CppUnitTestPlugIn *(*TestPlugInSignature)(); }
+
+
+ /*! \brief Implements the function exported by the test plug-in
diff --git a/external/cppunit/ExternalProject_cppunit.mk b/external/cppunit/ExternalProject_cppunit.mk
new file mode 100644
index 000000000..f0b4ff06a
--- /dev/null
+++ b/external/cppunit/ExternalProject_cppunit.mk
@@ -0,0 +1,62 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,cppunit))
+
+$(eval $(call gb_ExternalProject_register_targets,cppunit,\
+ build \
+))
+
+ifeq ($(OS),WNT)
+$(call gb_ExternalProject_get_state_target,cppunit,build) :
+ $(call gb_Trace_StartRange,cppunit,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ PROFILEFLAGS="$(gb_MSBUILD_CONFIG) \
+ /p:Platform=$(gb_MSBUILD_PLATFORM) \
+ /p:PlatformToolset=$(VCTOOLSET) /p:VisualStudioVersion=$(VCVER) /ToolsVersion:Current \
+ $(if $(filter 10,$(WINDOWS_SDK_VERSION)),/p:WindowsTargetPlatformVersion=$(UCRTVERSION))" \
+ && msbuild.exe cppunit_dll.vcxproj /p:Configuration=$${PROFILEFLAGS} \
+ && cd ../DllPlugInTester \
+ && msbuild.exe DllPlugInTester.vcxproj /p:Configuration=$${PROFILEFLAGS} \
+ ,src/cppunit)
+ $(call gb_Trace_EndRange,cppunit,EXTERNAL)
+else
+
+cppunit_CXXFLAGS=$(CXXFLAGS) $(gb_EMSCRIPTEN_CXXFLAGS)
+
+cppunit_CXXFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG)
+
+ifneq (,$(call gb_LinkTarget__symbols_enabled,cppunit))
+cppunit_CXXFLAGS+=-g
+endif
+
+$(call gb_ExternalProject_get_state_target,cppunit,build) :
+ $(call gb_Trace_StartRange,cppunit,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure \
+ --disable-dependency-tracking \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),--disable-shared,--disable-static) \
+ --disable-doxygen \
+ --disable-html-docs \
+ --disable-latex-docs \
+ --disable-werror \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________NONE) \
+ $(if $(filter WNT,$(OS)),LDFLAGS="-Wl$(COMMA)--enable-runtime-pseudo-reloc-v2") \
+ $(if $(filter SOLARIS,$(OS)),LIBS="-lm") \
+ $(if $(filter ANDROID,$(OS)),LIBS="$(gb_STDLIBS)") \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(cppunit_CXXFLAGS)" \
+ && cd src \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,cppunit,EXTERNAL)
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cppunit/Makefile b/external/cppunit/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/cppunit/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cppunit/Module_cppunit.mk b/external/cppunit/Module_cppunit.mk
new file mode 100644
index 000000000..296feeb74
--- /dev/null
+++ b/external/cppunit/Module_cppunit.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,cppunit))
+
+$(eval $(call gb_Module_add_targets,cppunit,\
+ UnpackedTarball_cppunit \
+ ExternalProject_cppunit \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cppunit/README b/external/cppunit/README
new file mode 100644
index 000000000..e1d4e82a5
--- /dev/null
+++ b/external/cppunit/README
@@ -0,0 +1,3 @@
+C++ port of the JUnit framework for unit testing.
+
+From [http://www.freedesktop.org/wiki/Software/cppunit/]
diff --git a/external/cppunit/UnpackedTarball_cppunit.mk b/external/cppunit/UnpackedTarball_cppunit.mk
new file mode 100644
index 000000000..5dc750bbd
--- /dev/null
+++ b/external/cppunit/UnpackedTarball_cppunit.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,cppunit))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,cppunit,$(CPPUNIT_TARBALL),,cppunit))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,cppunit))
+
+# * external/cppunit/order.patch.0 upstreamed at <https://gerrit.libreoffice.org/c/cppunit/+/123963>
+# "Run tests in deterministic order":
+$(eval $(call gb_UnpackedTarball_add_patches,cppunit,\
+ external/cppunit/windows.patch \
+ external/cppunit/unix.patch \
+ external/cppunit/CPPUNIT_PLUGIN_EXPORT.patch.0 \
+ external/cppunit/enable-win32-debug.patch \
+ external/cppunit/rtti.patch.0 \
+ external/cppunit/order.patch.0 \
+ external/cppunit/windows-arm64.patch.1 \
+))
+ifeq ($(DISABLE_DYNLOADING),TRUE)
+$(eval $(call gb_UnpackedTarball_add_patches,cppunit,\
+ external/cppunit/disable-dynloading.patch \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/cppunit/disable-dynloading.patch b/external/cppunit/disable-dynloading.patch
new file mode 100644
index 000000000..62ed1deeb
--- /dev/null
+++ b/external/cppunit/disable-dynloading.patch
@@ -0,0 +1,25 @@
+--- build/cppunit-1.13.1/include/cppunit/plugin/TestPlugIn.h
++++ misc/build/cppunit-1.13.1/include/cppunit/plugin/TestPlugIn.h
+@@ -106,7 +106,9 @@
+ * CppUnitTestPlugIn *CPPUNIT_PLUGIN_EXPORTED_NAME(void);
+ * \endcode
+ */
++#ifndef CPPUNIT_PLUGIN_EXPORTED_NAME
+ #define CPPUNIT_PLUGIN_EXPORTED_NAME cppunitTestPlugIn
++#endif
+
+ /*! \brief Type of the function exported by a plug-in.
+ * \ingroup WritingTestPlugIn
+@@ -143,6 +143,12 @@
+ #define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() \
+ typedef char __CppUnitPlugInImplementMainDummyTypeDef
+
++// Actually this is for iOS and Android where we build the cppunit tests libraries
++// as plain archives and just link them statically into test fixture programs,
++// and don't want any stinking duplicate main(), but shouldn't hurt for MacOSX either.
++#elif defined(__APPLE__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__)
++#define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() \
++ typedef char __CppUnitPlugInImplementMainDummyTypeDef
+ // Unix
+ #elif defined(CPPUNIT_HAVE_UNIX_DLL_LOADER) || defined(CPPUNIT_HAVE_UNIX_SHL_LOADER)
+ #define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() \
diff --git a/external/cppunit/enable-win32-debug.patch b/external/cppunit/enable-win32-debug.patch
new file mode 100644
index 000000000..2c7f4f956
--- /dev/null
+++ b/external/cppunit/enable-win32-debug.patch
@@ -0,0 +1,34 @@
+--- misc/cppunit-1.14.0/src/cppunit/cppunit_dll.vcxproj
++++ misc/build/cppunit-1.14.0/src/cppunit/cppunit_dll.vcxproj
+@@ -190,7 +190,6 @@
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>
+- <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CPPUNIT_BUILD_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AssemblerListingLocation>.\ReleaseDll\</AssemblerListingLocation>
+@@ -222,6 +221,7 @@
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OutputFile>.\ReleaseDll\cppunit_dll.dll</OutputFile>
+ <ImportLibrary>.\ReleaseDll\cppunit_dll.lib</ImportLibrary>
+@@ -237,7 +237,6 @@
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>
+- <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CPPUNIT_BUILD_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AssemblerListingLocation>.\ReleaseDll\</AssemblerListingLocation>
+@@ -266,6 +266,7 @@
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OutputFile>.\ReleaseDll\cppunit_dll.dll</OutputFile>
+ <ImportLibrary>.\ReleaseDll\cppunit_dll.lib</ImportLibrary>
diff --git a/external/cppunit/order.patch.0 b/external/cppunit/order.patch.0
new file mode 100644
index 000000000..523b3cd70
--- /dev/null
+++ b/external/cppunit/order.patch.0
@@ -0,0 +1,25 @@
+--- src/cppunit/TestFactoryRegistry.cpp
++++ src/cppunit/TestFactoryRegistry.cpp
+@@ -143,13 +143,21 @@
+ void
+ TestFactoryRegistry::addTestToSuite( TestSuite *suite )
+ {
++ std::multimap<std::string, Test *> sorted;
+ for ( Factories::iterator it = m_factories.begin();
+ it != m_factories.end();
+ ++it )
+ {
+ TestFactory *factory = *it;
+- suite->addTest( factory->makeTest() );
++ Test *test = factory->makeTest();
++ sorted.insert({test->getName(), test});
+ }
++ // In the unlikely case of multiple Tests with identical names, those will
++ // still be added in random order:
++ for (auto const &i: sorted)
++ {
++ suite->addTest( i.second );
++ }
+ }
+
+
diff --git a/external/cppunit/rtti.patch.0 b/external/cppunit/rtti.patch.0
new file mode 100644
index 000000000..38d2e6a90
--- /dev/null
+++ b/external/cppunit/rtti.patch.0
@@ -0,0 +1,15 @@
+--- include/cppunit/config/CppUnitApi.h
++++ include/cppunit/config/CppUnitApi.h
+@@ -20,6 +20,12 @@
+ #define CPPUNIT_NEED_DLL_DECL 1
+ #endif
+
++#elif defined __GNUC__ //TODO: actually only works for modern enough GCC
++
++#define CPPUNIT_API __attribute__ ((visibility("default")))
++#undef CPPUNIT_NEED_DLL_DECL
++#define CPPUNIT_NEED_DLL_DECL 0
++
+ #endif
+
+
diff --git a/external/cppunit/unix.patch b/external/cppunit/unix.patch
new file mode 100644
index 000000000..e75e72c6f
--- /dev/null
+++ b/external/cppunit/unix.patch
@@ -0,0 +1,10 @@
+--- misc/cppunit-1.13.1/src/cppunit/UnixDynamicLibraryManager.cpp
++++ misc/build/cppunit-1.13.1/src/cppunit/UnixDynamicLibraryManager.cpp
+@@ -20,7 +20,6 @@
+ void
+ DynamicLibraryManager::doReleaseLibrary()
+ {
+- ::dlclose( m_libraryHandle);
+ }
+
+
diff --git a/external/cppunit/windows-arm64.patch.1 b/external/cppunit/windows-arm64.patch.1
new file mode 100644
index 000000000..0e41fa005
--- /dev/null
+++ b/external/cppunit/windows-arm64.patch.1
@@ -0,0 +1,786 @@
+diff -ur cppunit-1.15.1.orig/src/cppunit/cppunit_dll.vcxproj cppunit-1.15.1/src/cppunit/cppunit_dll.vcxproj
+--- cppunit-1.15.1.orig/src/cppunit/cppunit_dll.vcxproj 2019-11-28 20:35:43.000000000 +0100
++++ cppunit-1.15.1/src/cppunit/cppunit_dll.vcxproj 2020-08-03 03:04:20.181281900 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -34,6 +42,11 @@
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+@@ -44,6 +57,11 @@
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -55,6 +73,10 @@
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+@@ -63,6 +85,10 @@
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>.\DebugDll\</OutDir>
+@@ -76,6 +102,12 @@
+ <LinkIncremental>true</LinkIncremental>
+ <TargetName>cppunitd_dll</TargetName>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <OutDir>.\DebugDll\</OutDir>
++ <IntDir>.\DebugDll\</IntDir>
++ <LinkIncremental>true</LinkIncremental>
++ <TargetName>cppunitd_dll</TargetName>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>.\ReleaseDll\</OutDir>
+ <IntDir>.\ReleaseDll\</IntDir>
+@@ -86,6 +116,11 @@
+ <IntDir>.\ReleaseDll\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <OutDir>.\ReleaseDll\</OutDir>
++ <IntDir>.\ReleaseDll\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+@@ -180,6 +213,52 @@
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
++ <FunctionLevelLinking>false</FunctionLevelLinking>
++ <Optimization>Disabled</Optimization>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <WarningLevel>Level3</WarningLevel>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CPPUNIT_BUILD_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <AssemblerListingLocation>.\DebugDll\</AssemblerListingLocation>
++ <PrecompiledHeaderOutputFile>.\DebugDll\cppunit_dll.pch</PrecompiledHeaderOutputFile>
++ <ObjectFileName>.\DebugDll\</ObjectFileName>
++ <ProgramDataBaseFileName>.\DebugDll\</ProgramDataBaseFileName>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ </ClCompile>
++ <PostBuildEvent>
++ <Command>copy "$(TargetPath)" ..\..\lib\$(TargetName).dll
++copy "$(TargetDir)$(TargetName).lib" ..\..\lib\$(TargetName).lib</Command>
++ <Message>Copying target to lib/</Message>
++ </PostBuildEvent>
++ <Midl>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <TypeLibraryName>.\DebugDll\cppunit_dll.tlb</TypeLibraryName>
++ <MkTypLibCompatible>true</MkTypLibCompatible>
++ </Midl>
++ <ResourceCompile>
++ <Culture>0x040c</Culture>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ </ResourceCompile>
++ <Bscmake>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <OutputFile>.\DebugDll\cppunit_dll.bsc</OutputFile>
++ </Bscmake>
++ <Link>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <LinkDLL>true</LinkDLL>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OutputFile>DebugDll\cppunitd_dll.dll</OutputFile>
++ <ImportLibrary>.\DebugDll\cppunitd_dll.lib</ImportLibrary>
++ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+@@ -267,6 +345,52 @@
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OutputFile>.\ReleaseDll\cppunit_dll.dll</OutputFile>
++ <ImportLibrary>.\ReleaseDll\cppunit_dll.lib</ImportLibrary>
++ <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <StringPooling>true</StringPooling>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <Optimization>MaxSpeed</Optimization>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <WarningLevel>Level3</WarningLevel>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CPPUNIT_BUILD_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <AssemblerListingLocation>.\ReleaseDll\</AssemblerListingLocation>
++ <PrecompiledHeaderOutputFile>.\ReleaseDll\cppunit_dll.pch</PrecompiledHeaderOutputFile>
++ <ObjectFileName>.\ReleaseDll\</ObjectFileName>
++ <ProgramDataBaseFileName>.\ReleaseDll\</ProgramDataBaseFileName>
++ </ClCompile>
++ <PostBuildEvent>
++ <Command>copy "$(TargetPath)" ..\..\lib\$(TargetName).dll
++copy "$(TargetDir)$(TargetName).lib" ..\..\lib\$(TargetName).lib</Command>
++ <Message>Copying target to lib/</Message>
++ </PostBuildEvent>
++ <Midl>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <TypeLibraryName>.\ReleaseDll\cppunit_dll.tlb</TypeLibraryName>
++ <MkTypLibCompatible>true</MkTypLibCompatible>
++ </Midl>
++ <ResourceCompile>
++ <Culture>0x040c</Culture>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ </ResourceCompile>
++ <Bscmake>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <OutputFile>.\ReleaseDll\cppunit_dll.bsc</OutputFile>
++ </Bscmake>
++ <Link>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <LinkDLL>true</LinkDLL>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OutputFile>.\ReleaseDll\cppunit_dll.dll</OutputFile>
+ <ImportLibrary>.\ReleaseDll\cppunit_dll.lib</ImportLibrary>
+diff -ur cppunit-1.15.1.orig/src/DllPlugInTester/DllPlugInTester.vcxproj cppunit-1.15.1/src/DllPlugInTester/DllPlugInTester.vcxproj
+--- cppunit-1.15.1.orig/src/DllPlugInTester/DllPlugInTester.vcxproj 2019-11-28 20:35:43.000000000 +0100
++++ cppunit-1.15.1/src/DllPlugInTester/DllPlugInTester.vcxproj 2020-08-03 03:05:06.310642100 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug Static|ARM64">
++ <Configuration>Debug Static</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Static|Win32">
+ <Configuration>Debug Static</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug Static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug Unicode|ARM64">
++ <Configuration>Debug Unicode</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+@@ -17,6 +25,10 @@
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -25,6 +37,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release Static|ARM64">
++ <Configuration>Release Static</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Static|Win32">
+ <Configuration>Release Static</Configuration>
+ <Platform>Win32</Platform>
+@@ -33,6 +49,10 @@
+ <Configuration>Release Static</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release Unicode|ARM64">
++ <Configuration>Release Unicode</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+@@ -41,6 +61,10 @@
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -66,6 +90,11 @@
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+@@ -76,6 +105,11 @@
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+@@ -86,6 +120,11 @@
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+@@ -96,6 +135,11 @@
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+@@ -106,6 +150,11 @@
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+@@ -116,6 +165,11 @@
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <UseOfMfc>false</UseOfMfc>
++ <CharacterSet>MultiByte</CharacterSet>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -127,6 +181,10 @@
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+@@ -135,6 +193,10 @@
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+@@ -143,6 +205,10 @@
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+@@ -151,6 +217,10 @@
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+@@ -159,6 +229,10 @@
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+@@ -167,6 +241,10 @@
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
++ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <OutDir>.\ReleaseUnicode\</OutDir>
+@@ -180,6 +258,12 @@
+ <LinkIncremental>false</LinkIncremental>
+ <TargetName>$(ProjectName)u</TargetName>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|ARM64'">
++ <OutDir>.\Release\</OutDir>
++ <IntDir>.\Release\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ <TargetName>$(ProjectName)u</TargetName>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'">
+ <OutDir>.\Debug\</OutDir>
+ <IntDir>.\Debug\</IntDir>
+@@ -192,6 +274,12 @@
+ <LinkIncremental>false</LinkIncremental>
+ <TargetName>$(ProjectName)d</TargetName>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|ARM64'">
++ <OutDir>.\DebugDll\</OutDir>
++ <IntDir>.\DebugDll\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ <TargetName>$(ProjectName)d</TargetName>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'">
+ <OutDir>.\Release\</OutDir>
+ <IntDir>.\Release\</IntDir>
+@@ -202,6 +288,11 @@
+ <IntDir>.\Release\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|ARM64'">
++ <OutDir>.\Release\</OutDir>
++ <IntDir>.\Release\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>.\DebugDll\</OutDir>
+ <IntDir>.\DebugDll\</IntDir>
+@@ -214,6 +303,12 @@
+ <LinkIncremental>false</LinkIncremental>
+ <TargetName>DllPlugInTesterd_dll</TargetName>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <OutDir>.\DebugDll\</OutDir>
++ <IntDir>.\DebugDll\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ <TargetName>DllPlugInTesterd_dll</TargetName>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>.\ReleaseDll\</OutDir>
+ <IntDir>.\ReleaseDll\</IntDir>
+@@ -226,6 +319,12 @@
+ <LinkIncremental>false</LinkIncremental>
+ <TargetName>$(ProjectName)_dll</TargetName>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <OutDir>.\ReleaseDll\</OutDir>
++ <IntDir>.\ReleaseDll\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ <TargetName>$(ProjectName)_dll</TargetName>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <OutDir>.\DebugUnicode\</OutDir>
+ <IntDir>.\DebugUnicode\</IntDir>
+@@ -238,6 +335,12 @@
+ <LinkIncremental>false</LinkIncremental>
+ <TargetName>$(ProjectName)ud</TargetName>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|ARM64'">
++ <OutDir>.\DebugDll\</OutDir>
++ <IntDir>.\DebugDll\</IntDir>
++ <LinkIncremental>false</LinkIncremental>
++ <TargetName>$(ProjectName)ud</TargetName>
++ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+@@ -324,6 +425,49 @@
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunit.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|ARM64'">
++ <ClCompile>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <StringPooling>true</StringPooling>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <Optimization>MinSpace</Optimization>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <WarningLevel>Level3</WarningLevel>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <DebugInformationFormat>OldStyle</DebugInformationFormat>
++ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <AssemblerListingLocation>.\ReleaseUnicode\</AssemblerListingLocation>
++ <PrecompiledHeaderOutputFile>.\ReleaseUnicode\DllPlugInTester.pch</PrecompiledHeaderOutputFile>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <ObjectFileName>.\ReleaseUnicode\</ObjectFileName>
++ <ProgramDataBaseFileName>.\ReleaseUnicode\</ProgramDataBaseFileName>
++ </ClCompile>
++ <PostBuildEvent>
++ <Command>copy "$(TargetPath)" ..\..\lib\$(TargetName).exe</Command>
++ <Message>Copying target to lib/</Message>
++ </PostBuildEvent>
++ <Midl>
++ <TypeLibraryName>.\ReleaseUnicode\DllPlugInTester.tlb</TypeLibraryName>
++ </Midl>
++ <ResourceCompile>
++ <Culture>0x040c</Culture>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ </ResourceCompile>
++ <Bscmake>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <OutputFile>.\ReleaseUnicode\DllPlugInTester.bsc</OutputFile>
++ </Bscmake>
++ <Link>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <SubSystem>Console</SubSystem>
++ <OutputFile>ReleaseUnicode\DllPlugInTesteru.exe</OutputFile>
++ <AdditionalLibraryDirectories>../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
++ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunit.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+@@ -411,6 +555,49 @@
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunitd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|ARM64'">
++ <ClCompile>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
++ <FunctionLevelLinking>false</FunctionLevelLinking>
++ <Optimization>Disabled</Optimization>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <WarningLevel>Level3</WarningLevel>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <AssemblerListingLocation>.\Debug\</AssemblerListingLocation>
++ <PrecompiledHeaderOutputFile>.\Debug\DllPlugInTester.pch</PrecompiledHeaderOutputFile>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <ObjectFileName>.\Debug\</ObjectFileName>
++ <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ </ClCompile>
++ <PostBuildEvent>
++ <Command>copy $(TargetPath) ..\..\lib\$(TargetName).exe</Command>
++ <Message>Copying target to lib/</Message>
++ </PostBuildEvent>
++ <Midl>
++ <TypeLibraryName>.\Debug\DllPlugInTester.tlb</TypeLibraryName>
++ </Midl>
++ <ResourceCompile>
++ <Culture>0x040c</Culture>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ </ResourceCompile>
++ <Bscmake>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <OutputFile>.\Debug\DllPlugInTester.bsc</OutputFile>
++ </Bscmake>
++ <Link>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OutputFile>Debug\DllPlugInTesterd.exe</OutputFile>
++ <AdditionalLibraryDirectories>../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
++ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunitd.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+@@ -497,6 +684,49 @@
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunit.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|ARM64'">
++ <ClCompile>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <StringPooling>true</StringPooling>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <Optimization>MinSpace</Optimization>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <WarningLevel>Level3</WarningLevel>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <DebugInformationFormat>OldStyle</DebugInformationFormat>
++ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <AssemblerListingLocation>.\Release\</AssemblerListingLocation>
++ <PrecompiledHeaderOutputFile>.\Release\DllPlugInTester.pch</PrecompiledHeaderOutputFile>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <ObjectFileName>.\Release\</ObjectFileName>
++ <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName>
++ </ClCompile>
++ <PostBuildEvent>
++ <Command>copy $(TargetPath) ..\..\lib\$(TargetName).exe</Command>
++ <Message>Copying target to lib/</Message>
++ </PostBuildEvent>
++ <Midl>
++ <TypeLibraryName>.\Release\DllPlugInTester.tlb</TypeLibraryName>
++ </Midl>
++ <ResourceCompile>
++ <Culture>0x040c</Culture>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ </ResourceCompile>
++ <Bscmake>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <OutputFile>.\Release\DllPlugInTester.bsc</OutputFile>
++ </Bscmake>
++ <Link>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <SubSystem>Console</SubSystem>
++ <OutputFile>.\Release\DllPlugInTester.exe</OutputFile>
++ <AdditionalLibraryDirectories>../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
++ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunit.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+@@ -584,6 +814,49 @@
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunitd_dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
++ <FunctionLevelLinking>false</FunctionLevelLinking>
++ <Optimization>Disabled</Optimization>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <WarningLevel>Level3</WarningLevel>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;CPPUNIT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <AssemblerListingLocation>.\DebugDll\</AssemblerListingLocation>
++ <PrecompiledHeaderOutputFile>.\DebugDll\DllPlugInTester.pch</PrecompiledHeaderOutputFile>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <ObjectFileName>.\DebugDll\</ObjectFileName>
++ <ProgramDataBaseFileName>.\DebugDll\</ProgramDataBaseFileName>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ </ClCompile>
++ <PostBuildEvent>
++ <Command>copy "$(TargetPath)" ..\..\lib\$(TargetName).exe</Command>
++ <Message>Copying target to lib/</Message>
++ </PostBuildEvent>
++ <Midl>
++ <TypeLibraryName>.\DebugDll\DllPlugInTester.tlb</TypeLibraryName>
++ </Midl>
++ <ResourceCompile>
++ <Culture>0x040c</Culture>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ </ResourceCompile>
++ <Bscmake>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <OutputFile>.\DebugDll\DllPlugInTester.bsc</OutputFile>
++ </Bscmake>
++ <Link>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OutputFile>DebugDll\DllPlugInTesterd_dll.exe</OutputFile>
++ <AdditionalLibraryDirectories>../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
++ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunitd_dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+@@ -670,6 +943,49 @@
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunit_dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <StringPooling>true</StringPooling>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <Optimization>MinSpace</Optimization>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <WarningLevel>Level3</WarningLevel>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <DebugInformationFormat>OldStyle</DebugInformationFormat>
++ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;CPPUNIT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <AssemblerListingLocation>.\ReleaseDll\</AssemblerListingLocation>
++ <PrecompiledHeaderOutputFile>.\ReleaseDll\DllPlugInTester.pch</PrecompiledHeaderOutputFile>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <ObjectFileName>.\ReleaseDll\</ObjectFileName>
++ <ProgramDataBaseFileName>.\ReleaseDll\</ProgramDataBaseFileName>
++ </ClCompile>
++ <PostBuildEvent>
++ <Command>copy "$(TargetPath)" ..\..\lib\$(TargetName).exe</Command>
++ <Message>Copying target to lib/</Message>
++ </PostBuildEvent>
++ <Midl>
++ <TypeLibraryName>.\ReleaseDll\DllPlugInTester.tlb</TypeLibraryName>
++ </Midl>
++ <ResourceCompile>
++ <Culture>0x040c</Culture>
++ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ </ResourceCompile>
++ <Bscmake>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <OutputFile>.\ReleaseDll\DllPlugInTester.bsc</OutputFile>
++ </Bscmake>
++ <Link>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <SubSystem>Console</SubSystem>
++ <OutputFile>ReleaseDll\DllPlugInTester_dll.exe</OutputFile>
++ <AdditionalLibraryDirectories>../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
++ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunit_dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+@@ -718,6 +1034,49 @@
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
++ <FunctionLevelLinking>false</FunctionLevelLinking>
++ <Optimization>Disabled</Optimization>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <WarningLevel>Level3</WarningLevel>
++ <RuntimeTypeInfo>true</RuntimeTypeInfo>
++ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <AssemblerListingLocation>.\DebugUnicode\</AssemblerListingLocation>
++ <PrecompiledHeaderOutputFile>.\DebugUnicode\DllPlugInTester.pch</PrecompiledHeaderOutputFile>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <ObjectFileName>.\DebugUnicode\</ObjectFileName>
++ <ProgramDataBaseFileName>.\DebugUnicode\</ProgramDataBaseFileName>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ </ClCompile>
++ <PostBuildEvent>
++ <Command>copy "$(TargetPath)" ..\..\lib\$(TargetName).exe</Command>
++ <Message>Copying target to lib/</Message>
++ </PostBuildEvent>
++ <Midl>
++ <TypeLibraryName>.\DebugUnicode\DllPlugInTester.tlb</TypeLibraryName>
++ </Midl>
++ <ResourceCompile>
++ <Culture>0x040c</Culture>
++ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ </ResourceCompile>
++ <Bscmake>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <OutputFile>.\DebugUnicode\DllPlugInTester.bsc</OutputFile>
++ </Bscmake>
++ <Link>
++ <SuppressStartupBanner>true</SuppressStartupBanner>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OutputFile>DebugUnicode\DllPlugInTesterud.exe</OutputFile>
++ <AdditionalLibraryDirectories>../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
++ <AdditionalDependencies>odbc32.lib;odbccp32.lib;cppunitd.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ </Link>
++ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|ARM64'">
++ <ClCompile>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
diff --git a/external/cppunit/windows.patch b/external/cppunit/windows.patch
new file mode 100644
index 000000000..e6ca26cbb
--- /dev/null
+++ b/external/cppunit/windows.patch
@@ -0,0 +1,50 @@
+--- misc/cppunit-1.15.0/include/cppunit/plugin/TestPlugIn.h 2010-01-11 14:42:25.084658287 +0100
++++ misc/build/cppunit-1.15.0/include/cppunit/plugin/TestPlugIn.h 2010-01-11 14:42:18.660706180 +0100
+@@ -133,9 +133,8 @@
+ /*! \def CPPUNIT_PLUGIN_IMPLEMENT_MAIN()
+ * \brief Implements the 'main' function for the plug-in.
+ *
+- * This macros implements the main() function for dynamic library.
+- * For example, WIN32 requires a DllMain function, while some Unix
+- * requires a main() function. This macros takes care of the implementation.
++ * This macro implements the main() function for dynamic library
++ * on Unix for some weird reason.
+ */
+
+ // Win32
+@@ -149,23 +149,7 @@
+
+ // Win32
+ #if defined(CPPUNIT_HAVE_WIN32_DLL_LOADER)
+-#if !defined(APIENTRY)
+-#define WIN32_LEAN_AND_MEAN
+-#define NOGDI
+-#define NOUSER
+-#define NOKERNEL
+-#define NOSOUND
+-#ifndef NOMINMAX
+-#define NOMINMAX
+-#endif
+-#define BLENDFUNCTION void // for mingw & gcc
+-#include <windows.h>
+-#endif
+ #define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() \
+- BOOL APIENTRY DllMain( HANDLE, DWORD, LPVOID ) \
+- { \
+- return TRUE; \
+- } \
+ typedef char __CppUnitPlugInImplementMainDummyTypeDef
+
+ // Unix
+--- misc/cppunit-1.15.0/include/cppunit/TestAssert.h
++++ misc/build/cppunit-1.15.0/include/cppunit/TestAssert.h
+@@ -76,7 +76,7 @@
+ const int precision = 15;
+ #endif // #ifdef DBL_DIG
+ char buffer[128];
+-#ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning.
++#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning.
+ sprintf_s(buffer, sizeof(buffer), "%.*g", precision, x);
+ #else
+ sprintf(buffer, "%.*g", precision, x);
+
diff --git a/external/curl/ExternalPackage_curl.mk b/external/curl/ExternalPackage_curl.mk
new file mode 100644
index 000000000..ee0cf4501
--- /dev/null
+++ b/external/curl/ExternalPackage_curl.mk
@@ -0,0 +1,28 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,curl,curl))
+
+$(eval $(call gb_ExternalPackage_use_external_project,curl,curl))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+
+ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl$(if $(MSVC_USE_DEBUG_RUNTIME),_debug).dll,builds/libcurl-vc12-$(gb_MSBUILD_PLATFORM)-$(gb_MSBUILD_CONFIG)-dll-zlib-static-ipv6-sspi-schannel/bin/libcurl$(if $(MSVC_USE_DEBUG_RUNTIME),_debug).dll))
+else ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl.4.dylib,lib/.libs/libcurl.4.dylib))
+else ifeq ($(OS),AIX)
+$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl.so,lib/.libs/libcurl.so.4))
+else
+$(eval $(call gb_ExternalPackage_add_file,curl,$(LIBO_LIB_FOLDER)/libcurl.so.4,lib/.libs/libcurl.so.4.8.0))
+endif
+
+endif # $(DISABLE_DYNLOADING)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/curl/ExternalProject_curl.mk b/external/curl/ExternalProject_curl.mk
new file mode 100644
index 000000000..8d8bd13ae
--- /dev/null
+++ b/external/curl/ExternalProject_curl.mk
@@ -0,0 +1,99 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,curl))
+
+$(eval $(call gb_ExternalProject_use_externals,curl,\
+ $(if $(ENABLE_NSS),nss3) \
+ zlib \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,curl,\
+ build \
+))
+
+ifneq ($(OS),WNT)
+
+curl_CPPFLAGS :=
+curl_LDFLAGS := $(if $(filter LINUX FREEBSD,$(OS)),-Wl$(COMMA)-z$(COMMA)origin -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN)
+
+ifneq ($(OS),ANDROID)
+ifneq ($(SYSBASE),)
+curl_CPPFLAGS += -I$(SYSBASE)/usr/include
+curl_LDFLAGS += -L$(SYSBASE)/usr/lib
+endif
+endif
+
+# there are 2 include paths, the other one is passed to --with-nss below
+ifeq ($(SYSTEM_NSS),)
+curl_CPPFLAGS += -I$(call gb_UnpackedTarball_get_dir,nss)/dist/public/nss
+endif
+
+# use --with-secure-transport on macOS >10.5 and iOS to get a native UI for SSL certs for CMIS usage
+# use --with-nss only on platforms other than macOS and iOS
+$(call gb_ExternalProject_get_state_target,curl,build):
+ $(call gb_Trace_StartRange,curl,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure \
+ $(if $(filter iOS MACOSX,$(OS)),\
+ --with-secure-transport,\
+ $(if $(ENABLE_NSS),--with-nss$(if $(SYSTEM_NSS),,="$(call gb_UnpackedTarball_get_dir,nss)/dist/out") --with-nss-deprecated,--without-nss)) \
+ --without-openssl --without-gnutls --without-polarssl --without-cyassl --without-axtls --without-mbedtls \
+ --enable-ftp --enable-http --enable-ipv6 \
+ --without-libidn2 --without-libpsl --without-librtmp \
+ --without-libssh2 --without-metalink --without-nghttp2 \
+ --without-libssh --without-brotli \
+ --without-ngtcp2 --without-quiche \
+ --without-zstd --without-hyper --without-gsasl --without-gssapi \
+ --disable-mqtt --disable-ares \
+ --disable-dict --disable-file --disable-gopher --disable-imap \
+ --disable-ldap --disable-ldaps --disable-manual --disable-pop3 \
+ --disable-rtsp --disable-smb --disable-smtp --disable-telnet \
+ --disable-tftp \
+ $(if $(filter LINUX,$(OS)),--without-ca-bundle --without-ca-path) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),--disable-shared,--disable-static) \
+ $(if $(ENABLE_DEBUG),--enable-debug) \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(filter MACOSX,$(OS)),CFLAGS='$(CFLAGS) \
+ -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET)') \
+ CPPFLAGS='$(curl_CPPFLAGS)' \
+ CFLAGS="$(gb_CFLAGS) $(call gb_ExternalProject_get_build_flags,curl)" \
+ LDFLAGS='$(call gb_ExternalProject_get_link_flags,curl) $(curl_LDFLAGS)' \
+ ZLIB_CFLAGS='$(ZLIB_CFLAGS)' ZLIB_LIBS='$(ZLIB_LIBS)' \
+ && cd lib \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,curl,EXTERNAL)
+
+else ifeq ($(COM),MSC)
+
+$(eval $(call gb_ExternalProject_use_nmake,curl,build))
+
+$(call gb_ExternalProject_get_state_target,curl,build):
+ $(call gb_Trace_StartRange,curl,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ nmake -f Makefile.vc \
+ mode=dll \
+ VC=12 \
+ MACHINE=$(gb_MSBUILD_PLATFORM) \
+ GEN_PDB=$(if $(call gb_Module__symbols_enabled,curl),yes,no) \
+ $(if $(call gb_Module__symbols_enabled,curl),CFLAGS_PDB_VALUE="$(gb_DEBUGINFO_FLAGS)") \
+ DEBUG=$(if $(MSVC_USE_DEBUG_RUNTIME),yes,no) \
+ ENABLE_IPV6=yes \
+ ENABLE_SSPI=yes \
+ ENABLE_WINSSL=yes \
+ WITH_ZLIB=static \
+ ,winbuild)
+ $(call gb_Trace_EndRange,curl,EXTERNAL)
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/curl/Makefile b/external/curl/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/curl/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/curl/Module_curl.mk b/external/curl/Module_curl.mk
new file mode 100644
index 000000000..2b4c61c04
--- /dev/null
+++ b/external/curl/Module_curl.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,curl))
+
+$(eval $(call gb_Module_add_targets,curl,\
+ UnpackedTarball_curl \
+ ExternalPackage_curl \
+ ExternalProject_curl \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/curl/README b/external/curl/README
new file mode 100644
index 000000000..292e4edf5
--- /dev/null
+++ b/external/curl/README
@@ -0,0 +1 @@
+A URL manipulation engine from [http://curl.haxx.se/].
diff --git a/external/curl/UnpackedTarball_curl.mk b/external/curl/UnpackedTarball_curl.mk
new file mode 100644
index 000000000..e78adabb8
--- /dev/null
+++ b/external/curl/UnpackedTarball_curl.mk
@@ -0,0 +1,48 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,curl))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,curl,$(CURL_TARBALL),,curl))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,curl))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,curl,1))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,curl,\
+ winbuild/MakefileBuild.vc \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,curl,\
+ external/curl/curl-msvc.patch.1 \
+ external/curl/curl-msvc-zlib.patch.1 \
+ external/curl/curl-msvc-disable-protocols.patch.1 \
+ external/curl/zlib.patch.0 \
+ external/curl/configurable-z-option.patch.0 \
+))
+
+ifeq ($(SYSTEM_NSS),)
+$(eval $(call gb_UnpackedTarball_add_patches,curl,\
+ external/curl/curl-nss.patch.1 \
+))
+endif
+
+ifeq ($(OS)-$(COM_IS_CLANG),WNT-TRUE)
+$(eval $(call gb_UnpackedTarball_add_patches,curl, \
+ external/curl/clang-cl.patch.0 \
+))
+endif
+
+ifneq ($(filter -fsanitize=%,$(CC)),)
+$(eval $(call gb_UnpackedTarball_add_patches,curl, \
+ external/curl/asan-poison-nsspem.patch.0 \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/curl/asan-poison-nsspem.patch.0 b/external/curl/asan-poison-nsspem.patch.0
new file mode 100644
index 000000000..b348d44ee
--- /dev/null
+++ b/external/curl/asan-poison-nsspem.patch.0
@@ -0,0 +1,11 @@
+--- lib/vtls/nss.c
++++ lib/vtls/nss.c
+@@ -1926,7 +1926,7 @@
+
+ PK11_SetPasswordFunc(nss_get_password);
+
+- result = nss_load_module(&pem_module, pem_library, "PEM");
++ result = CURLE_FAILED_INIT;
+ PR_Unlock(nss_initlock);
+ if(result == CURLE_FAILED_INIT)
+ infof(data, "WARNING: failed to load NSS PEM library %s. Using "
diff --git a/external/curl/clang-cl.patch.0 b/external/curl/clang-cl.patch.0
new file mode 100644
index 000000000..5dfb19d5b
--- /dev/null
+++ b/external/curl/clang-cl.patch.0
@@ -0,0 +1,11 @@
+--- winbuild/MakefileBuild.vc
++++ winbuild/MakefileBuild.vc
+@@ -52,7 +52,7 @@
+ !ELSE
+ CC_NODEBUG = $(CC) /O2 /DNDEBUG
+ CC_DEBUG = $(CC) /Od /D_DEBUG /RTC1 /Z7 /LDd
+-CFLAGS = /I. /I ../lib /I../include /nologo /W4 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL $(SOLARINC)
++CFLAGS = /I. /I ../lib /I../include /nologo /W4 /EHsc /DWIN32 /c /DBUILDING_LIBCURL $(SOLARINC)
+ !ENDIF
+
+ LFLAGS = /nologo /machine:$(MACHINE)
diff --git a/external/curl/configurable-z-option.patch.0 b/external/curl/configurable-z-option.patch.0
new file mode 100644
index 000000000..84516ad21
--- /dev/null
+++ b/external/curl/configurable-z-option.patch.0
@@ -0,0 +1,20 @@
+--- winbuild/MakefileBuild.vc.sav 2021-11-13 11:43:40.756226600 +0000
++++ winbuild/MakefileBuild.vc 2021-11-13 11:52:08.921692300 +0000
+@@ -47,7 +47,7 @@
+
+ !IF "$(VC)"=="6"
+ CC_NODEBUG = $(CC) /O2 /DNDEBUG
+-CC_DEBUG = $(CC) /Od /Gm /Zi /D_DEBUG /GZ
++CC_DEBUG = $(CC) /Od /Gm $(DEBUG_FLAGS_VALUE) /D_DEBUG /GZ
+ CFLAGS = /I. /I../lib /I../include /nologo /W4 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
+ !ELSE
+ CC_NODEBUG = $(CC) /O2 /DNDEBUG
+@@ -64,7 +64,7 @@
+ # Instead of id: just create an archive, that contains all objects
+ LNKLIB = lib.exe
+
+-CFLAGS_PDB = /Zi
++CFLAGS_PDB = $(DEBUG_FLAGS_VALUE)
+ LFLAGS_PDB = /incremental:no /opt:ref,icf /DEBUG
+
+ CFLAGS_LIBCURL_STATIC = /DCURL_STATICLIB
diff --git a/external/curl/curl-msvc-disable-protocols.patch.1 b/external/curl/curl-msvc-disable-protocols.patch.1
new file mode 100644
index 000000000..71ff0c01a
--- /dev/null
+++ b/external/curl/curl-msvc-disable-protocols.patch.1
@@ -0,0 +1,36 @@
+disable protocols nobody needs in MSVC build
+
+--- curl/lib/config-win32.h.orig 2017-08-09 16:43:29.464000000 +0200
++++ curl/lib/config-win32.h 2017-08-09 16:47:38.549200000 +0200
+@@ -654,4 +654,20 @@
+ # define ENABLE_IPV6 1
+ #endif
+
++#define CURL_DISABLE_DICT 1
++#define CURL_DISABLE_FILE 1
++#undef CURL_DISABLE_FTP
++#define CURL_DISABLE_GOPHER 1
++#undef CURL_DISABLE_HTTP
++#define CURL_DISABLE_IMAP 1
++#define CURL_DISABLE_LDAP 1
++#define CURL_DISABLE_LDAPS 1
++#define CURL_DISABLE_MQTT 1
++#define CURL_DISABLE_POP3 1
++#define CURL_DISABLE_RTSP 1
++#define CURL_DISABLE_SMB 1
++#define CURL_DISABLE_SMTP 1
++#define CURL_DISABLE_TELNET 1
++#define CURL_DISABLE_TFTP 1
++
+ #endif /* HEADER_CURL_CONFIG_WIN32_H */
+--- curl/winbuild/MakefileBuild.vc.orig 2017-10-23 23:41:21.393200000 +0200
++++ curl/winbuild/MakefileBuild.vc 2017-10-23 23:34:16.028000000 +0200
+@@ -562,7 +562,7 @@
+
+ EXE_OBJS = $(CURL_OBJS) $(CURL_DIROBJ)\curl.res
+
+-all : $(TARGET) $(PROGRAM_NAME)
++all : $(TARGET)
+
+ package: $(TARGET)
+ @cd $(DIRDIST)
diff --git a/external/curl/curl-msvc-zlib.patch.1 b/external/curl/curl-msvc-zlib.patch.1
new file mode 100644
index 000000000..a9ee0013d
--- /dev/null
+++ b/external/curl/curl-msvc-zlib.patch.1
@@ -0,0 +1,16 @@
+find internal zlib in nmake buildsystem
+
+--- curl/winbuild/MakefileBuild.vc.orig2 2021-10-27 20:44:48.685237000 +0200
++++ curl/winbuild/MakefileBuild.vc 2021-10-27 20:47:23.792407400 +0200
+@@ -244,8 +244,9 @@
+ ZLIB_LIB_DIR = $(ZLIB_PATH)\lib
+ ZLIB_LFLAGS = $(ZLIB_LFLAGS) "/LIBPATH:$(ZLIB_LIB_DIR)"
+ !ELSE
+-ZLIB_INC_DIR = $(DEVEL_INCLUDE)
+-ZLIB_LIB_DIR = $(DEVEL_LIB)
++ZLIB_INC_DIR = $(WORKDIR)/UnpackedTarball/zlib
++ZLIB_LIB_DIR = $(WORKDIR)/LinkTarget/StaticLibrary
++ZLIB_LFLAGS = $(ZLIB_LFLAGS) "/LIBPATH:$(ZLIB_LIB_DIR)"
+ !ENDIF
+
+ # Depending on how zlib is built the libraries have different names, we
diff --git a/external/curl/curl-msvc.patch.1 b/external/curl/curl-msvc.patch.1
new file mode 100644
index 000000000..54ad026ec
--- /dev/null
+++ b/external/curl/curl-msvc.patch.1
@@ -0,0 +1,27 @@
+MSVC: using SOLARINC
+
+--- curl/winbuild/MakefileBuild.vc.orig 2017-10-23 16:36:07.713550851 +0200
++++ curl/winbuild/MakefileBuild.vc 2017-10-23 16:38:19.301547594 +0200
+@@ -52,7 +52,7 @@
+ !ELSE
+ CC_NODEBUG = $(CC) /O2 /DNDEBUG
+ CC_DEBUG = $(CC) /Od /D_DEBUG /RTC1 /Z7 /LDd
+-CFLAGS = /I. /I ../lib /I../include /nologo /W4 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL
++CFLAGS = /I. /I ../lib /I../include /nologo /W4 /EHsc /DWIN32 /FD /c /DBUILDING_LIBCURL $(SOLARINC)
+ !ENDIF
+
+ LFLAGS = /nologo /machine:$(MACHINE)
+@@ -426,11 +426,11 @@
+ # CURL_XX macros are for the curl.exe command
+
+ !IF "$(DEBUG)"=="yes"
+-RC_FLAGS = /dDEBUGBUILD=1 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
++RC_FLAGS = $(SOLARINC) /dDEBUGBUILD=1 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
+ CURL_CC = $(CC_DEBUG) $(RTLIB_DEBUG)
+ CURL_RC_FLAGS = $(CURL_RC_FLAGS) /i../include /dDEBUGBUILD=1 /Fo $@ $(CURL_SRC_DIR)\curl.rc
+ !ELSE
+-RC_FLAGS = /dDEBUGBUILD=0 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
++RC_FLAGS = $(SOLARINC) /dDEBUGBUILD=0 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
+ CURL_CC = $(CC_NODEBUG) $(RTLIB)
+ CURL_RC_FLAGS = $(CURL_RC_FLAGS) /i../include /dDEBUGBUILD=0 /Fo $@ $(CURL_SRC_DIR)\curl.rc
+ !ENDIF
diff --git a/external/curl/curl-nss.patch.1 b/external/curl/curl-nss.patch.1
new file mode 100644
index 000000000..2e8766b3d
--- /dev/null
+++ b/external/curl/curl-nss.patch.1
@@ -0,0 +1,17 @@
+diff -ur curl.org/configure curl/configure
+--- curl.orig/configure 2023-02-20 16:11:55.000000000 +0900
++++ curl/configure 2023-02-23 15:40:58.617432471 +0900
+@@ -28675,7 +28675,12 @@
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Using hard-wired libraries and compilation flags for NSS." >&5
+ printf "%s\n" "$as_me: WARNING: Using hard-wired libraries and compilation flags for NSS." >&2;}
+ addld="-L$OPT_NSS/lib"
+- addlib="-lssl3 -lsmime3 -lnss3 -lplds4 -lplc4 -lnspr4"
++ addlib="-lssl3 -lsmime3 -lnss3 -lplds4 -lplc4 -lnspr4 -lnssutil3"
++ case $host_os in
++ *android*)
++ addlib="${addlib} -llog"
++ ;;
++ esac
+ addcflags="-I$OPT_NSS/include"
+ version="unknown"
+ nssprefix=$OPT_NSS
diff --git a/external/curl/zlib.patch.0 b/external/curl/zlib.patch.0
new file mode 100644
index 000000000..b4442ba26
--- /dev/null
+++ b/external/curl/zlib.patch.0
@@ -0,0 +1,90 @@
+--- configure
++++ configure
+@@ -23035,7 +23035,6 @@
+ clean_CPPFLAGS=$CPPFLAGS
+ clean_LDFLAGS=$LDFLAGS
+ clean_LIBS=$LIBS
+-ZLIB_LIBS=""
+
+ # Check whether --with-zlib was given.
+ if test ${with_zlib+y}
+@@ -23045,6 +23044,7 @@
+
+
+ if test "$OPT_ZLIB" = "no" ; then
++ ZLIB_LIBS=""
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: zlib disabled" >&5
+ printf "%s\n" "$as_me: WARNING: zlib disabled" >&2;}
+ else
+@@ -23052,6 +23052,21 @@
+ OPT_ZLIB=""
+ fi
+
++ if test -n "$ZLIB_CFLAGS$ZLIB_LIBS"; then
++ CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS"
++ LIBS="$ZLIB_LIBS $LIBS"
++ HAVE_LIBZ="1"
++
++
++$as_echo "#define HAVE_ZLIB_H 1" >>confdefs.h
++
++
++$as_echo "#define HAVE_LIBZ 1" >>confdefs.h
++
++ AMFIXLIB="1"
++ else
++ ZLIB_LIBS=""
++
+ if test -z "$OPT_ZLIB" ; then
+
+ if test -n "$PKG_CONFIG"; then
+@@ -23344,6 +23359,7 @@
+ printf "%s\n" "$as_me: found both libz and libz.h header" >&6;}
+ curl_zlib_msg="enabled"
+ fi
++ fi
+ fi
+
+ if test x"$AMFIXLIB" = x1; then
+--- configure.ac
++++ configure.ac
+@@ -1243,19 +1243,30 @@
+ clean_CPPFLAGS=$CPPFLAGS
+ clean_LDFLAGS=$LDFLAGS
+ clean_LIBS=$LIBS
+-ZLIB_LIBS=""
+ AC_ARG_WITH(zlib,
+ AS_HELP_STRING([--with-zlib=PATH],[search for zlib in PATH])
+ AS_HELP_STRING([--without-zlib],[disable use of zlib]),
+ [OPT_ZLIB="$withval"])
+
+ if test "$OPT_ZLIB" = "no" ; then
++ ZLIB_LIBS=""
+ AC_MSG_WARN([zlib disabled])
+ else
+ if test "$OPT_ZLIB" = "yes" ; then
+ OPT_ZLIB=""
+ fi
+
++ if test -n "$ZLIB_CFLAGS$ZLIB_LIBS"; then
++ CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS"
++ LIBS="$ZLIB_LIBS $LIBS"
++ HAVE_LIBZ="1"
++ AC_SUBST(HAVE_LIBZ)
++ AC_DEFINE(HAVE_ZLIB_H, 1, [if you have the zlib.h header file])
++ AC_DEFINE(HAVE_LIBZ, 1, [if zlib is available])
++ AMFIXLIB="1"
++ else
++ ZLIB_LIBS=""
++
+ if test -z "$OPT_ZLIB" ; then
+ CURL_CHECK_PKGCONFIG(zlib)
+
+@@ -1336,6 +1347,7 @@
+ AC_MSG_NOTICE([found both libz and libz.h header])
+ curl_zlib_msg="enabled"
+ fi
++ fi
+ fi
+
+ dnl set variable for use in automakefile(s)
diff --git a/external/dragonbox/Module_dragonbox.mk b/external/dragonbox/Module_dragonbox.mk
new file mode 100644
index 000000000..2ed608f1e
--- /dev/null
+++ b/external/dragonbox/Module_dragonbox.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,dragonbox))
+
+$(eval $(call gb_Module_add_targets,dragonbox,\
+ UnpackedTarball_dragonbox \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/dragonbox/README b/external/dragonbox/README
new file mode 100644
index 000000000..28db2711b
--- /dev/null
+++ b/external/dragonbox/README
@@ -0,0 +1,4 @@
+Dragonbox is available from [ https://github.com/jk-jeon/dragonbox ].
+
+Used to convert a double to a decimal string, providing breakout of significand and exponent
+as integers, allowing to create custom number representation (e.g., locale-specific).
diff --git a/external/dragonbox/UnpackedTarball_dragonbox.mk b/external/dragonbox/UnpackedTarball_dragonbox.mk
new file mode 100644
index 000000000..c483f19a3
--- /dev/null
+++ b/external/dragonbox/UnpackedTarball_dragonbox.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,dragonbox))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,dragonbox,$(DRAGONBOX_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/dtoa/Makefile b/external/dtoa/Makefile
new file mode 100644
index 000000000..6427d44e3
--- /dev/null
+++ b/external/dtoa/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/dtoa/Module_dtoa.mk b/external/dtoa/Module_dtoa.mk
new file mode 100644
index 000000000..c652f97e0
--- /dev/null
+++ b/external/dtoa/Module_dtoa.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,dtoa))
+
+$(eval $(call gb_Module_add_targets,dtoa,\
+ UnpackedTarball_dtoa \
+ StaticLibrary_dtoa \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/dtoa/README b/external/dtoa/README
new file mode 100644
index 000000000..9f46b9865
--- /dev/null
+++ b/external/dtoa/README
@@ -0,0 +1,10 @@
+dtoa is available from [ https://www.netlib.org/fp/ ].
+
+Used to convert a decimal string to double (until std::from_chars is available on used compilers).
+Packaged using
+
+ mkdir dtoa && mkdir dtoa/src && wget https://www.netlib.org/fp/dtoa.c -O dtoa/src/dtoa.c && \
+ printf 'd8bab255476f39ea495c8c8ed164f9077da926e6ca7afb9ad3c56d337c4484fe dtoa/src/dtoa.c' | sha256sum -c && \
+ tar -c --owner=0 --group=0 --mode=go=r,u=rw --mtime='Wed, 11 Apr 2018 15:59:39 GMT' dtoa/src/dtoa.c | gzip -n > dtoa-20180411.tgz && \
+ printf '0082d0684f7db6f62361b76c4b7faba19e0c7ce5cb8e36c4b65fea8281e711b4 dtoa-20180411.tgz' | sha256sum -c
+(where the date "Wed, 11 Apr 2018 15:59:39 GMT" is from `wget -S https://www.netlib.org/fp/dtoa.c` "Last-Modified: Wed, 11 Apr 2018 15:59:39 GMT" header).
diff --git a/external/dtoa/StaticLibrary_dtoa.mk b/external/dtoa/StaticLibrary_dtoa.mk
new file mode 100644
index 000000000..09f4231a2
--- /dev/null
+++ b/external/dtoa/StaticLibrary_dtoa.mk
@@ -0,0 +1,30 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,dtoa))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,dtoa,dtoa))
+
+# A place that duplicates these settings is jurt/Library_jpipe.mk
+$(eval $(call gb_StaticLibrary_add_defs,dtoa,\
+ $(if $(filter little,$(ENDIANNESS)),-DIEEE_8087,-DIEEE_MC68k)\
+))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,dtoa))
+
+$(eval $(call gb_StaticLibrary_set_include,dtoa,\
+ -I$(call gb_UnpackedTarball_get_dir,dtoa/src/)\
+ $$(INCLUDE)\
+))
+
+$(eval $(call gb_StaticLibrary_add_exception_objects,dtoa,\
+ external/dtoa/source/dtoa \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/dtoa/UnpackedTarball_dtoa.mk b/external/dtoa/UnpackedTarball_dtoa.mk
new file mode 100644
index 000000000..bc4fe55b5
--- /dev/null
+++ b/external/dtoa/UnpackedTarball_dtoa.mk
@@ -0,0 +1,22 @@
+#-*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,dtoa))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,dtoa,$(DTOA_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,dtoa,1))
+
+$(eval $(call gb_UnpackedTarball_add_patches,dtoa, \
+ external/dtoa/include_header.patch \
+ external/dtoa/coverity.patch \
+ external/dtoa/ubsan.patch.0 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/dtoa/coverity.patch b/external/dtoa/coverity.patch
new file mode 100644
index 000000000..8fb176531
--- /dev/null
+++ b/external/dtoa/coverity.patch
@@ -0,0 +1,51 @@
+--- dtor/src/dtoa.c.coverity
++++ dtor/src/dtoa.c
+@@ -216,14 +216,14 @@
+ typedef unsigned Long ULong;
+ #endif
+
+-#ifdef DEBUG
+ #include <assert.h>
++
++#ifdef DEBUG
+ #include "stdio.h"
+ #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+ #define Debug(x) x
+ int dtoa_stats[7]; /* strtod_{64,96,bigcomp},dtoa_{exact,64,96,bigcomp} */
+ #else
+-#define assert(x) /*nothing*/
+ #define Debug(x) /*nothing*/
+ #endif
+
+@@ -2301,6 +2301,7 @@
+ if ((y = d1)) {
+ if ((k = lo0bits(&y))) {
+ x[0] = y | z << (32 - k);
++ assert(k < 32); /* https://bugs.python.org/issue23999 */
+ z >>= k;
+ }
+ else
+@@ -3029,6 +3030,7 @@
+ || ((n = nbits & kmask) !=0
+ && hi0bits(x[k-1]) < 32-n)) {
+ rshift(b,1);
++ /* coverity[dead_error_line] - not worth investigating */
+ if (++e > Emax)
+ goto ovfl;
+ }
+@@ -3345,6 +3347,7 @@
+ if ((dd = s0[j++] - '0' - dig))
+ goto ret;
+ if (!b->x[0] && b->wds == 1) {
++ /* coverity[copy_paste_error : FALSE] */
+ if (i < nd)
+ dd = 1;
+ goto ret;
+@@ -3607,6 +3610,7 @@
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
++ /* fall through */
+ case '+':
+ c = *++s;
+ }
diff --git a/external/dtoa/include_header.patch b/external/dtoa/include_header.patch
new file mode 100644
index 000000000..7cf0a8a21
--- /dev/null
+++ b/external/dtoa/include_header.patch
@@ -0,0 +1,100 @@
+--- /dev/null
++++ dtoa/include/dtoa.h
+@@ -0,0 +1,1 @@
++extern "C" double strtod_nolocale(const char *s00, char **se);
+--- dtoa/src/dtoa.c.orig
++++ dtoa/src/dtoa.c
+@@ -268,7 +268,7 @@ #ifndef PRIVATE_MEM
+ #define PRIVATE_MEM 2304
+ #endif
+ #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+-static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
++static thread_local double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+ #endif
+
+ #undef IEEE_Arith
+@@ -1502,9 +1502,7 @@ static unsigned int maxthreads = 0;
+ #define Kmax 7
+
+ #ifdef __cplusplus
+-extern "C" double strtod(const char *s00, char **se);
+-extern "C" char *dtoa(double d, int mode, int ndigits,
+- int *decpt, int *sign, char **rve);
++extern "C" double strtod_nolocale(const char *s00, char **se);
+ #endif
+
+ struct
+@@ -1521,7 +1519,7 @@ ThInfo {
+ Bigint *P5s;
+ } ThInfo;
+
+- static ThInfo TI0;
++ static thread_local ThInfo TI0;
+
+ #ifdef MULTIPLE_THREADS
+ static ThInfo *TI1;
+@@ -1529,7 +1527,7 @@ #ifdef MULTIPLE_THREADS
+ static ThInfo *TI1;
+ static int TI0_used;
+
+- void
++ static void
+ set_max_dtoa_threads(unsigned int n)
+ {
+ size_t L;
+@@ -2717,7 +2715,7 @@ enum { /* rounding values: same as FLT_ROUNDS */
+ Round_down = 3
+ };
+
+- void
++ static void
+ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
+ {
+ Bigint *b;
+@@ -3429,7 +3427,7 @@ retlow1:
+ #endif /* NO_STRTOD_BIGCOMP */
+
+ double
+-strtod(const char *s00, char **se)
++strtod_nolocale(const char *s00, char **se)
+ {
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1;
+ int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign;
+@@ -4851,7 +4849,7 @@ strtod_nolocale(const char *s00, char **se)
+ }
+
+ #ifndef MULTIPLE_THREADS
+- static char *dtoa_result;
++ static thread_local char *dtoa_result;
+ #endif
+
+ static char *
+@@ -4902,7 +4900,7 @@ nrv_alloc(const char *s, char *s0, size_t s0len, char **rve, int n MTd)
+ * when MULTIPLE_THREADS is not defined.
+ */
+
+- void
++ static void
+ freedtoa(char *s)
+ {
+ #ifdef MULTIPLE_THREADS
+@@ -4951,7 +4949,7 @@ freedtoa(char *s)
+ * calculation.
+ */
+
+- char *
++ static char *
+ dtoa_r(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve, char *buf, size_t blen)
+ {
+ /* Arguments ndigits, decpt, sign are similar to those
+@@ -6184,8 +6182,8 @@ dtoa_r(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve, char
+ return buf;
+ }
+
+- char *
+-dtoa(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
++ static char *
++dtoa_nolocale(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
+ {
+ /* Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
diff --git a/external/dtoa/source/dtoa.cxx b/external/dtoa/source/dtoa.cxx
new file mode 100644
index 000000000..d3c8b8211
--- /dev/null
+++ b/external/dtoa/source/dtoa.cxx
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+// build this as C++ code, to allow e.g. thread_local keyword in MSVC
+#include <dtoa.c>
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/external/dtoa/ubsan.patch.0 b/external/dtoa/ubsan.patch.0
new file mode 100644
index 000000000..de39d41ac
--- /dev/null
+++ b/external/dtoa/ubsan.patch.0
@@ -0,0 +1,11 @@
+--- src/dtoa.c
++++ src/dtoa.c
+@@ -3618,7 +3618,7 @@
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+- L = c - '0';
++ ULong L = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
diff --git a/external/epm/ExternalProject_epm.mk b/external/epm/ExternalProject_epm.mk
new file mode 100644
index 000000000..7b0dde219
--- /dev/null
+++ b/external/epm/ExternalProject_epm.mk
@@ -0,0 +1,26 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,epm))
+
+$(eval $(call gb_ExternalProject_register_targets,epm,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,epm,build) :
+ $(call gb_Trace_StartRange,epm,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure --disable-fltk \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________NONE) \
+ && $(MAKE) \
+ && touch $@ \
+ )
+ $(call gb_Trace_EndRange,epm,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/epm/Makefile b/external/epm/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/epm/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/epm/Module_epm.mk b/external/epm/Module_epm.mk
new file mode 100644
index 000000000..179537c6b
--- /dev/null
+++ b/external/epm/Module_epm.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,epm))
+
+ifeq ($(CROSS_COMPILING),)
+
+$(eval $(call gb_Module_add_targets,epm,\
+ ExternalProject_epm \
+ UnpackedTarball_epm \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/epm/README b/external/epm/README
new file mode 100644
index 000000000..c3ec2986e
--- /dev/null
+++ b/external/epm/README
@@ -0,0 +1,3 @@
+Enhanced Package Manager, From [http://freshmeat.net/projects/epm]
+
+Nasty hack for packaging, not useful, but default build uses, every linux packager disables this.
diff --git a/external/epm/UnpackedTarball_epm.mk b/external/epm/UnpackedTarball_epm.mk
new file mode 100644
index 000000000..c064a5bac
--- /dev/null
+++ b/external/epm/UnpackedTarball_epm.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,epm))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,epm,$(EPM_TARBALL),,epm))
+
+$(eval $(call gb_UnpackedTarball_add_patches,epm,\
+ external/epm/epm-3.7.patch \
+ external/epm/asan.patch.0 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/epm/asan.patch.0 b/external/epm/asan.patch.0
new file mode 100644
index 000000000..b17ac26be
--- /dev/null
+++ b/external/epm/asan.patch.0
@@ -0,0 +1,16 @@
+--- dist.c
++++ dist.c
+@@ -405,7 +405,12 @@
+ for (temp = platform->machine; *temp != '\0'; temp ++)
+ if (*temp == '-' || *temp == '_')
+ {
+- strcpy(temp, temp + 1);
++ char * t2 = temp;
++ for (;; ++t2) {
++ char c = t2[1];
++ t2[0] = c;
++ if (c == '\0') break;
++ }
+ temp --;
+ }
+ else
diff --git a/external/epm/epm-3.7.patch b/external/epm/epm-3.7.patch
new file mode 100644
index 000000000..167490121
--- /dev/null
+++ b/external/epm/epm-3.7.patch
@@ -0,0 +1,666 @@
+diff -urN epm-3.7-old//bsd.c epm-3.7/bsd.c
+--- misc/epm-3.7/bsd.c 2003-01-14 17:05:01.000000000 +0000
++++ misc/build/epm-3.7/bsd.c 2010-04-19 22:52:32.000000000 +0000
+@@ -26,6 +26,13 @@
+
+ #include "epm.h"
+
++void cr2semicolon(char *command)
++{
++ int len, i;
++ len=strlen(command);
++ for (i=0;i<len;i++)
++ if(*(command+i)=='\n') *(command+i)=';';
++}
+
+ /*
+ * 'make_bsd()' - Make a FreeBSD software distribution package.
+@@ -149,8 +156,17 @@
+
+ for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++)
+ {
++#ifdef __FreeBSD__
++ if (d->type == DEPEND_REQUIRES) {
++ if (dist->relnumber)
++ fprintf(fp, "@pkgdep %s-%s-%d-%s", d->product, dist->version, dist->relnumber, platname);
++ else
++ fprintf(fp, "@pkgdep %s-%s-%s", d->product, dist->version, platname);
++ }
++#else
+ if (d->type == DEPEND_REQUIRES)
+ fprintf(fp, "@pkgdep %s", d->product);
++#endif
+ else
+ #ifdef __FreeBSD__
+ /*
+@@ -179,9 +195,11 @@
+ " by the BSD packager.\n", stderr);
+ break;
+ case COMMAND_POST_INSTALL :
++ cr2semicolon(c->command);
+ fprintf(fp, "@exec %s\n", c->command);
+ break;
+ case COMMAND_PRE_REMOVE :
++ cr2semicolon(c->command);
+ fprintf(fp, "@unexec %s\n", c->command);
+ break;
+ case COMMAND_POST_REMOVE :
+@@ -199,7 +217,7 @@
+ */
+
+ fprintf(fp, "@exec /bin/mkdir -p %s\n", file->dst);
+- fprintf(fp, "@exec /bin/chown %s:%s %s\n", file->user, file->group,
++ fprintf(fp, "@exec /usr/sbin/chown %s:%s %s\n", file->user, file->group,
+ file->dst);
+ fprintf(fp, "@exec /bin/chmod %04o %s\n", file->mode, file->dst);
+ }
+@@ -326,12 +344,13 @@
+ if (Verbosity)
+ puts("Building FreeBSD pkg binary distribution...");
+
+- if (run_command(NULL, "pkg_create -p / -s %s -c %s -d %s -f %s %s",
++ if (run_command(NULL, "/usr/sbin/pkg_create -p / -s %s -c %s -d %s -f %s %s",
+ current, commentname, descrname, plistname, name))
+ return (1);
+
+- if (run_command(NULL, "mv %s.tgz %s", name, directory))
+- return (1);
++ if (run_command(NULL, "mv %s.tbz %s", name, directory))
++ if (run_command(NULL, "mv %s.tgz %s", name, directory))
++ return (1);
+
+ /*
+ * Remove temporary files...
+diff -urN epm-3.7-old//configure epm-3.7/configure
+--- misc/epm-3.7/configure 2003-07-24 01:20:54.000000000 +0000
++++ misc/build/epm-3.7/configure 2010-04-19 22:52:32.000000000 +0000
+@@ -1238,6 +1238,11 @@
+ fi
+ fi;
+
++# Check whether --enable-fltk or --disable-fltk was given.
++if test "${enable_fltk+set}" = set; then
++ enableval="$enable_fltk"
++fi;
++
+
+ # Check whether --with-docdir or --without-docdir was given.
+ if test "${with_docdir+set}" = set; then
+@@ -4904,36 +4909,38 @@
+ fi
+
+
+-# Extract the first word of "fltk-config", so it can be a program name with args.
+-set dummy fltk-config; ac_word=$2
+-echo "$as_me:$LINENO: checking for $ac_word" >&5
+-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+-if test "${ac_cv_path_FLTKCONFIG+set}" = set; then
+- echo $ECHO_N "(cached) $ECHO_C" >&6
+-else
+- case $FLTKCONFIG in
+- [\\/]* | ?:[\\/]*)
+- ac_cv_path_FLTKCONFIG="$FLTKCONFIG" # Let the user override the test with a path.
+- ;;
+- *)
+- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+-for as_dir in $PATH
+-do
+- IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
+- for ac_exec_ext in '' $ac_executable_extensions; do
+- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+- ac_cv_path_FLTKCONFIG="$as_dir/$ac_word$ac_exec_ext"
+- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+- break 2
++if eval "test x$enable_fltk = xyes"; then
++ # Extract the first word of "fltk-config", so it can be a program name with args.
++ set dummy fltk-config; ac_word=$2
++ echo "$as_me:$LINENO: checking for $ac_word" >&5
++ echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++ if test "${ac_cv_path_FLTKCONFIG+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++ else
++ case $FLTKCONFIG in
++ [\\/]* | ?:[\\/]*)
++ ac_cv_path_FLTKCONFIG="$FLTKCONFIG" # Let the user override the test with a path.
++ ;;
++ *)
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++ for as_dir in $PATH
++ do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_path_FLTKCONFIG="$as_dir/$ac_word$ac_exec_ext"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++ done
++ done
++
++ ;;
++ esac
+ fi
+-done
+-done
+-
+- ;;
+-esac
++ FLTKCONFIG=$ac_cv_path_FLTKCONFIG
+ fi
+-FLTKCONFIG=$ac_cv_path_FLTKCONFIG
+
+ if test -n "$FLTKCONFIG"; then
+ echo "$as_me:$LINENO: result: $FLTKCONFIG" >&5
+@@ -4950,8 +4957,10 @@
+ INSTALL_GUIS=""
+ INSTALL_OSX=""
+
++if eval "test x$enable_fltk = xyes"; then
+ { echo "$as_me:$LINENO: WARNING: Sorry, setup GUI requires FLTK 1.1.x." >&5
+ echo "$as_me: WARNING: Sorry, setup GUI requires FLTK 1.1.x." >&2;}
++fi
+ else
+ CXXFLAGS="`$FLTKCONFIG --cflags` ${CXXFLAGS}"
+ GUIS="setup uninst"
+diff -urN epm-3.7-old//deb.c epm-3.7/deb.c
+--- misc/epm-3.7/deb.c 2003-01-15 14:29:24.000000000 +0000
++++ misc/build/epm-3.7/deb.c 2010-04-19 22:53:34.000000000 +0000
+@@ -26,6 +26,28 @@
+
+ #include "epm.h"
+
++/*
++ * 'add_size()' - Append Installed-Size tag to DEBIAN/control file
++ */
++
++int /* O - 0 = success, 1 = fail */
++add_size(FILE *fpControl, /* Control file stream */
++ const char *directory) /* Directory containing all files to package */
++{
++ FILE *fp;
++ char command[1024];
++
++ snprintf(command, sizeof(command), "du -k -s %s", directory);
++ fp = popen(command, "r");
++ if( NULL != fp )
++ {
++ char size[1024];
++ fscanf(fp, "%s .", size);
++ fprintf(fpControl, "Installed-Size: %s\n", size);
++ return pclose(fp);
++ }
++ return 1;
++}
+
+ /*
+ * 'make_deb()' - Make a Debian software distribution package.
+@@ -61,18 +83,37 @@
+ if (Verbosity)
+ puts("Creating Debian distribution...");
+
++ /*
++ * Use debian default naming scheme
++ */
++
++ if (!strcmp(platform->machine, "intel"))
++#ifdef __FreeBSD_kernel__
++ platname = "kfreebsd-i386";
++#else
++ platname = "i386";
++#endif
++ else if (!strcmp(platform->machine, "x86_64"))
++#ifdef __FreeBSD_kernel__
++ platname = "kfreebsd-amd64";
++#else
++ platname = "amd64";
++#endif
++ else if (!strcmp(platform->machine, "ppc"))
++ platname = "powerpc";
++
+ if (dist->relnumber)
+ {
+ if (platname[0])
+- snprintf(name, sizeof(name), "%s-%s-%d-%s", prodname, dist->version, dist->relnumber,
++ snprintf(name, sizeof(name), "%s_%s-%d_%s", prodname, dist->version, dist->relnumber,
+ platname);
+ else
+- snprintf(name, sizeof(name), "%s-%s-%d", prodname, dist->version, dist->relnumber);
++ snprintf(name, sizeof(name), "%s_%s-%d", prodname, dist->version, dist->relnumber);
+ }
+ else if (platname[0])
+- snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version, platname);
++ snprintf(name, sizeof(name), "%s_%s_%s", prodname, dist->version, platname);
+ else
+- snprintf(name, sizeof(name), "%s-%s", prodname, dist->version);
++ snprintf(name, sizeof(name), "%s_%s", prodname, dist->version);
+
+ /*
+ * Write the control file for DPKG...
+@@ -108,8 +141,20 @@
+ * (which we change in get_platform to a common name)
+ */
+
+- if (strcmp(platform->machine, "intel") == 0)
++ if (!strcmp(platform->machine, "intel"))
++#ifdef __FreeBSD_kernel__
++ fputs("Architecture: kfreebsd-i386\n", fp);
++#else
+ fputs("Architecture: i386\n", fp);
++#endif
++ else if (!strcmp(platform->machine, "x86_64"))
++#ifdef __FreeBSD_kernel__
++ fputs("Architecture: kfreebsd-amd64\n", fp);
++#else
++ fputs("Architecture: amd64\n", fp);
++#endif
++ else if (!strcmp(platform->machine, "ppc"))
++ fputs("Architecture: powerpc\n", fp);
+ else
+ fprintf(fp, "Architecture: %s\n", platform->machine);
+
+@@ -139,7 +192,7 @@
+ else
+ {
+ if (d->vernumber[1] < INT_MAX)
+- fprintf(fp, " (>= %s, <= %s)", d->version[0], d->version[1]);
++ fprintf(fp, " (>= %s), %s (<= %s)", d->version[0], d->product, d->version[1]);
+ else
+ fprintf(fp, " (>= %s)", d->version[0]);
+ }
+@@ -148,9 +193,9 @@
+ putc('\n', fp);
+ }
+ }
+-
++
+ fclose(fp);
+-
++
+ /*
+ * Write the preinst file for DPKG...
+ */
+@@ -417,6 +462,27 @@
+ }
+ }
+
++
++ /*
++ * Calculate and append Installed-Size to DEBIAN/control
++ */
++
++ if (Verbosity)
++ puts("Calculating Installed-Size...");
++
++ snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/control", directory, name);
++ if ((fp = fopen(filename, "a")) == NULL)
++ {
++ fprintf(stderr, "epm: Unable to Installed-Size to file \"%s\" - %s\n", filename,
++ strerror(errno));
++ return (1);
++ }
++
++ snprintf(filename, sizeof(filename), "%s/%s", directory, name);
++ add_size(fp, filename);
++ fclose(fp);
++
++
+ /*
+ * Build the distribution from the spec file...
+ */
+diff -urN epm-3.7-old//dist.c epm-3.7/dist.c
+--- misc/epm-3.7/dist.c 2003-08-07 14:14:40.000000000 +0000
++++ misc/build/epm-3.7/dist.c 2010-04-19 22:52:32.000000000 +0000
+@@ -394,8 +394,13 @@
+ strcpy(platform->machine, "mips");
+ #elif defined(__hpux)
+ strcpy(platform->machine, "hppa");
+-#elif defined(_AIX) || defined(__APPLE__)
++#elif defined(_AIX)
+ strcpy(platform->machine, "powerpc");
++#elif defined(__APPLE__)
++ if (strstr(platform->machine, "86") != NULL)
++ strcpy(platform->machine, "intel");
++ else
++ strcpy(platform->machine, "powerpc");
+ #else
+ for (temp = platform->machine; *temp != '\0'; temp ++)
+ if (*temp == '-' || *temp == '_')
+@@ -407,7 +412,12 @@
+ *temp = tolower(*temp);
+
+ if (strstr(platform->machine, "86") != NULL)
+- strcpy(platform->machine, "intel");
++ {
++ if (strstr(platform->machine, "64") != NULL)
++ strcpy(platform->machine, "x86_64");
++ else
++ strcpy(platform->machine, "intel");
++ }
+ else if (strncmp(platform->machine, "sun", 3) == 0)
+ strcpy(platform->machine, "sparc");
+ #endif /* __sgi */
+diff -urN epm-3.7-old//epm.c epm-3.7/epm.c
+--- misc/epm-3.7/epm.c 2003-10-28 14:48:30.000000000 +0000
++++ misc/build/epm-3.7/epm.c 2010-04-19 22:52:32.000000000 +0000
+@@ -547,6 +547,7 @@
+ {
+ puts(EPM_VERSION);
+ puts("Copyright 1999-2003 by Easy Software Products.");
++ puts("Patched for LibreOffice");
+ puts("");
+ puts("EPM is free software and comes with ABSOLUTELY NO WARRANTY; for details");
+ puts("see the GNU General Public License in the file COPYING or at");
+diff -urN epm-3.7-old//file.c epm-3.7/file.c
+--- misc/epm-3.7/file.c 2003-07-23 21:41:08.000000000 +0000
++++ misc/build/epm-3.7/file.c 2010-04-19 22:52:32.000000000 +0000
+@@ -108,7 +108,6 @@
+ fclose(dstfile);
+
+ chmod(dst, mode);
+- chown(dst, owner, group);
+
+ return (0);
+ }
+@@ -138,7 +137,6 @@
+ {
+ mkdir(buffer, 0777);
+ chmod(buffer, mode | 0700);
+- chown(buffer, owner, group);
+ }
+ }
+
+@@ -151,7 +149,6 @@
+ {
+ mkdir(buffer, 0777);
+ chmod(buffer, mode | 0700);
+- chown(buffer, owner, group);
+ }
+
+ return (0);
+diff -urN epm-3.7-old//osx.c epm-3.7/osx.c
+--- misc/epm-3.7/osx.c 2003-07-23 21:41:08.000000000 +0000
++++ misc/build/epm-3.7/osx.c 2010-04-19 22:52:32.000000000 +0000
+@@ -373,7 +373,7 @@
+ else
+ snprintf(filename, sizeof(filename), "%s/%s", current, directory);
+
+- run_command(NULL, "/Developer/Applications/PackageMaker.app/"
++ run_command(NULL, "/Developer/Applications/Utilities/PackageMaker.app/"
+ "Contents/MacOS/PackageMaker -build "
+ "-p %s/%s.pkg -f %s/Package -r %s/Resources -d %s/%s-desc.plist -i %s/%s-info.plist",
+ filename, prodname, filename, filename, filename, prodname, filename, prodname);
+diff -urN epm-3.7-old//pkg.c epm-3.7/pkg.c
+--- misc/epm-3.7/pkg.c 2002-12-17 18:57:56.000000000 +0000
++++ misc/build/epm-3.7/pkg.c 2010-04-19 22:52:32.000000000 +0000
+@@ -429,75 +429,6 @@
+
+ fclose(fp);
+
+- /*
+- * Build the distribution from the prototype file...
+- */
+-
+- if (Verbosity)
+- puts("Building PKG binary distribution...");
+-
+- if (run_command(NULL, "pkgmk -o -f %s/%s.prototype -d %s/%s",
+- directory, prodname, current, directory))
+- return (1);
+-
+- /*
+- * Tar and compress the distribution...
+- */
+-
+- if (Verbosity)
+- puts("Creating tar.gz file for distribution...");
+-
+- snprintf(filename, sizeof(filename), "%s/%s.tar.gz", directory, name);
+-
+- if ((tarfile = tar_open(filename, 1)) == NULL)
+- return (1);
+-
+- snprintf(filename, sizeof(filename), "%s/%s", directory, prodname);
+-
+- if (tar_directory(tarfile, filename, prodname))
+- {
+- tar_close(tarfile);
+- return (1);
+- }
+-
+- tar_close(tarfile);
+-
+- /*
+- * Make a package stream file...
+- */
+-
+- if (Verbosity)
+- puts("Copying into package stream file...");
+-
+- if (run_command(directory, "pkgtrans -s %s/%s %s.pkg %s",
+- current, directory, name, prodname))
+- return (1);
+-
+- /*
+- * Remove temporary files...
+- */
+-
+- if (!KeepFiles)
+- {
+- if (Verbosity)
+- puts("Removing temporary distribution files...");
+-
+- snprintf(filename, sizeof(filename), "%s/%s.pkginfo", directory, prodname);
+- unlink(filename);
+- snprintf(filename, sizeof(filename), "%s/%s.depend", directory, prodname);
+- unlink(filename);
+- snprintf(filename, sizeof(filename), "%s/%s.prototype", directory, prodname);
+- unlink(filename);
+- if (preinstall[0])
+- unlink(preinstall);
+- if (postinstall[0])
+- unlink(postinstall);
+- if (preremove[0])
+- unlink(preremove);
+- if (postremove[0])
+- unlink(postremove);
+- }
+-
+ return (0);
+ }
+
+diff -urN epm-3.7-old//qprintf.c epm-3.7/qprintf.c
+--- misc/epm-3.7-old/qprintf.c 2003-01-27 21:48:03.000000000 +0000
++++ misc/build/epm-3.7/qprintf.c 2010-04-19 22:52:32.000000000 +0000
+@@ -181,12 +181,19 @@
+
+ for (i = slen; i > 0; i --, s ++, bytes ++)
+ {
++#if defined(__FreeBSD__)
++ if (strchr("`~!#%^&*()[{]}\\|;\'\"<>? ", *s))
++ {
++ putc('\\', fp);
++ bytes ++;
++ }
++#else
+ if (strchr("`~!#$%^&*()[{]}\\|;\'\"<>? ", *s))
+ {
+ putc('\\', fp);
+ bytes ++;
+ }
+-
++#endif
+ putc(*s, fp);
+ }
+
+diff -urN epm-3.7-old//rpm.c epm-3.7/rpm.c
+--- misc/epm-3.7/rpm.c 2003-10-01 19:27:15.000000000 +0000
++++ misc/build/epm-3.7/rpm.c 2010-04-19 22:52:32.000000000 +0000
+@@ -38,7 +38,7 @@
+ dist_t *dist, /* I - Distribution information */
+ struct utsname *platform) /* I - Platform information */
+ {
+- int i; /* Looping var */
++ int i,n; /* Looping vars */
+ FILE *fp; /* Spec file */
+ char name[1024]; /* Full product name */
+ char specname[1024]; /* Spec filename */
+@@ -160,6 +160,8 @@
+ fprintf(fp, "Requires: %s", dname);
+ else if (d->type == DEPEND_PROVIDES)
+ fprintf(fp, "Provides: %s", dname);
++ else if (d->type == DEPEND_REPLACES)
++ fprintf(fp, "Obsoletes: %s", dname);
+ else
+ fprintf(fp, "Conflicts: %s", dname);
+
+@@ -186,15 +188,33 @@
+ for (i = 0; i < dist->num_descriptions; i ++)
+ fprintf(fp, "%s\n", dist->descriptions[i]);
+
+- fputs("%pre\n", fp);
++ /*
++ * %pre
++ */
++ n = 0;
+ for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
++ {
+ if (c->type == COMMAND_PRE_INSTALL)
++ {
++ if (1 == ++n) /* Only write %pre if there is at least one command */
++ fputs("%pre\n", fp);
+ fprintf(fp, "%s\n", c->command);
++ }
++ }
+
+- fputs("%post\n", fp);
++ /*
++ * %post
++ */
++ n = 0;
+ for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
++ {
+ if (c->type == COMMAND_POST_INSTALL)
++ {
++ if (1 == ++n) /* Only write %post if there is at least one command */
++ fputs("%post\n", fp);
+ fprintf(fp, "%s\n", c->command);
++ }
++ }
+
+ for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
+ if (tolower(file->type) == 'i')
+@@ -202,6 +222,8 @@
+
+ if (i)
+ {
++ if (1 == ++n) /* If not previously done so, write %post here */
++ fputs("%post\n", fp);
+ fputs("if test \"x$1\" = x1; then\n", fp);
+ fputs(" echo Setting up init scripts...\n", fp);
+
+@@ -259,13 +281,17 @@
+ fputs("fi\n", fp);
+ }
+
+- fputs("%preun\n", fp);
++ /*
++ * %preun
++ */
++ n = 0;
+ for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
+ if (tolower(file->type) == 'i')
+ break;
+
+ if (i)
+ {
++ fputs("%preun\n", fp); ++n; /* Need to write %preun here */
+ fputs("if test \"x$1\" = x0; then\n", fp);
+ fputs(" echo Cleaning up init scripts...\n", fp);
+
+@@ -315,13 +341,29 @@
+ }
+
+ for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
++ {
+ if (c->type == COMMAND_PRE_REMOVE)
++ {
++ if (1 == ++n) /* Only write %preun if not previously done so */
++ fputs("%preun\n", fp);
++
+ fprintf(fp, "%s\n", c->command);
++ }
++ }
+
+- fputs("%postun\n", fp);
++ /*
++ * %post
++ */
++ n = 0;
+ for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
++ {
+ if (c->type == COMMAND_POST_REMOVE)
++ {
++ if (1 == ++n) /* Only write %post if there is at least one command */
++ fputs("%postun\n", fp);
+ fprintf(fp, "%s\n", c->command);
++ }
++ }
+
+ fputs("%files\n", fp);
+ for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
+@@ -415,53 +457,6 @@
+ }
+ }
+
+- /*
+- * Build the distribution from the spec file...
+- */
+-
+- if (Verbosity)
+- puts("Building RPM binary distribution...");
+-
+- if (strcmp(platform->machine, "intel") == 0)
+- {
+- if (run_command(NULL, EPM_RPMBUILD " %s -bb " EPM_RPMARCH "i386 %s",
+- Verbosity == 0 ? "--quiet" : "", specname))
+- return (1);
+- }
+- else if (run_command(NULL, EPM_RPMBUILD " %s -bb " EPM_RPMARCH "%s %s",
+- Verbosity == 0 ? "--quiet" : "", platform->machine,
+- specname))
+- return (1);
+-
+- /*
+- * Move the RPM to the local directory and rename the RPM using the
+- * product name specified by the user...
+- */
+-
+- if (strcmp(platform->machine, "intel") == 0)
+- run_command(NULL, "/bin/mv %s/RPMS/i386/%s-%s-%d.i386.rpm %s/%s.rpm",
+- rpmdir, prodname, dist->version, dist->relnumber,
+- directory, name);
+- else
+- run_command(NULL, "/bin/mv %s/RPMS/%s/%s-%s-%d.%s.rpm %s/%s.rpm",
+- rpmdir, platform->machine, prodname, dist->version,
+- dist->relnumber, platform->machine, directory, name);
+-
+- /*
+- * Remove temporary files...
+- */
+-
+- if (!KeepFiles)
+- {
+- if (Verbosity)
+- puts("Removing temporary distribution files...");
+-
+- run_command(NULL, "/bin/rm -rf %s/RPMS", directory);
+- run_command(NULL, "/bin/rm -rf %s/buildroot", directory);
+-
+- unlink(specname);
+- }
+-
+ return (0);
+ }
+
diff --git a/external/epoxy/Library_epoxy.mk b/external/epoxy/Library_epoxy.mk
new file mode 100644
index 000000000..81c35d695
--- /dev/null
+++ b/external/epoxy/Library_epoxy.mk
@@ -0,0 +1,65 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,epoxy))
+
+$(eval $(call gb_Library_use_unpacked,epoxy,epoxy))
+
+$(eval $(call gb_Library_set_warnings_disabled,epoxy))
+
+$(eval $(call gb_Library_set_include,epoxy,\
+ -I$(call gb_UnpackedTarball_get_dir,epoxy)/include \
+ -I$(call gb_UnpackedTarball_get_dir,epoxy)/src \
+ $$(INCLUDE) \
+))
+
+ifeq ($(OS),LINUX)
+$(eval $(call gb_Library_add_libs,epoxy,\
+ -ldl \
+))
+endif
+
+$(eval $(call gb_Library_add_generated_cobjects,epoxy,\
+ UnpackedTarball/epoxy/src/dispatch_common \
+ UnpackedTarball/epoxy/src/gl_generated_dispatch \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_Library_add_generated_cobjects,epoxy,\
+ UnpackedTarball/epoxy/src/dispatch_wgl \
+ UnpackedTarball/epoxy/src/wgl_generated_dispatch \
+))
+else ifneq ($(filter iOS MACOSX,$(OS)),)
+# nothing
+else ifeq ($(OS),ANDROID)
+$(eval $(call gb_Library_add_generated_cobjects,epoxy,\
+ UnpackedTarball/epoxy/src/dispatch_egl \
+ UnpackedTarball/epoxy/src/egl_generated_dispatch \
+))
+else
+$(eval $(call gb_Library_add_generated_cobjects,epoxy,\
+ UnpackedTarball/epoxy/src/dispatch_glx \
+ UnpackedTarball/epoxy/src/glx_generated_dispatch \
+))
+ifeq ($(ENABLE_GTK3),TRUE)
+$(eval $(call gb_Library_add_cflags,epoxy,\
+ -DPLATFORM_HAS_EGL=1 \
+))
+$(eval $(call gb_Library_add_generated_cobjects,epoxy,\
+ UnpackedTarball/epoxy/src/dispatch_egl \
+ UnpackedTarball/epoxy/src/egl_generated_dispatch \
+))
+else
+$(eval $(call gb_Library_add_cflags,epoxy,\
+ -DPLATFORM_HAS_EGL=0 \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/epoxy/Makefile b/external/epoxy/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/epoxy/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/epoxy/Module_epoxy.mk b/external/epoxy/Module_epoxy.mk
new file mode 100644
index 000000000..ea65176b8
--- /dev/null
+++ b/external/epoxy/Module_epoxy.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,epoxy))
+
+$(eval $(call gb_Module_add_targets,epoxy,\
+ Library_epoxy \
+ UnpackedTarball_epoxy \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/epoxy/README b/external/epoxy/README
new file mode 100644
index 000000000..8bd467af5
--- /dev/null
+++ b/external/epoxy/README
@@ -0,0 +1,5 @@
+Epoxy is an OpenGL Extension Wrangler
+
+Epoxy is a library for handling OpenGL function pointer management for you
+
+https://github.com/anholt/libepoxy
diff --git a/external/epoxy/UnpackedTarball_epoxy.mk b/external/epoxy/UnpackedTarball_epoxy.mk
new file mode 100644
index 000000000..b8508c6b9
--- /dev/null
+++ b/external/epoxy/UnpackedTarball_epoxy.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,epoxy))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,epoxy,$(EPOXY_TARBALL)))
+
+$(call gb_UnpackedTarball_get_target,epoxy) :| $(call gb_ExternalExecutable_get_dependencies,python)
+
+epoxy_PYTHON := $(call gb_ExternalExecutable_get_command,python)
+
+# previous versions of epoxy bundled the output, but now it has to be generated
+$(eval $(call gb_UnpackedTarball_set_pre_action,epoxy,\
+ $(epoxy_PYTHON) ./src/gen_dispatch.py --srcdir src --includedir include/epoxy registry/gl.xml && \
+ $(epoxy_PYTHON) ./src/gen_dispatch.py --srcdir src --includedir include/epoxy registry/glx.xml && \
+ $(epoxy_PYTHON) ./src/gen_dispatch.py --srcdir src --includedir include/epoxy registry/egl.xml && \
+ $(epoxy_PYTHON) ./src/gen_dispatch.py --srcdir src --includedir include/epoxy registry/wgl.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,epoxy,0))
+
+# * external/external/epoxy/epoxy.android.patch upstream at
+# <https://github.com/anholt/libepoxy/pull/263> "fix error: use of undeclared identifier 'OPENGL_LIB'":
+$(eval $(call gb_UnpackedTarball_add_patches,epoxy, \
+ external/epoxy/epoxy.visibility.patch \
+ external/epoxy/epoxy.windows.api.patch \
+ external/epoxy/epoxy.noegl.by.default.patch \
+ external/epoxy/clang-cl.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/epoxy/clang-cl.patch b/external/epoxy/clang-cl.patch
new file mode 100644
index 000000000..0e0232cea
--- /dev/null
+++ b/external/epoxy/clang-cl.patch
@@ -0,0 +1,14 @@
+--- src/dispatch_common.c
++++ src/dispatch_common.c
+@@ -272,7 +272,11 @@
+ #endif
+ };
+
++#if defined _MSC_VER && defined __clang__
++static bool library_initialized = true;
++#else
+ static bool library_initialized;
++#endif
+
+ static bool epoxy_current_context_is_glx(void);
+
diff --git a/external/epoxy/epoxy.noegl.by.default.patch b/external/epoxy/epoxy.noegl.by.default.patch
new file mode 100644
index 000000000..bf8945336
--- /dev/null
+++ b/external/epoxy/epoxy.noegl.by.default.patch
@@ -0,0 +1,28 @@
+--- src/dispatch_common.h
++++ src/dispatch_common.h
+@@ -24,20 +24,19 @@
+ #include "config.h"
+
+ #ifdef _WIN32
+-#define PLATFORM_HAS_EGL ENABLE_EGL
+-#define PLATFORM_HAS_GLX ENABLE_GLX
++#define PLATFORM_HAS_EGL 0
++#define PLATFORM_HAS_GLX 0
+ #define PLATFORM_HAS_WGL 1
+ #elif defined(__APPLE__)
+ #define PLATFORM_HAS_EGL 0
+-#define PLATFORM_HAS_GLX ENABLE_GLX
++#define PLATFORM_HAS_GLX 0
+ #define PLATFORM_HAS_WGL 0
+ #elif defined(ANDROID)
+-#define PLATFORM_HAS_EGL ENABLE_EGL
++#define PLATFORM_HAS_EGL 1
+ #define PLATFORM_HAS_GLX 0
+ #define PLATFORM_HAS_WGL 0
+ #else
+-#define PLATFORM_HAS_EGL ENABLE_EGL
+-#define PLATFORM_HAS_GLX ENABLE_GLX
++#define PLATFORM_HAS_GLX 1
+ #define PLATFORM_HAS_WGL 0
+ #endif
+
diff --git a/external/epoxy/epoxy.visibility.patch b/external/epoxy/epoxy.visibility.patch
new file mode 100644
index 000000000..12297b5e2
--- /dev/null
+++ b/external/epoxy/epoxy.visibility.patch
@@ -0,0 +1,5 @@
+--- src/config.h 2018-08-28 13:19:40.699141662 +0100
++++ src/config.h 2018-08-28 13:21:51.942139881 +0100
+@@ -0,0 +1,2 @@
++#include <sal/types.h>
++#define EPOXY_PUBLIC SAL_DLLPUBLIC_EXPORT extern
diff --git a/external/epoxy/epoxy.windows.api.patch b/external/epoxy/epoxy.windows.api.patch
new file mode 100644
index 000000000..985f2d880
--- /dev/null
+++ b/external/epoxy/epoxy.windows.api.patch
@@ -0,0 +1,12 @@
+--- include/epoxy/gl.h
++++ include/epoxy/gl.h
+@@ -59,7 +59,8 @@
+
+ #else
+ #ifndef APIENTRY
+-#define APIENTRY __stdcall
++#define WINAPI __stdcall
++#define APIENTRY WINAPI
+ #endif
+
+ #ifndef GLAPIENTRY
diff --git a/external/expat/ExternalProject_expat.mk b/external/expat/ExternalProject_expat.mk
new file mode 100644
index 000000000..1e9609a4a
--- /dev/null
+++ b/external/expat/ExternalProject_expat.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,expat))
+
+$(eval $(call gb_ExternalProject_register_targets,expat,\
+ configure \
+))
+
+$(call gb_ExternalProject_get_state_target,expat,configure) :
+ $(call gb_Trace_StartRange,expat,EXTERNAL)
+ $(call gb_ExternalProject_run,configure,\
+ $(gb_RUN_CONFIGURE) ./configure --without-docbook \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),$(if $(filter INTEL ARM,$(CPUNAME)),ac_cv_c_bigendian=no)) \
+ ,,expat_configure.log)
+ $(call gb_Trace_EndRange,expat,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/expat/Makefile b/external/expat/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/expat/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/expat/Module_expat.mk b/external/expat/Module_expat.mk
new file mode 100644
index 000000000..baac0b595
--- /dev/null
+++ b/external/expat/Module_expat.mk
@@ -0,0 +1,30 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,expat))
+
+$(eval $(call gb_Module_add_targets,expat,\
+ UnpackedTarball_expat \
+ StaticLibrary_expat \
+))
+
+ifneq ($(OS),WNT)
+$(eval $(call gb_Module_add_targets,expat,\
+ ExternalProject_expat \
+))
+endif
+
+# ---------------- X64 stuff special ---------------------
+ifeq ($(BUILD_X64),TRUE)
+$(eval $(call gb_Module_add_targets,expat,\
+ StaticLibrary_expat_x64 \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/expat/README b/external/expat/README
new file mode 100644
index 000000000..e7c93c246
--- /dev/null
+++ b/external/expat/README
@@ -0,0 +1,4 @@
+Simple SAX parser library with added UTF-16 support.
+
+From:
+[https://github.com/libexpat/libexpat]
diff --git a/external/expat/StaticLibrary_expat.mk b/external/expat/StaticLibrary_expat.mk
new file mode 100644
index 000000000..025ab617a
--- /dev/null
+++ b/external/expat/StaticLibrary_expat.mk
@@ -0,0 +1,51 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,expat))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,expat))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,expat,expat))
+
+# no configure step on windows, no dependency
+ifneq ($(OS),WNT)
+$(eval $(call gb_StaticLibrary_use_external_project,expat,expat,full))
+endif
+
+$(eval $(call gb_StaticLibrary_set_include,expat,\
+ -I$(call gb_UnpackedTarball_get_dir,expat) \
+ $$(INCLUDE) \
+))
+
+ifeq ($(OS),MACOSX)
+ifneq ($(strip $(SYSBASE)),)
+$(eval $(call gb_StaticLibrary_add_defs,expat,\
+ -DHAVE_MEMMOVE \
+ -DHAVE_BCOPY \
+))
+endif
+endif
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_StaticLibrary_add_defs,expat,\
+ -DCOMPILED_FROM_DSP \
+))
+else
+$(eval $(call gb_StaticLibrary_add_defs,expat,\
+ -DHAVE_EXPAT_CONFIG_H \
+))
+endif
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,expat,\
+ UnpackedTarball/expat/lib/xmlparse \
+ UnpackedTarball/expat/lib/xmlrole \
+ UnpackedTarball/expat/lib/xmltok \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/expat/StaticLibrary_expat_x64.mk b/external/expat/StaticLibrary_expat_x64.mk
new file mode 100644
index 000000000..68bb7f86a
--- /dev/null
+++ b/external/expat/StaticLibrary_expat_x64.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,expat_x64))
+
+$(eval $(call gb_StaticLibrary_set_x64,expat_x64,YES))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,expat_x64))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,expat_x64,expat))
+
+$(eval $(call gb_StaticLibrary_set_include,expat_x64,\
+ -I$(call gb_UnpackedTarball_get_dir,expat) \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_StaticLibrary_add_defs,expat_x64,\
+ -DCOMPILED_FROM_DSP \
+))
+
+$(eval $(call gb_StaticLibrary_add_x64_generated_cobjects,expat_x64,\
+ UnpackedTarball/expat/lib/xmlparse_x64 \
+ UnpackedTarball/expat/lib/xmltok_x64 \
+ UnpackedTarball/expat/lib/xmlrole_x64 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/expat/UnpackedTarball_expat.mk b/external/expat/UnpackedTarball_expat.mk
new file mode 100644
index 000000000..5d4f41f6d
--- /dev/null
+++ b/external/expat/UnpackedTarball_expat.mk
@@ -0,0 +1,34 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,expat))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,expat,$(EXPAT_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,expat,conftools))
+
+$(eval $(call gb_UnpackedTarball_add_patches,expat,\
+ external/expat/expat-winapi.patch \
+))
+
+# This is a bit hackish.
+
+# When building for Windows (as 32-bit) we need to build it twice: as
+# 32- and 64-bit code, to be able to produce a 64-bit Explorer
+# ("shell") extension that is used when the 32-bit LibreOffice is
+# installed on a 64-bit OS.
+
+$(eval $(call gb_UnpackedTarball_set_post_action,expat,\
+ $(if $(filter $(BUILD_X64),TRUE), \
+ cp lib/xmlparse.c lib/xmlparse_x64.c && \
+ cp lib/xmltok.c lib/xmltok_x64.c && \
+ cp lib/xmlrole.c lib/xmlrole_x64.c) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/expat/expat-winapi.patch b/external/expat/expat-winapi.patch
new file mode 100644
index 000000000..fed65644a
--- /dev/null
+++ b/external/expat/expat-winapi.patch
@@ -0,0 +1,25 @@
+--- misc/expat-2.5.0/lib/expat_external.h 2022-10-25 01:32:54.000000000 +0900
++++ misc/build/expat-2.5.0/lib/expat_external.h 2022-10-30 23:09:47.339459134 +0900
+@@ -88,10 +88,6 @@
+ # ifndef XML_BUILDING_EXPAT
+ /* using Expat from an application */
+
+-# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__)
+-# define XMLIMPORT __declspec(dllimport)
+-# endif
+-
+ # endif
+ #endif /* not defined XML_STATIC */
+
+--- misc/expat-2.5.0/lib/xmlparse.c 2022-10-26 00:09:08.000000000 +0900
++++ misc/build/expat-2.5.0/lib/xmlparse.c 2022-10-30 23:09:01.843006341 +0900
+@@ -67,6 +67,9 @@
+ #endif
+
+ #ifdef _WIN32
++# undef HAVE_ARC4RANDOM_BUF
++# undef HAVE_GETRANDOM
++# undef HAVE_SYSCALL_GETRANDOM
+ /* force stdlib to define rand_s() */
+ # if ! defined(_CRT_RAND_S)
+ # define _CRT_RAND_S
diff --git a/external/firebird/0001-Fix-checks-for-null-HANDLE-in-Windows-only-code.patch.1 b/external/firebird/0001-Fix-checks-for-null-HANDLE-in-Windows-only-code.patch.1
new file mode 100644
index 000000000..22cc1e119
--- /dev/null
+++ b/external/firebird/0001-Fix-checks-for-null-HANDLE-in-Windows-only-code.patch.1
@@ -0,0 +1,41 @@
+From f4c0aa3ba070e5c3ce996b33a31323a3a6820f0c Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman@redhat.com>
+Date: Wed, 2 Dec 2020 10:44:28 +0100
+Subject: Fix checks for null HANDLE in Windows-only code
+
+clang-cl failed with "error: unordered comparison between pointer and zero
+('HANDLE' (aka 'void *') and 'int')" in these two places introduced with
+f219283b72ab537c2b5938222708f35227c1ebde "Sub-task CORE-4463: Windows
+implementation for CORE-4462 (Make it possible to restore compressed .nbk files
+without explicitly decompressing them)" and
+c2cfa7824189ed7c3e5a19721effdf97c07dadfd "Prevent child process hung if it
+writes too much data to the pipe and overflow the pipe buffer".
+---
+ src/utilities/nbackup/nbackup.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/utilities/nbackup/nbackup.cpp b/src/utilities/nbackup/nbackup.cpp
+index 6598b6e331..4703079d67 100644
+--- a/src/utilities/nbackup/nbackup.cpp
++++ b/src/utilities/nbackup/nbackup.cpp
+@@ -385,7 +385,7 @@ FB_SIZE_T NBackup::read_file(FILE_HANDLE &file, void *buffer, FB_SIZE_T bufsize)
+ #ifdef WIN_NT
+ // Read child's stderr often to prevent child process hung if it writes
+ // too much data to the pipe and overflow the pipe buffer.
+- const bool checkChild = (childStdErr > 0 && file == backup);
++ const bool checkChild = (childStdErr != 0 && file == backup);
+ if (checkChild)
+ print_child_stderr();
+
+@@ -790,7 +790,7 @@ void NBackup::close_backup()
+ return;
+ #ifdef WIN_NT
+ CloseHandle(backup);
+- if (childId > 0)
++ if (childId != 0)
+ {
+ const bool killed = (WaitForSingleObject(childId, 5000) != WAIT_OBJECT_0);
+ if (killed)
+--
+2.28.0
+
diff --git a/external/firebird/0001-Fix-warning-on-Win64-build-231.patch.1 b/external/firebird/0001-Fix-warning-on-Win64-build-231.patch.1
new file mode 100644
index 000000000..0e21f9e27
--- /dev/null
+++ b/external/firebird/0001-Fix-warning-on-Win64-build-231.patch.1
@@ -0,0 +1,37 @@
+From 60cb8e07b17ad8533d7d13f52435aa11e48f4659 Mon Sep 17 00:00:00 2001
+From: Dimitry Sibiryakov <sd@ibphoenix.com>
+Date: Tue, 12 Nov 2019 13:42:49 +0100
+Subject: [PATCH] Fix warning on Win64 build (#231)
+
+---
+ src/common/ThreadStart.cpp | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/common/ThreadStart.cpp b/src/common/ThreadStart.cpp
+index 184c93a32b..758056432f 100644
+--- a/src/common/ThreadStart.cpp
++++ b/src/common/ThreadStart.cpp
+@@ -309,13 +309,16 @@ Thread Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Han
+ * Advanced Windows by Richter pg. # 109. */
+
+ unsigned thread_id;
+- unsigned long real_handle =
+- _beginthreadex(NULL, 0, THREAD_ENTRYPOINT, THREAD_ARG, CREATE_SUSPENDED, &thread_id);
+- if (!real_handle)
++ HANDLE handle =
++ reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, THREAD_ENTRYPOINT, THREAD_ARG, CREATE_SUSPENDED, &thread_id));
++ if (!handle)
+ {
++ // Though MSDN says that _beginthreadex() returns error in errno,
++ // GetLastError() still works because RTL call no other system
++ // functions after CreateThread() in the case of error.
++ // Watch out if it is ever changed.
+ Firebird::system_call_failed::raise("_beginthreadex", GetLastError());
+ }
+- HANDLE handle = reinterpret_cast<HANDLE>(real_handle);
+
+ SetThreadPriority(handle, priority);
+
+--
+2.20.1
+
diff --git a/external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1 b/external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1
new file mode 100644
index 000000000..42c677f7e
--- /dev/null
+++ b/external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1
@@ -0,0 +1,49 @@
+From 15390d75ee6ca429dbbe15ea04214df8a30fbd48 Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman@redhat.com>
+Date: Mon, 21 Oct 2019 17:54:18 +0200
+Subject: [PATCH] Make comparison operator member functions const
+
+...which avoids overload resolution ambiguities in C++20, when a synthesized
+candidate of operator == for a reversed-argument rewrite conflicts with the
+actual operator ==, due to the asymmetric const-ness of the implicit object
+parameter and the RHS parameter. (As observed with recent Clang 10 trunk with
+-std=c++2a when building firebird as part of LibreOffice:
+
+> workdir/UnpackedTarball/firebird/src/jrd/inf.cpp:1139:62: error: use of overloaded operator '!=' is ambiguous (with operand types 'RuntimeStatistics::Iterator' and 'Jrd::RuntimeStatistics::Iterator')
+> for (RuntimeStatistics::Iterator iter = stats.begin(); iter != stats.end(); ++iter)
+> ~~~~ ^ ~~~~~~~~~~~
+> workdir/UnpackedTarball/firebird/src/jrd/../dsql/../jrd/RuntimeStatistics.h:283:8: note: candidate function
+> bool operator!=(const Iterator& other)
+> ^
+> workdir/UnpackedTarball/firebird/src/jrd/../dsql/../jrd/RuntimeStatistics.h:278:8: note: candidate function
+> bool operator==(const Iterator& other)
+> ^
+> workdir/UnpackedTarball/firebird/src/jrd/../dsql/../jrd/RuntimeStatistics.h:278:8: note: candidate function (with reversed parameter order)
+
+)
+---
+ src/jrd/RuntimeStatistics.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/jrd/RuntimeStatistics.h b/src/jrd/RuntimeStatistics.h
+index 74a03de2ad..fab286ad1a 100644
+--- a/src/jrd/RuntimeStatistics.h
++++ b/src/jrd/RuntimeStatistics.h
+@@ -290,12 +290,12 @@ public:
+ {}
+
+ public:
+- bool operator==(const Iterator& other)
++ bool operator==(const Iterator& other) const
+ {
+ return (m_counts == other.m_counts);
+ }
+
+- bool operator!=(const Iterator& other)
++ bool operator!=(const Iterator& other) const
+ {
+ return (m_counts != other.m_counts);
+ }
+--
+2.21.0
+
diff --git a/external/firebird/0001-extern-cloop-Missing-dependencies-of-compilations-on.patch.1 b/external/firebird/0001-extern-cloop-Missing-dependencies-of-compilations-on.patch.1
new file mode 100644
index 000000000..a59e70e06
--- /dev/null
+++ b/external/firebird/0001-extern-cloop-Missing-dependencies-of-compilations-on.patch.1
@@ -0,0 +1,41 @@
+From 8305b41bb262b6e249f2551639fa88392e152287 Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman@redhat.com>
+Date: Tue, 7 Sep 2021 08:47:32 +0200
+Subject: [PATCH] extern/cloop: Missing dependencies of compilations on output
+ directories
+
+When building Firebird 3.0.7 as part of LibreOffice, we noticed occasional build
+failures like <https://ci.libreoffice.org/job/gerrit_linux_clang_dbgutil/96392/>
+
+> error: unable to open output file '/home/tdf/lode/jenkins/workspace/lo_gerrit/Config/linux_clang_dbgutil_64/workdir/UnpackedTarball/firebird/temp/Debug/cloop/release/tests/test1/CTest.o': 'No such file or directory'
+> 1 error generated.
+> Makefile:72: recipe for target '/home/tdf/lode/jenkins/workspace/lo_gerrit/Config/linux_clang_dbgutil_64/workdir/UnpackedTarball/firebird/temp/Debug/cloop/release/tests/test1/CTest.o' failed
+
+and while target "all" depends on target "mkdirs" (which would create all those
+directories) in extern/cloop/Makefile, there is no order among the dependencies
+of "all", so no guarantee that the directories are already created when the
+compilation recipes are executed.
+---
+ extern/cloop/Makefile | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/extern/cloop/Makefile b/extern/cloop/Makefile
+index 3fca0c7356..c5a2b52628 100644
+--- a/extern/cloop/Makefile
++++ b/extern/cloop/Makefile
+@@ -54,10 +54,10 @@ vpath %.c $(SRC_DIRS)
+ vpath %.cpp $(SRC_DIRS)
+
+ define compile
+-$1/%.o: %.c
++$1/%.o: %.c | $1
+ $(CC) -c $$(C_FLAGS) $$< -o $$@
+
+-$1/%.o: %.cpp
++$1/%.o: %.cpp | $1
+ $(CXX) -c $$(CXX_FLAGS) $$< -o $$@
+ endef
+
+--
+2.31.1
+
diff --git a/external/firebird/0001-extern-cloop-Missing-dependency-of-BIN_DIR-cloop-on-.patch.1 b/external/firebird/0001-extern-cloop-Missing-dependency-of-BIN_DIR-cloop-on-.patch.1
new file mode 100644
index 000000000..816f65376
--- /dev/null
+++ b/external/firebird/0001-extern-cloop-Missing-dependency-of-BIN_DIR-cloop-on-.patch.1
@@ -0,0 +1,67 @@
+From e594cf4c8590bd75a544860b472a5bbf6d5a3d0e Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman@redhat.com>
+Date: Thu, 3 Dec 2020 13:56:34 +0100
+Subject: [PATCH] extern/cloop: Missing dependency of $(BIN_DIR)/cloop on
+ $(BIN_DIR)
+
+When building Firebird 3.0.7 as part of LibreOffice, I saw it fail once (at
+<https://ci.libreoffice.org/job/gerrit_linux_clang_dbgutil/74624/>) with
+
+[...]
+> config.status: creating gen/Makefile.extern.editline
+> config.status: creating src/include/gen/autoconfig.auto
+> config.status: executing libtool commands
+>
+>
+> The Firebird3 package has been configured with the following options:
+>
+> Raw devices : enabled
+> Service name : gds_db
+> Service port : 3050
+> GPRE modules : c_cxx.cpp
+>
+> Install Dir : /usr/local/firebird
+>
+> mkpar.c:182:2: warning: add explicit braces to avoid dangling else [-Wdangling-else]
+> else
+> ^
+> 1 warning generated.
+> main.o: In function `create_file_names':
+> main.c:(.text+0x976): warning: the use of `mktemp' is dangerous, better use `mkstemp'
+> /usr/bin/ld: cannot open output file /home/tdf/lode/jenkins/workspace/lo_gerrit/Config/linux_clang_dbgutil_64/workdir/UnpackedTarball/firebird/gen/Debug/cloop/release/bin/cloop: No such file or directory
+> clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
+> Makefile:84: recipe for target '/home/tdf/lode/jenkins/workspace/lo_gerrit/Config/linux_clang_dbgutil_64/workdir/UnpackedTarball/firebird/gen/Debug/cloop/release/bin/cloop' failed
+> make[6]: *** [/home/tdf/lode/jenkins/workspace/lo_gerrit/Config/linux_clang_dbgutil_64/workdir/UnpackedTarball/firebird/gen/Debug/cloop/release/bin/cloop] Error 1
+> make[6]: Target 'all' not remade because of errors.
+> Makefile:130: recipe for target 'extern' failed
+> make[5]: *** [extern] Error 2
+> Makefile:181: recipe for target 'master_process' failed
+> make[4]: *** [master_process] Error 2
+> Makefile:72: recipe for target 'Debug' failed
+> make[3]: *** [Debug] Error 2
+> Makefile:6: recipe for target 'Debug' failed
+> make[2]: *** [Debug] Error 2
+> /home/tdf/lode/jenkins/workspace/lo_gerrit/Config/linux_clang_dbgutil_64/external/firebird/ExternalProject_firebird.mk:29: recipe for target '/home/tdf/lode/jenkins/workspace/lo_gerrit/Config/linux_clang_dbgutil_64/workdir/ExternalProject/firebird/build' failed
+> make[1]: *** [/home/tdf/lode/jenkins/workspace/lo_gerrit/Config/linux_clang_dbgutil_64/workdir/ExternalProject/firebird/build] Error 1
+[...]
+
+(cherry picked from commit 8e9c48a94659d0c8ac80f716d321b934d47bbed1)
+---
+ extern/cloop/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/extern/cloop/Makefile b/extern/cloop/Makefile
+index 6bc6af41a1..811711fcab 100644
+--- a/extern/cloop/Makefile
++++ b/extern/cloop/Makefile
+@@ -80,6 +80,7 @@ $(BIN_DIR)/cloop: \
+ $(OBJ_DIR)/cloop/Lexer.o \
+ $(OBJ_DIR)/cloop/Parser.o \
+ $(OBJ_DIR)/cloop/Main.o \
++ | $(BIN_DIR)
+
+ $(LD) $^ -o $@
+
+--
+2.28.0
+
diff --git a/external/firebird/ExternalPackage_firebird.mk b/external/firebird/ExternalPackage_firebird.mk
new file mode 100644
index 000000000..2416c13d6
--- /dev/null
+++ b/external/firebird/ExternalPackage_firebird.mk
@@ -0,0 +1,28 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,firebird,firebird))
+
+$(eval $(call gb_ExternalPackage_use_external_project,firebird,firebird))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/ifbclient.dll,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/bin/ifbclient.dll))
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/Engine12.dll,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/Engine12.dll))
+else ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libfbclient.dylib.3.0.7,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/lib/libfbclient.dylib.3.0.7))
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libEngine12.dylib,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/libEngine12.dylib))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libfbclient.so.2,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/lib/libfbclient.so.3.0.7))
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libEngine12.so,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/libEngine12.so))
+endif
+
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_SHARE_FOLDER)/firebird/firebird.msg,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/firebird.msg))
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_SHARE_FOLDER)/firebird/security3.fdb,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/security3.fdb))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/firebird/ExternalProject_firebird.mk b/external/firebird/ExternalProject_firebird.mk
new file mode 100644
index 000000000..ccbd69fff
--- /dev/null
+++ b/external/firebird/ExternalProject_firebird.mk
@@ -0,0 +1,107 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,firebird))
+
+$(eval $(call gb_ExternalProject_use_autoconf,firebird,build))
+
+$(eval $(call gb_ExternalProject_use_externals,firebird,\
+ boost_headers \
+ icu \
+ libatomic_ops \
+ libtommath \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,firebird,\
+ build \
+))
+
+firebird_BUILDDIR = $(EXTERNAL_WORKDIR)/gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird
+firebird_VERSION := 3.0.7
+
+$(call gb_ExternalProject_get_state_target,firebird,build):
+ $(call gb_Trace_StartRange,firebird,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && export CPPFLAGS=" \
+ $(BOOST_CPPFLAGS) \
+ $(if $(SYSTEM_LIBATOMIC_OPS),$(LIBATOMIC_OPS_CFLAGS), \
+ -I$(call gb_UnpackedTarball_get_dir,libatomic_ops)/src \
+ ) \
+ $(if $(SYSTEM_LIBTOMMATH),$(LIBTOMMATH_CFLAGS), \
+ -I$(call gb_UnpackedTarball_get_dir,libtommath) \
+ ) \
+ $(if $(SYSTEM_ICU),$(ICU_CPPFLAGS), \
+ -I$(call gb_UnpackedTarball_get_dir,icu)/source \
+ -I$(call gb_UnpackedTarball_get_dir,icu)/source/i18n \
+ -I$(call gb_UnpackedTarball_get_dir,icu)/source/common \
+ ) \
+ $(if $(filter GCC-INTEL,$(COM)-$(CPUNAME)),-Di386=1) \
+ " \
+ && export CFLAGS=" \
+ $(if $(filter MSC,$(COM)),$(if $(MSVC_USE_DEBUG_RUNTIME),-DMSVC_USE_DEBUG_RUNTIME)) \
+ $(if $(filter MSC-TRUE-X86_64,$(COM)-$(COM_IS_CLANG)-$(CPUNAME)),-march=x86-64-v2) \
+ $(if $(HAVE_GCC_FNO_SIZED_DEALLOCATION),-fno-sized-deallocation -fno-delete-null-pointer-checks) \
+ $(call gb_ExternalProject_get_build_flags,firebird) \
+ $(if $(ENABLE_DEBUG),$(if $(filter MSC,$(COM)),-Od -Z7)) \
+ " \
+ && export CXXFLAGS=" \
+ $(BOOST_CXXFLAGS) \
+ $(if $(filter MSC,$(COM)),$(if $(MSVC_USE_DEBUG_RUNTIME),-DMSVC_USE_DEBUG_RUNTIME)) \
+ $(if $(filter MSC-TRUE-X86_64,$(COM)-$(COM_IS_CLANG)-$(CPUNAME)),-march=x86-64-v2) \
+ $(if $(HAVE_GCC_FNO_SIZED_DEALLOCATION),-fno-sized-deallocation -fno-delete-null-pointer-checks) \
+ $(CXXFLAGS_CXX11) \
+ $(if $(filter TRUE,$(COM_IS_CLANG)), -Wno-c++11-narrowing) \
+ $(call gb_ExternalProject_get_build_flags,firebird) \
+ $(if $(ENABLE_DEBUG),$(if $(filter MSC,$(COM)),-Od -Z7)) \
+ " \
+ && export LDFLAGS=" \
+ $(call gb_ExternalProject_get_link_flags,firebird) \
+ $(if $(SYSTEM_LIBATOMIC_OPS),$(LIBATOMIC_OPS_LIBS), \
+ -L$(call gb_UnpackedTarball_get_dir,libatomic_ops)/src \
+ ) \
+ $(if $(SYSTEM_LIBTOMMATH),$(LIBTOMMATH_LIBS), \
+ -L$(call gb_UnpackedTarball_get_dir,libtommath) \
+ ) \
+ $(if $(SYSTEM_ICU),$(ICU_LIBS), \
+ -L$(call gb_UnpackedTarball_get_dir,icu)/source/lib \
+ ) \
+ " \
+ && export LIBREOFFICE_ICU_LIB="$(call gb_UnpackedTarball_get_dir,icu)/source/lib" \
+ && export MSVC_USE_INDIVIDUAL_PDBS=TRUE \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --without-editline \
+ --with-wire-compress=no \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ && LC_ALL=C $(MAKE) \
+ $(if $(ENABLE_DEBUG),Debug) SHELL='$(SHELL)' $(if $(filter LINUX,$(OS)),CXXFLAGS="$$CXXFLAGS -std=gnu++11") \
+ MATHLIB="$(if $(SYSTEM_LIBTOMMATH),$(LIBTOMMATH_LIBS),-L$(call gb_UnpackedTarball_get_dir,libtommath) -ltommath)" \
+ LIBO_TUNNEL_LIBRARY_PATH='$(subst ','\'',$(subst $$,$$$$,$(call gb_Helper_extend_ld_path,$(call gb_UnpackedTarball_get_dir,icu)/source/lib)))' \
+ $(if $(filter MACOSX,$(OS)), \
+ && install_name_tool -id @__________________________________________________OOO/libfbclient.dylib.$(firebird_VERSION) \
+ -delete_rpath @loader_path/.. \
+ $(firebird_BUILDDIR)/lib/libfbclient.dylib.$(firebird_VERSION) \
+ && install_name_tool -id @__________________________________________________OOO/libEngine12.dylib \
+ -delete_rpath @loader_path/.. \
+ $(firebird_BUILDDIR)/plugins/libEngine12.dylib \
+ && install_name_tool -change @rpath/lib/libfbclient.dylib \
+ @loader_path/libfbclient.dylib.$(firebird_VERSION) $(firebird_BUILDDIR)/plugins/libEngine12.dylib \
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(firebird_BUILDDIR)/lib/libfbclient.dylib.$(firebird_VERSION) \
+ $(firebird_BUILDDIR)/plugins/libEngine12.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,firebird,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/firebird/Makefile b/external/firebird/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/firebird/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/firebird/Module_firebird.mk b/external/firebird/Module_firebird.mk
new file mode 100644
index 000000000..d74963f7f
--- /dev/null
+++ b/external/firebird/Module_firebird.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,firebird))
+
+$(eval $(call gb_Module_add_targets,firebird,\
+ ExternalPackage_firebird \
+ ExternalProject_firebird \
+ UnpackedTarball_firebird \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/firebird/README b/external/firebird/README
new file mode 100644
index 000000000..cc7c72743
--- /dev/null
+++ b/external/firebird/README
@@ -0,0 +1,3 @@
+Firebird is an embeddable SQL RDBMS implemented in C++
+
+http://firebirdsql.org/
diff --git a/external/firebird/UnpackedTarball_firebird.mk b/external/firebird/UnpackedTarball_firebird.mk
new file mode 100644
index 000000000..0233ce24d
--- /dev/null
+++ b/external/firebird/UnpackedTarball_firebird.mk
@@ -0,0 +1,82 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,firebird))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,firebird,$(FIREBIRD_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,firebird,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,firebird,\
+ builds/make.new/config \
+ extern/editline \
+))
+
+# * external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1 is upstream at
+# <https://github.com/FirebirdSQL/firebird/pull/227> "Make comparison operator member functions
+# const";
+# * external/firebird/0001-Fix-checks-for-null-HANDLE-in-Windows-only-code.patch.1 is upstream at
+# <https://github.com/FirebirdSQL/firebird/pull/301> "Fix checks for null HANDLE in Windows-only
+# code",
+# * external/firebird/0001-extern-cloop-Missing-dependency-of-BIN_DIR-cloop-on-.patch.1 is upstream
+# at <https://github.com/FirebirdSQL/firebird/pull/302> "extern/cloop: Missing dependency of
+# $(BIN_DIR)/cloop on $(BIN_DIR)",
+# * external/firebird/0001-extern-cloop-Missing-dependencies-of-compilations-on.patch.1 is upstream
+# at <https://github.com/FirebirdSQL/firebird/pull/6948> "extern/cloop: Missing dependencies of
+# compilations on output directories":
+$(eval $(call gb_UnpackedTarball_add_patches,firebird,\
+ external/firebird/firebird.disable-ib-util-not-found.patch.1 \
+ external/firebird/firebird-Engine12.patch \
+ external/firebird/firebird-rpath.patch.0 \
+ external/firebird/wnt-dbgutil.patch \
+ external/firebird/c++17.patch \
+ external/firebird/ubsan.patch \
+ external/firebird/asan.patch \
+ external/firebird/firebird-tdf125284.patch.1 \
+ external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1 \
+ external/firebird/0001-Fix-warning-on-Win64-build-231.patch.1 \
+ external/firebird/macos-arm64.patch.0 \
+ external/firebird/firebird-btyacc-add-explicit-rule.patch \
+ external/firebird/firebird-307.patch.1 \
+ external/firebird/0001-Fix-checks-for-null-HANDLE-in-Windows-only-code.patch.1 \
+ external/firebird/0001-extern-cloop-Missing-dependency-of-BIN_DIR-cloop-on-.patch.1 \
+ external/firebird/msvc.patch \
+ external/firebird/wnt-per-process-trace-storage.patch.1 \
+ external/firebird/0001-extern-cloop-Missing-dependencies-of-compilations-on.patch.1 \
+ external/firebird/configure-c99.patch \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,firebird,\
+ external/firebird/firebird-cygwin-msvc.patch \
+ external/firebird/firebird-cygwin-msvc-warnings.patch \
+ external/firebird/firebird-vs2017.patch.1 \
+))
+endif
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_UnpackedTarball_add_patches,firebird,\
+ external/firebird/firebird-macosx.patch.1 \
+ external/firebird/macosx-elcapitan-dyld.patch \
+))
+endif
+
+ifeq ($(ENABLE_MACOSX_SANDBOX),TRUE)
+$(eval $(call gb_UnpackedTarball_add_patches,firebird,\
+ external/firebird/firebird-macosx-sandbox.patch.1 \
+))
+endif
+
+ifneq ($(filter -fsanitize=%,$(CC)),)
+$(eval $(call gb_UnpackedTarball_add_patches,firebird, \
+ external/firebird/sanitizer.patch \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/firebird/asan.patch b/external/firebird/asan.patch
new file mode 100644
index 000000000..2564c54d4
--- /dev/null
+++ b/external/firebird/asan.patch
@@ -0,0 +1,252 @@
+--- builds/posix/Makefile.in
++++ builds/posix/Makefile.in
+@@ -323,8 +323,8 @@
+
+ metadata.fdb: $(RUN_ISQL) $(SRC_ROOT)/dbs/metadata.sql
+ -$(RM) $@
+- $(RUN_ISQL) -q -i $(SRC_ROOT)/dbs/metadata.sql
+- $(RUN_GFIX) -mode read_only $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL) -q -i $(SRC_ROOT)/dbs/metadata.sql
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GFIX) -mode read_only $@
+ $(CHMOD) 0444 $@
+
+ $(HELP_FDB): help.fdb
+@@ -333,7 +333,7 @@
+ $(CHMOD) 0444 $@
+
+ help.fdb: $(BLD_ROOT)/misc/help.gbak
+- $(RUN_GBAK) -MODE read_only -R $< $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GBAK) -MODE read_only -R $< $@
+ $(CHMOD) 0444 $@
+
+ $(SECURITY_FDB): security.fdb
+@@ -343,18 +343,18 @@
+ security.fdb: $(SRC_ROOT)/dbs/security.sql
+ -$(RM) $@
+ -$(RM) $(SECURITY_TMP)
+- echo create database \'$(SECURITY_TMP)\'\; | $(RUN_ISQL)
+- $(RUN_GFIX) -write async $(SECURITY_TMP)
+- $(RUN_ISQL) -i $^ $(SECURITY_TMP)
++ echo create database \'$(SECURITY_TMP)\'\; | $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL)
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GFIX) -write async $(SECURITY_TMP)
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL) -i $^ $(SECURITY_TMP)
+ $(CHMOD) a=rw $(SECURITY_TMP)
+ $(CP) $(SECURITY_TMP) $@
+- $(RUN_GFIX) -write sync $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GFIX) -write sync $@
+
+ msg.timestamp: $(MSG_FILES)
+ -$(RM) msg.fdb
+- echo create database \'msg.fdb\'\; | $(RUN_ISQL)
+- $(RUN_GFIX) -write async msg.fdb
+- for sql in $(MSG_FILES); do (echo $$sql; $(RUN_ISQL) -i $$sql msg.fdb) || exit; done
++ echo create database \'msg.fdb\'\; | $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL)
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GFIX) -write async msg.fdb
++ for sql in $(MSG_FILES); do (echo $$sql; $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL) -i $$sql msg.fdb) || exit; done
+ $(TOUCH) $@
+
+
+@@ -560,7 +560,7 @@
+ message_file: $(FIREBIRD_MSG)
+
+ $(FIREBIRD_MSG): $(BUILD_FILE) msg.timestamp
+- $(BUILD_FILE) -d msg.fdb -f $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(BUILD_FILE) -d msg.fdb -f $@
+ $(CHMOD_6) $@
+
+ $(BUILD_FILE): $(BUILD_Objects) $(COMMON_LIB)
+--- builds/posix/Makefile.in.examples
++++ builds/posix/Makefile.in.examples
+@@ -123,8 +123,8 @@
+
+ $(EMPLOYEE_DB): $(EXAMPLES_DEST)/empbuild$(EXEC_EXT) $(INPUT_Sources) $(EXAMPLES_DEST)/isql$(EXEC_EXT)
+ -$(RM) $(EMPLOYEE_DB)
+- ./empbuild $(EMPLOYEE_DB)
+- $(GFIX) -write sync $(EMPLOYEE_DB)
++ $(LIBO_TUNNEL_LIBRARY_PATH) ./empbuild $(EMPLOYEE_DB)
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GFIX) -write sync $(EMPLOYEE_DB)
+ -$(CHMOD_6) $(EMPLOYEE_DB)
+
+ # To get past the fact isql is called from the programs, we create a local link in this directory
+@@ -140,7 +140,7 @@
+
+ $(EXAMPLES_DEST)/empbuild.fdb : $(EXAMPLES_DEST)/empddl.sql $(EXAMPLES_DEST)/empbld.sql $(EXAMPLES_DEST)/isql$(EXEC_EXT)
+ -$(RM) $(EXAMPLES_DEST)/empbuild.fdb
+- $(EXAMPLES_DEST)/isql$(EXEC_EXT) -i empbld.sql
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(EXAMPLES_DEST)/isql$(EXEC_EXT) -i empbld.sql
+
+ # The chain for intlemp.fdb is the same a script file to create an empty database
+ # to allow a .e program to be compiled, to then create and populate with data
+@@ -158,7 +158,7 @@
+
+ $(EXAMPLES_DEST)/intlbuild.fdb : $(EXAMPLES_DEST)/intlddl.sql $(EXAMPLES_DEST)/intlbld.sql $(EXAMPLES_DEST)/isql$(EXEC_EXT)
+ -$(RM) intlbuild.fdb
+- $(EXAMPLES_DEST)/isql$(EXEC_EXT) -i intlbld.sql
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(EXAMPLES_DEST)/isql$(EXEC_EXT) -i intlbld.sql
+
+
+ $(EXAMPLES_DEST)/%.sql: $(EXAMPLES_SRC)/empbuild/%.sql
+--- builds/posix/make.rules
++++ builds/posix/make.rules
+@@ -68,17 +68,17 @@
+ .SUFFIXES: .c .e .epp .cpp
+
+ .e.c:
+- $(GPRE_CURRENT) $(GPRE_FLAGS) $< $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GPRE_CURRENT) $(GPRE_FLAGS) $< $@
+
+
+ $(OBJ)/jrd/%.cpp: $(SRC_ROOT)/jrd/%.epp
+- $(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@
+
+ $(OBJ)/isql/%.cpp: $(SRC_ROOT)/isql/%.epp
+- $(GPRE_CURRENT) $(ISQL_GPRE_FLAGS) $< $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GPRE_CURRENT) $(ISQL_GPRE_FLAGS) $< $@
+
+ $(OBJ)/%.cpp: $(SRC_ROOT)/%.epp
+- $(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@
+
+
+ .SUFFIXES: .lo .o .cpp .c
+--- src/common/classes/alloc.cpp
++++ src/common/classes/alloc.cpp
+@@ -2187,7 +2187,7 @@
+
+ void* MemPool::allocRaw(size_t size)
+ {
+-#ifndef USE_VALGRIND
++#if !(defined USE_VALGRIND || defined USE_ASAN)
+ if (size == DEFAULT_ALLOCATION)
+ {
+ MutexLockGuard guard(*cache_mutex, "MemPool::allocRaw");
+@@ -2267,7 +2267,7 @@
+
+ void MemPool::releaseRaw(bool destroying, void* block, size_t size, bool use_cache) throw ()
+ {
+-#ifndef USE_VALGRIND
++#if !(defined USE_VALGRIND || defined USE_ASAN)
+ if (use_cache && (size == DEFAULT_ALLOCATION))
+ {
+ MutexLockGuard guard(*cache_mutex, "MemPool::releaseRaw");
+@@ -2277,7 +2277,7 @@
+ return;
+ }
+ }
+-#else
++#elif defined USE_VALGRIND
+ // Set access protection for block to prevent memory from deleted pool being accessed
+ int handle = /* //VALGRIND_MAKE_NOACCESS */ VALGRIND_MAKE_MEM_DEFINED(block, size);
+
+--- src/common/classes/alloc.h
++++ src/common/classes/alloc.h
+@@ -295,40 +295,60 @@
+
+ // operators new and delete
+
++#if !defined USE_ASAN
+ inline void* operator new(size_t s ALLOC_PARAMS)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS);
+ }
+ inline void* operator new[](size_t s ALLOC_PARAMS)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS);
+ }
++#endif
+
+ inline void* operator new(size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS)
+ {
++#if defined USE_ASAN
++ return operator new(s);
++#else
+ return pool.allocate(s ALLOC_PASS_ARGS);
++#endif
+ }
+ inline void* operator new[](size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS)
+ {
++#if defined USE_ASAN
++ return operator new[](s);
++#else
+ return pool.allocate(s ALLOC_PASS_ARGS);
++#endif
+ }
+
++#if !defined USE_ASAN
+ inline void operator delete(void* mem ALLOC_PARAMS) throw()
+ {
+ MemoryPool::globalFree(mem);
+ }
+ inline void operator delete[](void* mem ALLOC_PARAMS) throw()
+ {
+ MemoryPool::globalFree(mem);
+ }
++#endif
+
+ inline void operator delete(void* mem, Firebird::MemoryPool& pool ALLOC_PARAMS) throw()
+ {
++#if defined USE_ASAN
++ return operator delete(mem);
++#else
+ MemoryPool::globalFree(mem);
++#endif
+ }
+ inline void operator delete[](void* mem, Firebird::MemoryPool& pool ALLOC_PARAMS) throw()
+ {
++#if defined USE_ASAN
++ return operator delete[](mem);
++#else
+ MemoryPool::globalFree(mem);
++#endif
+ }
+
+ #ifdef DEBUG_GDS_ALLOC
+--- src/include/firebird.h
++++ src/include/firebird.h
+@@ -38,8 +38,17 @@
+ #include "gen/autoconfig.h"
+ #endif
+
++#if defined __clang__
++//#if __has_feature(address_sanitizer)
++#define USE_ASAN
++//#endif
++#endif
++#if defined __SANITIZE_ADDRESS__
++#define USE_ASAN
++#endif
++
+ // Using our debugging code is pointless when we may use Valgrind features
+-#if defined(DEV_BUILD) && !defined(USE_VALGRIND)
++#if defined(DEV_BUILD) && !(defined(USE_VALGRIND) || defined(USE_ASAN))
+ #define DEBUG_GDS_ALLOC
+ #endif
+
+--- src/jrd/SimilarToMatcher.h
++++ src/jrd/SimilarToMatcher.h
+@@ -338,7 +338,7 @@
+ private:
+ static const unsigned INCREASE_FACTOR = 50;
+ unsigned size;
+- AutoPtr<UCHAR> data;
++ AutoPtr<UCHAR, ArrayDelete> data;
+ T* end;
+ };
+ #endif // RECURSIVE_SIMILAR
+--- configure.orig 2018-06-03 17:44:50.152951348 +0200
++++ configure 2018-06-03 17:45:11.708907807 +0200
+@@ -18479,11 +18479,11 @@
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+-char dlopen ();
++char dlsym ();
+ int
+ main ()
+ {
+-return dlopen ();
++return dlsym ();
+ ;
+ return 0;
+ }
diff --git a/external/firebird/c++17.patch b/external/firebird/c++17.patch
new file mode 100644
index 000000000..4863b89bd
--- /dev/null
+++ b/external/firebird/c++17.patch
@@ -0,0 +1,311 @@
+--- src/common/DynamicStrings.cpp
++++ src/common/DynamicStrings.cpp
+@@ -37,7 +37,7 @@
+
+ namespace Firebird {
+
+-unsigned makeDynamicStrings(unsigned length, ISC_STATUS* const dst, const ISC_STATUS* const src) throw(BadAlloc)
++unsigned makeDynamicStrings(unsigned length, ISC_STATUS* const dst, const ISC_STATUS* const src)
+ {
+ const ISC_STATUS* end = &src[length];
+
+--- src/common/DynamicStrings.h
++++ src/common/DynamicStrings.h
+@@ -34,7 +34,7 @@
+
+ namespace Firebird {
+
+-unsigned makeDynamicStrings(unsigned len, ISC_STATUS* const dst, const ISC_STATUS* const src) throw(BadAlloc);
++unsigned makeDynamicStrings(unsigned len, ISC_STATUS* const dst, const ISC_STATUS* const src);
+ char* findDynamicStrings(unsigned len, ISC_STATUS* ptr) throw();
+
+ } // namespace Firebird
+--- src/common/StatusArg.cpp
++++ src/common/StatusArg.cpp
+@@ -53,7 +53,7 @@
+
+ namespace Arg {
+
+-Base::Base(ISC_STATUS k, ISC_STATUS c) throw(Firebird::BadAlloc) :
++Base::Base(ISC_STATUS k, ISC_STATUS c) :
+ implementation(FB_NEW_POOL(*getDefaultMemoryPool()) ImplBase(k, c))
+ {
+ }
+@@ -94,28 +94,28 @@
+ assign(ex);
+ }
+
+-StatusVector::StatusVector(ISC_STATUS k, ISC_STATUS c) throw(Firebird::BadAlloc) :
++StatusVector::StatusVector(ISC_STATUS k, ISC_STATUS c) :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(k, c))
+ {
+ operator<<(*(static_cast<Base*>(this)));
+ }
+
+-StatusVector::StatusVector(const ISC_STATUS* s) throw(Firebird::BadAlloc) :
++StatusVector::StatusVector(const ISC_STATUS* s) :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(s))
+ {
+ }
+
+-StatusVector::StatusVector(const IStatus* s) throw(Firebird::BadAlloc) :
++StatusVector::StatusVector(const IStatus* s) :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(s))
+ {
+ }
+
+-StatusVector::StatusVector(const Exception& ex) throw(Firebird::BadAlloc) :
++StatusVector::StatusVector(const Exception& ex) :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(ex))
+ {
+ }
+
+-StatusVector::StatusVector() throw(Firebird::BadAlloc) :
++StatusVector::StatusVector() :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(0, 0))
+ {
+ }
+--- src/common/StatusArg.h
++++ src/common/StatusArg.h
+@@ -87,7 +87,7 @@
+ virtual ~ImplBase() { }
+ };
+
+- Base(ISC_STATUS k, ISC_STATUS c) throw(Firebird::BadAlloc);
++ Base(ISC_STATUS k, ISC_STATUS c);
+ explicit Base(ImplBase* i) throw() : implementation(i) { }
+ ~Base() throw() { delete implementation; }
+
+@@ -144,13 +144,13 @@
+ explicit ImplStatusVector(const Exception& ex) throw();
+ };
+
+- StatusVector(ISC_STATUS k, ISC_STATUS v) throw(Firebird::BadAlloc);
++ StatusVector(ISC_STATUS k, ISC_STATUS v);
+
+ public:
+- explicit StatusVector(const ISC_STATUS* s) throw(Firebird::BadAlloc);
+- explicit StatusVector(const IStatus* s) throw(Firebird::BadAlloc);
+- explicit StatusVector(const Exception& ex) throw(Firebird::BadAlloc);
+- StatusVector() throw(Firebird::BadAlloc);
++ explicit StatusVector(const ISC_STATUS* s);
++ explicit StatusVector(const IStatus* s);
++ explicit StatusVector(const Exception& ex);
++ StatusVector();
+ ~StatusVector() { }
+
+ const ISC_STATUS* value() const throw() { return implementation->value(); }
+--- src/common/classes/alloc.cpp
++++ src/common/classes/alloc.cpp
+@@ -1635,7 +1635,7 @@
+
+ ~FreeObjects();
+
+- FreeObjPtr allocateBlock(MemPool* pool, size_t from, size_t& size) throw (OOM_EXCEPTION)
++ FreeObjPtr allocateBlock(MemPool* pool, size_t from, size_t& size)
+ {
+ size_t full_size = size + (from ? 0 : ListBuilder::MEM_OVERHEAD);
+ if (full_size > Limits::TOP_LIMIT)
+@@ -1705,7 +1705,7 @@
+ ListBuilder listBuilder;
+ Extent* currentExtent;
+
+- MemBlock* newBlock(MemPool* pool, unsigned slot) throw (OOM_EXCEPTION);
++ MemBlock* newBlock(MemPool* pool, unsigned slot);
+ };
+
+
+@@ -1787,26 +1787,26 @@
+ };
+ #endif // VALIDATE_POOL
+
+- MemBlock* alloc(size_t from, size_t& length, bool flagRedirect) throw (OOM_EXCEPTION);
++ MemBlock* alloc(size_t from, size_t& length, bool flagRedirect);
+ void releaseBlock(MemBlock *block, bool flagDecr) throw ();
+
+ public:
+- void* allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION);
+- MemBlock* allocate2(size_t from, size_t& size ALLOC_PARAMS) throw (OOM_EXCEPTION);
++ void* allocate(size_t size ALLOC_PARAMS);
++ MemBlock* allocate2(size_t from, size_t& size ALLOC_PARAMS);
+
+ private:
+- virtual void memoryIsExhausted(void) throw (OOM_EXCEPTION);
+- void* allocRaw(size_t length) throw (OOM_EXCEPTION);
++ virtual void memoryIsExhausted(void);
++ void* allocRaw(size_t length);
+ static void releaseMemory(void* block, bool flagExtent) throw ();
+ static void releaseRaw(bool destroying, void *block, size_t size, bool use_cache = true) throw ();
+- void* getExtent(size_t from, size_t& to) throw (OOM_EXCEPTION);
++ void* getExtent(size_t from, size_t& to);
+
+ public:
+ static void releaseExtent(bool destroying, void *block, size_t size, MemPool* pool) throw ();
+
+ // pass desired size, return actual extent size
+ template <class Extent>
+- void newExtent(size_t& size, Extent** linkedList) throw (OOM_EXCEPTION);
++ void newExtent(size_t& size, Extent** linkedList);
+
+ private:
+ #ifdef USE_VALGRIND
+@@ -1942,7 +1942,7 @@
+
+
+ template <class ListBuilder, class Limits>
+-MemBlock* FreeObjects<ListBuilder, Limits>::newBlock(MemPool* pool, unsigned slot) throw (OOM_EXCEPTION)
++MemBlock* FreeObjects<ListBuilder, Limits>::newBlock(MemPool* pool, unsigned slot)
+ {
+ size_t size = Limits::getSize(slot);
+
+@@ -2151,7 +2151,7 @@
+ }
+
+ template <class Extent>
+-void MemPool::newExtent(size_t& size, Extent** linkedList) throw(OOM_EXCEPTION)
++void MemPool::newExtent(size_t& size, Extent** linkedList)
+ {
+ // No large enough block found. We need to extend the pool
+ void* memory = NULL;
+@@ -2216,7 +2216,7 @@
+ pool->setStatsGroup(newStats);
+ }
+
+-MemBlock* MemPool::alloc(size_t from, size_t& length, bool flagRedirect) throw (OOM_EXCEPTION)
++MemBlock* MemPool::alloc(size_t from, size_t& length, bool flagRedirect)
+ {
+ MutexEnsureUnlock guard(mutex, "MemPool::alloc");
+ guard.enter();
+@@ -2275,7 +2275,7 @@
+ #ifdef DEBUG_GDS_ALLOC
+ , const char* fileName, int line
+ #endif
+-) throw (OOM_EXCEPTION)
++)
+ {
+ size_t length = from ? size : ROUNDUP(size + VALGRIND_REDZONE, roundingSize) + GUARD_BYTES;
+ MemBlock* memory = alloc(from, length, true);
+@@ -2305,7 +2305,7 @@
+ }
+
+
+-void* MemPool::allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION)
++void* MemPool::allocate(size_t size ALLOC_PARAMS)
+ {
+ #ifdef VALIDATE_POOL
+ MutexLockGuard guard(mutex, "MemPool::allocate");
+@@ -2445,12 +2445,12 @@
+ releaseRaw(pool_destroying, hunk, hunk->length, false);
+ }
+
+-void MemPool::memoryIsExhausted(void) throw (OOM_EXCEPTION)
++void MemPool::memoryIsExhausted(void)
+ {
+ Firebird::BadAlloc::raise();
+ }
+
+-void* MemPool::allocRaw(size_t size) throw (OOM_EXCEPTION)
++void* MemPool::allocRaw(size_t size)
+ {
+ #ifndef USE_VALGRIND
+ if (size == DEFAULT_ALLOCATION)
+@@ -2530,7 +2530,7 @@
+ }
+
+
+-void* MemPool::getExtent(size_t from, size_t& to) throw(OOM_EXCEPTION) // pass desired minimum size, return actual extent size
++void* MemPool::getExtent(size_t from, size_t& to) // pass desired minimum size, return actual extent size
+ {
+ #ifdef VALIDATE_POOL
+ MutexLockGuard guard(mutex, "MemPool::getExtent");
+@@ -2653,7 +2653,7 @@
+ deallocate(block);
+ }
+
+-void* MemoryPool::calloc(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION)
++void* MemoryPool::calloc(size_t size ALLOC_PARAMS)
+ {
+ void* block = allocate(size ALLOC_PASS_ARGS);
+ memset(block, 0, size);
+@@ -2800,7 +2800,7 @@
+ }
+
+ #ifdef LIBC_CALLS_NEW
+-void* MemoryPool::globalAlloc(size_t s ALLOC_PARAMS) throw (OOM_EXCEPTION)
++void* MemoryPool::globalAlloc(size_t s ALLOC_PARAMS)
+ {
+ if (!defaultMemoryManager)
+ {
+@@ -2818,7 +2818,7 @@
+ MemPool::globalFree(block);
+ }
+
+-void* MemoryPool::allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION)
++void* MemoryPool::allocate(size_t size ALLOC_PARAMS)
+ {
+ return pool->allocate(size ALLOC_PASS_ARGS);
+ }
+@@ -2876,11 +2876,11 @@
+ // in a case when we actually need "new" only with file/line information
+ // this version should be also present as a pair for "delete".
+ #ifdef DEBUG_GDS_ALLOC
+-void* operator new(size_t s) throw (OOM_EXCEPTION)
++void* operator new(size_t s)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_ARGS);
+ }
+-void* operator new[](size_t s) throw (OOM_EXCEPTION)
++void* operator new[](size_t s)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_ARGS);
+ }
+--- src/common/classes/alloc.h
++++ src/common/classes/alloc.h
+@@ -186,18 +186,18 @@
+ #define ALLOC_PASS_ARGS
+ #endif // DEBUG_GDS_ALLOC
+
+- void* calloc(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION);
++ void* calloc(size_t size ALLOC_PARAMS);
+
+ #ifdef LIBC_CALLS_NEW
+- static void* globalAlloc(size_t s ALLOC_PARAMS) throw (OOM_EXCEPTION);
++ static void* globalAlloc(size_t s ALLOC_PARAMS);
+ #else
+- static void* globalAlloc(size_t s ALLOC_PARAMS) throw (OOM_EXCEPTION)
++ static void* globalAlloc(size_t s ALLOC_PARAMS)
+ {
+ return defaultMemoryManager->allocate(s ALLOC_PASS_ARGS);
+ }
+ #endif // LIBC_CALLS_NEW
+
+- void* allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION);
++ void* allocate(size_t size ALLOC_PARAMS);
+
+ static void globalFree(void* mem) throw ();
+ void deallocate(void* mem) throw ();
+@@ -289,20 +289,20 @@
+
+ // operators new and delete
+
+-inline void* operator new(size_t s ALLOC_PARAMS) throw (OOM_EXCEPTION)
++inline void* operator new(size_t s ALLOC_PARAMS)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS);
+ }
+-inline void* operator new[](size_t s ALLOC_PARAMS) throw (OOM_EXCEPTION)
++inline void* operator new[](size_t s ALLOC_PARAMS)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS);
+ }
+
+-inline void* operator new(size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS) throw (OOM_EXCEPTION)
++inline void* operator new(size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS)
+ {
+ return pool.allocate(s ALLOC_PASS_ARGS);
+ }
+-inline void* operator new[](size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS) throw (OOM_EXCEPTION)
++inline void* operator new[](size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS)
+ {
+ return pool.allocate(s ALLOC_PASS_ARGS);
+ }
diff --git a/external/firebird/configure-c99.patch b/external/firebird/configure-c99.patch
new file mode 100644
index 000000000..f582d383e
--- /dev/null
+++ b/external/firebird/configure-c99.patch
@@ -0,0 +1,23 @@
+--- configure
++++ configure
+@@ -21478,8 +21478,9 @@
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
++#include <stdlib.h>
+ #include <semaphore.h>
+-main () {
++int main () {
+ struct s {
+ char a;
+ union { long long x; sem_t y; } b;
+@@ -21514,7 +21515,8 @@
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-main () {
++#include <stdlib.h>
++int main () {
+ struct s {
+ char a;
+ double b;
diff --git a/external/firebird/firebird-307.patch.1 b/external/firebird/firebird-307.patch.1
new file mode 100644
index 000000000..6af479838
--- /dev/null
+++ b/external/firebird/firebird-307.patch.1
@@ -0,0 +1,12 @@
+diff -ur firebird.org/builds/posix/Makefile.in firebird/builds/posix/Makefile.in
+--- firebird.org/builds/posix/Makefile.in 2020-11-08 15:11:29.262993342 +0100
++++ firebird/builds/posix/Makefile.in 2020-11-08 15:16:53.628545143 +0100
+@@ -264,7 +264,7 @@
+ ODS_TEST:=$(GEN_ROOT)/odstest$(EXEC_EXT)
+
+ preliminaryCheck: $(STD_SIZES) $(RUN_SIZES)
+- diff -u $^
++ diff -u --strip-trailing-cr $^
+
+ $(RUN_SIZES): $(ODS_H) $(ODS_AWK)
+ awk -f $(ODS_AWK) <$(ODS_H) >$(ODS_TEST_CPP)
diff --git a/external/firebird/firebird-Engine12.patch b/external/firebird/firebird-Engine12.patch
new file mode 100644
index 000000000..f6590b300
--- /dev/null
+++ b/external/firebird/firebird-Engine12.patch
@@ -0,0 +1,16 @@
+--- src/common/utils.cpp
++++ src/common/utils.cpp
+@@ -1026,6 +1026,13 @@
+ PathUtils::concatPath(s, configDir[prefType], name);
+ return s;
+ }
++
++ // Set relative path to Engine12 dynamic library
++ if(prefType == Firebird::IConfigManager::DIR_PLUGINS)
++ {
++ s = name;
++ return s;
++ }
+ }
+
+ switch(prefType)
diff --git a/external/firebird/firebird-btyacc-add-explicit-rule.patch b/external/firebird/firebird-btyacc-add-explicit-rule.patch
new file mode 100644
index 000000000..c4d88d911
--- /dev/null
+++ b/external/firebird/firebird-btyacc-add-explicit-rule.patch
@@ -0,0 +1,12 @@
+--- extern/btyacc/Makefile.orig 2020-11-13 18:57:44.831455058 +0100
++++ extern/btyacc/Makefile 2020-11-13 18:59:19.071078333 +0100
+@@ -44,6 +44,9 @@
+ $(PROGRAM): $(OBJS) $(LIBS)
+ $(CC) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LIBS)
+
++%.o: %.c
++ $(CC) $(CCFLAGS) -c $< -o $@
++
+ clean:; rm -f $(OBJS)
+
+ clobber:; rm -f $(OBJS) $(PROGRAM)
diff --git a/external/firebird/firebird-cygwin-msvc-warnings.patch b/external/firebird/firebird-cygwin-msvc-warnings.patch
new file mode 100644
index 000000000..942522439
--- /dev/null
+++ b/external/firebird/firebird-cygwin-msvc-warnings.patch
@@ -0,0 +1,300 @@
+diff -ur builds/posix/make.defaults builds/posix/make.defaults
+--- builds/posix/make.defaults 2016-07-07 13:56:13.036235166 +0200
++++ builds/posix/make.defaults 2016-07-07 14:29:52.368289242 +0200
+@@ -102,7 +102,7 @@
+ #____________________________________________________________________________
+
+ # Firebird needs no RTTI
+-RTTI_FLAG:= -fno-rtti
++RTTI_FLAG:=
+
+ # If this is defined then we use special rules useful for developers only
+ IsDeveloper = @DEVEL_FLG@
+@@ -175,6 +175,7 @@
+ # Default extensions
+
+ ARCH_EXT= .lib
++OBJ_EXT= obj
+ EXEC_EXT= @EXEEXT@
+ SHRLIB_EXT=@SHRLIB_EXT@
+ LIB_PREFIX=
+--- builds/posix/Makefile.in 2016-07-07 15:56:06.459221300 +0200
++++ builds/posix/Makefile.in 2016-07-13 12:44:57.134217200 +0200
+@@ -665,7 +666,7 @@
+
+ include $(ROOT)/gen/make.shared.targets
+
+-Dependencies = $(AllObjects:.o=.d)
++Dependencies = $(AllObjects:.$(OBJ_EXT)=.d)
+ -include $(Dependencies)
+
+
+@@ -729,14 +730,14 @@
+ -$(MAKE) -C $(ROOT)/extern/libtommath clean
+
+ clean_objects:
+- $(RM) `find $(TMP_ROOT)/ -type f -name '*.o' -print`
++ $(RM) `find $(TMP_ROOT)/ -type f -name '*.$(OBJ_EXT)' -print`
+ $(RM) `find $(TMP_ROOT)/ -type f -name '*.a' -print`
+ $(RM) `find $(TMP_ROOT)/ -type f -name '*.cpp' -print`
+ $(RM) `find $(TMP_ROOT)/ -type f -name '*.pas' -print`
+
+ clean_extern_objects:
+ $(RM) `find $(ROOT)/extern/ -type f -name '*.lo' -print`
+- $(RM) `find $(ROOT)/extern/ -type f -name '*.o' -print`
++ $(RM) `find $(ROOT)/extern/ -type f -name '*.$(OBJ_EXT)' -print`
+
+ # Clear out dependancies files created by the gcc compiler
+ # since when .o and other files are deleted the dependant
+diff -ur builds/posix/make.rules builds/posix/make.rules
+--- builds/posix/make.rules 2016-07-07 13:56:13.036235166 +0200
++++ builds/posix/make.rules 2016-07-07 14:31:16.116291485 +0200
+@@ -92,21 +92,21 @@
+ $(LIBO_TUNNEL_LIBRARY_PATH) $(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@
+
+
+-.SUFFIXES: .lo .o .cpp .c
++.SUFFIXES: .lo .$(OBJ_EXT) .cpp .c
+
+-%.o: %.c
++%.$(OBJ_EXT): %.c
+ $(CC) $(WCFLAGS) -c $(firstword $<) -o $@
+
+-$(OBJ)/%.o: $(SRC_ROOT)/%.c
++$(OBJ)/%.$(OBJ_EXT): $(SRC_ROOT)/%.c
+ $(CC) $(WCFLAGS) -c $(firstword $<) -o $@
+
+-$(OBJ)/%.o: $(OBJ)/%.cpp
++$(OBJ)/%.$(OBJ_EXT): $(OBJ)/%.cpp
+ $(CXX) $(WCXXFLAGS) -c $(firstword $<) -o $@
+
+-$(OBJ)/%.o: $(SRC_ROOT)/%.cpp
++$(OBJ)/%.$(OBJ_EXT): $(SRC_ROOT)/%.cpp
+ $(CXX) $(WCXXFLAGS) -c $(firstword $<) -o $@
+
+-$(OBJ)/%.o: $(ROOT)/%.cpp
++$(OBJ)/%.$(OBJ_EXT): $(ROOT)/%.cpp
+ $(CC) $(WCFLAGS) -c $(firstword $<) -o $@
+
+ .SUFFIXES: .epp .e
+--- builds/posix/make.shared.variables.orig 2020-11-12 19:36:29.773409900 +0100
++++ builds/posix/make.shared.variables 2020-11-12 19:37:14.976503300 +0100
+@@ -1,5 +1,5 @@
+ # Helper functions
+-doObjects= $(patsubst %.y,%.o,$(patsubst %.epp,%.o,$(patsubst %.c,%.o,$(1:.cpp=.o))))
++doObjects= $(patsubst %.y,%.$(OBJ_EXT),$(patsubst %.epp,%.$(OBJ_EXT),$(patsubst %.c,%.$(OBJ_EXT),$(1:.cpp=.$(OBJ_EXT)))))
+ makeObjects= $(addprefix $(OBJ)/$(patsubst ../%,%,$(1))/,$(call doObjects,$2))
+ dirFiles= $(notdir $(wildcard ../src/$(1)/*.cpp)) $(notdir $(wildcard ../src/$(1)/*.c)) \
+ $(notdir $(wildcard ../src/$(1)/*.epp)) $(notdir $(wildcard ../src/$(1)/*.y))
+--- src/include/gen/autoconfig.h.in.orig 2020-11-12 20:52:49.835722200 +0100
++++ src/include/gen/autoconfig.h.in 2020-11-12 20:53:18.148311100 +0100
+@@ -773,7 +773,9 @@
+ #pragma warning(disable:4996) // 'identificator' was declared deprecated
+ #endif
+
++#ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
++#endif
+
+ //#ifdef _MSC_VER // don't know if this is useful for MinGW
+ #define NOATOM
+--- builds/posix/prefix.mingw.orig 2020-11-12 21:37:39.574461300 +0100
++++ builds/posix/prefix.mingw 2020-11-12 21:37:55.448422500 +0100
+@@ -20,8 +20,8 @@
+ #
+
+ # -Wno-unused-variable is used due to unused gpre generated variables
+-PROD_FLAGS=-O2 -DMINGW -Dlint -DWIN32_LEAN_AND_MEAN
+-DEV_FLAGS=-ggdb -DMINGW -Dlint -DWIN32_LEAN_AND_MEAN
++PROD_FLAGS=-O2 -DMINGW -Dlint -DWIN32_LEAN_AND_MEAN -wd4291 -wd4477
++DEV_FLAGS=-ggdb -DMINGW -Dlint -DWIN32_LEAN_AND_MEAN -wd4291 -wd4477
+
+ PLATFORM_PATH=os/win32
+
+--- extern/btyacc/Makefile.orig 2020-11-12 21:39:13.833012400 +0100
++++ extern/btyacc/Makefile 2020-11-12 21:39:54.861473300 +0100
+@@ -25,8 +25,8 @@
+
+ MAKEFILE = Makefile
+
+-OBJS = closure.o error.o lalr.o lr0.o main.o mkpar.o output.o \
+- mstring.o reader.o readskel.o skeleton.o symtab.o verbose.o warshall.o
++OBJS = closure.obj error.obj lalr.obj lr0.obj main.obj mkpar.obj output.obj \
++ mstring.obj reader.obj readskel.obj skeleton.obj symtab.obj verbose.obj warshall.obj
+
+ PRINT = pr -f -l88
+
+@@ -44,7 +44,7 @@
+ $(PROGRAM): $(OBJS) $(LIBS)
+ $(CC) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LIBS)
+
+-%.o: %.c
++%.obj: %.c
+ $(CC) $(CCFLAGS) -c $< -o $@
+
+ clean:; rm -f $(OBJS)
+@@ -93,16 +93,16 @@
+ etags *.c *.h
+
+ ###
+-closure.o: defs.h
+-error.o: defs.h
+-lalr.o: defs.h
+-lr0.o: defs.h
+-main.o: defs.h
+-mkpar.o: defs.h
+-mstring.o: mstring.h
+-output.o: defs.h
+-reader.o: defs.h mstring.h
+-skeleton.o: defs.h
+-symtab.o: defs.h
+-verbose.o: defs.h
+-warshall.o: defs.h
++closure.obj: defs.h
++error.obj: defs.h
++lalr.obj: defs.h
++lr0.obj: defs.h
++main.obj: defs.h
++mkpar.obj: defs.h
++mstring.obj: mstring.h
++output.obj: defs.h
++reader.obj: defs.h mstring.h
++skeleton.obj: defs.h
++symtab.obj: defs.h
++verbose.obj: defs.h
++warshall.obj: defs.h
+--- extern/cloop/Makefile.orig 2020-11-13 10:59:53.282923700 +0100
++++ extern/cloop/Makefile 2020-11-13 11:00:24.267079900 +0100
+@@ -24,8 +24,8 @@
+ SRCS_C := $(foreach sdir,$(SRC_DIRS),$(wildcard $(sdir)/*.c))
+ SRCS_CPP := $(foreach sdir,$(SRC_DIRS),$(wildcard $(sdir)/*.cpp))
+
+-OBJS_C := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS_C))
+-OBJS_CPP := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRCS_CPP))
++OBJS_C := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.obj,$(SRCS_C))
++OBJS_CPP := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.obj,$(SRCS_CPP))
+
+ C_FLAGS := -fPIC
+ CXX_FLAGS := $(C_FLAGS)
+@@ -43,10 +43,10 @@
+ vpath %.cpp $(SRC_DIRS)
+
+ define compile
+-$1/%.o: %.c | $1
++$1/%.obj: %.c | $1
+ $(CC) -c $$(C_FLAGS) $$< -o $$@
+
+-$1/%.o: %.cpp | $1
++$1/%.obj: %.cpp | $1
+ $(CXX) -c $$(CXX_FLAGS) $$< -o $$@
+ endef
+
+@@ -75,11 +75,11 @@
+ -include $(addsuffix .d,$(basename $(OBJS_CPP)))
+
+ $(BIN_DIR)/cloop$(EXE_EXT): \
+- $(OBJ_DIR)/cloop/Expr.o \
+- $(OBJ_DIR)/cloop/Generator.o \
+- $(OBJ_DIR)/cloop/Lexer.o \
+- $(OBJ_DIR)/cloop/Parser.o \
+- $(OBJ_DIR)/cloop/Main.o \
++ $(OBJ_DIR)/cloop/Expr.obj \
++ $(OBJ_DIR)/cloop/Generator.obj \
++ $(OBJ_DIR)/cloop/Lexer.obj \
++ $(OBJ_DIR)/cloop/Parser.obj \
++ $(OBJ_DIR)/cloop/Main.obj \
+ | $(BIN_DIR)
+
+ $(LD) $^ -o $@
+@@ -105,24 +105,24 @@
+ $(SRC_DIR)/tests/test1/CppTest.cpp: $(SRC_DIR)/tests/test1/CalcCppApi.h
+
+ $(BIN_DIR)/test1-c$(SHRLIB_EXT): \
+- $(OBJ_DIR)/tests/test1/CalcCApi.o \
+- $(OBJ_DIR)/tests/test1/CTest.o \
++ $(OBJ_DIR)/tests/test1/CalcCApi.obj \
++ $(OBJ_DIR)/tests/test1/CTest.obj \
+
+ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-c$(EXE_EXT): \
+- $(OBJ_DIR)/tests/test1/CalcCApi.o \
+- $(OBJ_DIR)/tests/test1/CTest.o \
++ $(OBJ_DIR)/tests/test1/CalcCApi.obj \
++ $(OBJ_DIR)/tests/test1/CTest.obj \
+
+ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-cpp$(SHRLIB_EXT): \
+- $(OBJ_DIR)/tests/test1/CppTest.o \
++ $(OBJ_DIR)/tests/test1/CppTest.obj \
+
+ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-cpp$(EXE_EXT): \
+- $(OBJ_DIR)/tests/test1/CppTest.o \
++ $(OBJ_DIR)/tests/test1/CppTest.obj \
+
+ $(LD) $^ -o $@
+
+--- src/include/gen/autoconfig_msvc.h.orig 2020-11-13 12:42:36.231813100 +0100
++++ src/include/gen/autoconfig_msvc.h 2020-11-13 12:43:12.669012900 +0100
+@@ -68,7 +68,9 @@
+ #pragma warning(disable:4996) // 'identificator' was declared deprecated
+
+
++#ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
++#endif
+
+ #ifdef _MSC_VER // don't know if this is useful for MinGW
+ #define NOATOM
+diff -ur builds/posix/Makefile.in.examples builds/posix/Makefile.in.examples
+--- builds/posix/Makefile.in.examples 2016-07-07 13:56:13.048235166 +0200
++++ builds/posix/Makefile.in.examples 2016-07-07 14:37:36.904301682 +0200
+@@ -65,9 +65,9 @@
+ EXAMPLES_SRC= $(ROOT)/examples
+
+
+-EMPBLD_Objects= $(EXAMPLES_DEST)/empbuild.o
++EMPBLD_Objects= $(EXAMPLES_DEST)/empbuild.$(OBJ_EXT)
+
+-INTLBLD_Objects= $(EXAMPLES_DEST)/intlbld.o
++INTLBLD_Objects= $(EXAMPLES_DEST)/intlbld.$(OBJ_EXT)
+
+ INPUT_Files = empddl.sql empdml.sql indexoff.sql indexon.sql \
+ job.inp lang.inp proj.inp qtr.inp
+@@ -172,3 +175,6 @@
+
+ $(EXAMPLES_DEST)/%.h: $(EXAMPLES_SRC)/common/%.h
+ $(CP) $^ $@
++
++$(EXAMPLES_DEST)/%.$(OBJ_EXT): $(EXAMPLES_DEST)/%.c
++ $(CC) -c $(firstword $<) -Fo$@ $(WCFLAGS)
+--- src/lock/lock.cpp.orig 2020-11-13 17:57:23.485241200 +0100
++++ src/lock/lock.cpp 2020-11-13 17:57:51.001010600 +0100
+@@ -463,6 +463,7 @@
+
+ LockTableGuard guard(This, FB_FUNCTION, owner_offset);
+
++#undef SRQ_BASE
+ #define SRQ_BASE ((UCHAR*) This->m_sharedMemory->getHeader())
+ own* owner = (own*) SRQ_ABS_PTR(owner_offset);
+ if (!owner->own_count)
+@@ -486,6 +487,7 @@
+ // released before destroying the lock owner. This is not strictly required,
+ // but it enforces the proper object lifetime discipline through the codebase.
+ fb_assert(SRQ_EMPTY(owner->own_requests));
++#undef SRQ_BASE
+ #define SRQ_BASE ((UCHAR*) m_sharedMemory->getHeader())
+
+ This->purge_owner(owner_offset, owner);
+--- builds/posix/Makefile.in.plugins_examples.orig 2020-11-13 20:25:55.865485400 +0100
++++ builds/posix/Makefile.in.plugins_examples 2020-11-13 20:26:13.084191800 +0100
+@@ -104,5 +104,5 @@
+
+ include $(ROOT)/gen/make.shared.targets
+
+-Dependencies = $(AllObjects:.o=.d)
++Dependencies = $(AllObjects:.$(OBJ_EXT)=.d)
+ -include $(Dependencies)
diff --git a/external/firebird/firebird-cygwin-msvc.patch b/external/firebird/firebird-cygwin-msvc.patch
new file mode 100644
index 000000000..c59c614ba
--- /dev/null
+++ b/external/firebird/firebird-cygwin-msvc.patch
@@ -0,0 +1,686 @@
+--- src/include/firebird.h 2016-07-15 11:31:27.151443500 +0200
++++ src/include/firebird.h 2016-07-17 14:50:04.043792400 +0200
+@@ -32,11 +32,7 @@
+ #ifndef INCLUDE_Firebird_H
+ #define INCLUDE_Firebird_H
+
+-#ifdef _MSC_VER
+-#include "gen/autoconfig_msvc.h"
+-#else
+ #include "gen/autoconfig.h"
+-#endif
+
+ #if defined __clang__
+ //#if __has_feature(address_sanitizer)
+--- src/misc/writeBuildNum.sh 2016-07-07 15:57:04.538983200 +0200
++++ src/misc/writeBuildNum.sh 2016-07-13 11:31:18.132820200 +0200
+@@ -95,9 +95,9 @@
+ createMakeVersion() {
+
+ OdsH="${Root}/src/jrd/ods.h"
+-Mini="/tmp/miniods.h"
+-TestCpp="/tmp/test.cpp"
+-AOut="/tmp/a.out"
++Mini=$(cygpath -m "/tmp/miniods.h")
++TestCpp=$(cygpath -m "/tmp/test.cpp")
++AOut=$(cygpath -m "/tmp/a.out")
+
+ grep ODS_VERSION $OdsH | grep -v ENCODE_ODS >$Mini
+
+--- configure 2016-07-07 15:57:04.538983200 +0200
++++ configure 2016-07-13 11:31:18.132820200 +0200
+@@ -21490,13 +21490,12 @@
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ #include <stdlib.h>
+-#include <semaphore.h>
+ int main () {
+ struct s {
+ char a;
+- union { long long x; sem_t y; } b;
++ long long b;
+ };
+ exit((int)&((struct s*)1024)->b - 1024);
+ }
+ _ACEOF
+ if ac_fn_c_try_run "$LINENO"; then :
+--- builds/make.new/config/config.h.in 2016-07-07 15:55:55.693112800 +0200
++++ builds/make.new/config/config.h.in 2016-07-08 13:38:49.994986400 +0200
+@@ -211,7 +211,7 @@
+ #undef HAVE_GETMNTENT
+
+ /* Define to 1 if you have the `getpagesize' function. */
+-#undef HAVE_GETPAGESIZE
++#define HAVE_GETPAGESIZE 1
+
+ /* Define to 1 if you have the `getrlimit' function. */
+ #undef HAVE_GETRLIMIT
+@@ -396,7 +396,7 @@
+ #undef HAVE_SIGSET
+
+ /* Define to 1 if you have the `snprintf' function. */
+-#undef HAVE_SNPRINTF
++#define HAVE_SNPRINTF
+
+ /* Define to 1 if you have the <socket.h> header file. */
+ #undef HAVE_SOCKET_H
+@@ -551,7 +551,7 @@
+ #undef HAVE_VFORK_H
+
+ /* Define to 1 if you have the `vsnprintf' function. */
+-#undef HAVE_VSNPRINTF
++#define HAVE_VSNPRINTF
+
+ /* Define to 1 if you have the <winsock2.h> header file. */
+ #undef HAVE_WINSOCK2_H
+@@ -646,7 +646,7 @@
+ #undef TIME_WITH_SYS_TIME
+
+ /* Define this if OS is Windows NT */
+-#undef WIN_NT
++#define WIN_NT
+
+ /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+@@ -703,3 +703,20 @@
+ #ifndef HAVE_SOCKLEN_T
+ typedef int socklen_t;
+ #endif
++
++/* taken from src/include/gen/autoconfig_msvc.h */
++#ifndef WIN32_LEAN_AND_MEAN
++#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
++#endif
++/* target architecture */
++#if defined(_M_AMD64)
++#define AMD64
++#endif
++
++#define HAVE_IO_H
++#define HAVE_CTIME_S
++
++#if defined _MSC_VER
++#define isnan _isnan
++#endif
++
+--- src/common/common.h 2016-07-15 11:31:26.366735500 +0200
++++ src/common/common.h 2016-07-17 16:18:39.121579400 +0200
+@@ -551,15 +551,6 @@
+ #endif /* WIN_NT */
+
+
+-#ifndef FB_CPU
+-#error Define FB_CPU for your platform
+-#endif
+-#ifndef FB_OS
+-#error Define FB_OS for your platform
+-#endif
+-#ifndef FB_CC
+-#error Define FB_CC for your platform
+-#endif
+
+
+ /*****************************************************
+diff -ur builds/posix/make.defaults builds/posix/make.defaults
+--- builds/posix/make.defaults 2016-07-07 13:56:13.036235166 +0200
++++ builds/posix/make.defaults 2016-07-07 14:29:52.368289242 +0200
+@@ -56,7 +56,7 @@
+ else
+ FIREBIRD=$(FB_BUILD)
+ endif
+-FIREBIRD_LOCK=$(FIREBIRD)
++FIREBIRD_LOCK=$(shell cygpath -w $(FIREBIRD))
+
+ export FIREBIRD
+ export FIREBIRD_LOCK
+@@ -153,7 +153,7 @@
+ CD= cd
+ CAT= cat
+ AR= ar @AR_OPTIONS@
+-LN= @LN_S@
++LN= cp
+ RANLIB= @RANLIB@
+ BTYACC=$(ROOT)/extern/btyacc/btyacc
+ CLOOP=$(GEN_ROOT)/$(TARGET)/cloop/release/bin/cloop
+@@ -175,10 +175,10 @@
+
+ # Default extensions
+
+-ARCH_EXT= .a
++ARCH_EXT= .lib
+ EXEC_EXT= @EXEEXT@
+ SHRLIB_EXT=@SHRLIB_EXT@
+-LIB_PREFIX= lib
++LIB_PREFIX=
+ SHRLIB_FOREIGN_EXT= $(SHRLIB_EXT)
+
+ #_____________________________________________________________________________
+@@ -201,9 +202,8 @@
+
+ # Search path for libraries
+
+-vpath %.so $(LIB)
+-vpath %.a $(LIB)
+ vpath %.dll $(LIB)
++vpath %.lib $(LIB)
+
+ #_____________________________________________________________________________
+
+@@ -217,9 +217,9 @@
+ #
+
+ #LibraryFileName=libfbclient
+-LibraryFileName=libfbclient
+-LibraryFullName=$(LibraryFileName).${SHRLIB_EXT}.${FirebirdVersion}
+-LibrarySoName=$(LibraryFileName).${SHRLIB_EXT}.2
++LibraryFileName=ifbclient
++LibraryFullName=$(LibraryFileName).${SHRLIB_EXT}
++LibrarySoName=$(LibraryFileName).${SHRLIB_EXT}
+ LibraryBaseName=$(LibraryFileName).${SHRLIB_EXT}
+
+ LIBFIREBIRD_FULLNAME = $(LIB)/$(LibraryFullName)
+@@ -228,7 +228,7 @@
+
+ # The firebird engine library name
+
+-EngineFileName=libEngine${OdsVersion}
++EngineFileName=Engine12
+ EngineSoName=$(EngineFileName).${SHRLIB_EXT}
+ ENGINE_SONAME = $(PLUGINS)/$(EngineSoName)
+
+@@ -242,7 +242,7 @@
+ ifeq ($(STD_EDITLINE), true)
+ LIBEDITLINE := -l$(READLINE)
+ else
+- LIBEDITLINE := $(LIB)/libedit.a
++ LIBEDITLINE := $(LIB)/$(LIB_PREFIX)edit$(ARCH_EXT)
+ endif
+ endif
+
+@@ -313,7 +313,7 @@
+
+ LIB_LINK_SONAME= -Wl,-soname,$(1)
+ LIB_LINK_MAPFILE= -Wl,--version-script,$(1)
+-FIREBIRD_LIBRARY_LINK= -L$(LIB) -lfbclient $(MATHLIB)
++FIREBIRD_LIBRARY_LINK= -L$(LIB) -lifbclient $(MATHLIB)
+
+ EXE_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) $(UNDEF_FLAGS) $(LIB_PATH_OPTS) $(LINK_EMPTY_SYMBOLS)
+ LIB_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) -shared
+@@ -355,7 +355,7 @@
+
+ # Pay attention - we place common library into obj, not lib dir
+ # It's just a set of object files, prepared to be used by ld, not an output library
+-COMMON_LIB = $(OBJ)/common.a
++COMMON_LIB = $(OBJ)/$(LIB_PREFIX)common$(ARCH_EXT)
+
+ # From utilities
+ CREATE_DB = $(RBIN)/create_db$(EXEC_EXT)
+--- builds/posix/Makefile.in 2016-07-07 15:56:06.459221300 +0200
++++ builds/posix/Makefile.in 2016-07-13 12:44:57.134217200 +0200
+@@ -33,7 +33,7 @@
+ # Alex Peshkoff - created single makefile based on Mark's files
+ #
+
+-ROOT=$(shell cd ..; pwd)
++ROOT=$(shell cygpath -m '$(shell cd ..; pwd)')
+
+ include make.defaults
+ ifeq ($(CROSS_OUT), Y)
+@@ -178,7 +178,7 @@
+ .PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes ids examples cross_rest preliminaryCheck
+
+ master_process:
+- ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
++ cp -f $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
+ $(MAKE) updateBuildNum
+ $(MAKE) export_lists
+ $(MAKE) extern
+@@ -214,7 +215,7 @@
+ $(MAKE) CROSS_OUT=Y cross2
+
+ cross1:
+- ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
++ cp -f $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
+ $(MAKE) updateBuildNum
+ $(MAKE) export_lists
+ $(MAKE) extern
+@@ -239,7 +240,7 @@
+ $(MAKE) -f Makefile.examples -C $(GEN_ROOT)/examples/
+
+ cross2:
+- ln -sf $(SRC_ROOT)/include/cross/$(CROSS_CONFIG) $(SRC_ROOT)/include/gen/autoconfig.h
++ cp -f $(SRC_ROOT)/include/cross/$(CROSS_CONFIG) $(SRC_ROOT)/include/gen/autoconfig.h
+ $(MAKE) prerequisites
+ $(MAKE) tommath
+ $(MAKE) yvalve
+@@ -310,7 +311,7 @@
+
+ # remote redirector is statically linked in main FB library
+ $(LIBFIREBIRD_FULLNAME): $(YValve_Objects) $(Remote_Client_Objects) $(COMMON_LIB)
+- $(LINK_FIREBIRD) -o $@ $^ $(LINK_FIREBIRD_LIBS) $(call LIB_LINK_DARWIN_INSTALL_NAME,lib/libfbclient.$(SHRLIB_EXT))
++ $(LINK_FIREBIRD) $(CPPFLAGS) -o $@ $^ $(LINK_FIREBIRD_LIBS) $(call LIB_LINK_DARWIN_INSTALL_NAME,lib/libfbclient.$(SHRLIB_EXT))
+
+
+ #___________________________________________________________________________
+@@ -320,8 +321,8 @@
+
+ engine: $(ENGINE_SONAME)
+
+-$(ENGINE_SONAME): $(Engine_Objects) $(SVC_Objects) $(COMMON_LIB)
+- $(LINK_ENGINE) -o $@ $^ $(LINK_ENGINE_LIBS) $(call LIB_LINK_DARWIN_INSTALL_NAME,plugins/$(EngineSoName))
++$(ENGINE_SONAME): $(Engine_Objects) $(SVC_Objects) $(YValve_Objects) $(Remote_Client_Objects) $(COMMON_LIB)
++ $(LINK_ENGINE) $(CPPFLAGS) -o $@ $^ $(LINK_ENGINE_LIBS) $(call LIB_LINK_DARWIN_INSTALL_NAME,plugins/$(EngineSoName))
+
+
+ #___________________________________________________________________________
+@@ -330,8 +331,8 @@
+
+ fbintl: $(LIBFBINTL_SO)
+
+-$(LIBFBINTL_SO): $(INTL_Objects) $(COMMON_LIB)
+- $(LINK_INTL) -o $@ $^ $(LINK_INTL_LIBS) $(call LIB_LINK_DARWIN_INSTALL_NAME,intl/libfbintl.$(SHRLIB_EXT))
++$(LIBFBINTL_SO): $(INTL_Objects) $(YValve_Objects) $(Remote_Client_Objects) $(COMMON_LIB)
++ $(LINK_INTL) $(CPPFLAGS) -o $@ $^ $(LINK_INTL_LIBS) $(call LIB_LINK_DARWIN_INSTALL_NAME,intl/libfbintl.$(SHRLIB_EXT))
+
+
+ #___________________________________________________________________________
+@@ -427,12 +429,13 @@
+
+ .PHONY: firebird_server fb_lock_print fbguard fbsvcmgr fbtracemgr gbak gfix gsec gsplit gstat isql nbackup
+
+-utilities: firebird_server fb_lock_print fbguard fbsvcmgr fbtracemgr gbak gfix gsec gsplit gstat isql nbackup udfsupport
++# fbguard currently fails to link, with missing fork etc, in util.cpp
++utilities: firebird_server fb_lock_print fbsvcmgr fbtracemgr gbak gfix gsec gsplit gstat isql nbackup udfsupport
+
+ firebird_server: $(FB_DAEMON)
+
+-$(FB_DAEMON): $(Remote_Server_Objects) $(COMMON_LIB)
+- $(EXE_LINK) $(EXE_LINK_OPTIONS) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) $(LINK_LIBS) $(call LINK_DARWIN_RPATH,..)
++$(FB_DAEMON): $(Remote_Server_Objects) $(Remote_Client_Objects) $(COMMON_LIB)
++ $(EXE_LINK) $(EXE_LINK_OPTIONS) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) $(LINK_LIBS) $(LIB_GUI) $(call LINK_DARWIN_RPATH,..)
+
+ fb_lock_print: $(LOCKPRINT)
+
+@@ -633,7 +635,7 @@
+ IBASE_ExtraFiles = include/types_pub.h include/consts_pub.h dsql/sqlda_pub.h common/dsc_pub.h jrd/ibase.h jrd/inf_pub.h jrd/blr.h include/gen/iberror.h
+ SRC_IBASE_ExtraFiles = $(addprefix $(SRC_ROOT)/, $(IBASE_ExtraFiles))
+ MAKE_HEADER_Src = $(addprefix $(SRC_ROOT)/, misc/makeHeader.cpp)
+-MAKE_HEADER_Bin = ./makeHeader
++MAKE_HEADER_Bin = ./makeHeader$(EXEC_EXT)
+
+ $(INCLUDE_DEST)/ibase.h: $(SRC_IBASE_ExtraFiles)
+ $(STATICEXE_LINK) -o $(MAKE_HEADER_Bin) $(MAKE_HEADER_Src)
+diff -ur builds/posix/make.rules builds/posix/make.rules
+--- builds/posix/make.rules 2016-07-07 13:56:13.036235166 +0200
++++ builds/posix/make.rules 2016-07-07 14:31:16.116291485 +0200
+@@ -92,26 +92,23 @@
+
+ $(OBJ)/%.o: $(SRC_ROOT)/%.c
+ $(CC) $(WCFLAGS) -c $(firstword $<) -o $@
+- @sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)
+
+ $(OBJ)/%.o: $(OBJ)/%.cpp
+ $(CXX) $(WCXXFLAGS) -c $(firstword $<) -o $@
+- @sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)
+
+ $(OBJ)/%.o: $(SRC_ROOT)/%.cpp
+ $(CXX) $(WCXXFLAGS) -c $(firstword $<) -o $@
+- @sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)
+
+ $(OBJ)/%.o: $(ROOT)/%.cpp
+ $(CC) $(WCFLAGS) -c $(firstword $<) -o $@
+- @sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)
+
+ .SUFFIXES: .epp .e
+
+ # Rules for making resource files
+
+ $(GEN_ROOT)/%.res: $(SRC_ROOT)/%.rc
+- windres --output-format=coff --include-dir=$(<D) $< $@
++ mkdir -p $(@D)
++ rc.exe $(SOLARINC) /fo $@ $<
+
+ # Rule for making gbak files when cross-compiling
+
+--- src/common/utils.cpp 2016-07-15 11:31:26.746871100 +0200
++++ src/common/utils.cpp 2016-07-19 19:14:45.370689300 +0200
+@@ -880,15 +880,15 @@
+ FILETIME utime, stime, dummy;
+ if (GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, &stime, &utime))
+ {
+- LARGE_INTEGER lint;
++ LARGE_INTEGER myLargeInt;
+
+- lint.HighPart = stime.dwHighDateTime;
+- lint.LowPart = stime.dwLowDateTime;
+- sysTime = lint.QuadPart / 10000;
+-
+- lint.HighPart = utime.dwHighDateTime;
+- lint.LowPart = utime.dwLowDateTime;
+- userTime = lint.QuadPart / 10000;
++ myLargeInt.HighPart = stime.dwHighDateTime;
++ myLargeInt.LowPart = stime.dwLowDateTime;
++ sysTime = myLargeInt.QuadPart / 10000;
++
++ myLargeInt.HighPart = utime.dwHighDateTime;
++ myLargeInt.LowPart = utime.dwLowDateTime;
++ userTime = myLargeInt.QuadPart / 10000;
+ }
+ else
+ {
+diff -ur builds/posix/prefix.mingw builds/posix/prefix.mingw
+--- builds/posix/prefix.mingw 2016-07-07 13:56:13.048235166 +0200
++++ builds/posix/prefix.mingw 2016-07-07 14:50:54.704323046 +0200
+@@ -20,8 +20,8 @@
+ #
+
+ # -Wno-unused-variable is used due to unused gpre generated variables
+-PROD_FLAGS=-O2 -DMINGW -Wall -Wshadow -Wundef -Wno-long-long -Wno-unused-variable -Wno-sign-compare -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD -mthreads -Wno-non-virtual-dtor
+-DEV_FLAGS=-ggdb -DMINGW -Wall -Wshadow -Wundef -Wno-long-long -Wno-unused-variable -Wno-sign-compare -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD -mthreads -Wno-non-virtual-dtor
++PROD_FLAGS=-O2 -DMINGW -Dlint -DWIN32_LEAN_AND_MEAN
++DEV_FLAGS=-ggdb -DMINGW -Dlint -DWIN32_LEAN_AND_MEAN
+
+ PLATFORM_PATH=os/win32
+
+@@ -29,6 +29,7 @@
+ LIB_LINK=$(LD)
+
+ LIB_LINK_OPTIONS+=-Wl,--enable-stdcall-fixup
++LIB_PLATFORM_RPATH=
+
+ # Strip symbols from release versions to decrease size
+ ifeq ($(IsProdTypeBuild),Y)
+@@ -36,6 +37,9 @@
+ LIB_LINK_OPTIONS+=-Wl,-s
+ endif
+
++LIB_LINK_OPTIONS=
++LINK_OPTS=
++
+ # Generation of fbclient_ms.lib
+ LIB_LINK_IMPLIB:=-Wl,--out-implib,firebird/lib/fbclient_ms.lib
+ LIB_GUI:= -mwindows -lcomctl32 -lgdi32
+@@ -55,7 +59,9 @@
+ ClientLibrarySoName := $(ClientLibraryName)
+
+ # Looks like MinGW 3 does not support version scripts but support def-files
+-LINK_FIREBIRD_SYMBOLS = $(BLD_ROOT)/win32/defs/fbclient_s.def $(BLD_ROOT)/win32/defs/fbclient.def
++LINK_FIREBIRD_SYMBOLS = /def:$(BLD_ROOT)/win32/defs/fbclient_s.def /def:$(BLD_ROOT)/win32/defs/firebird.def
++LINK_PLUGIN_SYMBOLS = /def:$(BLD_ROOT)/win32/defs/plugin.def
++LINK_IBUTIL_SYMBOLS = /def:$(BLD_ROOT)/win32/defs/ib_util.def
+
+ # This is required for newly built executable to find newly built shared
+ # libraries because on Win32 there is no such thing as LD_LIBRARY_PATH
+--- builds/posix/make.shared.variables 2016-07-22 17:07:46.650672300 +0200
++++ builds/posix/make.shared.variables 2016-07-23 10:44:41.311454600 +0200
+@@ -62,6 +62,7 @@
+ $(SecDbCache)
+ Remote_Client:= $(call dirObjects,remote/client) $(call dirObjects,auth/SecureRemotePassword/client) \
+ $(call makeObjects,auth/SecurityDatabase,LegacyClient.cpp) \
++ $(call dirObjects,auth/trusted) \
+ $(call dirObjects,plugins/crypt/arc4)
+ Remote_Server_Objects:= $(Remote_Common) $(Remote_Server)
+ Remote_Client_Objects:= $(Remote_Common) $(Remote_Client)
+diff -ur configure configure
+--- configure 2016-07-07 13:55:54.976234682 +0200
++++ configure 2016-07-07 14:54:30.012328812 +0200
+@@ -3337,6 +3337,14 @@
+ SHRLIB_EXT=dll
+ ;;
+
++ *-*-cygwin*)
++ MAKEFILE_PREFIX=mingw
++ PLATFORM=win32
++ EDITLINE_FLG=N
++ RAW_DEVICES_FLG=N
++ SHRLIB_EXT=dll
++ ;;
++
+ *)
+ as_fn_error $? "unsupported platform ${build}" "$LINENO" 5
+ ;;
+@@ -8432,6 +8432,9 @@
+ mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
++cygwin*)
++ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
++ ;;
+ esac
+
+ # Try without a prefix underscore, then with it.
+diff -ur extern/btyacc/main.c extern/btyacc/main.c
+--- extern/btyacc/main.c 2016-07-07 13:55:55.448234695 +0200
++++ extern/btyacc/main.c 2016-07-07 14:56:03.560331317 +0200
+@@ -2,7 +2,7 @@
+ #include <signal.h>
+ #include <stdio.h>
+
+-#if defined(WIN32)
++#if defined(WIN32) || defined(_WIN32)
+ #include <io.h>
+ #else
+ #include <unistd.h>
+diff -ur extern/btyacc/Makefile extern/btyacc/Makefile
+--- extern/btyacc/Makefile 2016-07-07 13:55:55.448234695 +0200
++++ extern/btyacc/Makefile 2016-07-07 14:57:42.284333961 +0200
+@@ -30,7 +30,7 @@
+
+ PRINT = pr -f -l88
+
+-PROGRAM = btyacc
++PROGRAM = btyacc.exe
+
+ SRCS = closure.c error.c lalr.c lr0.c main.c mkpar.c output.c \
+ mstring.c reader.c readskel.c skeleton.c symtab.c verbose.c warshall.c
+@@ -58,7 +58,7 @@
+ index:; ctags -wx $(HDRS) $(SRCS)
+
+ install: $(PROGRAM)
+- cp $(PROGRAM).exe /bin
++ cp $(PROGRAM) /bin
+
+ oldinstall: $(PROGRAM)
+ @echo Installing $(PROGRAM) in $(DEST)
+--- extern/cloop/src/tests/test1/CppTest.cpp 2016-07-07 15:56:27.948015300 +0200
++++ extern/cloop/src/tests/test1/CppTest.cpp 2016-07-13 18:58:48.529822600 +0200
+@@ -24,6 +24,7 @@
+ #include <stdio.h>
+ #include <assert.h>
+
++#define WIN32
+ #ifdef WIN32
+ #include <windows.h>
+ #define DLL_EXPORT __declspec(dllexport)
+--- extern/cloop/src/tests/test1/CTest.c 2016-07-07 15:56:27.611791300 +0200
++++ extern/cloop/src/tests/test1/CTest.c 2016-07-13 17:04:22.805090300 +0200
+@@ -23,6 +23,7 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+
++#define WIN32
+ #ifdef WIN32
+ #include <windows.h>
+ #define DLL_EXPORT __declspec(dllexport)
+--- extern/cloop/Makefile 2016-07-07 15:56:28.279136300 +0200
++++ extern/cloop/Makefile 2016-07-13 16:22:38.493479800 +0200
+@@ -11,8 +11,8 @@
+ SRC_DIR := src
+ BUILD_DIR := build
+ OUT_DIR := output
+-SHRLIB_EXT := .so
+-EXE_EXT :=
++SHRLIB_EXT := .dll
++EXE_EXT := .exe
+
+ OBJ_DIR := $(BUILD_DIR)/$(TARGET)
+ BIN_DIR := $(OUT_DIR)/$(TARGET)/bin
+@@ -27,7 +27,7 @@
+ OBJS_C := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS_C))
+ OBJS_CPP := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRCS_CPP))
+
+-C_FLAGS := -ggdb -fPIC -MMD -MP -W -Wall -Wno-unused-parameter
++C_FLAGS := -fPIC
+ CXX_FLAGS := $(C_FLAGS)
+ FPC_FLAGS := -Mdelphi
+
+@@ -53,7 +53,7 @@
+ .PHONY: all mkdirs clean
+
+ all: mkdirs \
+- $(BIN_DIR)/cloop \
++ $(BIN_DIR)/cloop$(EXE_EXT) \
+ $(BIN_DIR)/test1-c$(SHRLIB_EXT) \
+ $(BIN_DIR)/test1-c$(EXE_EXT) \
+ $(BIN_DIR)/test1-cpp$(SHRLIB_EXT) \
+@@ -63,6 +63,10 @@
+
+ mkdirs: $(OBJ_DIRS) $(BIN_DIR) $(LIB_DIR)
+
++# These files have the same basename, so various conflicting intermediate files break the build
++$(BIN_DIR)/test1-c$(EXE_EXT): | $(BIN_DIR)/test1-c$(SHRLIB_EXT)
++$(BIN_DIR)/test1-cpp$(EXE_EXT): | $(BIN_DIR)/test1-cpp$(SHRLIB_EXT)
++
+ $(OBJ_DIRS) $(BIN_DIR) $(LIB_DIR):
+ @mkdir -p $@
+
+@@ -74,7 +74,7 @@
+ -include $(addsuffix .d,$(basename $(OBJS_C)))
+ -include $(addsuffix .d,$(basename $(OBJS_CPP)))
+
+-$(BIN_DIR)/cloop: \
++$(BIN_DIR)/cloop$(EXE_EXT): \
+ $(OBJ_DIR)/cloop/Expr.o \
+ $(OBJ_DIR)/cloop/Generator.o \
+ $(OBJ_DIR)/cloop/Lexer.o \
+@@ -83,20 +83,20 @@
+
+ $(LD) $^ -o $@
+
+-$(SRC_DIR)/tests/test1/CalcCApi.h: $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl
+- $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl c-header $@ CALC_C_API_H CALC_I
++$(SRC_DIR)/tests/test1/CalcCApi.h: $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl
++ $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl c-header $@ CALC_C_API_H CALC_I
+
+-$(SRC_DIR)/tests/test1/CalcCApi.c: $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl $(SRC_DIR)/tests/test1/CalcCApi.h
+- $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl c-impl $@ CalcCApi.h CALC_I
++$(SRC_DIR)/tests/test1/CalcCApi.c: $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl $(SRC_DIR)/tests/test1/CalcCApi.h
++ $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl c-impl $@ CalcCApi.h CALC_I
+
+-$(SRC_DIR)/tests/test1/CalcCppApi.h: $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl
+- $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl c++ $@ CALC_CPP_API_H calc I
++$(SRC_DIR)/tests/test1/CalcCppApi.h: $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl
++ $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl c++ $@ CALC_CPP_API_H calc I
+
+-$(SRC_DIR)/tests/test1/CalcPascalApi.pas: $(BIN_DIR)/cloop \
++$(SRC_DIR)/tests/test1/CalcPascalApi.pas: $(BIN_DIR)/cloop$(EXE_EXT) \
+ $(SRC_DIR)/tests/test1/Interface.idl \
+ $(SRC_DIR)/tests/test1/CalcPascalApi.interface.pas \
+ $(SRC_DIR)/tests/test1/CalcPascalApi.implementation.pas
+- $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl pascal $@ CalcPascalApi \
++ $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl pascal $@ CalcPascalApi \
+ --uses "SysUtils" \
+ --interfaceFile $(SRC_DIR)/tests/test1/CalcPascalApi.interface.pas \
+ --implementationFile $(SRC_DIR)/tests/test1/CalcPascalApi.implementation.pas \
+@@ -108,23 +108,23 @@
+ $(OBJ_DIR)/tests/test1/CalcCApi.o \
+ $(OBJ_DIR)/tests/test1/CTest.o \
+
+- $(LD) $^ -shared -ldl -o $@
++ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-c$(EXE_EXT): \
+ $(OBJ_DIR)/tests/test1/CalcCApi.o \
+ $(OBJ_DIR)/tests/test1/CTest.o \
+
+- $(LD) $^ -ldl -o $@
++ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-cpp$(SHRLIB_EXT): \
+ $(OBJ_DIR)/tests/test1/CppTest.o \
+
+- $(LD) $^ -shared -ldl -o $@
++ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-cpp$(EXE_EXT): \
+ $(OBJ_DIR)/tests/test1/CppTest.o \
+
+- $(LD) $^ -ldl -o $@
++ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-pascal$(SHRLIB_EXT): \
+ $(SRC_DIR)/tests/test1/PascalClasses.pas \
+diff -ur src/common/classes/fb_string.cpp src/common/classes/fb_string.cpp
+--- src/common/classes/fb_string.cpp 2016-07-07 13:55:56.064234711 +0200
++++ src/common/classes/fb_string.cpp 2016-07-07 14:59:01.516336083 +0200
+@@ -32,6 +32,12 @@
+ #include <ctype.h>
+ #include <stdarg.h>
+
++#ifdef WIN_NT
++#pragma comment(lib, "User32.lib")
++#pragma comment(lib, "advapi32")
++#pragma comment(lib, "shell32.lib")
++#endif
++
+ #ifdef HAVE_STRCASECMP
+ #define STRNCASECMP strncasecmp
+ #else
+diff -ur src/misc/makeHeader.cpp src/misc/makeHeader.cpp
+--- src/misc/makeHeader.cpp 2016-07-07 13:56:00.100234819 +0200
++++ src/misc/makeHeader.cpp 2016-07-07 15:00:14.780338045 +0200
+@@ -1,9 +1,9 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <errno.h>
+-//#ifdef HAVE_UNISTD_H
++#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+-//#endif
++#endif
+
+
+
+--- builds/posix/Makefile.in.plugins_examples.orig 2020-11-13 18:07:52.515550600 +0100
++++ builds/posix/Makefile.in.plugins_examples 2020-11-13 18:08:33.218626500 +0100
+@@ -28,7 +28,7 @@
+ # Adriano dos Santos Fernandes
+ #
+
+-ROOT=$(shell cd ..; pwd)
++ROOT=$(shell cygpath -m '$(shell cd ..; pwd)')
+
+ ifeq ($(IsDeveloper), Y)
+ DefaultTarget := Debug
+--- examples/dbcrypt/CryptApplication.cpp.orig 2020-11-13 20:57:11.222938900 +0100
++++ examples/dbcrypt/CryptApplication.cpp 2020-11-13 21:01:19.332316100 +0100
+@@ -27,6 +27,13 @@
+ #include "../interfaces/ifaceExamples.h"
+ #include <firebird/Message.h>
+
++#include "gen/autoconfig.h"
++
++#ifdef WIN_NT
++#include <windows.h>
++#include <winbase.h>
++#endif
++
+ using namespace Firebird;
+
+ class CryptKey : public ICryptKeyCallbackImpl<CryptKey, CheckStatusWrapper>
+@@ -238,8 +238,15 @@
+ av++;
+ }
+
++#ifdef WIN_NT
++ if (!getenv("ISC_USER"))
++ SetEnvironmentVariable("ISC_USER", "sysdba");
++ if (!getenv("ISC_PASSWORD"))
++ SetEnvironmentVariable("ISC_PASSWORD", "masterkey");
++#else
+ setenv("ISC_USER", "sysdba", 0);
+ setenv("ISC_PASSWORD", "masterkey", 0);
++#endif
+
+ App app;
+ try
diff --git a/external/firebird/firebird-macosx-sandbox.patch.1 b/external/firebird/firebird-macosx-sandbox.patch.1
new file mode 100644
index 000000000..3bf246c68
--- /dev/null
+++ b/external/firebird/firebird-macosx-sandbox.patch.1
@@ -0,0 +1,13 @@
+-*- Mode: Diff -*-
+
+--- firebird/src/common/isc_s_proto.h
++++ firebird/src/common/isc_s_proto.h
+@@ -37,6 +37,8 @@
+ // Firebird platform-specific synchronization data structures
+
+ #if defined(DARWIN)
++#define USE_POSIX_SEMAPHORE
++#define USE_SHARED_FUTEX
+ #define USE_FILELOCKS
+ #endif
+
diff --git a/external/firebird/firebird-macosx.patch.1 b/external/firebird/firebird-macosx.patch.1
new file mode 100644
index 000000000..676f2195a
--- /dev/null
+++ b/external/firebird/firebird-macosx.patch.1
@@ -0,0 +1,87 @@
+--- firebird.org/builds/posix/Makefile.in.examples
++++ firebird/builds/posix/Makefile.in.examples
+@@ -134,7 +134,7 @@
+ $(LN) $(ISQL) $(EXAMPLES_DEST)/isql$(EXEC_EXT)
+
+ $(EXAMPLES_DEST)/empbuild$(EXEC_EXT): $(EMPBLD_Objects) $(COMMON_LIB)
+- $(EXE_LINK) $(EXE_LINK_OPTIONS) $^ -o $@ -L$(LIB) $(FIREBIRD_LIBRARY_LINK) $(LINK_LIBS)
++ $(EXE_LINK) $(EXE_LINK_OPTIONS) $^ -o $@ -L$(LIB) $(FIREBIRD_LIBRARY_LINK) $(LINK_LIBS) $(call LINK_DARWIN_RPATH,../$(if $(ENABLE_DEBUG),Debug,Release)/firebird)
+
+ $(EXAMPLES_DEST)/empbuild.c: $(EXAMPLES_DEST)/empbuild.fdb $(EXAMPLES_DEST)/empbuild.e
+
+--- firebird.org/builds/posix/prefix.darwin_x86_64 2016-08-01 20:02:48.000000000 +0200
++++ firebird/builds/posix/prefix.darwin_x86_64 2016-08-01 21:42:45.000000000 +0200
+@@ -27,9 +27,6 @@
+ # configure using --with-builtin-tommath
+ # or add the relevant -I, -L for an installed version of libtommath
+
+-DYLD_LIBRARY_PATH=$(HOME)/icu54/icu/source/lib
+-export DYLD_LIBRARY_PATH
+-
+ #DYLD_PRINT_ENV=1
+ #export DYLD_PRINT_ENV
+
+@@ -31,8 +31,8 @@
+ MACOSX_DEPLOYMENT_TARGET=10.9
+ export MACOSX_DEPLOYMENT_TARGET
+
+-PROD_FLAGS=-DDARWIN -pipe -O2 -MMD -fPIC -fno-common -mmacosx-version-min=10.9
+-DEV_FLAGS=-ggdb -DDARWIN -pipe -MMD -fPIC -fno-omit-frame-pointer -fno-common -Wall -fno-optimize-sibling-calls -mmacosx-version-min=10.9 -Wno-non-virtual-dtor
++PROD_FLAGS=-DDARWIN -pipe -O2 -MMD -fPIC -fno-common
++DEV_FLAGS=-ggdb -DDARWIN -pipe -MMD -fPIC -fno-omit-frame-pointer -fno-common -Wall -fno-optimize-sibling-calls -Wno-non-virtual-dtor
+ CXXFLAGS:=$(CXXFLAGS) -fvisibility-inlines-hidden -fvisibility=hidden -stdlib=libc++ -msse4
+
+ EXE_LINK_OPTIONS:=
+--- firebird.org/src/common/unicode_util.cpp 2016-07-07 13:55:55.992234709 +0200
++++ firebird/src/common/unicode_util.cpp 2016-08-10 11:25:46.422331020 +0200
+@@ -63,8 +63,8 @@
+ const char* const ucTemplate = "icuuc%s.dll";
+ #endif
+ #elif defined(DARWIN)
+-const char* const inTemplate = "lib/libicui18n.%s.dylib";
+-const char* const ucTemplate = "lib/libicuuc.%s.dylib";
++const char* const inTemplate = "libicui18n.dylib.%s";
++const char* const ucTemplate = "libicuuc.dylib.%s";
+ #elif defined(HPUX)
+ const char* const inTemplate = "libicui18n.sl.%s";
+ const char* const ucTemplate = "libicuuc.sl.%s";
+@@ -354,6 +354,16 @@
+ {
+ s.printf(*p, majorVersion, minorVersion);
+ filename.printf(templateName, s.c_str());
++ const char * envpath = getenv("LIBREOFFICE_FIREBIRD_LIB");
++ if(envpath == nullptr)
++ {
++ envpath = getenv("LIBREOFFICE_ICU_LIB");
++ }
++ if(envpath != nullptr)
++ {
++ s = filename.c_str();
++ PathUtils::concatPath(filename, envpath, s.c_str());
++ }
+
+ ModuleLoader::Module* module = ModuleLoader::fixAndLoadModule(NULL, filename);
+ if (module)
+--- firebird.org/src/common/utils.cpp 2016-08-16 10:11:10.000000000 +0200
++++ firebird/src/common/utils.cpp 2016-08-16 11:27:09.000000000 +0200
+@@ -1027,10 +1027,18 @@
+ return s;
+ }
+
+- // Set relative path to Engine12 dynamic library
++ // Set path to Engine12 dynamic library.
+ if(prefType == Firebird::IConfigManager::DIR_PLUGINS)
+ {
+- s = name;
++ const char * const envpath = getenv("LIBREOFFICE_FIREBIRD_LIB");
++ if(envpath != nullptr)
++ {
++ PathUtils::concatPath(s, envpath, name);
++ }
++ else
++ {
++ s = name;
++ }
+ return s;
+ }
+ }
diff --git a/external/firebird/firebird-rpath.patch.0 b/external/firebird/firebird-rpath.patch.0
new file mode 100644
index 000000000..bc9fd3a3f
--- /dev/null
+++ b/external/firebird/firebird-rpath.patch.0
@@ -0,0 +1,11 @@
+--- builds/posix/make.defaults
++++ builds/posix/make.defaults
+@@ -292,7 +292,7 @@
+ LIB_PLATFORM_RPATH = -Wl,-rpath,$(1)
+ ifeq (@USE_RPATH@,1)
+ ifeq ($(strip @BINRELOC_CFLAGS@),)
+- LIB_LINK_RPATH = $(call LIB_PLATFORM_RPATH,$(if $(subst intl,,$(1)),@FB_LIBDIR@,@FB_INTLDIR@))
++ LIB_LINK_RPATH = $(call LIB_PLATFORM_RPATH,'$$ORIGIN')
+ else
+ LIB_LINK_RPATH = $(call LIB_PLATFORM_RPATH,'$$ORIGIN/../$(1)')
+ endif
diff --git a/external/firebird/firebird-tdf125284.patch.1 b/external/firebird/firebird-tdf125284.patch.1
new file mode 100644
index 000000000..a1cb2043e
--- /dev/null
+++ b/external/firebird/firebird-tdf125284.patch.1
@@ -0,0 +1,27 @@
+--- firebird/src/common/config/config_file.cpp 2019-08-23 16:42:26.721439468 +0100
++++ firebird/src/common/config/config_file.cpp 2019-08-23 16:43:07.506579222 +0100
+@@ -521,16 +521,14 @@
+ unsigned code;
+ const char* name;
+ } dirs[] = {
+-#define NMDIR(a) {Firebird::IConfigManager::a, "FB_"#a},
+- NMDIR(DIR_CONF)
+- NMDIR(DIR_SECDB)
+- NMDIR(DIR_PLUGINS)
+- NMDIR(DIR_UDF)
+- NMDIR(DIR_SAMPLE)
+- NMDIR(DIR_SAMPLEDB)
+- NMDIR(DIR_INTL)
+- NMDIR(DIR_MSG)
+-#undef NMDIR
++ {Firebird::IConfigManager::DIR_CONF, "FB_dir_conf"},
++ {Firebird::IConfigManager::DIR_SECDB, "FB_dir_secdb"},
++ {Firebird::IConfigManager::DIR_PLUGINS, "FB_dir_plugins"},
++ {Firebird::IConfigManager::DIR_UDF, "FB_dir_udf"},
++ {Firebird::IConfigManager::DIR_SAMPLE, "FB_dir_sample"},
++ {Firebird::IConfigManager::DIR_SAMPLEDB, "FB_dir_sampledb"},
++ {Firebird::IConfigManager::DIR_INTL, "FB_dir_intl"},
++ {Firebird::IConfigManager::DIR_MSG, "FB_dir_msg"},
+ {Firebird::IConfigManager::DIR_COUNT, NULL}
+ };
+
diff --git a/external/firebird/firebird-vs2017.patch.1 b/external/firebird/firebird-vs2017.patch.1
new file mode 100644
index 000000000..3c7db1874
--- /dev/null
+++ b/external/firebird/firebird-vs2017.patch.1
@@ -0,0 +1,12 @@
+diff -ru firebird.orig/src/common/os/win32/mod_loader.cpp firebird/src/common/os/win32/mod_loader.cpp
+--- firebird.orig/src/common/os/win32/mod_loader.cpp 2017-02-15 22:11:48.939042400 +0100
++++ firebird/src/common/os/win32/mod_loader.cpp 2017-02-15 22:12:30.062262700 +0100
+@@ -101,7 +101,7 @@
+ "msvcr110.dll",
+ #elif _MSC_VER == 1800
+ "msvcr120.dll",
+-#elif _MSC_VER >= 1900 && _MSC_VER < 1920
++#elif _MSC_VER >= 1900 && _MSC_VER < 2000
+ "vcruntime140.dll",
+ #else
+ #error Specify CRT DLL name here !
diff --git a/external/firebird/firebird.disable-ib-util-not-found.patch.1 b/external/firebird/firebird.disable-ib-util-not-found.patch.1
new file mode 100644
index 000000000..86dedd0dd
--- /dev/null
+++ b/external/firebird/firebird.disable-ib-util-not-found.patch.1
@@ -0,0 +1,17 @@
+--- firebird.org/src/jrd/fun.epp 2015-01-23 22:11:26.751475044 +0100
++++ firebird/src/jrd/fun.epp 2015-01-23 22:16:42.507322568 +0100
+@@ -164,10 +164,14 @@
+ if (tryLibrary(LIBNAME, message[3]))
+ return;
+
++ /* fdo#72543: quote from https://bugs.freedesktop.org/show_bug.cgi?id=72543#c8
++ "we don't need UDF support for embedded firebird,
++ hence the lack of ib_util isn't an issue and can safely be ignored"
+ // all failed - log error
+ gds__log("ib_util init failed, UDFs can't be used - looks like firebird misconfigured\n"
+ "\t%s\n\t%s\n\t%s\n\t%s", message[0].c_str(), message[1].c_str(),
+ message[2].c_str(), message[3].c_str());
++ */
+ }
+
+ void* IbUtil::alloc(long size)
diff --git a/external/firebird/macos-arm64.patch.0 b/external/firebird/macos-arm64.patch.0
new file mode 100644
index 000000000..ab2596dbd
--- /dev/null
+++ b/external/firebird/macos-arm64.patch.0
@@ -0,0 +1,109 @@
+-*- Mode: diff -*-
+--- configure
++++ configure
+@@ -2901,6 +2901,22 @@
+ RAW_DEVICES_FLG=N
+ ;;
+
++ aarch64-*-darwin*)
++ MAKEFILE_PREFIX=darwin_arm64
++ MAKEFILE_POSTFIX=darwin
++ PLATFORM=DARWIN
++ INSTALL_PREFIX=darwin
++
++$as_echo "#define DARWIN 1" >>confdefs.h
++
++ LIBS="$LIBS -framework CoreFoundation"
++ EDITLINE_FLG=Y
++ SHRLIB_EXT=dylib
++ CPU_TYPE=arm64
++ EXPORT_SYMBOLS_STYLE=darwin
++ RAW_DEVICES_FLG=N
++ ;;
++
+ i*86-*-darwin*)
+ MAKEFILE_PREFIX=darwin_i386
+ MAKEFILE_POSTFIX=darwin
+--- src/common/common.h
++++ src/common/common.h
+@@ -234,6 +234,12 @@
+ #define DARWINPPC64
+ #define FB_CPU CpuPowerPc64
+ #endif
++#ifdef __aarch64__
++// This means x86_64, but does it matter? There is no arch_arm64, arch_aarch64, arch_darwin_arm64,
++// or arch_darwin_aarch64 in the P_ARCH enum in src/remote/protocol.h.
++#define DARWIN64
++#define FB_CPU CpuArm64
++#endif
+ #define IEEE
+ #define QUADCONST(n) (n##LL)
+ #define QUADFORMAT "q"
+--- src/jrd/license.h
++++ src/jrd/license.h
+@@ -128,6 +128,9 @@
+ #if defined(ARM)
+ #define FB_PLATFORM "UA"
+ #endif
++#if defined(__aarch64__)
++#define FB_PLATFORM "UB"
++#endif
+ #endif
+
+ #ifdef DEV_BUILD
+--- /dev/null
++++ builds/posix/prefix.darwin_arm64
+@@ -0,0 +0,42 @@
++# The contents of this file are subject to the Interbase Public
++# License Version 1.0 (the "License"); you may not use this file
++# except in compliance with the License. You may obtain a copy
++# of the License at http://www.Inprise.com/IPL.html
++#
++# Software distributed under the License is distributed on an
++# "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
++# or implied. See the License for the specific language governing
++# rights and limitations under the License.
++#
++# The Original Code was created by Inprise Corporation
++# and its predecessors. Portions created by Inprise Corporation are
++#
++# Copyright (C) 2000 Inprise Corporation
++# All Rights Reserved.
++# Contributor(s): ______________________________________.
++# Start of file prefix.darwin: $(VERSION) @PLATFORM@
++# 2 Oct 2002, Nickolay Samofatov - Major Cleanup
++#
++
++
++#DYLD_PRINT_ENV=1
++#export DYLD_PRINT_ENV
++
++#DYLD_PRINT_LIBRARIES=1
++#export DYLD_PRINT_LIBRARIES
++
++MACOSX_DEPLOYMENT_TARGET=11.0
++export MACOSX_DEPLOYMENT_TARGET
++
++PROD_FLAGS=-DDARWIN -pipe -O2 -MMD -fPIC -fno-common
++DEV_FLAGS=-ggdb -DDARWIN -pipe -MMD -fPIC -fno-omit-frame-pointer -fno-common -Wall -fno-optimize-sibling-calls -Wno-non-virtual-dtor
++CXXFLAGS:=$(CXXFLAGS) -fvisibility-inlines-hidden -fvisibility=hidden
++
++EXE_LINK_OPTIONS:=
++UNDEF_PLATFORM=
++
++LINK_LIBS+=-liconv
++#MATHLIB=$(ROOT)/extern/libtommath/.libs/libtommath.a
++SO_LINK_LIBS+=-liconv
++
++include $(ROOT)/gen/darwin.defaults
+--- src/isql/InputDevices.cpp
++++ src/isql/InputDevices.cpp
+@@ -23,7 +23,7 @@
+
+ #include "firebird.h"
+ #if defined(DARWIN) && !defined(IOS)
+-#if defined(i386) || defined(__x86_64__)
++#if defined(i386) || defined(__x86_64__) || defined(__arm64__)
+ #include <architecture/i386/io.h>
+ #else
+ #include <io.h>
diff --git a/external/firebird/macosx-elcapitan-dyld.patch b/external/firebird/macosx-elcapitan-dyld.patch
new file mode 100644
index 000000000..134cdd974
--- /dev/null
+++ b/external/firebird/macosx-elcapitan-dyld.patch
@@ -0,0 +1,58 @@
+--- examples/empbuild/empbuild.e
++++ examples/empbuild/empbuild.e
+@@ -64,7 +64,7 @@
+ * Functional description
+ *
+ **************************************/
+-TEXT cmd [140];
++TEXT cmd [8000];
+
+ if (argc > 1)
+ strcpy (Db_name, argv[1]);
+@@ -94,7 +94,9 @@
+ }
+
+ printf ("Turning forced writes off\n");
++char const * lp = getenv("DYLD_LIBRARY_PATH");
++if (!lp) lp = "";
+-sprintf (cmd, "gfix -write async %s", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s gfix -write async %s", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't turn forced writes off\n");
+@@ -104,7 +106,7 @@
+ }
+
+ printf ("Creating tables\n");
+-sprintf (cmd, "isql %s -q -i empddl.sql", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s isql %s -q -i empddl.sql", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't create tables \n");
+@@ -120,7 +122,7 @@
+ }
+
+ printf ("Turning off indices and triggers \n");
+-sprintf (cmd, "isql %s -i indexoff.sql", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s isql %s -i indexoff.sql", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't turn off indices and triggers \n");
+@@ -128,7 +130,7 @@
+ }
+
+ printf ("Loading column data\n");
+-sprintf (cmd, "isql %s -i empdml.sql", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s isql %s -i empdml.sql", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't load column data \n");
+@@ -136,7 +138,7 @@
+ }
+
+ printf ("Turning on indices and triggers \n");
+-sprintf (cmd, "isql %s -i indexon.sql", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s isql %s -i indexon.sql", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't turn on indices and triggers \n");
diff --git a/external/firebird/msvc.patch b/external/firebird/msvc.patch
new file mode 100644
index 000000000..3f403b496
--- /dev/null
+++ b/external/firebird/msvc.patch
@@ -0,0 +1,11 @@
+--- src/auth/trusted/AuthSspi.cpp
++++ src/auth/trusted/AuthSspi.cpp
+@@ -109,7 +109,7 @@
+ groupNames(*getDefaultMemoryPool()), sessionKey(*getDefaultMemoryPool())
+ {
+ TimeStamp timeOut;
+- hasCredentials = initEntries() && (fAcquireCredentialsHandle(0, "NTLM",
++ hasCredentials = initEntries() && (fAcquireCredentialsHandle(0, const_cast<char *>("NTLM"),
+ SECPKG_CRED_BOTH, 0, 0, 0, 0,
+ &secHndl, &timeOut) == SEC_E_OK);
+ }
diff --git a/external/firebird/sanitizer.patch b/external/firebird/sanitizer.patch
new file mode 100644
index 000000000..3707b5bf5
--- /dev/null
+++ b/external/firebird/sanitizer.patch
@@ -0,0 +1,63 @@
+--- builds/posix/fbintl.vers
++++ builds/posix/fbintl.vers
+@@ -29,3 +29,4 @@
+ LD_lookup_texttype
+ LD_setup_attributes
+ LD_version
++_ZTI*
+--- builds/posix/fbplugin.vers
++++ builds/posix/fbplugin.vers
+@@ -26,3 +26,4 @@
+ #
+
+ firebird_plugin
++_ZTI*
+--- builds/posix/firebird.vers
++++ builds/posix/firebird.vers
+@@ -367,3 +367,4 @@
+
+ KEYWORD_stringIsAToken
+ KEYWORD_getTokens
++_ZTI*
+--- builds/posix/make.defaults
++++ builds/posix/make.defaults
+@@ -252,7 +252,7 @@
+ # LINKER OPTIONS
+ #
+
+-UNDEF_PLATFORM = -Wl,--no-undefined
++UNDEF_PLATFORM =
+ ifeq ($(TARGET),Debug)
+ UNDEF_FLAGS = $(UNDEF_PLATFORM)
+ endif
+@@ -291,7 +291,7 @@
+ LIB_LINK_MAPFILE= -Wl,--version-script,$(1)
+ FIREBIRD_LIBRARY_LINK= -L$(LIB) -lfbclient $(MATHLIB)
+
+-EXE_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) $(UNDEF_FLAGS) $(LIB_PATH_OPTS) $(LINK_EMPTY_SYMBOLS)
++EXE_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) $(UNDEF_FLAGS) $(LIB_PATH_OPTS)
+ LIB_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) -shared
+
+ FB_DAEMON = $(BIN)/firebird$(EXEC_EXT)
+--- src/common/classes/alloc.cpp
++++ src/common/classes/alloc.cpp
+@@ -2535,7 +2535,7 @@
+ const char* myStack = &probeVar;
+ const char* thisLocation = (const char*) this;
+ ptrdiff_t distance = thisLocation - myStack;
+- fb_assert(absVal(distance) < 128 * 1024);
++ //fb_assert(absVal(distance) < 128 * 1024);
+ }
+ #endif
+
+--- src/common/os/posix/mod_loader.cpp
++++ src/common/os/posix/mod_loader.cpp
+@@ -92,7 +92,7 @@
+
+ ModuleLoader::Module* ModuleLoader::loadModule(ISC_STATUS* status, const Firebird::PathName& modPath)
+ {
+- void* module = dlopen(modPath.nullStr(), FB_RTLD_MODE);
++ void* module = dlopen(modPath.nullStr(), FB_RTLD_MODE | RTLD_GLOBAL);
+ if (module == NULL)
+ {
+ if (status)
diff --git a/external/firebird/ubsan.patch b/external/firebird/ubsan.patch
new file mode 100644
index 000000000..fa296108d
--- /dev/null
+++ b/external/firebird/ubsan.patch
@@ -0,0 +1,307 @@
+--- configure
++++ configure
+@@ -21506,7 +21468,7 @@
+ char a;
+ union { long long x; sem_t y; } b;
+ };
+- exit((int)&((struct s*)0)->b);
++ exit((int)&((struct s*)1024)->b - 1024);
+ }
+ _ACEOF
+ if ac_fn_c_try_run "$LINENO"; then :
+@@ -21541,7 +21503,7 @@
+ char a;
+ double b;
+ };
+- exit((int)&((struct s*)0)->b);
++ exit((int)&((struct s*)1024)->b - 1024);
+ }
+ _ACEOF
+ if ac_fn_c_try_run "$LINENO"; then :
+--- src/common/classes/array.h
++++ src/common/classes/array.h
+@@ -149,7 +149,7 @@
+ void copyFrom(const Array<T, Storage>& source)
+ {
+ ensureCapacity(source.count, false);
+- memcpy(data, source.data, sizeof(T) * source.count);
++ if (source.count != 0) memcpy(data, source.data, sizeof(T) * source.count);
+ count = source.count;
+ }
+
+@@ -227,7 +227,7 @@
+ fb_assert(count <= FB_MAX_SIZEOF - itemsCount);
+ ensureCapacity(count + itemsCount);
+ memmove(data + index + itemsCount, data + index, sizeof(T) * (count - index));
+- memcpy(data + index, items, sizeof(T) * itemsCount);
++ if (itemsCount != 0) memcpy(data + index, items, sizeof(T) * itemsCount);
+ count += itemsCount;
+ }
+
+@@ -242,7 +242,7 @@
+ {
+ fb_assert(count <= FB_MAX_SIZEOF - itemsCount);
+ ensureCapacity(count + itemsCount);
+- memcpy(data + count, items, sizeof(T) * itemsCount);
++ if (itemsCount != 0) memcpy(data + count, items, sizeof(T) * itemsCount);
+ count += itemsCount;
+ }
+
+@@ -294,7 +294,7 @@
+ {
+ fb_assert(newCount >= count);
+ ensureCapacity(newCount);
+- memset(data + count, 0, sizeof(T) * (newCount - count));
++ if (newCount != count) memset(data + count, 0, sizeof(T) * (newCount - count));
+ count = newCount;
+ }
+
+@@ -328,7 +328,7 @@
+ {
+ fb_assert(count <= FB_MAX_SIZEOF - L.count);
+ ensureCapacity(count + L.count);
+- memcpy(data + count, L.data, sizeof(T) * L.count);
++ if (L.count != 0) memcpy(data + count, L.data, sizeof(T) * L.count);
+ count += L.count;
+ }
+
+@@ -462,7 +462,7 @@
+
+ T* newdata = static_cast<T*>
+ (this->getPool().allocate(sizeof(T) * newcapacity ALLOC_ARGS));
+- if (preserve)
++ if (preserve && count != 0)
+ memcpy(newdata, data, sizeof(T) * count);
+ freeData();
+ data = newdata;
+--- src/common/classes/fb_string.h
++++ src/common/classes/fb_string.h
+@@ -674,7 +674,8 @@
+ }
+ StringType& assign(const void* s, size_type n)
+ {
+- memcpy(baseAssign(n), s, n);
++ auto const p = baseAssign(n);
++ if (n != 0) memcpy(p, s, n);
+ return *this;
+ }
+ StringType& assign(const_pointer s)
+--- src/common/common.h
++++ src/common/common.h
+@@ -1002,6 +1002,5 @@
+ }
+
+ #undef UCHAR_TYPE
+-#define UCHAR_TYPE uint16_t
+
+ #endif /* COMMON_COMMON_H */
+--- src/common/unicode_util.cpp
++++ src/common/unicode_util.cpp
+@@ -187,7 +187,7 @@
+ Mutex ciAiTransCacheMutex;
+ Array<UTransliterator*> ciAiTransCache;
+
+- void (U_EXPORT2 *uVersionToString)(UVersionInfo versionArray, char* versionString);
++ void (U_EXPORT2 *uVersionToString)(UVersionInfo const versionArray, char* versionString);
+
+ int32_t (U_EXPORT2 *ulocCountAvailable)();
+ const char* (U_EXPORT2 *ulocGetAvailable)(int32_t n);
+--- src/dsql/StmtNodes.cpp
++++ src/dsql/StmtNodes.cpp
+@@ -6643,7 +6643,7 @@
+
+ void StoreNode::genBlr(DsqlCompilerScratch* dsqlScratch)
+ {
+- const dsql_msg* message = dsqlGenDmlHeader(dsqlScratch, dsqlRse->as<RseNode>());
++ const dsql_msg* message = dsqlGenDmlHeader(dsqlScratch, dsqlRse == nullptr ? nullptr : dsqlRse->as<RseNode>());
+
+ dsqlScratch->appendUChar(statement2 ? blr_store2 : blr_store);
+ GEN_expr(dsqlScratch, dsqlRelation);
+--- src/gpre/hsh.cpp
++++ src/gpre/hsh.cpp
+@@ -232,7 +232,7 @@
+ {
+ SCHAR c;
+
+- SLONG value = 0;
++ ULONG value = 0;
+
+ while (c = *string++)
+ value = (value << 1) + UPPER(c);
+--- src/jrd/GlobalRWLock.cpp
++++ src/jrd/GlobalRWLock.cpp
+@@ -78,7 +78,7 @@
+
+ cachedLock = FB_NEW_RPT(getPool(), lockLen)
+ Lock(tdbb, lockLen, lckType, this, lockCaching ? blocking_ast_cached_lock : NULL);
+- memcpy(cachedLock->getKeyString(), lockStr, lockLen);
++ if (lockLen != 0) memcpy(cachedLock->getKeyString(), lockStr, lockLen);
+ }
+
+ GlobalRWLock::~GlobalRWLock()
+--- src/jrd/Optimizer.cpp
++++ src/jrd/Optimizer.cpp
+@@ -368,7 +368,7 @@
+
+ // Allocate needed indexScratches
+
+- index_desc* idx = csb_tail->csb_idx->items;
++ index_desc* idx = csb_tail->csb_idx == nullptr ? nullptr : csb_tail->csb_idx->items;
+ for (int i = 0; i < csb_tail->csb_indices; ++i, ++idx)
+ indexScratches.add(IndexScratch(p, tdbb, idx, csb_tail));
+ }
+--- src/jrd/blb.cpp
++++ src/jrd/blb.cpp
+@@ -1786,7 +1786,7 @@
+ arg.slice_base = array->arr_data;
+
+ SLONG variables[64];
+- memcpy(variables, param, MIN(sizeof(variables), param_length));
++ if (param_length != 0) memcpy(variables, param, MIN(sizeof(variables), param_length));
+
+ if (SDL_walk(tdbb->tdbb_status_vector, sdl, array->arr_data, &array_desc->arr_desc,
+ variables, slice_callback, &arg))
+--- src/jrd/btn.cpp
++++ src/jrd/btn.cpp
+@@ -387,7 +387,7 @@
+
+ put_short(pagePointer, offset);
+ pagePointer += sizeof(USHORT);
+- memmove(pagePointer, data, length);
++ if (length != 0) memmove(pagePointer, data, length);
+ pagePointer += length;
+ return pagePointer;
+ }
+@@ -622,7 +622,7 @@
+ }
+
+ // Store data
+- if (withData) {
++ if (withData && length != 0) {
+ memcpy(pagePointer, data, length);
+ }
+ pagePointer += length;
+--- src/jrd/btr.cpp
++++ src/jrd/btr.cpp
+@@ -5206,7 +5206,7 @@
+ // Push node on end in list
+ jumpNodes->add(jumpNode);
+ // Store new data in jumpKey, so a new jump node can calculate prefix
+- memcpy(jumpData + jumpNode.prefix, jumpNode.data, jumpNode.length);
++ if (jumpNode.length != 0) memcpy(jumpData + jumpNode.prefix, jumpNode.data, jumpNode.length);
+ jumpLength = jumpNode.length + jumpNode.prefix;
+
+ // Check if this could be our split point (if we need to split)
+@@ -5391,7 +5391,7 @@
+ // First, store needed data for beforeInsertNode into tempData.
+ HalfStaticArray<UCHAR, MAX_KEY> tempBuf;
+ UCHAR* tempData = tempBuf.getBuffer(newLength);
+- memcpy(tempData, beforeInsertNode.data + newPrefix - beforeInsertNode.prefix, newLength);
++ if (newLength != 0) memcpy(tempData, beforeInsertNode.data + newPrefix - beforeInsertNode.prefix, newLength);
+
+ beforeInsertNode.prefix = newPrefix;
+ beforeInsertNode.length = newLength;
+@@ -5611,7 +5611,7 @@
+ for (size_t i = 0; i < jumpNodes->getCount(); i++, index++)
+ {
+ UCHAR* q = new_key->key_data + walkJumpNode[i].prefix;
+- memcpy(q, walkJumpNode[i].data, walkJumpNode[i].length);
++ if (walkJumpNode[i].length != 0) memcpy(q, walkJumpNode[i].data, walkJumpNode[i].length);
+ if (index == splitJumpNodeIndex)
+ {
+ jn = &walkJumpNode[i];
+@@ -5636,7 +5636,7 @@
+ const USHORT length = walkJumpNode[i].prefix + walkJumpNode[i].length;
+ UCHAR* newData = FB_NEW_POOL(*tdbb->getDefaultPool()) UCHAR[length];
+ memcpy(newData, new_key->key_data, walkJumpNode[i].prefix);
+- memcpy(newData + walkJumpNode[i].prefix, walkJumpNode[i].data,
++ if (walkJumpNode[i].length != 0) memcpy(newData + walkJumpNode[i].prefix, walkJumpNode[i].data,
+ walkJumpNode[i].length);
+ delete[] walkJumpNode[i].data;
+ walkJumpNode[i].prefix = 0;
+--- src/jrd/evl.cpp
++++ src/jrd/evl.cpp
+@@ -415,7 +415,7 @@
+ case dtype_real:
+ case dtype_sql_time:
+ case dtype_sql_date:
+- value->vlu_misc.vlu_long = *((SLONG*) from.dsc_address);
++ memcpy(&value->vlu_misc.vlu_long, from.dsc_address, sizeof (SLONG));
+ return;
+
+ case dtype_int64:
+--- src/jrd/lck.cpp
++++ src/jrd/lck.cpp
+@@ -488,7 +488,7 @@
+ break;
+ }
+
+- dbb->dbb_lock_mgr->shutdownOwner(tdbb, owner_handle_ptr);
++ LockManager::shutdownOwner(dbb->dbb_lock_mgr, tdbb, owner_handle_ptr);
+ }
+
+
+--- src/lock/lock.cpp
++++ src/lock/lock.cpp
+@@ -441,7 +441,7 @@
+ }
+
+
+-void LockManager::shutdownOwner(thread_db* tdbb, SRQ_PTR* owner_handle)
++void LockManager::shutdownOwner(LockManager* This, thread_db* tdbb, SRQ_PTR* owner_handle)
+ {
+ /**************************************
+ *
+@@ -460,8 +460,9 @@
+ if (!owner_offset)
+ return;
+
+- LockTableGuard guard(this, FB_FUNCTION, owner_offset);
++ LockTableGuard guard(This, FB_FUNCTION, owner_offset);
+
++#define SRQ_BASE ((UCHAR*) This->m_sharedMemory->getHeader())
+ own* owner = (own*) SRQ_ABS_PTR(owner_offset);
+ if (!owner->own_count)
+ return;
+@@ -472,7 +473,7 @@
+ while (owner->own_ast_count)
+ {
+ { // checkout scope
+- LockTableCheckout checkout(this, FB_FUNCTION);
++ LockTableCheckout checkout(This, FB_FUNCTION);
+ EngineCheckout cout(tdbb, FB_FUNCTION, true);
+ Thread::sleep(10);
+ }
+@@ -484,8 +485,9 @@
+ // released before destroying the lock owner. This is not strictly required,
+ // but it enforces the proper object lifetime discipline through the codebase.
+ fb_assert(SRQ_EMPTY(owner->own_requests));
++#define SRQ_BASE ((UCHAR*) m_sharedMemory->getHeader())
+
+- purge_owner(owner_offset, owner);
++ This->purge_owner(owner_offset, owner);
+
+ *owner_handle = 0;
+ }
+--- src/lock/lock_proto.h
++++ src/lock/lock_proto.h
+@@ -402,7 +402,7 @@
+ static void destroy(LockManager*);
+
+ bool initializeOwner(Firebird::CheckStatusWrapper*, LOCK_OWNER_T, UCHAR, SRQ_PTR*);
+- void shutdownOwner(thread_db*, SRQ_PTR*);
++ static void shutdownOwner(LockManager* This, thread_db*, SRQ_PTR*);
+
+ SRQ_PTR enqueue(thread_db*, Firebird::CheckStatusWrapper*, SRQ_PTR, const USHORT,
+ const UCHAR*, const USHORT, UCHAR, lock_ast_t, void*, SINT64, SSHORT, SRQ_PTR);
+--- src/yvalve/gds.cpp
++++ src/yvalve/gds.cpp
+@@ -2561,7 +2561,7 @@
+ value += ((SLONG) *ptr++) << shift;
+ shift += 8;
+ }
+- value += ((SLONG)(SCHAR) *ptr) << shift;
++ value += ((ULONG)(SCHAR) *ptr) << shift;
+
+ return value;
+ }
diff --git a/external/firebird/wnt-dbgutil.patch b/external/firebird/wnt-dbgutil.patch
new file mode 100644
index 000000000..94fbd1dff
--- /dev/null
+++ b/external/firebird/wnt-dbgutil.patch
@@ -0,0 +1,63 @@
+--- configure
++++ configure
+@@ -18430,44 +18430,6 @@
+ as_fn_error $? "ICU support not found - please install development ICU package" "$LINENO" 5
+ fi
+
+-
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -licuuc" >&5
+-$as_echo_n "checking for main in -licuuc... " >&6; }
+-if ${ac_cv_lib_icuuc_main+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-licuuc $LIBS"
+-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-
+-int
+-main ()
+-{
+-return main ();
+- ;
+- return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+- ac_cv_lib_icuuc_main=yes
+-else
+- ac_cv_lib_icuuc_main=no
+-fi
+-rm -f core conftest.err conftest.$ac_objext \
+- conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
+-fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_icuuc_main" >&5
+-$as_echo "$ac_cv_lib_icuuc_main" >&6; }
+-if test "x$ac_cv_lib_icuuc_main" = xyes; then :
+- ICU_OK=yes
+-else
+- as_fn_error $? "ICU support not found - please install development ICU package" "$LINENO" 5
+-fi
+-
+-
+ if test "$TOMBUILD" = "Y"; then
+ MATHLIB=-ltommath
+ else
+--- src/common/unicode_util.cpp
++++ src/common/unicode_util.cpp
+@@ -55,8 +55,13 @@
+
+ namespace {
+ #if defined(WIN_NT)
++#if defined(MSVC_USE_DEBUG_RUNTIME)
++const char* const inTemplate = "icuind%s.dll";
++const char* const ucTemplate = "icuucd%s.dll";
++#else
+ const char* const inTemplate = "icuin%s.dll";
+ const char* const ucTemplate = "icuuc%s.dll";
++#endif
+ #elif defined(DARWIN)
+ const char* const inTemplate = "lib/libicui18n.%s.dylib";
+ const char* const ucTemplate = "lib/libicuuc.%s.dylib";
diff --git a/external/firebird/wnt-per-process-trace-storage.patch.1 b/external/firebird/wnt-per-process-trace-storage.patch.1
new file mode 100644
index 000000000..46af6c5e5
--- /dev/null
+++ b/external/firebird/wnt-per-process-trace-storage.patch.1
@@ -0,0 +1,18 @@
+diff --git a/src/jrd/trace/TraceConfigStorage.cpp b/src/jrd/trace/TraceConfigStorage.cpp
+index 05fce3211ae7..d267713e85de 100644
+--- a/src/jrd/trace/TraceConfigStorage.cpp
++++ b/src/jrd/trace/TraceConfigStorage.cpp
+@@ -103,11 +103,11 @@ ConfigStorage::ConfigStorage()
+ pfnProcessIdToSessionId(GetCurrentProcessId(), &sesID) == 0 ||
+ sesID == 0)
+ {
+- filename.printf(TRACE_FILE); // TODO: it must be per engine instance
++ filename.printf("%s.0.%u", TRACE_FILE, GetCurrentProcessId()); // TODO: it must be per engine instance
+ }
+ else
+ {
+- filename.printf("%s.%u", TRACE_FILE, sesID);
++ filename.printf("%s.%u.%u", TRACE_FILE, sesID, GetCurrentProcessId());
+ }
+ #else
+ filename.printf(TRACE_FILE); // TODO: it must be per engine instance
diff --git a/external/fontconfig/ExternalPackage_fontconfig_data.mk b/external/fontconfig/ExternalPackage_fontconfig_data.mk
new file mode 100644
index 000000000..cc33c2670
--- /dev/null
+++ b/external/fontconfig/ExternalPackage_fontconfig_data.mk
@@ -0,0 +1,58 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fontconfig_data,fontconfig))
+
+$(eval $(call gb_ExternalPackage_use_external_project,fontconfig_data,fontconfig))
+
+$(eval $(call gb_ExternalPackage_add_files,fontconfig_data,$(LIBO_SHARE_FOLDER)/fontconfig,\
+ fonts.conf \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fontconfig_data,$(LIBO_SHARE_FOLDER)/fontconfig/conf.d,\
+ conf.d/05-reset-dirs-sample.conf \
+ conf.d/09-autohint-if-no-hinting.conf \
+ conf.d/10-autohint.conf \
+ conf.d/10-hinting-full.conf \
+ conf.d/10-hinting-medium.conf \
+ conf.d/10-hinting-none.conf \
+ conf.d/10-hinting-slight.conf \
+ conf.d/10-no-sub-pixel.conf \
+ conf.d/10-scale-bitmap-fonts.conf \
+ conf.d/10-sub-pixel-bgr.conf \
+ conf.d/10-sub-pixel-rgb.conf \
+ conf.d/10-sub-pixel-vbgr.conf \
+ conf.d/10-sub-pixel-vrgb.conf \
+ conf.d/10-unhinted.conf \
+ conf.d/11-lcdfilter-default.conf \
+ conf.d/11-lcdfilter-legacy.conf \
+ conf.d/11-lcdfilter-light.conf \
+ conf.d/20-unhint-small-vera.conf \
+ conf.d/25-unhint-nonlatin.conf \
+ conf.d/30-metric-aliases.conf \
+ conf.d/35-lang-normalize.conf \
+ conf.d/40-nonlatin.conf \
+ conf.d/45-generic.conf \
+ conf.d/45-latin.conf \
+ conf.d/49-sansserif.conf \
+ conf.d/50-user.conf \
+ conf.d/51-local.conf \
+ conf.d/60-generic.conf \
+ conf.d/60-latin.conf \
+ conf.d/65-fonts-persian.conf \
+ conf.d/65-khmer.conf \
+ conf.d/65-nonlatin.conf \
+ conf.d/69-unifont.conf \
+ conf.d/70-no-bitmaps.conf \
+ conf.d/70-yes-bitmaps.conf \
+ conf.d/80-delicious.conf \
+ conf.d/90-synthetic.conf \
+))
+
+# vim: set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/external/fontconfig/ExternalProject_fontconfig.mk b/external/fontconfig/ExternalProject_fontconfig.mk
new file mode 100644
index 000000000..9f85faa39
--- /dev/null
+++ b/external/fontconfig/ExternalProject_fontconfig.mk
@@ -0,0 +1,48 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,fontconfig))
+
+$(eval $(call gb_ExternalProject_use_externals,fontconfig,\
+ expat \
+ freetype \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,fontconfig,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,fontconfig,build) :
+ $(call gb_Trace_StartRange,fontconfig,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ CFLAGS="$(CFLAGS) \
+ $(call gb_ExternalProject_get_build_flags,fontconfig) \
+ $(gb_VISIBILITY_FLAGS) \
+ $(if $(filter EMSCRIPTEN,$(OS)),-pthread)" \
+ $(if $(filter ANDROID,$(OS)),LIBS="-lm") \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,fontconfig)" \
+ $(gb_RUN_CONFIGURE) ./configure \
+ --disable-shared \
+ --disable-silent-rules \
+ --with-pic \
+ $(if $(filter ANDROID,$(OS)),--with-arch=arm) \
+ --with-expat-includes=$(call gb_UnpackedTarball_get_dir,expat)/lib \
+ --with-expat-lib=$(gb_StaticLibrary_WORKDIR) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter EMSCRIPTEN,$(OS)), \
+ --with-baseconfigdir=/instdir/share/fontconfig \
+ --with-cache-dir=/instdir/share/fontconfig/cache \
+ --with-add-fonts=/instdir/share/fonts \
+ ac_cv_func_fstatfs=no ac_cv_func_fstatvfs=no \
+ ) \
+ && $(MAKE) -C src && $(MAKE) fonts.conf \
+ )
+ $(call gb_Trace_EndRange,fontconfig,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/fontconfig/Makefile b/external/fontconfig/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/fontconfig/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/fontconfig/Module_fontconfig.mk b/external/fontconfig/Module_fontconfig.mk
new file mode 100644
index 000000000..2f8f9c8f5
--- /dev/null
+++ b/external/fontconfig/Module_fontconfig.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,fontconfig))
+
+$(eval $(call gb_Module_add_targets,fontconfig,\
+ ExternalProject_fontconfig \
+ $(if $(filter EMSCRIPTEN,$(OS)),ExternalPackage_fontconfig_data) \
+ UnpackedTarball_fontconfig \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/fontconfig/README b/external/fontconfig/README
new file mode 100644
index 000000000..220ee6078
--- /dev/null
+++ b/external/fontconfig/README
@@ -0,0 +1,6 @@
+This "bundled" fontconfig is built only in an Android build
+
+Fontconfig is a font configuration and customization library. It is designed to locate fonts
+within the system and select them according to requirements specified by applications.
+
+From [ http://packages.debian.org/squeeze/fontconfig ] \ No newline at end of file
diff --git a/external/fontconfig/UnpackedTarball_fontconfig.mk b/external/fontconfig/UnpackedTarball_fontconfig.mk
new file mode 100644
index 000000000..6026a817c
--- /dev/null
+++ b/external/fontconfig/UnpackedTarball_fontconfig.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,fontconfig))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,fontconfig,$(FONTCONFIG_TARBALL),,fontconfig))
+
+$(eval $(call gb_UnpackedTarball_add_patches,fontconfig,\
+ external/fontconfig/fontconfig-2.12.1.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/fontconfig/fontconfig-2.12.1.patch.1 b/external/fontconfig/fontconfig-2.12.1.patch.1
new file mode 100644
index 000000000..f348d2aa8
--- /dev/null
+++ b/external/fontconfig/fontconfig-2.12.1.patch.1
@@ -0,0 +1,135 @@
+diff -up fontconfig/configure.dt fontconfig/configure
+--- fontconfig/configure.dt 2017-02-01 22:07:29.671668568 +0100
++++ fontconfig/configure 2017-02-01 22:09:53.335215490 +0100
+@@ -10469,7 +10469,7 @@ _LT_EOF
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+@@ -10485,7 +10485,7 @@ _LT_EOF
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+- archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags -o $lib'
+ else
+ ld_shlibs=no
+ fi
+@@ -10519,7 +10519,7 @@ _LT_EOF
+ ;;
+
+ haiku*)
+- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+@@ -10614,13 +10614,13 @@ _LT_EOF
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
++ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+@@ -10650,8 +10650,8 @@ _LT_EOF
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags -o $lib'
++ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+@@ -10669,8 +10669,8 @@ _LT_EOF
+
+ _LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags -o $lib'
++ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+@@ -10698,8 +10698,8 @@ _LT_EOF
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $lib'
++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+@@ -10716,8 +10716,8 @@ _LT_EOF
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags -o $lib'
++ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+@@ -11016,7 +11016,7 @@ fi
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+@@ -11285,7 +11285,7 @@ fi
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+@@ -11313,7 +11313,7 @@ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
++ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+@@ -11408,7 +11408,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >
+ osf3*)
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+- archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
++ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+@@ -11421,7 +11421,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+- archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
++ archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
diff --git a/external/freetype/ExternalProject_freetype.mk b/external/freetype/ExternalProject_freetype.mk
new file mode 100644
index 000000000..2a61ac7d7
--- /dev/null
+++ b/external/freetype/ExternalProject_freetype.mk
@@ -0,0 +1,38 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,freetype))
+
+$(eval $(call gb_ExternalProject_register_targets,freetype,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,freetype,build) :
+ $(call gb_Trace_StartRange,freetype,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure \
+ --disable-shared \
+ --with-pic \
+ --without-zlib \
+ --without-brotli \
+ --without-bzip2 \
+ --without-harfbuzz \
+ --without-png \
+ --prefix=$(call gb_UnpackedTarball_get_dir,freetype/instdir) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ CFLAGS="$(CFLAGS) \
+ $(call gb_ExternalProject_get_build_flags,freetype) \
+ $(gb_VISIBILITY_FLAGS) \
+ $(gb_EMSCRIPTEN_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,freetype)" \
+ && $(MAKE) install \
+ && touch $@ )
+ $(call gb_Trace_EndRange,freetype,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/freetype/Makefile b/external/freetype/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/freetype/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/freetype/Module_freetype.mk b/external/freetype/Module_freetype.mk
new file mode 100644
index 000000000..290014c47
--- /dev/null
+++ b/external/freetype/Module_freetype.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,freetype))
+
+$(eval $(call gb_Module_add_targets,freetype,\
+ ExternalProject_freetype \
+ UnpackedTarball_freetype \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/freetype/README b/external/freetype/README
new file mode 100644
index 000000000..481466432
--- /dev/null
+++ b/external/freetype/README
@@ -0,0 +1,6 @@
+FreeType 2 is a software font engine that is designed to be small, efficient, highly customizable,
+and portable while capable of producing high-quality output (glyph images). It can be
+used in graphics libraries, display servers, font conversion tools, text image generation
+tools, and many other products as well.
+
+From [http://freetype.sourceforge.net/freetype2/index.html]
diff --git a/external/freetype/UnpackedTarball_freetype.mk b/external/freetype/UnpackedTarball_freetype.mk
new file mode 100644
index 000000000..076edb9e3
--- /dev/null
+++ b/external/freetype/UnpackedTarball_freetype.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,freetype))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,freetype,$(FREETYPE_TARBALL),,freetype))
+
+$(eval $(call gb_UnpackedTarball_add_patches,freetype,\
+ external/freetype/freetype-2.6.5.patch.1 \
+ external/freetype/ubsan.patch \
+))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,freetype,0))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/freetype/freetype-2.6.5.patch.1 b/external/freetype/freetype-2.6.5.patch.1
new file mode 100644
index 000000000..c10c0bb38
--- /dev/null
+++ b/external/freetype/freetype-2.6.5.patch.1
@@ -0,0 +1,157 @@
+diff -up freetype/builds/unix/configure.dt freetype/builds/unix/configure
+--- freetype/builds/unix/configure.dt 2017-02-01 22:14:45.206257952 +0100
++++ freetype/builds/unix/configure 2017-02-01 22:16:31.076183707 +0100
+@@ -9386,7 +9386,7 @@
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+@@ -9402,7 +9402,7 @@
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+- archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags -o $lib'
+ else
+ ld_shlibs=no
+ fi
+@@ -9436,7 +9436,7 @@
+ ;;
+
+ haiku*)
+- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+@@ -9531,13 +9531,13 @@
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
++ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+@@ -9567,8 +9567,8 @@
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags -o $lib'
++ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+@@ -9586,8 +9586,8 @@
+
+ _LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags -o $lib'
++ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+@@ -9615,8 +9615,8 @@
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $lib'
++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+@@ -9633,8 +9633,8 @@
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags -o $lib'
++ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+@@ -9937,7 +9937,7 @@
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+@@ -10207,7 +10207,7 @@
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+@@ -10237,7 +10237,7 @@
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+ printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; }
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+- archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
++ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+@@ -10332,7 +10332,7 @@
+ osf3*)
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+- archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
++ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+@@ -10345,7 +10345,7 @@
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+- archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
++ archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+@@ -13620,10 +13620,10 @@
+ XX_CFLAGS="-Wall"
+ case "$host" in
+ *-*-mingw*)
+- XX_ANSIFLAGS="-pedantic"
++ XX_ANSIFLAGS=""
+ ;;
+ *-*-aix*)
+- XX_ANSIFLAGS="-pedantic"
++ XX_ANSIFLAGS=""
+ ;;
+ *)
+ XX_ANSIFLAGS=""
+@@ -13661,7 +13661,7 @@
+ then :
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok, adding to XX_ANSIFLAGS" >&5
+ printf "%s\n" "ok, adding to XX_ANSIFLAGS" >&6; }
+- XX_ANSIFLAGS="${XX_ANSIFLAGS} ${a}"
++ XX_ANSIFLAGS="${XX_ANSIFLAGS}"
+
+ else $as_nop
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
diff --git a/external/freetype/ubsan.patch b/external/freetype/ubsan.patch
new file mode 100644
index 000000000..c8173eeff
--- /dev/null
+++ b/external/freetype/ubsan.patch
@@ -0,0 +1,11 @@
+--- src/truetype/ttgxvar.c
++++ src/truetype/ttgxvar.c
+@@ -964,7 +964,7 @@
+ /* in the OpenType specification. */
+
+ varData = &itemStore->varData[outerIndex];
+- deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex];
++ deltaSet = varData->regionIdxCount * innerIndex == 0 ? varData->deltaSet : &varData->deltaSet[varData->regionIdxCount * innerIndex];
+
+ /* outer loop steps through master designs to be blended */
+ for ( master = 0; master < varData->regionIdxCount; master++ )
diff --git a/external/glm/Makefile b/external/glm/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/glm/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/glm/Module_glm.mk b/external/glm/Module_glm.mk
new file mode 100644
index 000000000..617b067a2
--- /dev/null
+++ b/external/glm/Module_glm.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,glm))
+
+$(eval $(call gb_Module_add_targets,glm,\
+ UnpackedTarball_glm \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/glm/README b/external/glm/README
new file mode 100644
index 000000000..30122f67b
--- /dev/null
+++ b/external/glm/README
@@ -0,0 +1,3 @@
+Glm provides a header only library for OpenGL mathematics.
+
+It is available from http://glm.g-truc.net/0.9.4/index.html
diff --git a/external/glm/UnpackedTarball_glm.mk b/external/glm/UnpackedTarball_glm.mk
new file mode 100644
index 000000000..934621eac
--- /dev/null
+++ b/external/glm/UnpackedTarball_glm.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,glm))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,glm,$(GLM_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchflags,glm,$(if $(filter MSC,$(COM)),--binary)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,glm,1))
+
+$(eval $(call gb_UnpackedTarball_add_patches,glm, \
+ external/glm/clang-cl.patch.0 \
+ external/glm/c++20.patch.0 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/glm/c++20.patch.0 b/external/glm/c++20.patch.0
new file mode 100644
index 000000000..9fdd813a1
--- /dev/null
+++ b/external/glm/c++20.patch.0
@@ -0,0 +1,11 @@
+--- glm/detail/type_half.inl
++++ glm/detail/type_half.inl
+@@ -6,7 +6,7 @@
+ volatile float f = 1e10;
+
+ for(int i = 0; i < 10; ++i)
+- f *= f; // this will overflow before the for loop terminates
++ f = f * f; // this will overflow before the for loop terminates
+ return f;
+ }
+
diff --git a/external/glm/clang-cl.patch.0 b/external/glm/clang-cl.patch.0
new file mode 100644
index 000000000..e5536e145
--- /dev/null
+++ b/external/glm/clang-cl.patch.0
@@ -0,0 +1,14 @@
+# "#pragma intrinsic" not (yet?) handled in the "if (LangOpts.MicrosoftExt)"
+# block in Preprocessor::RegisterBuiltinPragmas in Clang's lib/Lex/Pragma.cpp:
+--- glm/detail/func_integer.inl
++++ glm/detail/func_integer.inl
+@@ -3,7 +3,9 @@
+ #include "_vectorize.hpp"
+ #if(GLM_ARCH & GLM_ARCH_X86 && GLM_COMPILER & GLM_COMPILER_VC)
+ # include <intrin.h>
++#if !defined __clang__
+ # pragma intrinsic(_BitScanReverse)
++#endif
+ #endif//(GLM_ARCH & GLM_ARCH_X86 && GLM_COMPILER & GLM_COMPILER_VC)
+ #include <limits>
+
diff --git a/external/gpgmepp/0001-cpp-Fix-building-with-C-11.patch.1 b/external/gpgmepp/0001-cpp-Fix-building-with-C-11.patch.1
new file mode 100755
index 000000000..c7b288d72
--- /dev/null
+++ b/external/gpgmepp/0001-cpp-Fix-building-with-C-11.patch.1
@@ -0,0 +1,72 @@
+From f02c20cc9c5756690b07abfd02a43533547ba2ef Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= <dev@ingo-kloecker.de>
+Date: Fri, 19 Aug 2022 11:05:37 +0200
+Subject: [PATCH] cpp: Fix building with C++11
+
+* lang/cpp/src/importresult.cpp (ImportResult::mergeWith): Replace
+'auto' in lambdas with the actual type.
+--
+
+Generic lambdas require C++14.
+
+GnuPG-bug-id: 6141
+---
+ lang/cpp/src/importresult.cpp | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/lang/cpp/src/importresult.cpp b/lang/cpp/src/importresult.cpp
+index 06258729..0a7ad03d 100644
+--- a/lang/cpp/src/importresult.cpp
++++ b/lang/cpp/src/importresult.cpp
+@@ -152,17 +152,17 @@ void GpgME::ImportResult::mergeWith(const ImportResult &other)
+ }
+ // was this key also considered during the first import
+ const auto consideredInFirstImports =
+- std::any_of(std::begin(d->imports), std::end(d->imports), [fpr](const auto i) {
++ std::any_of(std::begin(d->imports), std::end(d->imports), [fpr](const gpgme_import_status_t i) {
+ return i->fpr && !strcmp(i->fpr, fpr);
+ });
+ // did we see this key already in the list of keys of the other import
+ const auto consideredInPreviousOtherImports =
+- std::any_of(std::begin(other.d->imports), it, [fpr](const auto i) {
++ std::any_of(std::begin(other.d->imports), it, [fpr](const gpgme_import_status_t i) {
+ return i->fpr && !strcmp(i->fpr, fpr);
+ });
+ // was anything added to this key during the other import
+ const auto changedInOtherImports =
+- std::any_of(std::begin(other.d->imports), std::end(other.d->imports), [fpr](const auto i) {
++ std::any_of(std::begin(other.d->imports), std::end(other.d->imports), [fpr](const gpgme_import_status_t i) {
+ return i->fpr && !strcmp(i->fpr, fpr) && (i->status != 0);
+ });
+ if (consideredInFirstImports && !consideredInPreviousOtherImports) {
+@@ -177,15 +177,15 @@ void GpgME::ImportResult::mergeWith(const ImportResult &other)
+
+ // now do the same for the secret key counts
+ const auto secretKeyConsideredInFirstImports =
+- std::any_of(std::begin(d->imports), std::end(d->imports), [fpr](const auto i) {
++ std::any_of(std::begin(d->imports), std::end(d->imports), [fpr](const gpgme_import_status_t i) {
+ return i->fpr && !strcmp(i->fpr, fpr) && (i->status & GPGME_IMPORT_SECRET);
+ });
+ const auto secretKeyConsideredInPreviousOtherImports =
+- std::any_of(std::begin(other.d->imports), it, [fpr](const auto i) {
++ std::any_of(std::begin(other.d->imports), it, [fpr](const gpgme_import_status_t i) {
+ return i->fpr && !strcmp(i->fpr, fpr) && (i->status & GPGME_IMPORT_SECRET);
+ });
+ const auto secretKeyChangedInOtherImports =
+- std::any_of(std::begin(other.d->imports), std::end(other.d->imports), [fpr](const auto i) {
++ std::any_of(std::begin(other.d->imports), std::end(other.d->imports), [fpr](const gpgme_import_status_t i) {
+ return i->fpr && !strcmp(i->fpr, fpr) && (i->status & GPGME_IMPORT_SECRET) && (i->status != GPGME_IMPORT_SECRET);
+ });
+ if (secretKeyConsideredInFirstImports && !secretKeyConsideredInPreviousOtherImports) {
+@@ -204,7 +204,7 @@ void GpgME::ImportResult::mergeWith(const ImportResult &other)
+ d->imports.reserve(d->imports.size() + other.d->imports.size());
+ std::transform(std::begin(other.d->imports), std::end(other.d->imports),
+ std::back_inserter(d->imports),
+- [](const auto import) {
++ [](const gpgme_import_status_t import) {
+ gpgme_import_status_t copy = new _gpgme_import_status{*import};
+ if (import->fpr) {
+ copy->fpr = strdup(import->fpr);
+--
+2.34.1
+
diff --git a/external/gpgmepp/ExternalPackage_gpgmepp.mk b/external/gpgmepp/ExternalPackage_gpgmepp.mk
new file mode 100644
index 000000000..2b8530872
--- /dev/null
+++ b/external/gpgmepp/ExternalPackage_gpgmepp.mk
@@ -0,0 +1,40 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,gpgmepp,gpgmepp))
+
+$(eval $(call gb_ExternalPackage_use_external_project,gpgmepp,gpgmepp))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+
+ifeq ($(OS),LINUX)
+
+$(eval $(call gb_ExternalPackage_add_file,gpgmepp,$(LIBO_LIB_FOLDER)/libgpgmepp.so.6,lang/cpp/src/.libs/libgpgmepp.so.6.15.0))
+$(eval $(call gb_ExternalPackage_add_file,gpgmepp,$(LIBO_LIB_FOLDER)/libgpgme.so.11,src/.libs/libgpgme.so.11.27.0))
+
+else ifeq ($(OS),MACOSX)
+
+$(eval $(call gb_ExternalPackage_add_file,gpgmepp,$(LIBO_LIB_FOLDER)/libgpgmepp.6.dylib,lang/cpp/src/.libs/libgpgmepp.6.dylib))
+$(eval $(call gb_ExternalPackage_add_file,gpgmepp,$(LIBO_LIB_FOLDER)/libgpgme.11.dylib,src/.libs/libgpgme.11.dylib))
+
+else ifeq ($(OS),WNT)
+
+$(eval $(call gb_ExternalPackage_add_file,gpgmepp,$(LIBO_LIB_FOLDER)/gpgme-w32spawn.exe,src/gpgme-w32spawn.exe))
+
+endif
+
+# If a tool executed during the build (like svidl) requires these gpgmepp libraries, it will also
+# require those libassuan and libgpg-error libraries that these gpgmepp libraries link against:
+$(call gb_Package_get_target_for_build,gpgmepp): \
+ $(call gb_Helper_optional,LIBASSUAN,$(call gb_Package_get_target_for_build,libassuan)) \
+ $(call gb_Helper_optional,LIBGPGERROR,$(call gb_Package_get_target_for_build,libgpg-error))
+
+endif # $(DISABLE_DYNLOADING)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/gpgmepp/ExternalProject_gpgmepp.mk b/external/gpgmepp/ExternalProject_gpgmepp.mk
new file mode 100644
index 000000000..a58717fe3
--- /dev/null
+++ b/external/gpgmepp/ExternalProject_gpgmepp.mk
@@ -0,0 +1,81 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,gpgmepp))
+
+$(eval $(call gb_ExternalProject_register_targets,gpgmepp,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_autoconf,gpgmepp,build))
+
+$(eval $(call gb_ExternalProject_use_externals,gpgmepp,\
+ libgpg-error \
+ libassuan \
+))
+
+ifeq ($(COM),MSC)
+$(call gb_ExternalProject_get_state_target,gpgmepp,build): $(call gb_Executable_get_target_for_build,cpp)
+ $(call gb_Trace_StartRange,gpgmepp,EXTERNAL)
+ $(call gb_ExternalProject_run,build, \
+ $(gb_WIN_GPG_cross_setup_exports) \
+ && autoreconf \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ $(gb_CONFIGURE_PLATFORMS) \
+ --disable-shared \
+ --disable-languages \
+ --disable-gpgconf-test \
+ --disable-gpg-test \
+ --disable-gpgsm-test \
+ --disable-g13-test \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CFLAGS='$(CFLAGS) \
+ $(call gb_ExternalProject_get_build_flags,gpgmepp)' \
+ $(gb_WIN_GPG_platform_switches) \
+ MAKE=$(MAKE) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,gpgmepp,EXTERNAL)
+else
+$(call gb_ExternalProject_get_state_target,gpgmepp,build):
+ $(call gb_Trace_StartRange,gpgmepp,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ autoreconf \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --disable-gpgconf-test \
+ --disable-gpg-test \
+ --disable-gpgsm-test \
+ --disable-g13-test \
+ --enable-languages="cpp" \
+ GPG_ERROR_CFLAGS="$(GPG_ERROR_CFLAGS)" \
+ GPG_ERROR_LIBS="$(GPG_ERROR_LIBS)" \
+ LIBASSUAN_CFLAGS="$(LIBASSUAN_CFLAGS)" \
+ LIBASSUAN_LIBS="$(LIBASSUAN_LIBS)" \
+ CFLAGS='$(CFLAGS) \
+ $(call gb_ExternalProject_get_build_flags,gpgmepp)' \
+ CXXFLAGS='$(CXXFLAGS) \
+ $(call gb_ExternalProject_get_build_flags,gpgmepp) \
+ $(gb_COMPILERDEFS_STDLIB_DEBUG)' \
+ $(if $(filter LINUX,$(OS)), \
+ 'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN') \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),--disable-shared,--disable-static) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/lang/cpp/src/.libs/libgpgmepp.6.dylib \
+ $(EXTERNAL_WORKDIR)/src/.libs/libgpgme.11.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,gpgmepp,EXTERNAL)
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/gpgmepp/Library_gpgmepp.mk b/external/gpgmepp/Library_gpgmepp.mk
new file mode 100644
index 000000000..ac71cf8b9
--- /dev/null
+++ b/external/gpgmepp/Library_gpgmepp.mk
@@ -0,0 +1,91 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,gpgmepp))
+
+$(eval $(call gb_Library_use_unpacked,gpgmepp,gpgmepp))
+
+$(eval $(call gb_Library_use_externals,gpgmepp,\
+ libgpg-error \
+ libassuan \
+))
+
+$(eval $(call gb_LinkTarget_use_external_project,\
+ $(call gb_Library_get_linktarget,gpgmepp),gpgmepp,full))
+
+$(eval $(call gb_Library_set_warnings_disabled,gpgmepp))
+
+$(eval $(call gb_Library_set_include,gpgmepp,\
+ -I$(call gb_UnpackedTarball_get_dir,gpgmepp)/lang/cpp/src \
+ -I$(call gb_UnpackedTarball_get_dir,gpgmepp)/lang/cpp/src/interfaces \
+ -I$(call gb_UnpackedTarball_get_dir,gpgmepp) \
+ -I$(call gb_UnpackedTarball_get_dir,gpgmepp)/src \
+ -I$(call gb_UnpackedTarball_get_dir,gpgmepp)/conf \
+ -I$(call gb_UnpackedTarball_get_dir,libgpg-error)/src \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_libs,gpgmepp,\
+ ws2_32.lib shell32.lib \
+ -LIBPATH:$(call gb_UnpackedTarball_get_dir,gpgmepp)/src/.libs libgpgme.lib \
+))
+
+$(eval $(call gb_Library_add_defs,gpgmepp,\
+ -DHAVE_CONFIG_H \
+ -DBUILDING_GPGMEPP \
+ -DDLL_EXPORT \
+ -DPIC \
+))
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,gpgmepp,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,gpgmepp,\
+ UnpackedTarball/gpgmepp/lang/cpp/src/callbacks \
+ UnpackedTarball/gpgmepp/lang/cpp/src/configuration \
+ UnpackedTarball/gpgmepp/lang/cpp/src/context \
+ UnpackedTarball/gpgmepp/lang/cpp/src/context_vanilla \
+ UnpackedTarball/gpgmepp/lang/cpp/src/data \
+ UnpackedTarball/gpgmepp/lang/cpp/src/decryptionresult \
+ UnpackedTarball/gpgmepp/lang/cpp/src/defaultassuantransaction \
+ UnpackedTarball/gpgmepp/lang/cpp/src/editinteractor \
+ UnpackedTarball/gpgmepp/lang/cpp/src/encryptionresult \
+ UnpackedTarball/gpgmepp/lang/cpp/src/engineinfo \
+ UnpackedTarball/gpgmepp/lang/cpp/src/eventloopinteractor \
+ UnpackedTarball/gpgmepp/lang/cpp/src/exception \
+ UnpackedTarball/gpgmepp/lang/cpp/src/gpgaddexistingsubkeyeditinteractor \
+ UnpackedTarball/gpgmepp/lang/cpp/src/gpgadduserideditinteractor \
+ UnpackedTarball/gpgmepp/lang/cpp/src/gpgagentgetinfoassuantransaction \
+ UnpackedTarball/gpgmepp/lang/cpp/src/gpggencardkeyinteractor \
+ UnpackedTarball/gpgmepp/lang/cpp/src/gpgrevokekeyeditinteractor \
+ UnpackedTarball/gpgmepp/lang/cpp/src/gpgsetexpirytimeeditinteractor \
+ UnpackedTarball/gpgmepp/lang/cpp/src/gpgsetownertrusteditinteractor \
+ UnpackedTarball/gpgmepp/lang/cpp/src/gpgsignkeyeditinteractor \
+ UnpackedTarball/gpgmepp/lang/cpp/src/importresult \
+ UnpackedTarball/gpgmepp/lang/cpp/src/key \
+ UnpackedTarball/gpgmepp/lang/cpp/src/keygenerationresult \
+ UnpackedTarball/gpgmepp/lang/cpp/src/keylistresult \
+ UnpackedTarball/gpgmepp/lang/cpp/src/scdgetinfoassuantransaction \
+ UnpackedTarball/gpgmepp/lang/cpp/src/signingresult \
+ UnpackedTarball/gpgmepp/lang/cpp/src/swdbresult \
+ UnpackedTarball/gpgmepp/lang/cpp/src/tofuinfo \
+ UnpackedTarball/gpgmepp/lang/cpp/src/trustitem \
+ UnpackedTarball/gpgmepp/lang/cpp/src/util \
+ UnpackedTarball/gpgmepp/lang/cpp/src/verificationresult \
+ UnpackedTarball/gpgmepp/lang/cpp/src/vfsmountresult \
+))
+
+ifeq ($(COM),MSC)
+ifeq ($(COM_IS_CLANG),TRUE)
+$(eval $(call gb_Library_add_cxxflags,gpgmepp, \
+ -Wno-c++11-narrowing \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/gpgmepp/Makefile b/external/gpgmepp/Makefile
new file mode 100644
index 000000000..569ad8a0b
--- /dev/null
+++ b/external/gpgmepp/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/gpgmepp/Module_gpgmepp.mk b/external/gpgmepp/Module_gpgmepp.mk
new file mode 100644
index 000000000..5763ccedb
--- /dev/null
+++ b/external/gpgmepp/Module_gpgmepp.mk
@@ -0,0 +1,26 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,gpgmepp))
+
+$(eval $(call gb_Module_add_targets,gpgmepp,\
+ UnpackedTarball_gpgmepp \
+ ExternalProject_gpgmepp \
+ ExternalPackage_gpgmepp \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,gpgmepp,\
+ Library_gpgmepp \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/gpgmepp/README b/external/gpgmepp/README
new file mode 100644
index 000000000..149ca3b5e
--- /dev/null
+++ b/external/gpgmepp/README
@@ -0,0 +1,7 @@
+A library for easy access to GnuPG (GnuPG Made Easy)
+[https://www.gnupg.org/related_software/gpgme/index.html]
+
+(The upstream project and its git repo at <https://dev.gnupg.org/source/gpgme/> are called "gpgme",
+not "gpgmepp". This external module was renamed from external/gpgme to external/gpgmepp with
+50a55d862034b7a06510c014332236f44e306831 "gpg4libre: cleanup gpgme & add gbuild lib for gpgmepp":
+"This moves the external to gpgmepp, since that's what we _actually_ link against [...]")
diff --git a/external/gpgmepp/UnpackedTarball_gpgmepp.mk b/external/gpgmepp/UnpackedTarball_gpgmepp.mk
new file mode 100644
index 000000000..be2b616d1
--- /dev/null
+++ b/external/gpgmepp/UnpackedTarball_gpgmepp.mk
@@ -0,0 +1,40 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,gpgmepp))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,gpgmepp,$(GPGME_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,gpgmepp,0))
+
+# * external/gpgmepp/configure.patch: see
+# <https://lists.gnu.org/archive/html/autoconf/2020-11/msg00004.html> "Fallout from
+# _AC_UNDECLARED_WARNING in autoconf 2.70beta" for upstream discussion
+$(eval $(call gb_UnpackedTarball_add_patches,gpgmepp, \
+ external/gpgmepp/find-libgpg-error-libassuan.patch \
+ external/gpgmepp/fix-autoconf-macros.patch \
+ $(if $(filter MSC,$(COM)),external/gpgmepp/w32-build-fixes.patch.1) \
+ $(if $(filter MSC,$(COM)),external/gpgmepp/w32-disable-docs.patch.1) \
+ $(if $(filter MSC,$(COM)),external/gpgmepp/w32-fix-win32-macro.patch.1) \
+ $(if $(filter MSC,$(COM)),external/gpgmepp/w32-fix-libtool.patch.1) \
+ $(if $(filter MSC,$(COM)),external/gpgmepp/w32-add-initializer.patch.1) \
+ external/gpgmepp/w32-build-fixes-2.patch \
+ $(if $(filter LINUX,$(OS)),external/gpgmepp/asan.patch) \
+ $(if $(filter LINUX,$(OS)),external/gpgmepp/rpath.patch) \
+ external/gpgmepp/gcc9.patch \
+ external/gpgmepp/ubsan.patch \
+ external/gpgmepp/c++20.patch \
+ external/gpgmepp/clang-cl.patch \
+ external/gpgmepp/configure.patch \
+ external/gpgmepp/w32-include.patch \
+ external/gpgmepp/Wincompatible-function-pointer-types.patch \
+ external/gpgmepp/0001-cpp-Fix-building-with-C-11.patch.1 \
+ external/gpgmepp/macos-include.patch \
+))
+# vim: set noet sw=4 ts=4:
diff --git a/external/gpgmepp/Wincompatible-function-pointer-types.patch b/external/gpgmepp/Wincompatible-function-pointer-types.patch
new file mode 100755
index 000000000..050d2e55c
--- /dev/null
+++ b/external/gpgmepp/Wincompatible-function-pointer-types.patch
@@ -0,0 +1,31 @@
+--- src/assuan-support.c
++++ src/assuan-support.c
+@@ -126,7 +126,7 @@
+ }
+
+
+-static gpgme_ssize_t
++static ssize_t
+ my_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size)
+ {
+ (void)ctx;
+@@ -134,7 +134,7 @@
+ }
+
+
+-static gpgme_ssize_t
++static ssize_t
+ my_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer, size_t size)
+ {
+ (void)ctx;
+--- src/gpgme-w32spawn.c
++++ src/gpgme-w32spawn.c
+@@ -243,7 +243,7 @@
+ handle = LoadLibrary ("user32.dll");
+ if (handle)
+ {
+- func = GetProcAddress (handle, "AllowSetForegroundWindow");
++ func = (BOOL (WINAPI *)(DWORD)) GetProcAddress (handle, "AllowSetForegroundWindow");
+ if (!func)
+ FreeLibrary (handle);
+ }
diff --git a/external/gpgmepp/asan.patch b/external/gpgmepp/asan.patch
new file mode 100644
index 000000000..e0b1c85fe
--- /dev/null
+++ b/external/gpgmepp/asan.patch
@@ -0,0 +1,12 @@
+--- src/posix-io.c
++++ src/posix-io.c
+@@ -563,6 +563,9 @@
+
+ if (atfork)
+ atfork (atforkvalue, 0);
++ char const * ld_path = getenv("LIBO_LD_PATH");
++ if (ld_path && setenv("LD_LIBRARY_PATH", ld_path, 1) != 0)
++ abort();
+
+ /* First close all fds which will not be inherited. If we
+ * have closefrom(2) we first figure out the highest fd we
diff --git a/external/gpgmepp/c++20.patch b/external/gpgmepp/c++20.patch
new file mode 100644
index 000000000..3141dca1e
--- /dev/null
+++ b/external/gpgmepp/c++20.patch
@@ -0,0 +1,11 @@
+--- lang/cpp/src/keylistresult.cpp
++++ lang/cpp/src/keylistresult.cpp
+@@ -77,7 +77,7 @@
+
+ void GpgME::KeyListResult::detach()
+ {
+- if (!d || d.unique()) {
++ if (!d || d.use_count() == 1) {
+ return;
+ }
+ d.reset(new Private(*d));
diff --git a/external/gpgmepp/clang-cl.patch b/external/gpgmepp/clang-cl.patch
new file mode 100644
index 000000000..3f63d0bc6
--- /dev/null
+++ b/external/gpgmepp/clang-cl.patch
@@ -0,0 +1,20 @@
+--- src/w32-util.c
++++ src/w32-util.c
+@@ -173,7 +173,7 @@
+ NULL; caller may use GetLastError to get the actual error number.
+ Calling this function with STRING set to NULL is not defined. */
+ static wchar_t *
+-utf8_to_wchar (const char *string)
++utf8_to_wchar_ (const char *string)
+ {
+ int n;
+ wchar_t *result;
+@@ -206,7 +206,7 @@
+ if (!string)
+ return NULL;
+
+- return utf8_to_wchar (string);
++ return utf8_to_wchar_ (string);
+ }
+
+
diff --git a/external/gpgmepp/configure.patch b/external/gpgmepp/configure.patch
new file mode 100644
index 000000000..ad3f97e63
--- /dev/null
+++ b/external/gpgmepp/configure.patch
@@ -0,0 +1,34 @@
+--- configure.ac
++++ configure.ac
+@@ -617,6 +617,15 @@
+ AC_SUBST(API__SSIZE_T)
+ AM_SUBST_NOTMAKE(API__SSIZE_T)
+
++# Try to find a thread-safe version of ttyname().
++gnupg_REPLACE_TTYNAME_R
++if test "$ac_cv_func_ttyname_r" != yes; then
++ AC_MSG_WARN([
++***
++*** ttyname() is not thread-safe and ttyname_r() does not exist
++***])
++fi
++
+ # Checks for compiler features.
+ if test "$GCC" = yes; then
+ CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
+@@ -677,15 +686,6 @@
+
+ AC_FUNC_FSEEKO
+
+-# Try to find a thread-safe version of ttyname().
+-gnupg_REPLACE_TTYNAME_R
+-if test "$ac_cv_func_ttyname_r" != yes; then
+- AC_MSG_WARN([
+-***
+-*** ttyname() is not thread-safe and ttyname_r() does not exist
+-***])
+-fi
+-
+ # Try to find a thread-safe version of getenv().
+ have_thread_safe_getenv=no
+ jm_GLIBC21
diff --git a/external/gpgmepp/find-libgpg-error-libassuan.patch b/external/gpgmepp/find-libgpg-error-libassuan.patch
new file mode 100644
index 000000000..a98a7d845
--- /dev/null
+++ b/external/gpgmepp/find-libgpg-error-libassuan.patch
@@ -0,0 +1,66 @@
+diff --git a/configure.ac b/configure.ac
+index f28480b..92a3e85 100644
+--- configure.ac
++++ configure.ac
+@@ -719,8 +719,18 @@
+
+ # Checking for libgpg-error.
+ have_gpg_error=no
+-AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION",
+- have_gpg_error=yes, have_gpg_error=no)
++if test "x${GPG_ERROR_CFLAGS}" = x; then
++ AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION",
++ have_gpg_error=yes, have_gpg_error=no)
++else
++ have_gpg_error=yes
++ GPG_ERROR_CFLAGS="$GPG_ERROR_CFLAGS"
++ GPG_ERROR_LIBS="$GPG_ERROR_LIBS"
++ AC_SUBST(GPG_ERROR_CFLAGS)
++ AC_SUBST(GPG_ERROR_LIBS)
++
++fi
++
+ AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME,
+ [The default error source for GPGME.])
+
+@@ -729,8 +739,17 @@
+
+ # And for libassuan.
+ have_libassuan=no
+-AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION",
++if test "x${LIBASSUAN_CFLAGS}" = x; then
++ AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION",
+ have_libassuan=yes, have_libassuan=no)
++else
++ have_libassuan=yes
++ LIBASSUAN_CFLAGS="$LIBASSUAN_CFLAGS"
++ LIBASSUAN_LIBS="$LIBASSUAN_LIBS"
++ AC_SUBST(LIBASSUAN_CFLAGS)
++ AC_SUBST(LIBASSUAN_LIBS)
++fi
++
+ if test "$have_libassuan" = "yes"; then
+ AC_DEFINE_UNQUOTED(GPGME_LIBASSUAN_VERSION, "$libassuan_version",
+ [version of the libassuan library])
+--- lang/cpp/tests/Makefile.am 2020-06-20 00:43:49.213657887 +0200
++++ lang/cpp/tests/Makefile.am~ 2019-01-25 13:27:34.000000000 +0100
+@@ -21,7 +21,7 @@
+ AM_LDFLAGS = -no-install
+
+ LDADD = ../../cpp/src/libgpgmepp.la \
++ ../../../src/libgpgme.la @LIBASSUAN_LIBS@ @GPG_ERROR_LIBS@ \
+- ../../../src/libgpgme.la @GPG_ERROR_LIBS@ \
+ @LDADD_FOR_TESTS_KLUDGE@ -lstdc++
+
+ AM_CPPFLAGS = -I$(top_srcdir)/lang/cpp/src -I$(top_builddir)/src \
+--- lang/cpp/tests/Makefile.in 2020-06-20 00:44:49.542344510 +0200
++++ lang/cpp/tests/Makefile.in~ 2020-06-13 00:55:19.021212970 +0200
+@@ -427,7 +427,7 @@
+ top_srcdir = @top_srcdir@
+ AM_LDFLAGS = -no-install
+ LDADD = ../../cpp/src/libgpgmepp.la \
++ ../../../src/libgpgme.la @LIBASSUAN_LIBS@ @GPG_ERROR_LIBS@ \
+- ../../../src/libgpgme.la @GPG_ERROR_LIBS@ \
+ @LDADD_FOR_TESTS_KLUDGE@ -lstdc++
+
+ AM_CPPFLAGS = -I$(top_srcdir)/lang/cpp/src -I$(top_builddir)/src \
diff --git a/external/gpgmepp/fix-autoconf-macros.patch b/external/gpgmepp/fix-autoconf-macros.patch
new file mode 100644
index 000000000..265703b00
--- /dev/null
+++ b/external/gpgmepp/fix-autoconf-macros.patch
@@ -0,0 +1,39 @@
+diff -ur gpgme.org/configure.ac gpgme/configure.ac
+--- configure.ac 2017-02-16 15:18:45.051417378 +0100
++++ configure.ac~ 2017-02-16 15:20:03.635059285 +0100
+@@ -38,6 +38,11 @@
+ # the decimalized short revision number, a beta version string and a
+ # flag indicating a development version (mym4_isbeta). Note that the
+ # m4 processing is done by autoconf and not during the configure run.
++m4_define([m4_chomp_all],
++[m4_format([[%.*s]], m4_bregexp(m4_translit([[$1]], [
++/], [/ ]), [/*$]), [$1])])
++
++m4_define([m4_esyscmd_s], [m4_chomp_all(m4_esyscmd([$1]))])
+ m4_define([mym4_verslist], m4_split(m4_esyscmd([./autogen.sh --find-version] \
+ mym4_package mym4_major mym4_minor mym4_micro),[:]))
+ m4_define([mym4_isbeta], m4_argn(2, mym4_verslist))
+@@ -98,7 +103,22 @@
+ AC_CONFIG_MACRO_DIR([m4])
+ AC_CONFIG_SRCDIR([src/gpgme.h.in])
+ AC_CONFIG_HEADERS([conf/config.h])
+-AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip])
++
++dnl Initialize automake. automake < 1.12 didn't have serial-tests and
++dnl gives an error if it sees this, but for automake >= 1.13
++dnl serial-tests is required so we have to include it. Solution is to
++dnl test for the version of automake (by running an external command)
++dnl and provide it if necessary. Note we have to do this entirely using
++dnl m4 macros since automake queries this macro by running
++dnl 'autoconf --trace ...'.
++m4_define([serial_tests], [
++ m4_esyscmd([automake --version |
++ head -1 |
++ awk '{split ($NF,a,"."); if (a[1] == 1 && a[2] >= 12) { print "serial-tests" }}'
++ ])
++])
++AM_INIT_AUTOMAKE(foreign serial_tests dist-bzip2 no-dist-gzip) dnl NB: Do not [quote] this parameter.
++
+ AM_MAINTAINER_MODE
+ AC_CANONICAL_HOST
+ AM_SILENT_RULES
diff --git a/external/gpgmepp/gcc9.patch b/external/gpgmepp/gcc9.patch
new file mode 100644
index 000000000..709154ec1
--- /dev/null
+++ b/external/gpgmepp/gcc9.patch
@@ -0,0 +1,10 @@
+--- lang/cpp/src/key.h
++++ lang/cpp/src/key.h
+@@ -68,6 +68,7 @@
+ /* implicit */ Key(const Null &);
+ Key(const shared_gpgme_key_t &key);
+ Key(gpgme_key_t key, bool acquireRef);
++ Key(Key const &) = default;
+
+ static const Null null;
+
diff --git a/external/gpgmepp/macos-include.patch b/external/gpgmepp/macos-include.patch
new file mode 100644
index 000000000..93dd297c7
--- /dev/null
+++ b/external/gpgmepp/macos-include.patch
@@ -0,0 +1,10 @@
+--- lang/cpp/src/importresult.cpp 2022-08-10 18:17:33.000000000 +0900
++++ lang/cpp/src/importresult.cpp 2022-11-29 01:37:44.786604882 +0900
+@@ -31,6 +31,7 @@
+ #include "result_p.h"
+
+ #include <gpgme.h>
++#include <algorithm>
+ #include <cstdlib>
+ #include <cstring>
+
diff --git a/external/gpgmepp/rpath.patch b/external/gpgmepp/rpath.patch
new file mode 100644
index 000000000..6e6c46105
--- /dev/null
+++ b/external/gpgmepp/rpath.patch
@@ -0,0 +1,12 @@
+--- configure.ac
++++ configure.ac
+@@ -187,6 +187,9 @@
+ LT_INIT([win32-dll disable-static])
+ LT_LANG([Windows Resource])
+
++hardcode_libdir_flag_spec=
++hardcode_libdir_flag_spec_CXX=
++
+ # For now we hardcode the use of version scripts. It would be better
+ # to write a test for this or even implement this within libtool.
+ have_ld_version_script=no
diff --git a/external/gpgmepp/ubsan.patch b/external/gpgmepp/ubsan.patch
new file mode 100644
index 000000000..2262291cd
--- /dev/null
+++ b/external/gpgmepp/ubsan.patch
@@ -0,0 +1,52 @@
+--- src/engine-gpg.c
++++ src/engine-gpg.c
+@@ -61,6 +61,15 @@
+ building command line to this location. */
+ char arg[FLEXIBLE_ARRAY_MEMBER]; /* Used if data above is not used. */
+ };
++struct arg_without_data_s
++{
++ struct arg_and_data_s *next;
++ gpgme_data_t data;
++ int inbound;
++ int dup_to;
++ int print_fd;
++ int *arg_locp;
++};
+
+
+ struct fd_data_map_s
+@@ -310,23 +319,24 @@
+ a = malloc (offsetof (struct arg_and_data_s, arg));
+ if (!a)
+ return gpg_error_from_syserror ();
+- a->next = NULL;
+- a->data = data;
+- a->inbound = inbound;
+- a->arg_locp = NULL;
++ struct arg_without_data_s *a2 = (struct arg_without_data_s *)a;
++ a2->next = NULL;
++ a2->data = data;
++ a2->inbound = inbound;
++ a2->arg_locp = NULL;
+
+ if (dup_to == -2)
+ {
+- a->print_fd = 1;
+- a->dup_to = -1;
++ a2->print_fd = 1;
++ a2->dup_to = -1;
+ }
+ else
+ {
+- a->print_fd = 0;
+- a->dup_to = dup_to;
++ a2->print_fd = 0;
++ a2->dup_to = dup_to;
+ }
+ *gpg->argtail = a;
+- gpg->argtail = &a->next;
++ gpg->argtail = &a2->next;
+ return 0;
+ }
+
diff --git a/external/gpgmepp/w32-add-initializer.patch.1 b/external/gpgmepp/w32-add-initializer.patch.1
new file mode 100644
index 000000000..b33f0d42a
--- /dev/null
+++ b/external/gpgmepp/w32-add-initializer.patch.1
@@ -0,0 +1,16 @@
+Make sure the gpgrt_lock_init gets called in libgpg-error, otherwise
+several critical section statics are uninitialized
+
+diff -ur gpgmepp.org/src/version.c gpgmepp/src/version.c
+--- gpgmepp.org/src/version.c 2016-11-16 13:22:41.000000000 +0100
++++ gpgmepp/src/version.c 2017-11-23 17:16:35.218735200 +0100
+@@ -66,6 +66,9 @@
+ return;
+
+ #ifdef HAVE_W32_SYSTEM
++ // initialize libgpg-error stuff
++ gpg_err_init();
++
+ /* We need to make sure that the sockets are initialized. */
+ {
+ WSADATA wsadat;
diff --git a/external/gpgmepp/w32-build-fixes-2.patch b/external/gpgmepp/w32-build-fixes-2.patch
new file mode 100644
index 000000000..09c23c064
--- /dev/null
+++ b/external/gpgmepp/w32-build-fixes-2.patch
@@ -0,0 +1,22 @@
+Avoid MFC dependency - can go with very basic includes instead
+
+--- src/versioninfo.rc.in~ 2017-03-28 15:12:30.000000000 +0200
++++ src/versioninfo.rc.in 2017-11-29 04:22:18.607421900 +0100
+@@ -14,7 +14,6 @@
+
+ #line __LINE__ "versioninfo.rc.in"
+
+-#include <afxres.h>
+
+
+ VS_VERSION_INFO VERSIONINFO
+--- lang/cpp/src/importresult.cpp~ 2020-06-11 16:00:46.410830500 +0200
++++ lang/cpp/src/importresult.cpp 2020-06-11 16:00:25.987900000 +0200
+@@ -35,7 +35,6 @@
+ #include <cstring>
+
+ #include <string.h>
+-#include <strings.h>
+ #include <istream>
+ #include <iterator>
+
diff --git a/external/gpgmepp/w32-build-fixes.patch.1 b/external/gpgmepp/w32-build-fixes.patch.1
new file mode 100644
index 000000000..d6d8af601
--- /dev/null
+++ b/external/gpgmepp/w32-build-fixes.patch.1
@@ -0,0 +1,138 @@
+diff -ru gpgme.orig/m4/ax_cxx_compile_stdcxx.m4 gpgme/m4/ax_cxx_compile_stdcxx.m4
+--- gpgme.orig/m4/ax_cxx_compile_stdcxx.m4 2016-05-27 22:04:36.000000000 +0200
++++ gpgme/m4/ax_cxx_compile_stdcxx.m4 2017-09-29 17:34:49.795243600 +0200
+@@ -156,7 +156,7 @@
+
+ #error "This is not a C++ compiler"
+
+-#elif __cplusplus < 201103L
++#elif __cplusplus < 201103L && !(defined _MSC_VER)
+
+ #error "This is not a C++11 compiler"
+
+diff -ru gpgme.orig/src/dirinfo.c gpgme/src/dirinfo.c
+--- gpgme.orig/src/dirinfo.c 2017-03-21 11:09:41.000000000 +0100
++++ gpgme/src/dirinfo.c 2017-09-30 08:36:13.239279300 +0200
+@@ -34,6 +34,10 @@
+
+ DEFINE_STATIC_LOCK (dirinfo_lock);
+
++#ifndef F_OK
++#define F_OK 0
++#endif
++
+ /* Constants used internally to select the data. */
+ enum
+ {
+diff -ru gpgme.orig/src/mbox-util.c gpgme/src/mbox-util.c
+--- gpgme.orig/src/mbox-util.c 2016-11-16 13:22:41.000000000 +0100
++++ gpgme/src/mbox-util.c 2017-09-30 08:18:29.270567500 +0200
+@@ -29,7 +29,9 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#if HAVE_UNISTD_H
+ #include <unistd.h>
++#endif
+ #include <errno.h>
+
+ #include "mbox-util.h"
+diff -ru gpgme.orig/src/priv-io.h gpgme/src/priv-io.h
+--- gpgme.orig/src/priv-io.h 2016-11-16 13:23:14.000000000 +0100
++++ gpgme/src/priv-io.h 2017-09-30 08:20:38.770562400 +0200
+@@ -33,6 +33,9 @@
+ #ifdef HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
++#if _MSC_VER
++typedef int pid_t;
++#endif
+
+
+ /* A single file descriptor passed to spawn. For child fds, dup_to
+diff -ru gpgme.orig/src/util.h gpgme/src/util.h
+--- gpgme.orig/src/util.h 2017-03-28 11:41:30.000000000 +0200
++++ gpgme/src/util.h 2017-09-30 08:10:54.194049100 +0200
+@@ -35,6 +35,9 @@
+ #ifdef HAVE_UNISTD_H
+ # include <unistd.h>
+ #endif
++#ifdef _MSC_VER
++typedef int pid_t;
++#endif
+
+ #include "gpgme.h"
+
+diff -ru gpgme.orig/src/w32-util.c gpgme/src/w32-util.c
+--- gpgme.orig/src/w32-util.c 2017-03-09 09:01:10.000000000 +0100
++++ gpgme/src/w32-util.c 2017-09-30 08:32:02.114330500 +0200
+@@ -772,7 +772,8 @@
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+- fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
++ //fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
++ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL);
+ if (fd >= 0)
+ {
+ gpg_err_set_errno (save_errno);
+diff -ru gpgme.orig/src/Makefile.am gpgme/src/Makefile.am
+--- gpgme.orig/src/Makefile.am 2017-09-30 11:50:07.456960000 +0200
++++ gpgme/src/Makefile.am 2017-09-30 11:51:29.609649400 +0200
+@@ -35,7 +35,7 @@
+ m4data_DATA = gpgme.m4
+ nodist_include_HEADERS = gpgme.h
+
+-bin_PROGRAMS = gpgme-tool gpgme-json
++bin_PROGRAMS =
+
+ if BUILD_W32_GLIB
+ ltlib_gpgme_glib = libgpgme-glib.la
+@@ -107,11 +107,11 @@
+ # versions, because then every object file is only compiled once.
+ AM_CFLAGS = @LIBASSUAN_CFLAGS@ @GPG_ERROR_CFLAGS@ @GLIB_CFLAGS@
+
+-gpgme_tool_SOURCES = gpgme-tool.c argparse.c argparse.h
+-gpgme_tool_LDADD = libgpgme.la @LIBASSUAN_LIBS@ @GPG_ERROR_LIBS@
++gpgme_tool_SOURCES =
++gpgme_tool_LDADD =
+
+-gpgme_json_SOURCES = gpgme-json.c cJSON.c cJSON.h
+-gpgme_json_LDADD = -lm libgpgme.la $(GPG_ERROR_LIBS)
++gpgme_json_SOURCES =
++gpgme_json_LDADD =
+
+
+ if HAVE_W32_SYSTEM
+@@ -126,7 +126,7 @@
+ SUFFIXES = .rc .lo
+
+ .rc.lo:
+- $(LTRCCOMPILE) -i "$<" -o "$@"
++ $(LTRCCOMPILE) -i $< -o $@
+
+ gpgme_res = versioninfo.lo
+ no_undefined = -no-undefined
+diff -ru gpgme.orig/src/vfs-mount.c gpgme/src/vfs-mount.c
+--- gpgme.orig/src/vfs-mount.c 2017-03-09 09:01:10.000000000 +0100
++++ gpgme/src/vfs-mount.c 2017-09-30 13:10:51.845807600 +0200
+@@ -68,7 +68,7 @@
+ if (err)
+ return err;
+
+- if (! strcasecmp ("MOUNTPOINT", code))
++ if (! _stricmp ("MOUNTPOINT", code))
+ {
+ if (opd->result.mount_dir)
+ free (opd->result.mount_dir);
+diff -ur gpgmepp.org/src/w32-glib-io.c gpgmepp/src/w32-glib-io.c
+--- gpgmepp.org/src/w32-glib-io.c 2016-11-16 13:22:41.000000000 +0100
++++ gpgmepp/src/w32-glib-io.c 2017-11-20 06:40:44.793945300 +0100
+@@ -37,6 +37,7 @@
+ #ifdef HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
++#include <winsock2.h>
+ #include <glib.h>
+ #include <windows.h>
+ #include <io.h>
diff --git a/external/gpgmepp/w32-disable-docs.patch.1 b/external/gpgmepp/w32-disable-docs.patch.1
new file mode 100644
index 000000000..1803ffa03
--- /dev/null
+++ b/external/gpgmepp/w32-disable-docs.patch.1
@@ -0,0 +1,15 @@
+Disable doc building the hard way - should rather be a config option
+like libgpg-error's --disable-doc
+
+diff -ur gpgmepp.org/Makefile.am gpgmepp/Makefile.am
+--- gpgmepp.org/Makefile.am 2016-11-16 13:20:18.000000000 +0100
++++ gpgmepp/Makefile.am 2017-11-20 15:34:49.086731000 +0100
+@@ -45,7 +45,7 @@
+ tests =
+ endif
+
+-SUBDIRS = src ${tests} doc lang
++SUBDIRS = src ${tests} lang
+
+ # Fix the version of the spec file.
+ dist-hook: gen-ChangeLog
diff --git a/external/gpgmepp/w32-fix-libtool.patch.1 b/external/gpgmepp/w32-fix-libtool.patch.1
new file mode 100644
index 000000000..40893908b
--- /dev/null
+++ b/external/gpgmepp/w32-fix-libtool.patch.1
@@ -0,0 +1,38 @@
+Gross hack to make libtool work with gcc-wrapper - frontended
+link.exe on Windows. Make libtool ignore all libs & simply pass
+them on as-is to the linker
+
+A proper fix would be to make gcc-wrapper behave like gcc during
+linking, by accepting cygwin path names, and correctly expanding
+-l<short_lib_name> to lib<short_lib_name>.lib
+
+diff -ur gpgmepp.org/m4/libtool.m4 gpgmepp/m4/libtool.m4
+--- gpgmepp.org/m4/libtool.m4 2016-11-16 13:20:16.000000000 +0100
++++ gpgmepp/m4/libtool.m4 2017-11-21 22:00:05.006587800 +0100
+@@ -3230,24 +3230,11 @@
+ ;;
+
+ cygwin*)
+- # func_win32_libid is a shell function defined in ltmain.sh
+- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+- lt_cv_file_magic_cmd='func_win32_libid'
++ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+ mingw* | pw32*)
+- # Base MSYS/MinGW do not provide the 'file' command needed by
+- # func_win32_libid shell function, so use a weaker test based on 'objdump',
+- # unless we find 'file', for example because we are cross-compiling.
+- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+- lt_cv_file_magic_cmd='func_win32_libid'
+- else
+- # Keep this pattern in sync with the one in func_win32_libid.
+- lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+- lt_cv_file_magic_cmd='$OBJDUMP -f'
+- fi
++ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+ cegcc*)
diff --git a/external/gpgmepp/w32-fix-win32-macro.patch.1 b/external/gpgmepp/w32-fix-win32-macro.patch.1
new file mode 100644
index 000000000..8ab7b0fab
--- /dev/null
+++ b/external/gpgmepp/w32-fix-win32-macro.patch.1
@@ -0,0 +1,176 @@
+diff -ur gpgmepp.org/lang/cpp/src/callbacks.cpp gpgmepp/lang/cpp/src/callbacks.cpp
+--- gpgmepp.org/lang/cpp/src/callbacks.cpp 2016-10-18 19:22:02.000000000 +0200
++++ gpgmepp/lang/cpp/src/callbacks.cpp 2017-11-20 18:03:04.290060900 +0100
+@@ -40,7 +40,9 @@
+ #include <cassert>
+ #include <cerrno>
+ #include <cstring>
++#if HAVE_UNISTD_H
+ #include <unistd.h>
++#endif
+ #include <stdlib.h>
+
+ static inline gpgme_error_t make_err_from_syserror()
+diff -ur gpgmepp.org/lang/cpp/src/data.h gpgmepp/lang/cpp/src/data.h
+--- gpgmepp.org/lang/cpp/src/data.h 2017-03-24 15:20:32.000000000 +0100
++++ gpgmepp/lang/cpp/src/data.h 2017-11-20 17:23:24.802711200 +0100
+@@ -31,6 +31,11 @@
+ #include <algorithm>
+ #include <memory>
+
++#ifdef _MSC_VER
++# include <BaseTsd.h>
++typedef SSIZE_T ssize_t;
++#endif
++
+ namespace GpgME
+ {
+
+diff -ur gpgmepp.org/lang/cpp/src/editinteractor.cpp gpgmepp/lang/cpp/src/editinteractor.cpp
+--- gpgmepp.org/lang/cpp/src/editinteractor.cpp 2017-03-09 09:01:10.000000000 +0100
++++ gpgmepp/lang/cpp/src/editinteractor.cpp 2017-11-20 18:09:33.022674700 +0100
+@@ -33,9 +33,11 @@
+
+ #include <gpgme.h>
+
+-#ifdef _WIN32
++#ifdef _MSC_VER
+ # include <io.h>
+-#include <windows.h>
++# include <windows.h>
++# include <BaseTsd.h>
++ typedef SSIZE_T ssize_t;
+ #else
+ # include <unistd.h>
+ #endif
+diff -ur gpgmepp.org/lang/cpp/src/gpgmepp_export.h gpgmepp/lang/cpp/src/gpgmepp_export.h
+--- gpgmepp.org/lang/cpp/src/gpgmepp_export.h 2016-08-04 15:03:09.000000000 +0200
++++ gpgmepp/lang/cpp/src/gpgmepp_export.h 2017-11-20 16:57:47.805691100 +0100
+@@ -30,14 +30,14 @@
+ # ifndef GPGMEPP_EXPORT
+ # ifdef BUILDING_GPGMEPP
+ /* We are building this library */
+-# ifdef WIN32
++# ifdef _MSC_VER
+ # define GPGMEPP_EXPORT __declspec(dllexport)
+ # else
+ # define GPGMEPP_EXPORT __attribute__((visibility("default")))
+ # endif
+ # else
+ /* We are using this library */
+-# ifdef WIN32
++# ifdef _MSC_VER
+ # define GPGMEPP_EXPORT __declspec(dllimport)
+ # else
+ # define GPGMEPP_EXPORT __attribute__((visibility("default")))
+@@ -46,7 +46,7 @@
+ # endif
+
+ # ifndef GPGMEPP_NO_EXPORT
+-# ifdef WIN32
++# ifdef _MSC_VER
+ # define GPGMEPP_NO_EXPORT
+ # else
+ # define GPGMEPP_NO_EXPORT __attribute__((visibility("hidden")))
+@@ -55,7 +55,11 @@
+ #endif
+
+ #ifndef GPGMEPP_DEPRECATED
+-# define GPGMEPP_DEPRECATED __attribute__ ((__deprecated__))
++# ifdef _MSC_VER
++# define GPGMEPP_DEPRECATED __declspec(deprecated("deprecated"))
++# else
++# define GPGMEPP_DEPRECATED __attribute__ ((__deprecated__))
++# endif
+ #endif
+
+ #ifndef GPGMEPP_DEPRECATED_EXPORT
+diff -ur gpgmepp.org/lang/cpp/src/interfaces/dataprovider.h gpgmepp/lang/cpp/src/interfaces/dataprovider.h
+--- gpgmepp.org/lang/cpp/src/interfaces/dataprovider.h 2016-05-17 14:32:37.000000000 +0200
++++ gpgmepp/lang/cpp/src/interfaces/dataprovider.h 2017-11-20 18:03:11.332715700 +0100
+@@ -31,6 +31,11 @@
+
+ #include <gpg-error.h>
+
++#ifdef _MSC_VER
++# include <BaseTsd.h>
++typedef SSIZE_T ssize_t;
++#endif
++
+ namespace GpgME
+ {
+
+diff -ur gpgmepp.org/lang/cpp/src/key.cpp gpgmepp/lang/cpp/src/key.cpp
+--- gpgmepp.org/lang/cpp/src/key.cpp 2017-03-20 20:10:15.000000000 +0100
++++ gpgmepp/lang/cpp/src/key.cpp 2017-11-20 17:44:50.321858800 +0100
+@@ -34,11 +34,17 @@
+ #include <gpgme.h>
+
+ #include <string.h>
++#if HAVE_STRINGS_H
+ #include <strings.h>
++#endif
+ #include <cassert>
+ #include <istream>
+ #include <iterator>
+
++#ifdef _MSC_VER
++# define strcasecmp _stricmp
++#endif
++
+ const GpgME::Key::Null GpgME::Key::null;
+
+ namespace GpgME
+diff -ur gpgmepp.org/lang/cpp/src/key.h gpgmepp/lang/cpp/src/key.h
+--- gpgmepp.org/lang/cpp/src/key.h 2017-03-20 20:10:15.000000000 +0100
++++ gpgmepp/lang/cpp/src/key.h 2017-11-20 17:07:51.551632000 +0100
+@@ -30,7 +30,6 @@
+ #include "gpgmefw.h"
+
+ #include <memory>
+-#include <sys/time.h>
+
+ #include <vector>
+ #include <algorithm>
+diff -ur gpgmepp.org/lang/qt/src/qgpgme_export.h gpgmepp/lang/qt/src/qgpgme_export.h
+--- gpgmepp.org/lang/qt/src/qgpgme_export.h 2016-11-03 17:32:30.000000000 +0100
++++ gpgmepp/lang/qt/src/qgpgme_export.h 2017-11-20 16:58:27.395388000 +0100
+@@ -40,14 +40,14 @@
+ # ifndef QGPGME_EXPORT
+ # ifdef BUILDING_QGPGME
+ /* We are building this library */
+-# ifdef WIN32
++# ifdef _WIN32
+ # define QGPGME_EXPORT __declspec(dllexport)
+ # else
+ # define QGPGME_EXPORT __attribute__((visibility("default")))
+ # endif
+ # else
+ /* We are using this library */
+-# ifdef WIN32
++# ifdef _WIN32
+ # define QGPGME_EXPORT __declspec(dllimport)
+ # else
+ # define QGPGME_EXPORT __attribute__((visibility("default")))
+@@ -56,7 +56,7 @@
+ # endif
+
+ # ifndef QGPGME_NO_EXPORT
+-# ifdef WIN32
++# ifdef _WIN32
+ # define QGPGME_NO_EXPORT
+ # else
+ # define QGPGME_NO_EXPORT __attribute__((visibility("hidden")))
+@@ -65,7 +65,11 @@
+ #endif
+
+ #ifndef QGPGME_DEPRECATED
+-# define QGPGME_DEPRECATED __attribute__ ((__deprecated__))
++# ifdef _MSC_VER
++# define QGPGME_DEPRECATED __declspec(deprecated("deprecated"))
++# else
++# define QGPGME_DEPRECATED __attribute__ ((__deprecated__))
++# endif
+ #endif
+
+ #ifndef QGPGME_DEPRECATED_EXPORT
diff --git a/external/gpgmepp/w32-include.patch b/external/gpgmepp/w32-include.patch
new file mode 100644
index 000000000..0fda72c2b
--- /dev/null
+++ b/external/gpgmepp/w32-include.patch
@@ -0,0 +1,42 @@
+--- src/data-fd.c
++++ src/data-fd.c
+@@ -28,6 +28,9 @@
+ #ifdef HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
++#if defined HAVE_W32_SYSTEM
++#include <io.h>
++#endif
+
+ #include "debug.h"
+ #include "data.h"
+--- src/gpgme-w32spawn.c
++++ src/gpgme-w32spawn.c
+@@ -36,6 +36,7 @@
+ # include <sys/stat.h>
+ #endif
+ #include <stdint.h>
++#include <io.h>
+ #include <process.h>
+
+ #include "priv-io.h"
+--- lang/cpp/src/gpgaddexistingsubkeyeditinteractor.h
++++ lang/cpp/src/gpgaddexistingsubkeyeditinteractor.h
+@@ -27,6 +27,7 @@
+ #include "editinteractor.h"
+
+ #include <memory>
++#include <string>
+
+ namespace GpgME
+ {
+--- lang/cpp/src/gpgrevokekeyeditinteractor.h
++++ lang/cpp/src/gpgrevokekeyeditinteractor.h
+@@ -28,6 +28,7 @@
+ #include "global.h"
+
+ #include <memory>
++#include <string>
+ #include <vector>
+
+ namespace GpgME
diff --git a/external/graphite/Makefile b/external/graphite/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/graphite/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/graphite/Module_graphite.mk b/external/graphite/Module_graphite.mk
new file mode 100644
index 000000000..ff981612b
--- /dev/null
+++ b/external/graphite/Module_graphite.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,graphite))
+
+$(eval $(call gb_Module_add_targets,graphite,\
+ StaticLibrary_graphite \
+ UnpackedTarball_graphite \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/graphite/README b/external/graphite/README
new file mode 100644
index 000000000..3174b7233
--- /dev/null
+++ b/external/graphite/README
@@ -0,0 +1,7 @@
+Library for providing rendering capabilities for complex non-Roman writing systems.
+
+From:
+[http://graphite.sil.org/]
+
+Development:
+[http://projects.palaso.org/projects/graphitedev]
diff --git a/external/graphite/StaticLibrary_graphite.mk b/external/graphite/StaticLibrary_graphite.mk
new file mode 100644
index 000000000..ee233a10b
--- /dev/null
+++ b/external/graphite/StaticLibrary_graphite.mk
@@ -0,0 +1,79 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,graphite))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,graphite,graphite))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,graphite))
+
+$(eval $(call gb_StaticLibrary_set_include,graphite,\
+ -I$(call gb_UnpackedTarball_get_dir,graphite/include) \
+ -I$(call gb_UnpackedTarball_get_dir,graphite/src) \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_StaticLibrary_add_defs,graphite,\
+ -DGRAPHITE2_NTRACING \
+ -DGRAPHITE2_STATIC \
+))
+
+ifeq ($(COM),GCC)
+ifneq ($(COM_IS_CLANG),TRUE)
+$(eval $(call gb_StaticLibrary_add_cxxflags,graphite,\
+ -fpermissive \
+))
+endif
+endif
+
+ifeq ($(OS),ANDROID)
+# Force optimizations on Android, because otherwise Pass.cpp triggers an
+# infinite loop in clang, at least in this version:
+# Android (5058415 based on r339409) clang version 8.0.2 (https://android.googlesource.com/toolchain/clang 40173bab62ec746213857d083c0e8b0abb568790) (https://android.googlesource.com/toolchain/llvm 7a6618d69e7e8111e1d49dc9e7813767c5ca756a) (based on LLVM 8.0.2svn)
+$(eval $(call gb_StaticLibrary_add_cxxflags,graphite,\
+ -Os \
+))
+endif
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,graphite,cpp))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,graphite,\
+ UnpackedTarball/graphite/src/$(if $(filter GCC,$(COM)),direct,call)_machine \
+ UnpackedTarball/graphite/src/gr_char_info \
+ UnpackedTarball/graphite/src/gr_face \
+ UnpackedTarball/graphite/src/gr_features \
+ UnpackedTarball/graphite/src/gr_font \
+ UnpackedTarball/graphite/src/gr_logging \
+ UnpackedTarball/graphite/src/gr_segment \
+ UnpackedTarball/graphite/src/gr_slot \
+ UnpackedTarball/graphite/src/json \
+ UnpackedTarball/graphite/src/CmapCache \
+ UnpackedTarball/graphite/src/Code \
+ UnpackedTarball/graphite/src/Collider \
+ UnpackedTarball/graphite/src/Decompressor \
+ UnpackedTarball/graphite/src/Face \
+ UnpackedTarball/graphite/src/FeatureMap \
+ UnpackedTarball/graphite/src/FileFace \
+ UnpackedTarball/graphite/src/Font \
+ UnpackedTarball/graphite/src/GlyphCache \
+ UnpackedTarball/graphite/src/GlyphFace \
+ UnpackedTarball/graphite/src/Intervals \
+ UnpackedTarball/graphite/src/Justifier \
+ UnpackedTarball/graphite/src/NameTable \
+ UnpackedTarball/graphite/src/Pass \
+ UnpackedTarball/graphite/src/Position \
+ UnpackedTarball/graphite/src/Segment \
+ UnpackedTarball/graphite/src/Silf \
+ UnpackedTarball/graphite/src/Slot \
+ UnpackedTarball/graphite/src/Sparse \
+ UnpackedTarball/graphite/src/TtfUtil \
+ UnpackedTarball/graphite/src/UtfCodec \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/graphite/UnpackedTarball_graphite.mk b/external/graphite/UnpackedTarball_graphite.mk
new file mode 100644
index 000000000..464fcc256
--- /dev/null
+++ b/external/graphite/UnpackedTarball_graphite.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,graphite))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,graphite,$(GRAPHITE_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,graphite,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,graphite, \
+ external/graphite/ubsan.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/graphite/ubsan.patch b/external/graphite/ubsan.patch
new file mode 100644
index 000000000..fd7a08f82
--- /dev/null
+++ b/external/graphite/ubsan.patch
@@ -0,0 +1,11 @@
+--- src/gr_face.cpp
++++ src/gr_face.cpp
+@@ -95,7 +95,7 @@
+
+ Face *res = new Face(appFaceHandle, *ops);
+ if (res && load_face(*res, faceOptions))
+- return static_cast<gr_face *>(res);
++ return reinterpret_cast<gr_face *>(res);
+
+ delete res;
+ return 0;
diff --git a/external/harfbuzz/ExternalProject_harfbuzz.mk b/external/harfbuzz/ExternalProject_harfbuzz.mk
new file mode 100644
index 000000000..f7767f7a7
--- /dev/null
+++ b/external/harfbuzz/ExternalProject_harfbuzz.mk
@@ -0,0 +1,58 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,harfbuzz))
+
+$(eval $(call gb_ExternalProject_use_autoconf,harfbuzz,build))
+
+$(eval $(call gb_ExternalProject_register_targets,harfbuzz,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,harfbuzz,\
+ icu \
+ graphite \
+))
+
+$(call gb_ExternalProject_get_state_target,harfbuzz,build) :
+ $(call gb_Trace_StartRange,harfbuzz,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(if $(CROSS_COMPILING),ICU_CONFIG=$(SRCDIR)/external/icu/cross-bin/icu-config) \
+ $(if $(SYSTEM_ICU),,ICU_CONFIG=$(SRCDIR)/external/icu/cross-bin/icu-config) \
+ GRAPHITE2_CFLAGS="$(GRAPHITE_CFLAGS)" \
+ GRAPHITE2_LIBS="$(GRAPHITE_LIBS)" \
+ $(gb_RUN_CONFIGURE) ./configure \
+ --enable-static \
+ --disable-shared \
+ --disable-gtk-doc \
+ --with-pic \
+ --with-icu=builtin \
+ --with-freetype=no \
+ --with-fontconfig=no \
+ --with-cairo=no \
+ --with-glib=no \
+ --with-graphite2=yes \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(gb_FULLDEPS),,--disable-dependency-tracking) \
+ --libdir=$(call gb_UnpackedTarball_get_dir,harfbuzz/src/.libs) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ CXXFLAGS=' \
+ $(if $(filter ANDROID,$(OS)),-DHB_NO_MMAP=1,) \
+ $(call gb_ExternalProject_get_build_flags,harfbuzz) \
+ $(if $(ENABLE_RUNTIME_OPTIMIZATIONS),,-frtti) \
+ $(CXXFLAGS) $(CXXFLAGS_CXX11) \
+ $(ICU_UCHAR_TYPE) \
+ $(if $(filter LINUX,$(OS)),-fvisibility=hidden)' \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,harfbuzz)" \
+ MAKE=$(MAKE) \
+ && (cd $(EXTERNAL_WORKDIR)/src && $(MAKE) lib) \
+ )
+ $(call gb_Trace_EndRange,harfbuzz,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/harfbuzz/Makefile b/external/harfbuzz/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/harfbuzz/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/harfbuzz/Module_harfbuzz.mk b/external/harfbuzz/Module_harfbuzz.mk
new file mode 100644
index 000000000..ffbadd710
--- /dev/null
+++ b/external/harfbuzz/Module_harfbuzz.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,harfbuzz))
+
+$(eval $(call gb_Module_add_targets,harfbuzz,\
+ ExternalProject_harfbuzz \
+ UnpackedTarball_harfbuzz \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/harfbuzz/README b/external/harfbuzz/README
new file mode 100644
index 000000000..149da5566
--- /dev/null
+++ b/external/harfbuzz/README
@@ -0,0 +1 @@
+HarfBuzz is an OpenType text shaping engine. From [https://harfbuzz.github.io/].
diff --git a/external/harfbuzz/UnpackedTarball_harfbuzz.mk b/external/harfbuzz/UnpackedTarball_harfbuzz.mk
new file mode 100644
index 000000000..9bc9e326b
--- /dev/null
+++ b/external/harfbuzz/UnpackedTarball_harfbuzz.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,harfbuzz))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,harfbuzz,$(HARFBUZZ_TARBALL),,harfbuzz))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,harfbuzz))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,harfbuzz,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,harfbuzz, \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hsqldb/ExternalPackage_hsqldb.mk b/external/hsqldb/ExternalPackage_hsqldb.mk
new file mode 100644
index 000000000..e4dbb363b
--- /dev/null
+++ b/external/hsqldb/ExternalPackage_hsqldb.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,hsqldb_project,hsqldb))
+
+$(eval $(call gb_ExternalPackage_use_external_project,hsqldb_project,hsqldb))
+
+$(eval $(call gb_ExternalPackage_add_file,hsqldb_project,$(LIBO_SHARE_JAVA_FOLDER)/hsqldb.jar,lib/hsqldb.jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hsqldb/ExternalProject_hsqldb.mk b/external/hsqldb/ExternalProject_hsqldb.mk
new file mode 100644
index 000000000..67ae75106
--- /dev/null
+++ b/external/hsqldb/ExternalProject_hsqldb.mk
@@ -0,0 +1,38 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,hsqldb))
+
+$(eval $(call gb_ExternalProject_register_targets,hsqldb,\
+ build \
+))
+
+# ANT_OPTS -Djava.security.manager=allow allows latest Apache Ant 1.10.12 to still run under
+# Java 18, where java.lang.System.setSecurityManager (as called from
+# org.apache.tools.ant.types.Permissions.setSecurityManager) would otherwise throw an
+# UnsupportedOperationException (see <https://openjdk.java.net/jeps/411> "Deprecate the Security
+# Manager for Removal"):
+$(call gb_ExternalProject_get_state_target,hsqldb,build) :
+ $(call gb_Trace_StartRange,hsqldb,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(if $(JDK_SECURITYMANAGER_DISALLOWED_FOR_BUILD), \
+ ANT_OPTS="$$ANT_OPTS -Djava.security.manager=allow") \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build/build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ $(if $(debug),-Dbuild.debug="on") \
+ jar \
+ )
+ $(call gb_Trace_EndRange,hsqldb,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hsqldb/Makefile b/external/hsqldb/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/hsqldb/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hsqldb/Module_hsqldb.mk b/external/hsqldb/Module_hsqldb.mk
new file mode 100644
index 000000000..d748faa2e
--- /dev/null
+++ b/external/hsqldb/Module_hsqldb.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,hsqldb))
+
+$(eval $(call gb_Module_add_targets,hsqldb,\
+ ExternalPackage_hsqldb \
+ ExternalProject_hsqldb \
+ UnpackedTarball_hsqldb \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hsqldb/README b/external/hsqldb/README
new file mode 100644
index 000000000..7d7f89f04
--- /dev/null
+++ b/external/hsqldb/README
@@ -0,0 +1,11 @@
+Java database engine from [http://hsqldb.org/].
+
+Default database format for LibreOffice.
+
+At some point the plan was to replace it as default by Firebird, but
+that seems increasingly unlikely to happen.
+
+See:
+https://bugs.freedesktop.org/show_bug.cgi?id=51781
+http://www.firebirdsql.org
+
diff --git a/external/hsqldb/UnpackedTarball_hsqldb.mk b/external/hsqldb/UnpackedTarball_hsqldb.mk
new file mode 100644
index 000000000..0b05b45ba
--- /dev/null
+++ b/external/hsqldb/UnpackedTarball_hsqldb.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,hsqldb))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,hsqldb,$(HSQLDB_TARBALL),,hsqldb))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,hsqldb,\
+ build/build.xml \
+ src/org/hsqldb/Library.java \
+ src/org/hsqldb/persist/HsqlDatabaseProperties.java \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,hsqldb,\
+ external/hsqldb/patches/i96823.patch \
+ external/hsqldb/patches/i97032.patch \
+ external/hsqldb/patches/i103528.patch \
+ external/hsqldb/patches/i104901.patch \
+ external/hsqldb/patches/fdo36824.patch \
+ external/hsqldb/patches/limit_as_table_alias.patch \
+ external/hsqldb/patches/hsqldb-runFinalizersOnExit.patch \
+ external/hsqldb/patches/jdbc-4.1.patch \
+ external/hsqldb/patches/multipleResultSets.patch \
+ external/hsqldb/patches/disable-dump-script.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hsqldb/patches/disable-dump-script.patch b/external/hsqldb/patches/disable-dump-script.patch
new file mode 100644
index 000000000..401dd38ab
--- /dev/null
+++ b/external/hsqldb/patches/disable-dump-script.patch
@@ -0,0 +1,14 @@
+--- a/hsqldb/src/org/hsqldb/DatabaseCommandInterpreter.java 2023-02-13 11:08:11.297243034 +0000
++++ b/hsqldb/src/org/hsqldb/DatabaseCommandInterpreter.java 2023-02-13 13:49:17.973089433 +0000
+@@ -403,6 +403,11 @@
+ throw Trace.error(Trace.INVALID_IDENTIFIER);
+ }
+
++ // added condition to avoid execution of spurious command in .script or .log file
++ if (session.isProcessingScript() || session.isProcessingLog()) {
++ return new Result(ResultConstants.UPDATECOUNT);
++ }
++
+ dsw = new ScriptWriterText(database, token, true, true, true);
+
+ dsw.writeAll();
diff --git a/external/hsqldb/patches/fdo36824.patch b/external/hsqldb/patches/fdo36824.patch
new file mode 100644
index 000000000..ad753e335
--- /dev/null
+++ b/external/hsqldb/patches/fdo36824.patch
@@ -0,0 +1,11 @@
+--- misc/hsqldb/src/org/hsqldb/Expression.java 2012-07-03 19:49:00.000000000 +0200
++++ misc/build/hsqldb/src/org/hsqldb/Expression.java 2012-07-03 19:39:00.000000000 +0200
+@@ -1552,7 +1552,7 @@
+ return columnQuoted;
+ }
+
+- return false;
++ return true;
+ }
+
+ /**
diff --git a/external/hsqldb/patches/hsqldb-runFinalizersOnExit.patch b/external/hsqldb/patches/hsqldb-runFinalizersOnExit.patch
new file mode 100644
index 000000000..214dc2c2b
--- /dev/null
+++ b/external/hsqldb/patches/hsqldb-runFinalizersOnExit.patch
@@ -0,0 +1,14 @@
+--- misc/hsqldb/src/org/hsqldb/lib/java/JavaSystem.java 2008-03-16 23:51:35.000000000 +0100
++++ misc/build/hsqldb/src/org/hsqldb/lib/java/JavaSystem.java 2018-07-12 11:46:57.997837180 +0200
+@@ -160,8 +160,9 @@
+ public static void runFinalizers() {
+
+ //#ifdef JAVA2FULL
+- System.runFinalizersOnExit(true);
+-
++ try {
++ System.class.getMethod("runFinalizersOnExit", boolean.class).invoke(null, true);
++ } catch (Exception e) {}
+ //#endif
+ }
+
diff --git a/external/hsqldb/patches/i103528.patch b/external/hsqldb/patches/i103528.patch
new file mode 100644
index 000000000..3cc7d2f1d
--- /dev/null
+++ b/external/hsqldb/patches/i103528.patch
@@ -0,0 +1,11 @@
+--- misc/hsqldb/src/org/hsqldb/Library.java
++++ misc/build/hsqldb/src/org/hsqldb/Library.java
+@@ -1957,7 +1957,7 @@
+ functionMap.put("bitand", bitand);
+ functionMap.put("bitlength", bitLength);
+ functionMap.put("bitor", bitor);
+- functionMap.put("bitxor", bitor);
++ functionMap.put("bitxor", bitxor);
+ functionMap.put("character", character);
+ functionMap.put("concat", concat);
+ functionMap.put("cot", cot);
diff --git a/external/hsqldb/patches/i104901.patch b/external/hsqldb/patches/i104901.patch
new file mode 100644
index 000000000..a38773f4b
--- /dev/null
+++ b/external/hsqldb/patches/i104901.patch
@@ -0,0 +1,27 @@
+--- misc/hsqldb/src/org/hsqldb/Table.java 2007-10-19 23:59:07.000000000 +0200
++++ misc/build/hsqldb/src/org/hsqldb/Table.java 2009-09-11 13:45:42.939231519 +0200
+@@ -149,10 +149,10 @@
+ Constraint[] constraintList; // constrainst for the table
+ HsqlArrayList[] triggerLists; // array of trigger lists
+ private int[] colTypes; // fredt - types of columns
+- private int[] colSizes; // fredt - copy of SIZE values for columns
++ int[] colSizes; // fredt - copy of SIZE values for columns
+ private int[] colScales; // fredt - copy of SCALE values for columns
+ private boolean[] colNullable; // fredt - modified copy of isNullable() values
+- private Expression[] colDefaults; // fredt - expressions of DEFAULT values
++ Expression[] colDefaults; // fredt - expressions of DEFAULT values
+ private int[] defaultColumnMap; // fred - holding 0,1,2,3,...
+ private boolean hasDefaultValues; //fredt - shortcut for above
+ boolean sqlEnforceSize; // inherited from the database -
+--- misc/hsqldb/src/org/hsqldb/TableWorks.java 2007-01-14 06:48:16.000000000 +0100
++++ misc/build/hsqldb/src/org/hsqldb/TableWorks.java 2009-09-11 13:47:50.328667463 +0200
+@@ -670,7 +670,8 @@
+ // default expressions can change
+ oldCol.setType(newCol);
+ oldCol.setDefaultExpression(newCol.getDefaultExpression());
+- table.setColumnTypeVars(colIndex);
++ table.colSizes[colIndex] = oldCol.getSize();
++ table.colDefaults[colIndex] = oldCol.getDefaultExpression();
+ table.resetDefaultsFlag();
+
+ return;
diff --git a/external/hsqldb/patches/i96823.patch b/external/hsqldb/patches/i96823.patch
new file mode 100644
index 000000000..bea4a2b7e
--- /dev/null
+++ b/external/hsqldb/patches/i96823.patch
@@ -0,0 +1,94 @@
+--- misc/hsqldb/src/org/hsqldb/Expression.java 2008-05-27 17:15:05.000000000 +0200
++++ misc/build/hsqldb/src/org/hsqldb/Expression.java 2009-01-27 11:42:16.890625000 +0100
+@@ -803,61 +803,62 @@
+
+ case EXISTS :
+ buf.append(' ').append(Token.T_EXISTS).append(' ');
+- break;
++
++ return buf.toString();
+
+ case COUNT :
+ buf.append(' ').append(Token.T_COUNT).append('(');
+- break;
++ if ( "(*)".equals(left))buf.append('*');else buf.append(left); buf.append(')'); return buf.toString();
+
+ case SUM :
+ buf.append(' ').append(Token.T_SUM).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+
+ case MIN :
+ buf.append(' ').append(Token.T_MIN).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+
+ case MAX :
+ buf.append(' ').append(Token.T_MAX).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+
+ case AVG :
+ buf.append(' ').append(Token.T_AVG).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+
+ case EVERY :
+ buf.append(' ').append(Token.T_EVERY).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+
+ case SOME :
+ buf.append(' ').append(Token.T_SOME).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+
+ case STDDEV_POP :
+ buf.append(' ').append(Token.T_STDDEV_POP).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+
+ case STDDEV_SAMP :
+ buf.append(' ').append(Token.T_STDDEV_SAMP).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+
+ case VAR_POP :
+ buf.append(' ').append(Token.T_VAR_POP).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+
+ case VAR_SAMP :
+ buf.append(' ').append(Token.T_VAR_SAMP).append('(');
+ buf.append(left).append(')');
+- break;
++ return buf.toString();
+ }
+
+ throw Trace.error(Trace.EXPRESSION_NOT_SUPPORTED);
+@@ -1522,6 +1523,16 @@
+ if (exprType == COLUMN) {
+ return columnName;
+ }
++ if ( isAggregate(exprType) )
++ {
++ try
++ {
++ return getDDL();
++ }
++ catch(Exception e)
++ {
++ }
++ }
+
+ return "";
+ }
diff --git a/external/hsqldb/patches/i97032.patch b/external/hsqldb/patches/i97032.patch
new file mode 100644
index 000000000..9703b8961
--- /dev/null
+++ b/external/hsqldb/patches/i97032.patch
@@ -0,0 +1,10 @@
+--- misc/hsqldb/src/org/hsqldb/persist/HsqlDatabaseProperties.java 2008-03-17 17:05:41.000000000 +0100
++++ misc/build/hsqldb/src/org/hsqldb/persist/HsqlDatabaseProperties.java 2009-01-21 13:09:24.493470142 +0100
+@@ -429,6 +429,7 @@
+ setProperty(hsqldb_log_size, 10);
+ setProperty(sql_enforce_strict_size, true);
+ setProperty(hsqldb_nio_data_file, false);
++ setProperty(hsqldb_lock_file, true);
+ }
+
+ // OOo end
diff --git a/external/hsqldb/patches/jdbc-4.1.patch b/external/hsqldb/patches/jdbc-4.1.patch
new file mode 100644
index 000000000..7884148c5
--- /dev/null
+++ b/external/hsqldb/patches/jdbc-4.1.patch
@@ -0,0 +1,320 @@
+--- misc/hsqldb/build/build.xml 2012-07-12 10:58:11.000000000 +0200
++++ misc/build/hsqldb/build/build.xml 2012-07-12 10:49:28.000000000 +0200
+@@ -98,16 +98,24 @@
+ <echo message="ant.java.hasjsse=${ant.java.hasjsse}" />
+ </target>
+
+- <target name="javaversion6">
++ <target name="javaversion7" unless="ant.java.iscjavaset">
++ <available classname="java.util.Objects" property="ant.java.iscjava17"/>
++ <available classname="java.util.Objects" property="ant.java.iscjavaset"/>
++ </target>
++
++ <target name="javaversion6" depends="javaversion7" unless="ant.java.iscjavaset">
+ <available classname="java.net.IDN" property="ant.java.iscjava16"/>
++ <available classname="java.net.IDN" property="ant.java.iscjavaset"/>
+ </target>
+
+- <target name="javaversion4" depends="javaversion6" unless="ant.java.iscjava16">
++ <target name="javaversion4" depends="javaversion6" unless="ant.java.iscjavaset">
+ <available classname="java.nio.Buffer" property="ant.java.iscjava14"/>
++ <available classname="java.nio.Buffer" property="ant.java.iscjavaset"/>
+ </target>
+
+- <target name="javaversion2" depends="javaversion4" unless="ant.java.iscjava14">
++ <target name="javaversion2" depends="javaversion4" unless="ant.java.iscjavaset">
+ <available classname="java.lang.ref.Reference" property="ant.java.iscjava12"/>
++ <available classname="java.lang.ref.Reference" property="ant.java.iscjavaset"/>
+ </target>
+
+ <target name="-prepare" depends="init,javaversion2">
+@@ -166,6 +177,7 @@
+ <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+ <arg file="${src}/org/hsqldb/lib/java/JavaSystem.java"/>
+ <arg file="${src}/org/hsqldb/lib/HsqlTimer.java"/>
++ <arg file="${src}/org/hsqldb/jdbcDriver.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcStatement.java"/>
+ <arg file="${src}/org/hsqldb/persist/LockFile.java"/>
+ <arg file="${src}/org/hsqldb/persist/Logger.java"/>
+@@ -183,6 +195,7 @@
+ <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+ <arg file="${src}/org/hsqldb/lib/java/JavaSystem.java"/>
+ <arg file="${src}/org/hsqldb/lib/HsqlTimer.java"/>
++ <arg file="${src}/org/hsqldb/jdbcDriver.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcBlob.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcDatabaseMetaData.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcDataSource.java"/>
+@@ -210,6 +223,7 @@
+ <arg value="+JAVA2FULL"/>
+ <arg value="-JAVA4"/>
+ <arg value="-JAVA6"/>
++ <arg value="-JAVA7"/>
+ </java>
+ </target>
+
+@@ -218,6 +232,7 @@
+ <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+ <arg file="${src}/org/hsqldb/lib/java/JavaSystem.java"/>
+ <arg file="${src}/org/hsqldb/lib/HsqlTimer.java"/>
++ <arg file="${src}/org/hsqldb/jdbcDriver.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcBlob.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcDatabaseMetaData.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcDataSource.java"/>
+@@ -244,6 +259,7 @@
+ <arg value="+JAVA2FULL"/>
+ <arg value="+JAVA4"/>
+ <arg value="-JAVA6"/>
++ <arg value="-JAVA7"/>
+ </java>
+ </target>
+
+@@ -253,6 +269,43 @@
+ <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
+ <arg file="${src}/org/hsqldb/lib/java/JavaSystem.java"/>
+ <arg file="${src}/org/hsqldb/lib/HsqlTimer.java"/>
++ <arg file="${src}/org/hsqldb/jdbcDriver.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcBlob.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcDatabaseMetaData.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcDataSource.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcCallableStatement.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcClob.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcConnection.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcParameterMetaData.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcPreparedStatement.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcResultSet.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcResultSetMetaData.java"/>
++ <arg file="${src}/org/hsqldb/jdbc/jdbcStatement.java"/>
++ <arg file="${src}/org/hsqldb/persist/LockFile.java"/>
++ <arg file="${src}/org/hsqldb/persist/Logger.java"/>
++ <arg file="${src}/org/hsqldb/persist/ScaledRAFile.java"/>
++ <arg file="${src}/org/hsqldb/rowio/RowInputTextLog.java"/>
++ <arg file="${src}/org/hsqldb/util/DatabaseManager.java"/>
++ <arg file="${src}/org/hsqldb/util/ConnectionDialogCommon.java"/>
++ <arg file="${src}/org/hsqldb/lib/SimpleLog.java"/>
++ <arg file="${src}/org/hsqldb/rowio/RowInputTextLog.java"/>
++ <arg file="${src}/org/hsqldb/lib/SimpleLog.java"/>
++ <arg file="${src}/org/hsqldb/rowio/RowInputTextLog.java"/>
++ <arg file="${src}/org/hsqldb/HsqlDateTime.java"/>
++ <arg value="+JAVA2"/>
++ <arg value="+JAVA2FULL"/>
++ <arg value="+JAVA4"/>
++ <arg value="+JAVA6"/>
++ <arg value="-JAVA7"/>
++ </java>
++ </target>
++
++ <target name="switchtojdk17" depends="switchtojdk16"
++ description="self explanatory" if="ant.java.iscjava17">
++ <java classname="org.hsqldb.util.CodeSwitcher" classpath="classes" >
++ <arg file="${src}/org/hsqldb/lib/java/JavaSystem.java"/>
++ <arg file="${src}/org/hsqldb/lib/HsqlTimer.java"/>
++ <arg file="${src}/org/hsqldb/jdbcDriver.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcBlob.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcDatabaseMetaData.java"/>
+ <arg file="${src}/org/hsqldb/jdbc/jdbcDataSource.java"/>
+@@ -279,10 +332,11 @@
+ <arg value="+JAVA2FULL"/>
+ <arg value="+JAVA4"/>
+ <arg value="+JAVA6"/>
++ <arg value="+JAVA7"/>
+ </java>
+ </target>
+
+- <target name="store" depends="switchtojdk16"
++ <target name="store" depends="switchtojdk17"
+ description="compiles the /store folder">
+ <javac srcdir="${src}"
+ destdir="classes"
+--- misc/hsqldb/src/org/hsqldb/jdbc/jdbcCallableStatement.java 2012-02-08 15:14:42.802123563 +0000
++++ misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcCallableStatement.java 2012-02-08 15:47:35.842635642 +0000
+@@ -3375,4 +3375,18 @@
+ */
+
+ //#endif JAVA6
++
++//#ifdef JAVA7
++ public <T> T getObject(String columnLabel, Class<T> type) throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ public <T> T getObject(int ColumnIndex, Class<T> type) throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++
++//#endif JAVA7
+ }
+--- misc/hsqldb/src/org/hsqldb/jdbc/jdbcConnection.java 2012-02-08 15:14:42.802123563 +0000
++++ misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcConnection.java 2012-02-08 15:47:35.851635628 +0000
+@@ -48,6 +48,12 @@
+ */
+
+ //#endif JAVA6
++
++//#ifdef JAVA7
++import java.util.concurrent.Executor;
++
++//#endif JAVA7
++
+ import java.sql.PreparedStatement;
+ import java.sql.SQLException;
+ import java.sql.SQLWarning;
+@@ -2793,4 +2799,31 @@
+ */
+
+ //#endif JAVA6
++
++//#ifdef JAVA7
++ public int getNetworkTimeout() throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ public void setNetworkTimeout(Executor executor, int millis) throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ public void abort(Executor executor) throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ public String getSchema() throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ public void setSchema(String schema) throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++//#endif JAVA7
+ }
+--- misc/hsqldb/src/org/hsqldb/jdbc/jdbcDatabaseMetaData.java 2012-02-08 15:14:42.802123563 +0000
++++ misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcDatabaseMetaData.java 2012-02-08 15:47:35.835635654 +0000
+@@ -5693,4 +5693,21 @@
+ */
+
+ //#endif JAVA6
++
++
++//#ifdef JAVA7
++ public boolean generatedKeyAlwaysReturned() throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ public ResultSet getPseudoColumns(String catalog, String schemaPattern,
++ String tableNamePattern, String columnNamePattern) throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++
++//#endif JAVA7
++
+ }
+--- misc/hsqldb/src/org/hsqldb/jdbc/jdbcDataSource.java 2012-02-08 15:14:42.802123563 +0000
++++ misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcDataSource.java 2012-02-08 15:47:35.836635653 +0000
+@@ -47,6 +47,11 @@
+ //#endif JAVA4
+ import org.hsqldb.jdbcDriver;
+
++//#ifdef JAVA7
++import java.sql.SQLFeatureNotSupportedException;
++import java.util.logging.Logger;
++//#endif JAVA7
++
+ // boucherb@users 20040411 - doc 1.7.2 - javadoc updates toward 1.7.2 final
+
+ /**
+@@ -323,4 +328,15 @@
+ */
+
+ //#endif JAVA6
++
++//#ifdef JAVA7
++ public Logger getParentLogger() throws SQLFeatureNotSupportedException
++ {
++ throw new AbstractMethodError(
++ "org.hsqldb.jdbc.jdbcDataSource.getParentLogger should throw" +
++ " SQLFeatureNotSupportedException, but that is not yet available" +
++ " in Java 5");
++ }
++
++//#endif JAVA7
+ }
+--- misc/hsqldb/src/org/hsqldb/jdbc/jdbcResultSet.java 2012-02-08 15:14:42.802123563 +0000
++++ misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcResultSet.java 2012-02-08 15:47:35.866635606 +0000
+@@ -5324,4 +5324,19 @@
+ */
+
+ //#endif JAVA6
++
++//#ifdef JAVA7
++
++ public <T> T getObject(String columnLabel, Class<T> type) throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ public <T> T getObject(int columnNum, Class<T> type) throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++//#endif JAVA7
++
+ }
+--- misc/hsqldb/src/org/hsqldb/jdbc/jdbcStatement.java 2012-02-08 15:14:42.802123563 +0000
++++ misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcStatement.java 2012-02-08 15:47:35.872635595 +0000
+@@ -1608,4 +1608,16 @@
+ }
+ */
+ //#endif JAVA6
++
++//#ifdef JAVA7
++ public boolean isCloseOnCompletion() throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++
++ public void closeOnCompletion() throws SQLException
++ {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++//#endif JAVA7
+ }
+--- misc/hsqldb/src/org/hsqldb/jdbcDriver.java 2012-02-08 15:14:42.800123566 +0000
++++ misc/build/hsqldb/src/org/hsqldb/jdbcDriver.java 2012-02-08 15:47:35.826635667 +0000
+@@ -42,6 +42,11 @@
+ import org.hsqldb.persist.HsqlDatabaseProperties;
+ import org.hsqldb.persist.HsqlProperties;
+
++//#ifdef JAVA7
++import java.sql.SQLFeatureNotSupportedException;
++import java.util.logging.Logger;
++//#endif JAVA7
++
+ // fredt@users 20011220 - patch 1.7.0 by fredt
+ // new version numbering scheme
+ // fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
+@@ -321,4 +326,15 @@
+ DriverManager.registerDriver(new jdbcDriver());
+ } catch (Exception e) {}
+ }
++
++//#ifdef JAVA7
++ public Logger getParentLogger() throws SQLFeatureNotSupportedException
++ {
++ throw new AbstractMethodError(
++ "org.hsqldb.jdbcDriver.getParentLogger should throw" +
++ " SQLFeatureNotSupportedException, but that is not yet available" +
++ " in Java 5");
++ }
++
++//#endif JAVA7
+ }
diff --git a/external/hsqldb/patches/limit_as_table_alias.patch b/external/hsqldb/patches/limit_as_table_alias.patch
new file mode 100644
index 000000000..09f49ccd5
--- /dev/null
+++ b/external/hsqldb/patches/limit_as_table_alias.patch
@@ -0,0 +1,11 @@
+--- misc/hsqldb/src/org/hsqldb/Token.java 2013-06-13 10:04:28.975934479 +0200
++++ misc/build/hsqldb/src/org/hsqldb/Token.java 2013-06-13 10:06:09.915931966 +0200
+@@ -819,7 +819,7 @@
+ Token.T_EXTRACT, Token.T_FOR, Token.T_FROM, Token.T_GROUP,
+ Token.T_HAVING, Token.T_IF, Token.T_INTO, Token.T_IFNULL,
+ Token.T_IS, Token.T_IN, Token.T_INTERSECT, Token.T_JOIN,
+- Token.T_INNER, Token.T_LEADING, Token.T_LIKE, Token.T_MAX,
++ Token.T_INNER, Token.T_LEADING, Token.T_LIKE, Token.T_LIMIT, Token.T_MAX,
+ Token.T_MIN, Token.T_NEXT, Token.T_NULLIF, Token.T_NOT,
+ Token.T_NVL, Token.T_MINUS, Token.T_ON, Token.T_ORDER, Token.T_OR,
+ Token.T_OUTER, Token.T_POSITION, Token.T_PRIMARY, Token.T_SELECT,
diff --git a/external/hsqldb/patches/multipleResultSets.patch b/external/hsqldb/patches/multipleResultSets.patch
new file mode 100644
index 000000000..56ddb13b4
--- /dev/null
+++ b/external/hsqldb/patches/multipleResultSets.patch
@@ -0,0 +1,11 @@
+--- misc/hsqldb/src/org/hsqldb/jdbc/jdbcDatabaseMetaData.java 2012-02-08 15:14:42.802123563 +0000
++++ misc/build/hsqldb/src/org/hsqldb/jdbc/jdbcDatabaseMetaData.java 2012-02-08 15:47:35.835635654 +0000
+@@ -1347,7 +1347,7 @@
+ * @exception SQLException if a database access error occurs
+ */
+ public boolean supportsMultipleResultSets() throws SQLException {
+- return false;
++ return true;
+ }
+
+ /**
diff --git a/external/hunspell/0001-invalid-read-memory-access-624.patch b/external/hunspell/0001-invalid-read-memory-access-624.patch
new file mode 100644
index 000000000..66b55e755
--- /dev/null
+++ b/external/hunspell/0001-invalid-read-memory-access-624.patch
@@ -0,0 +1,25 @@
+From ac938e2ecb48ab4dd21298126c7921689d60571b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
+Date: Tue, 12 Nov 2019 20:03:15 +0000
+Subject: [PATCH] invalid read memory access #624
+
+---
+ src/hunspell/suggestmgr.cxx | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/hunspell/suggestmgr.cxx b/src/hunspell/suggestmgr.cxx
+index dba084e..c23f165 100644
+--- a/src/hunspell/suggestmgr.cxx
++++ b/src/hunspell/suggestmgr.cxx
+@@ -2040,7 +2040,7 @@ int SuggestMgr::leftcommonsubstring(
+ int l2 = su2.size();
+ // decapitalize dictionary word
+ if (complexprefixes) {
+- if (su1[l1 - 1] == su2[l2 - 1])
++ if (l1 && l2 && su1[l1 - 1] == su2[l2 - 1])
+ return 1;
+ } else {
+ unsigned short idx = su2.empty() ? 0 : (su2[0].h << 8) + su2[0].l;
+--
+2.23.0
+
diff --git a/external/hunspell/ExternalProject_hunspell.mk b/external/hunspell/ExternalProject_hunspell.mk
new file mode 100644
index 000000000..c63498af7
--- /dev/null
+++ b/external/hunspell/ExternalProject_hunspell.mk
@@ -0,0 +1,39 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,hunspell))
+
+$(eval $(call gb_ExternalProject_register_targets,hunspell,\
+ build \
+))
+
+hunspell_CPPCLAGS=$(CPPFLAGS)
+
+hunspell_CPPFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG)
+
+hunspell_CXXFLAGS:=$(CXXFLAGS) $(gb_LTOFLAGS) \
+ $(gb_EMSCRIPTEN_CPPFLAGS) \
+ $(call gb_ExternalProject_get_build_flags,hunspell)
+
+hunspell_LDFLAGS:=$(gb_LTOFLAGS) $(call gb_ExternalProject_get_link_flags,hunspell)
+
+$(call gb_ExternalProject_get_state_target,hunspell,build):
+ $(call gb_Trace_StartRange,hunspell,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure --disable-shared --disable-nls --with-pic \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter AIX,$(OS)),CFLAGS="-D_LINUX_SOURCE_COMPAT") \
+ $(if $(hunspell_CPPFLAGS),CPPFLAGS='$(hunspell_CPPFLAGS)') \
+ $(if $(hunspell_CXXFLAGS),CXXFLAGS='$(hunspell_CXXFLAGS)') \
+ $(if $(hunspell_LDFLAGS),LDFLAGS='$(hunspell_LDFLAGS)') \
+ && cd src/hunspell && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,hunspell,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hunspell/Makefile b/external/hunspell/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/hunspell/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hunspell/Module_hunspell.mk b/external/hunspell/Module_hunspell.mk
new file mode 100644
index 000000000..505a9fb0c
--- /dev/null
+++ b/external/hunspell/Module_hunspell.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,hunspell))
+
+$(eval $(call gb_Module_add_targets,hunspell,\
+ UnpackedTarball_hunspell \
+))
+ifeq ($(COM),MSC)
+$(eval $(call gb_Module_add_targets,hunspell,\
+ StaticLibrary_hunspell \
+))
+else
+$(eval $(call gb_Module_add_targets,hunspell,\
+ ExternalProject_hunspell \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hunspell/README b/external/hunspell/README
new file mode 100644
index 000000000..1221735ca
--- /dev/null
+++ b/external/hunspell/README
@@ -0,0 +1,4 @@
+Library for spell checking.
+
+From:
+[http://hunspell.sourceforge.net/].
diff --git a/external/hunspell/StaticLibrary_hunspell.mk b/external/hunspell/StaticLibrary_hunspell.mk
new file mode 100644
index 000000000..3a2eccafb
--- /dev/null
+++ b/external/hunspell/StaticLibrary_hunspell.mk
@@ -0,0 +1,41 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,hunspell))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,hunspell,hunspell))
+
+$(eval $(call gb_StaticLibrary_use_external,hunspell,icu_headers))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,hunspell))
+
+$(eval $(call gb_StaticLibrary_add_defs,hunspell,\
+ -DHUNSPELL_STATIC \
+ -DOPENOFFICEORG \
+))
+
+ifneq ($(ENABLE_WASM_STRIP_HUNSPELL),TRUE)
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,hunspell,\
+ UnpackedTarball/hunspell/src/hunspell/hunspell \
+))
+endif
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,hunspell,\
+ UnpackedTarball/hunspell/src/hunspell/affentry \
+ UnpackedTarball/hunspell/src/hunspell/affixmgr \
+ UnpackedTarball/hunspell/src/hunspell/csutil \
+ UnpackedTarball/hunspell/src/hunspell/hashmgr \
+ UnpackedTarball/hunspell/src/hunspell/suggestmgr \
+ UnpackedTarball/hunspell/src/hunspell/phonet \
+ UnpackedTarball/hunspell/src/hunspell/hunzip \
+ UnpackedTarball/hunspell/src/hunspell/filemgr \
+ UnpackedTarball/hunspell/src/hunspell/replist \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hunspell/UnpackedTarball_hunspell.mk b/external/hunspell/UnpackedTarball_hunspell.mk
new file mode 100644
index 000000000..1cd24e225
--- /dev/null
+++ b/external/hunspell/UnpackedTarball_hunspell.mk
@@ -0,0 +1,28 @@
+ -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,hunspell))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,hunspell,$(HUNSPELL_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,hunspell))
+
+ifeq ($(COM),MSC)
+$(eval $(call gb_UnpackedTarball_set_post_action,hunspell,\
+ touch src/hunspell/config.h \
+))
+endif
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,hunspell,1))
+
+$(eval $(call gb_UnpackedTarball_add_patches,hunspell, \
+ external/hunspell/0001-invalid-read-memory-access-624.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hyphen/ExternalProject_hyphen.mk b/external/hyphen/ExternalProject_hyphen.mk
new file mode 100644
index 000000000..0d1a3e052
--- /dev/null
+++ b/external/hyphen/ExternalProject_hyphen.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,hyphen))
+
+ifneq ($(ENABLE_WASM_STRIP_HUNSPELL),TRUE)
+$(eval $(call gb_ExternalProject_use_external,hyphen,hunspell))
+endif
+
+$(eval $(call gb_ExternalProject_register_targets,hyphen,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,hyphen,build):
+ $(call gb_Trace_StartRange,hyphen,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure --disable-shared \
+ $(if $(filter-out iOS,$(OS)),--with-pic) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),gio_can_sniff=no) \
+ CFLAGS=" $(CFLAGS) $(call gb_ExternalProject_get_build_flags,libgpg-error)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,hyphen)" \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,hyphen,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hyphen/Makefile b/external/hyphen/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/hyphen/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hyphen/Module_hyphen.mk b/external/hyphen/Module_hyphen.mk
new file mode 100644
index 000000000..527def321
--- /dev/null
+++ b/external/hyphen/Module_hyphen.mk
@@ -0,0 +1,30 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,hyphen))
+
+$(eval $(call gb_Module_add_targets,hyphen,\
+ UnpackedTarball_hyphen \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,hyphen,\
+ StaticLibrary_hyphen \
+))
+
+else
+
+$(eval $(call gb_Module_add_targets,hyphen,\
+ ExternalProject_hyphen \
+))
+
+endif # $(COM)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hyphen/README b/external/hyphen/README
new file mode 100644
index 000000000..327b5b6e8
--- /dev/null
+++ b/external/hyphen/README
@@ -0,0 +1 @@
+Hyphenator library from [http://hunspell.sourceforge.net]
diff --git a/external/hyphen/StaticLibrary_hyphen.mk b/external/hyphen/StaticLibrary_hyphen.mk
new file mode 100644
index 000000000..e911feb9b
--- /dev/null
+++ b/external/hyphen/StaticLibrary_hyphen.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,hyphen))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,hyphen,hyphen))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,hyphen))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,hyphen,\
+ UnpackedTarball/hyphen/hyphen \
+ UnpackedTarball/hyphen/hnjalloc \
+))
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hyphen/UnpackedTarball_hyphen.mk b/external/hyphen/UnpackedTarball_hyphen.mk
new file mode 100644
index 000000000..c4bbb0226
--- /dev/null
+++ b/external/hyphen/UnpackedTarball_hyphen.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,hyphen))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,hyphen,$(HYPHEN_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,hyphen))
+
+$(eval $(call gb_UnpackedTarball_add_patches,hyphen,\
+ external/hyphen/hyphen-build.patch \
+ external/hyphen/hyphen-fdo48017-wfopen.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/hyphen/hyphen-build.patch b/external/hyphen/hyphen-build.patch
new file mode 100644
index 000000000..6df2bb680
--- /dev/null
+++ b/external/hyphen/hyphen-build.patch
@@ -0,0 +1,38 @@
+--- misc/hyphen-2.8.4/Makefile.am 2010-07-19 11:23:17.000000000 +0200
++++ misc/build/hyphen-2.8.4/Makefile.am 2010-12-02 10:15:44.390625000 +0100
+@@ -25,13 +25,13 @@
+
+ hyphen.us3:
+ cp -f $(srcdir)/hyphen.tex hyphen.us
+- patch < $(srcdir)/hyphen.patch
++ $(GNUPATCH) < $(srcdir)/hyphen.patch
+ $(srcdir)/tbhyphext.sh <$(srcdir)/tbhyphext.tex >hyphen.us2
+ cat hyphen.us hyphen.us2 | $(AWK) -f $(srcdir)/lig.awk >hyphen.us3
+ cat $(srcdir)/ligpatch.txt >>hyphen.us3
+
+-hyph_en_US.dic: hyphen.us3
+- perl $(srcdir)/substrings.pl hyphen.us3 hyph_en_US.dic UTF-8 2 3 >/dev/null
++hyph_en_US.dic:
++ @echo "hyph_en_US.txt distributed with Hyphen library"
+
+ clean-local:
+ rm -rf hyphen.us* hyph_en_US.dic
+--- misc/hyphen-2.8.4/Makefile.in 2010-12-01 02:31:29.000000000 +0100
++++ misc/build/hyphen-2.8.4/Makefile.in 2010-12-02 10:17:16.546875000 +0100
+@@ -940,13 +940,13 @@
+
+ hyphen.us3:
+ cp -f $(srcdir)/hyphen.tex hyphen.us
+- patch < $(srcdir)/hyphen.patch
++ $(GNUPATCH) < $(srcdir)/hyphen.patch
+ $(srcdir)/tbhyphext.sh <$(srcdir)/tbhyphext.tex >hyphen.us2
+ cat hyphen.us hyphen.us2 | $(AWK) -f $(srcdir)/lig.awk >hyphen.us3
+ cat $(srcdir)/ligpatch.txt >>hyphen.us3
+
+-hyph_en_US.dic: hyphen.us3
+- perl $(srcdir)/substrings.pl hyphen.us3 hyph_en_US.dic UTF-8 2 3 >/dev/null
++hyph_en_US.dic:
++ @echo "hyph_en_US.txt distributed with Hyphen library"
+
+ clean-local:
+ rm -rf hyphen.us* hyph_en_US.dic
diff --git a/external/hyphen/hyphen-fdo48017-wfopen.patch b/external/hyphen/hyphen-fdo48017-wfopen.patch
new file mode 100644
index 000000000..815eeda79
--- /dev/null
+++ b/external/hyphen/hyphen-fdo48017-wfopen.patch
@@ -0,0 +1,49 @@
+diff -u hyphen/hyphen.c build/hyphen/hyphen.c
+--- hyphen/hyphen.c 2014-05-22 00:28:13.164587974 +0200
++++ build/hyphen/hyphen.c 2015-05-22 11:08:55.000000000 +0200
+@@ -44,6 +44,11 @@
+ #include <unistd.h> /* for exit */
+ #endif
+
++#ifdef _WIN32
++#include <windows.h>
++#include <wchar.h>
++#endif
++
+ #define noVERBOSE
+
+ /* calculate hyphenmin values with long ligature length (2 or 3 characters
+@@ -371,12 +376,32 @@
+ }
+ }
+
++FILE * hnj_fopen(const char * path, const char * mode) {
++#ifdef _WIN32
++#define WIN32_LONG_PATH_PREFIX "\\\\?\\"
++ if (strncmp(path, WIN32_LONG_PATH_PREFIX, 4) == 0) {
++ int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
++ wchar_t *buff = (wchar_t *) malloc(len * sizeof(wchar_t));
++ wchar_t *buff2 = (wchar_t *) malloc(len * sizeof(wchar_t));
++ FILE * f = NULL;
++ MultiByteToWideChar(CP_UTF8, 0, path, -1, buff, len);
++ if (_wfullpath( buff2, buff, len ) != NULL) {
++ f = _wfopen(buff2, (strcmp(mode, "r") == 0) ? L"r" : L"rb");
++ }
++ free(buff);
++ free(buff2);
++ return f;
++ }
++#endif
++ return fopen(path, mode);
++}
++
+ HyphenDict *
+ hnj_hyphen_load (const char *fn)
+ {
+ HyphenDict *result;
+ FILE *f;
+- f = fopen (fn, "r");
++ f = hnj_fopen (fn, "r");
+ if (f == NULL)
+ return NULL;
+
diff --git a/external/icu/ExternalPackage_icu.mk b/external/icu/ExternalPackage_icu.mk
new file mode 100644
index 000000000..dcd4da216
--- /dev/null
+++ b/external/icu/ExternalPackage_icu.mk
@@ -0,0 +1,42 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+icu_VERSION := $(ICU_MAJOR).$(ICU_MINOR)$(if $(ICU_MICRO),.$(ICU_MICRO))
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,icu,icu))
+
+$(eval $(call gb_ExternalPackage_use_external_project,icu,icu))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+ifeq ($(OS),WNT)
+
+ifeq ($(COM),GCC)
+$(eval $(call gb_ExternalPackage_add_files,icu,$(LIBO_LIB_FOLDER),\
+ source/lib/icuin$(ICU_MAJOR).dll \
+))
+else
+$(eval $(call gb_ExternalPackage_add_files,icu,$(LIBO_LIB_FOLDER),\
+ source/lib/icuin$(if $(MSVC_USE_DEBUG_RUNTIME),d)$(ICU_MAJOR).dll \
+))
+endif # $(COM)
+
+else ifeq ($(OS),ANDROID)
+
+$(eval $(call gb_ExternalPackage_add_files,icu,$(LIBO_LIB_FOLDER),\
+ source/lib/libicui18nlo.so \
+))
+
+else # $(OS) != WNT/ANDROID
+
+$(eval $(call gb_ExternalPackage_add_file,icu,$(LIBO_LIB_FOLDER)/libicui18n$(gb_Library_DLLEXT).$(ICU_MAJOR),source/lib/libicui18n$(gb_Library_DLLEXT).$(icu_VERSION)))
+
+endif # $(OS)
+endif # DISABLE_DYNLOADING
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/icu/ExternalPackage_icu_ure.mk b/external/icu/ExternalPackage_icu_ure.mk
new file mode 100644
index 000000000..fefe71afd
--- /dev/null
+++ b/external/icu/ExternalPackage_icu_ure.mk
@@ -0,0 +1,48 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# libxml2 is in URE and depends on icuuc*.dll on Windows; the i18nlangtag lib is
+# in URE and depends on the icuuc lib (which in turn depends on the icudata lib)
+# on all platforms:
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,icu_ure,icu))
+
+$(eval $(call gb_ExternalPackage_use_external_project,icu_ure,icu))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+ifeq ($(OS),WNT)
+
+ifeq ($(COM),GCC)
+$(eval $(call gb_ExternalPackage_add_files,icu_ure,$(LIBO_URE_LIB_FOLDER),\
+ source/lib/icudt$(ICU_MAJOR).dll \
+ source/lib/icuuc$(ICU_MAJOR).dll \
+))
+else
+$(eval $(call gb_ExternalPackage_add_files,icu_ure,$(LIBO_URE_LIB_FOLDER),\
+ source/lib/icudt$(if $(MSVC_USE_DEBUG_RUNTIME),d)$(ICU_MAJOR).dll \
+ source/lib/icuuc$(if $(MSVC_USE_DEBUG_RUNTIME),d)$(ICU_MAJOR).dll \
+))
+endif # $(COM)
+
+else ifeq ($(OS),ANDROID)
+
+$(eval $(call gb_ExternalPackage_add_files,icu_ure,$(LIBO_URE_LIB_FOLDER),\
+ source/lib/libicudatalo.so \
+ source/lib/libicuuclo.so \
+))
+
+else # $(OS) != WNT/ANDROID
+
+$(eval $(call gb_ExternalPackage_add_file,icu_ure,$(LIBO_URE_LIB_FOLDER)/libicudata$(gb_Library_DLLEXT).$(ICU_MAJOR),source/lib/libicudata$(gb_Library_DLLEXT).$(icu_VERSION)))
+$(eval $(call gb_ExternalPackage_add_file,icu_ure,$(LIBO_URE_LIB_FOLDER)/libicuuc$(gb_Library_DLLEXT).$(ICU_MAJOR),source/lib/libicuuc$(gb_Library_DLLEXT).$(icu_VERSION)))
+
+endif # $(OS)
+endif # DISABLE_DYNLOADING
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/icu/ExternalProject_icu.mk b/external/icu/ExternalProject_icu.mk
new file mode 100644
index 000000000..d677016f9
--- /dev/null
+++ b/external/icu/ExternalProject_icu.mk
@@ -0,0 +1,100 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,icu))
+
+$(eval $(call gb_ExternalProject_register_targets,icu,\
+ build \
+))
+
+icu_CPPFLAGS:="-DHAVE_GCC_ATOMICS=$(if $(filter TRUE,$(GCC_HAVE_BUILTIN_ATOMIC)),1,0)"
+
+ifeq ($(OS),WNT)
+
+$(call gb_ExternalProject_get_state_target,icu,build) :
+ $(call gb_Trace_StartRange,icu,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ autoconf \
+ && export LIB="$(ILIB)" PYTHONWARNINGS="default" \
+ gb_ICU_XFLAGS="-FS $(SOLARINC) $(gb_DEBUGINFO_FLAGS) $(if $(MSVC_USE_DEBUG_RUNTIME),-MDd,-MD -Gy)" \
+ && CFLAGS="$${gb_ICU_XFLAGS}" CPPFLAGS="$(SOLARINC)" CXXFLAGS="$${gb_ICU_XFLAGS}" \
+ INSTALL=`cygpath -m /usr/bin/install` $(if $(MSVC_USE_DEBUG_RUNTIME),LDFLAGS="-DEBUG") \
+ $(gb_RUN_CONFIGURE) ./configure \
+ $(if $(MSVC_USE_DEBUG_RUNTIME),--enable-debug --disable-release) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING), \
+ --with-cross-build=$(WORKDIR_FOR_BUILD)/UnpackedTarball/icu/source \
+ --disable-tools --disable-extras) \
+ && $(MAKE) $(if $(CROSS_COMPILING),DATASUBDIR=data) $(if $(verbose),VERBOSE=1) \
+ ,source)
+ $(call gb_Trace_EndRange,icu,EXTERNAL)
+
+else # $(OS)
+
+icu_CFLAGS:="$(CFLAGS) \
+ $(if $(filter iOS,$(OS)),-DUCONFIG_NO_FILE_IO) \
+ $(if $(SYSBASE),-I$(SYSBASE)/usr/include) \
+ $(call gb_ExternalProject_get_build_flags,icu) \
+ $(if $(ENABLE_LTO),$(gb_LTOFLAGS)) \
+ $(if $(filter GCC,$(COM)),-fno-strict-aliasing) \
+ $(if $(filter FUZZERS,$(BUILD_TYPE)),-DU_USE_STRTOD_L=0) \
+ $(if $(filter ANDROID,$(OS)),-fvisibility=hidden -fno-omit-frame-pointer)"
+icu_CXXFLAGS:="$(CXXFLAGS) $(CXXFLAGS_CXX11) \
+ $(if $(filter iOS,$(OS)),-DUCONFIG_NO_FILE_IO) \
+ $(call gb_ExternalProject_get_build_flags,icu) \
+ $(if $(ENABLE_LTO),$(gb_LTOFLAGS)) \
+ $(if $(filter GCC,$(COM)),-fno-strict-aliasing) \
+ $(if $(filter FUZZERS,$(BUILD_TYPE)),-DU_USE_STRTOD_L=0) \
+ $(if $(filter ANDROID,$(OS)),-fvisibility=hidden -fno-omit-frame-pointer -I$(SRCDIR)/include)"
+icu_LDFLAGS:=" \
+ $(if $(ENABLE_LTO),$(gb_LTOFLAGS)) \
+ $(call gb_ExternalProject_get_link_flags,icu) \
+ $(if $(filter TRUE,$(HAVE_LD_HASH_STYLE)),-Wl$(COMMA)--hash-style=$(WITH_LINKER_HASH_STYLE)) \
+ $(if $(SYSBASE),-L../lib -L../../lib -L../stubdata -L../../stubdata -L$(SYSBASE)/usr/lib) \
+ $(if $(filter TRUE,$(HAVE_LD_BSYMBOLIC_FUNCTIONS)), -Wl$(COMMA)-Bsymbolic-functions) \
+ $(if $(filter ANDROID,$(OS)),$(gb_STDLIBS))"
+
+# DATASUBDIR=data in cross-compiling case, because --disable-tools completely skips the
+# data directory/doesn't build the requested library in that case (icu/source/Makefile.in)
+# so we need to add it back to the list of subdirectories to build
+$(call gb_ExternalProject_get_state_target,icu,build) :
+ $(call gb_Trace_StartRange,icu,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ autoconf && \
+ CPPFLAGS=$(icu_CPPFLAGS) CFLAGS=$(icu_CFLAGS) \
+ CXXFLAGS=$(icu_CXXFLAGS) LDFLAGS=$(icu_LDFLAGS) \
+ PYTHONWARNINGS="default" \
+ $(gb_RUN_CONFIGURE) ./configure \
+ --disable-layout --disable-samples \
+ $(if $(filter FUZZERS,$(BUILD_TYPE)),--disable-release) \
+ $(if $(filter EMSCRIPTEN ANDROID,$(OS)),--disable-strict ac_cv_c_bigendian=no) \
+ $(if $(filter SOLARIS AIX,$(OS)),--disable-64bit-libs) \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),\
+ --with-data-packaging=static --enable-static --disable-shared --disable-dyload,\
+ --disable-static --enable-shared $(if $(filter ANDROID,$(OS)),--with-library-suffix=lo)) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING), \
+ --with-cross-build=$(WORKDIR_FOR_BUILD)/UnpackedTarball/icu/source \
+ --disable-tools --disable-extras) \
+ AR="$(AR)" RANLIB="$(RANLIB)" \
+ && $(MAKE) $(if $(CROSS_COMPILING),DATASUBDIR=data) $(if $(verbose),VERBOSE=1) \
+ $(if $(filter MACOSX,$(OS)), \
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl \
+ URELIB \
+ $(EXTERNAL_WORKDIR)/source/lib/libicuuc$(gb_Library_DLLEXT).$(icu_VERSION) \
+ $(EXTERNAL_WORKDIR)/source/lib/libicui18n$(gb_Library_DLLEXT).$(icu_VERSION) \
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl \
+ OOO \
+ $(EXTERNAL_WORKDIR)/source/lib/libicudata$(gb_Library_DLLEXT).$(icu_VERSION)) \
+ ,source)
+ $(call gb_Trace_EndRange,icu,EXTERNAL)
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/icu/Makefile b/external/icu/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/icu/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/icu/Module_icu.mk b/external/icu/Module_icu.mk
new file mode 100644
index 000000000..5c99b930f
--- /dev/null
+++ b/external/icu/Module_icu.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,icu))
+
+$(eval $(call gb_Module_add_targets,icu,\
+ UnpackedTarball_icu \
+ ExternalPackage_icu \
+ ExternalPackage_icu_ure \
+ ExternalProject_icu \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/icu/README b/external/icu/README
new file mode 100644
index 000000000..484de1f41
--- /dev/null
+++ b/external/icu/README
@@ -0,0 +1 @@
+Library providing Unicode support, from [http://site.icu-project.org/].
diff --git a/external/icu/UnpackedTarball_icu.mk b/external/icu/UnpackedTarball_icu.mk
new file mode 100644
index 000000000..ccb1a1a8b
--- /dev/null
+++ b/external/icu/UnpackedTarball_icu.mk
@@ -0,0 +1,51 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,icu))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,icu,$(ICU_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,icu,source))
+
+# Data zip contains data/... and needs to end up in icu/source/data/...
+# Only data/misc/icudata.rc is needed for a Cygwin/MSVC build.
+$(eval $(call gb_UnpackedTarball_set_pre_action,icu,\
+ unzip -q -d source -o $(gb_UnpackedTarget_TARFILE_LOCATION)/$(ICU_DATA_TARBALL) data/misc/icudata.rc \
+))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,icu,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,icu,\
+ external/icu/icu4c-build.patch.1 \
+ external/icu/icu4c-aix.patch.1 \
+ external/icu/icu4c-warnings.patch.1 \
+ external/icu/icu4c-macosx.patch.1 \
+ external/icu/icu4c-solarisgcc.patch.1 \
+ external/icu/icu4c-mkdir.patch.1 \
+ external/icu/icu4c-ubsan.patch.1 \
+ external/icu/icu4c-scriptrun.patch.1 \
+ external/icu/icu4c-rtti.patch.1 \
+ external/icu/icu4c-clang-cl.patch.1 \
+ external/icu/gcc9.patch \
+ external/icu/c++20-comparison.patch.1 \
+ external/icu/ubsan.patch.1 \
+ external/icu/Wdeprecated-copy-dtor.patch \
+ external/icu/strict_ansi.patch \
+ external/icu/icu4c-windows-cygwin-cross.patch.1 \
+ external/icu/icu4c-emscripten-cross.patch.1 \
+ external/icu/icu4c-use-pkgdata-single-ccode-file-mode.patch.1 \
+ external/icu/do-not-reset-useful-cache-to-empty-in-populateNear.patch.2 \
+ external/icu/icu4c-khmerbreakengine.patch.1 \
+ external/icu/icu4c-$(if $(filter ANDROID,$(OS)),android,rpath).patch.1 \
+ $(if $(filter-out ANDROID,$(OS)),external/icu/icu4c-icudata-stdlibs.patch.1) \
+))
+
+$(eval $(call gb_UnpackedTarball_add_file,icu,source/data/brkitr/khmerdict.dict,external/icu/khmerdict.dict))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/icu/Wdeprecated-copy-dtor.patch b/external/icu/Wdeprecated-copy-dtor.patch
new file mode 100644
index 000000000..67078ef1b
--- /dev/null
+++ b/external/icu/Wdeprecated-copy-dtor.patch
@@ -0,0 +1,25 @@
+--- source/common/unicode/uobject.h
++++ source/common/unicode/uobject.h
+@@ -245,10 +245,10 @@
+ // direct use of UObject itself
+
+ // default constructor
+- // inline UObject() {}
++ UObject() = default;
+
+ // copy constructor
+- // inline UObject(const UObject &other) {}
++ UObject(const UObject &other) = default;
+
+ #if 0
+ // TODO Sometime in the future. Implement operator==().
+@@ -280,8 +280,8 @@
+ * Subclasses need this assignment operator if they use compiler-provided
+ * assignment operators of their own. An alternative to not declaring one
+ * here would be to declare and empty-implement a protected or public one.
+- UObject &UObject::operator=(const UObject &);
+ */
++ UObject &operator=(const UObject &) = default;
+ };
+
+ #ifndef U_HIDE_INTERNAL_API
diff --git a/external/icu/c++20-comparison.patch.1 b/external/icu/c++20-comparison.patch.1
new file mode 100644
index 000000000..3d2d7c042
--- /dev/null
+++ b/external/icu/c++20-comparison.patch.1
@@ -0,0 +1,82 @@
+diff -ur icu.org/source/i18n/unicode/rbtz.h icu/source/i18n/unicode/rbtz.h
+--- icu.org/source/i18n/unicode/rbtz.h 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/i18n/unicode/rbtz.h 2021-11-15 18:56:24.364137609 +0100
+@@ -87,6 +87,7 @@
+ * @stable ICU 3.8
+ */
+ virtual bool operator!=(const TimeZone& that) const;
++ bool operator!=(const RuleBasedTimeZone& that) const {return !operator==(that);}
+
+ /**
+ * Adds the `TimeZoneRule` which represents time transitions.
+diff -ur icu.org/source/i18n/unicode/simpletz.h icu/source/i18n/unicode/simpletz.h
+--- icu.org/source/i18n/unicode/simpletz.h 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/i18n/unicode/simpletz.h 2021-11-15 19:01:41.774487719 +0100
+@@ -112,6 +112,7 @@
+ * @stable ICU 2.0
+ */
+ virtual bool operator==(const TimeZone& that) const override;
++ bool operator!=(const SimpleTimeZone& that) const {return !operator==(that);}
+
+ /**
+ * Constructs a SimpleTimeZone with the given raw GMT offset and time zone ID,
+diff -ur icu.org/source/i18n/unicode/smpdtfmt.h icu/source/i18n/unicode/smpdtfmt.h
+--- icu.org/source/i18n/unicode/smpdtfmt.h 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/i18n/unicode/smpdtfmt.h 2021-11-15 19:02:47.382353381 +0100
+@@ -877,6 +877,7 @@
+ * @stable ICU 2.0
+ */
+ virtual bool operator==(const Format& other) const override;
++ bool operator!=(const SimpleDateFormat& that) const {return !operator==(that);}
+
+
+ using DateFormat::format;
+diff -ur icu.org/source/i18n/unicode/stsearch.h icu/source/i18n/unicode/stsearch.h
+--- icu.org/source/i18n/unicode/stsearch.h 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/i18n/unicode/stsearch.h 2021-11-15 19:03:27.014272230 +0100
+@@ -298,6 +298,7 @@
+ * @stable ICU 2.0
+ */
+ virtual bool operator==(const SearchIterator &that) const override;
++ bool operator!=(const StringSearch &that) const {return !operator==(that);}
+
+ // public get and set methods ----------------------------------------
+
+diff -ur icu.org/source/i18n/unicode/tzrule.h icu/source/i18n/unicode/tzrule.h
+--- icu.org/source/i18n/unicode/tzrule.h 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/i18n/unicode/tzrule.h 2021-11-15 19:14:52.191331967 +0100
+@@ -257,6 +257,7 @@
+ * @stable ICU 3.8
+ */
+ virtual bool operator!=(const TimeZoneRule& that) const override;
++ bool operator!=(const InitialTimeZoneRule& that) const {return !operator==(that);}
+
+ /**
+ * Gets the time when this rule takes effect in the given year.
+@@ -468,6 +469,7 @@
+ * @stable ICU 3.8
+ */
+ virtual bool operator!=(const TimeZoneRule& that) const override;
++ bool operator!=(const AnnualTimeZoneRule& that) const {return !operator==(that);}
+
+ /**
+ * Gets the start date/time rule used by this rule.
+@@ -684,6 +686,7 @@
+ * @stable ICU 3.8
+ */
+ virtual bool operator!=(const TimeZoneRule& that) const override;
++ bool operator!=(const TimeArrayTimeZoneRule& that) const {return !operator==(that);}
+
+ /**
+ * Gets the time type of the start times used by this rule. The return value
+diff -ur icu.org/source/i18n/unicode/vtzone.h icu/source/i18n/unicode/vtzone.h
+--- icu.org/source/i18n/unicode/vtzone.h 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/i18n/unicode/vtzone.h 2021-11-15 19:16:07.461130004 +0100
+@@ -83,6 +83,7 @@
+ * @stable ICU 3.8
+ */
+ virtual bool operator!=(const TimeZone& that) const;
++ bool operator!=(const VTimeZone& that) const {return !operator==(that);}
+
+ /**
+ * Create a <code>VTimeZone</code> instance by the time zone ID.
diff --git a/external/icu/cross-bin/icu-config b/external/icu/cross-bin/icu-config
new file mode 100755
index 000000000..8ccf94f9b
--- /dev/null
+++ b/external/icu/cross-bin/icu-config
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+case $1 in
+--version)
+ echo whatever
+ ;;
+--cppflags)
+ echo ${ICU_CFLAGS}
+ ;;
+--ldflags-searchpath)
+ echo ${ICU_LIBS}
+esac
diff --git a/external/icu/do-not-reset-useful-cache-to-empty-in-populateNear.patch.2 b/external/icu/do-not-reset-useful-cache-to-empty-in-populateNear.patch.2
new file mode 100644
index 000000000..bd7fe74fb
--- /dev/null
+++ b/external/icu/do-not-reset-useful-cache-to-empty-in-populateNear.patch.2
@@ -0,0 +1,37 @@
+From 34b2f7174ba187d99dfb8704b9cf19d369accc13 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= <l.lunak@centrum.cz>
+Date: Wed, 16 Mar 2022 10:54:03 +0100
+Subject: [PATCH] do not reset useful cache to empty in populateNear()
+
+---
+ icu4c/source/common/rbbi_cache.cpp | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/icu4c/source/common/rbbi_cache.cpp b/icu4c/source/common/rbbi_cache.cpp
+index 26d82df781..54a77c97c6 100644
+--- a/icu/source/common/rbbi_cache.cpp
++++ b/icu/source/common/rbbi_cache.cpp
+@@ -352,7 +352,7 @@ UBool RuleBasedBreakIterator::BreakCache
+ if ((position < fBoundaries[fStartBufIdx] - 15) || position > (fBoundaries[fEndBufIdx] + 15)) {
+ int32_t aBoundary = 0;
+ int32_t ruleStatusIndex = 0;
+- if (position > 20) {
++ if (position > 20 && false) { // handleSafePrevious() is broken and always returns 0
+ int32_t backupPos = fBI->handleSafePrevious(position);
+
+ if (backupPos > 0) {
+@@ -376,7 +376,10 @@ UBool RuleBasedBreakIterator::BreakCache::populateNear(int32_t position, UErrorC
+ ruleStatusIndex = fBI->fRuleStatusIndex;
+ }
+ }
+- reset(aBoundary, ruleStatusIndex); // Reset cache to hold aBoundary as a single starting point.
++ // Reset cache to hold aBoundary as a single starting point.
++ // Do not do so if what's in the cache is still more useful than an empty cache.
++ if (!(aBoundary == 0 && position > fBoundaries[fEndBufIdx]))
++ reset(aBoundary, ruleStatusIndex);
+ }
+
+ // Fill in boundaries between existing cache content and the new requested position.
+--
+2.34.1
+
diff --git a/external/icu/gcc9.patch b/external/icu/gcc9.patch
new file mode 100644
index 000000000..5c9808f8c
--- /dev/null
+++ b/external/icu/gcc9.patch
@@ -0,0 +1,26 @@
+--- source/i18n/unicode/format.h
++++ source/i18n/unicode/format.h
+@@ -22,6 +22,13 @@
+
+ #ifndef FORMAT_H
+ #define FORMAT_H
++
++#ifdef __GNUC__
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wpragmas" // for old GCC
++#pragma GCC diagnostic ignored "-Wunknown-warning-option" // for Clang
++#pragma GCC diagnostic ignored "-Wdeprecated-copy"
++#endif
+
+
+ #include "unicode/utypes.h"
+@@ -314,5 +314,9 @@
+
+ #endif /* U_SHOW_CPLUSPLUS_API */
+
++#ifdef __GNUC__
++#pragma GCC diagnostic pop
++#endif
++
+ #endif // _FORMAT
+ //eof
diff --git a/external/icu/icu4c-aix.patch.1 b/external/icu/icu4c-aix.patch.1
new file mode 100644
index 000000000..bcbbe3ab9
--- /dev/null
+++ b/external/icu/icu4c-aix.patch.1
@@ -0,0 +1,143 @@
+diff -ur icu.org/source/config/mh-aix-gcc icu/source/config/mh-aix-gcc
+--- icu.org/source/config/mh-aix-gcc 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/config/mh-aix-gcc 2021-11-15 18:35:48.737774348 +0100
+@@ -18,84 +18,29 @@
+ GEN_DEPS.c= $(CC) -E -MM $(DEFS) $(CPPFLAGS)
+ GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS)
+
+-## Commands to link
+-## We need to use the C++ linker, even when linking C programs, since
+-## our libraries contain C++ code (C++ static init not called)
+-LINK.c= $(AIX_PREDELETE) $(CXX) $(CXXFLAGS) $(LDFLAGS)
+-LINK.cc= $(AIX_PREDELETE) $(CXX) $(CXXFLAGS) $(LDFLAGS)
+-
+-## Shared library options
+-LD_SOOPTIONS= -Wl,-bsymbolic
+-
+-## Commands to make a shared library
+-SHLIB.c= $(AIX_PREDELETE) $(CC) $(CFLAGS) $(LDFLAGS) -shared $(LD_SOOPTIONS)
+-SHLIB.cc= $(AIX_PREDELETE) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(LD_SOOPTIONS)
+-
+-## Compiler switch to embed a runtime search path
+-LD_RPATH= -I
+-LD_RPATH_PRE=
++## Flags for position independent code
++SHAREDLIBCFLAGS = -fPIC
++SHAREDLIBCXXFLAGS = -fPIC
++SHAREDLIBCPPFLAGS = -DPIC
++
++## Additional flags when building libraries and with threads
++THREADSCPPFLAGS = -D_REENTRANT -D_THREAD_SAFE
++LIBCPPFLAGS =
+
+-## enable the shared lib loader
+-LDFLAGS += -Wl,-bbigtoc
++LD_RPATH=
++LD_RPATH_PRE=
+
+ ## These are the library specific LDFLAGS
+ LDFLAGSICUDT=-nodefaultlibs -nostdlib
+
+-## We need to delete things prior to linking, or else we'll get
+-## SEVERE ERROR: output file in use .. on AIX.
+-## But, shell script version should NOT delete target as we don't
+-## have $@ in that context. (SH = only shell script, icu-config)
+-AIX_PREDELETE=rm -f $@ ;
+-#SH# AIX_PREDELETE=
+-
+ ## Environment variable to set a runtime search path
+ LDLIBRARYPATH_ENVVAR = LIBPATH
+
+-## Override Versioned target for a shared library.
+-FINAL_SO_TARGET= $(basename $(SO_TARGET))$(SO_TARGET_VERSION).$(SO)
+-MIDDLE_SO_TARGET= $(basename $(SO_TARGET))$(SO_TARGET_VERSION_MAJOR).$(SO)
+-SHARED_OBJECT = $(notdir $(FINAL_SO_TARGET:.$(SO)=.$(SOBJ)))
+-SHARED_OBJECT_NO_VERSION = $(basename $(SO_TARGET)).$(SOBJ)
+-
+-# The following is for Makefile.inc's use.
+-ICULIBSUFFIX_VERSION = $(LIB_VERSION_MAJOR)
+-
+-# this one is for icudefs.mk's use
+-ifeq ($(ENABLE_SHARED),YES)
+-SO_TARGET_VERSION_SUFFIX = $(SO_TARGET_VERSION_MAJOR)
+-endif
+-
+-## Compiler switch to embed a library name. Not present on AIX.
+-LD_SONAME =
+-
+-## The type of assembly needed when pkgdata is used for generating shared libraries.
+-GENCCODE_ASSEMBLY=-a xlc
+-
+ ## Shared object suffix
+-SOBJ= so
+-# without the -brtl option, the library names use .a. AIX is funny that way.
+-SO= a
+-A= a
++SO= so
+
+ ## Non-shared intermediate object suffix
+-STATIC_O = o
+-
+-## Special AIX rules
+-
+-## Build archive from shared object
+-%.a : %.so
+- ln -f $< $(SHARED_OBJECT_NO_VERSION)
+- $(AR) $(ARFLAGS) $@ $(SHARED_OBJECT_NO_VERSION)
+- rm -f $(SHARED_OBJECT_NO_VERSION)
+-$(LIBDIR)/%.a : %.so
+- ln -f $< $(SHARED_OBJECT_NO_VERSION)
+- $(AR) $(ARFLAGS) $@ $(SHARED_OBJECT_NO_VERSION)
+- rm -f $(SHARED_OBJECT_NO_VERSION)
+-
+-## Build import list from export list
+-%.e : %.exp
+- @echo "Building an import list for $<"
+- @$(SHELL) -ec "echo '#! $*.a($*.so)' | cat - $< > $@"
++STATIC_O = ao
+
+ ## Compilation rules
+ %.$(STATIC_O): $(srcdir)/%.c
+@@ -123,10 +68,10 @@
+ [ -s $@ ] || rm -f $@'
+
+ ## Versioned libraries rules
+-%$(SO_TARGET_VERSION_MAJOR).$(SO): %$(SO_TARGET_VERSION).$(SO)
+- $(RM) $@ && ln -s ${*F}$(SO_TARGET_VERSION).$(SO) $@
+-%.$(SO): %$(SO_TARGET_VERSION).$(SO)
+- $(RM) $@ && ln -s ${*F}$(SO_TARGET_VERSION).$(SO) $@
++%.$(SO).$(SO_TARGET_VERSION_MAJOR): %.$(SO).$(SO_TARGET_VERSION)
++ $(RM) $@ && ln -s ${<F} $@
++%.$(SO): %.$(SO).$(SO_TARGET_VERSION_MAJOR)
++ $(RM) $@ && ln -s ${*F}.$(SO).$(SO_TARGET_VERSION) $@
+
+
+ ## BIR - bind with internal references [so app data and icu data doesn't collide]
+diff -ur icu.org/source/tools/pkgdata/pkgdata.cpp icu/source/tools/pkgdata/pkgdata.cpp
+--- icu.org/source/tools/pkgdata/pkgdata.cpp 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/tools/pkgdata/pkgdata.cpp 2021-11-15 18:28:38.342143852 +0100
+@@ -959,7 +959,7 @@
+
+ uprv_strcat(pkgDataFlags[SO_EXT], ".");
+ uprv_strcat(pkgDataFlags[SO_EXT], pkgDataFlags[A_EXT]);
+-#elif U_PLATFORM == U_PF_OS400 || defined(_AIX)
++#elif U_PLATFORM == U_PF_OS400
+ sprintf(libFileNames[LIB_FILE_VERSION_TMP], "%s%s%s",
+ libFileNames[LIB_FILE],
+ FILE_EXTENSION_SEP,
+@@ -1439,15 +1439,6 @@
+ pkgDataFlags[LDICUDTFLAGS],
+ targetDir,
+ libFileNames[LIB_FILE_CYGWIN_VERSION],
+-#elif U_PLATFORM == U_PF_AIX
+- sprintf(cmd, "%s %s%s;%s %s -o %s%s %s %s%s %s %s",
+- RM_CMD,
+- targetDir,
+- libFileNames[LIB_FILE_VERSION_TMP],
+- pkgDataFlags[GENLIB],
+- pkgDataFlags[LDICUDTFLAGS],
+- targetDir,
+- libFileNames[LIB_FILE_VERSION_TMP],
+ #else
+ sprintf(cmd, "%s %s -o %s%s %s %s%s %s %s",
+ pkgDataFlags[GENLIB],
diff --git a/external/icu/icu4c-android.patch.1 b/external/icu/icu4c-android.patch.1
new file mode 100644
index 000000000..9ba252b40
--- /dev/null
+++ b/external/icu/icu4c-android.patch.1
@@ -0,0 +1,75 @@
+diff -ur icu.org/source/common/unicode/platform.h icu/source/common/unicode/platform.h
+--- icu.org/source/common/unicode/platform.h 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/common/unicode/platform.h 2021-11-15 21:03:11.474638494 +0100
+@@ -818,7 +818,7 @@
+ UPRV_HAS_DECLSPEC_ATTRIBUTE(__dllimport__))
+ # define U_EXPORT __declspec(dllexport)
+ #elif defined(__GNUC__)
+-# define U_EXPORT __attribute__((visibility("default")))
++# define U_EXPORT
+ #elif (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x550) \
+ || (defined(__SUNPRO_C) && __SUNPRO_C >= 0x550)
+ # define U_EXPORT __global
+diff -ur icu.org/source/config/mh-linux icu/source/config/mh-linux
+--- icu.org/source/config/mh-linux 2021-11-15 20:56:39.460705065 +0100
++++ icu/source/config/mh-linux 2021-11-15 21:03:11.474638494 +0100
+@@ -27,7 +27,7 @@
+
+ ## Compiler switch to embed a library name
+ # The initial tab in the next line is to prevent icu-config from reading it.
+- LD_SONAME = -Wl,-soname -Wl,$(notdir $(MIDDLE_SO_TARGET))
++ #LD_SONAME = -Wl,-soname -Wl,$(notdir $(MIDDLE_SO_TARGET))
+ #SH# # We can't depend on MIDDLE_SO_TARGET being set.
+ #SH# LD_SONAME=
+
+diff -ur icu.org/source/configure icu/source/configure
+--- icu.org/source/configure 2021-11-15 20:56:39.875703936 +0100
++++ icu/source/configure 2021-11-15 21:03:11.475638491 +0100
+@@ -5272,7 +5273,7 @@
+ else
+ icu_cv_host_frag=mh-linux-va
+ fi ;;
+-*-*-linux*|*-*-gnu|*-*-k*bsd*-gnu|*-*-kopensolaris*-gnu) icu_cv_host_frag=mh-linux ;;
++*-*-linux*|*-*-gnu|*-*-k*bsd*-gnu|*-*-kopensolaris*-gnu|*-*-*-androideabi*) icu_cv_host_frag=mh-linux ;;
+ i[34567]86-*-cygwin)
+ if test "$GCC" = yes; then
+ icu_cv_host_frag=mh-cygwin
+@@ -6472,6 +6466,10 @@
+ # Check to see if genccode can generate simple assembly.
+ GENCCODE_ASSEMBLY=
+ case "${host}" in
++arm-*-linux-androideabi)
++ if test "$GCC" = yes; then
++ GENCCODE_ASSEMBLY="-a gcc-android-arm"
++ fi ;;
+ *-linux*|*-kfreebsd*-gnu*|i*86-*-*bsd*|i*86-pc-gnu)
+ if test "$GCC" = yes; then
+ # We're using gcc, and the simple -a gcc command line works for genccode
+@@ -7594,6 +7592,10 @@
+ # wchar_t can be used
+ CHECK_UTF16_STRING_RESULT="available"
+ ;;
++*-*-*-androideabi|mips-unknown-linux-android)
++ # no UTF-16 strings thanks, I think, this is to avoid the -std=c++0x which causes trouble with uint64_t
++ CHECK_UTF16_STRING_RESULT="nope"
++ ;;
+ *)
+ ;;
+ esac
+diff -ur icu.org/source/i18n/decimfmt.cpp icu/source/i18n/decimfmt.cpp
+--- icu.org/source/i18n/decimfmt.cpp 2021-10-28 18:04:57.000000000 +0200
++++ icu/source/i18n/decimfmt.cpp 2021-11-15 21:03:11.476638489 +0100
+@@ -9,6 +9,13 @@
+ // Helpful in toString methods and elsewhere.
+ #define UNISTR_FROM_STRING_EXPLICIT
+
++#ifdef __ANDROID__
++#ifndef ARM
++#define ARM
++#endif
++#include <android/compatibility.hxx>
++#endif
++
+ #include <cmath>
+ #include <cstdlib>
+ #include <stdlib.h>
diff --git a/external/icu/icu4c-build.patch.1 b/external/icu/icu4c-build.patch.1
new file mode 100644
index 000000000..a878de732
--- /dev/null
+++ b/external/icu/icu4c-build.patch.1
@@ -0,0 +1,91 @@
+diff -ur icu.org/source/config/mh-darwin icu/source/config/mh-darwin
+--- icu.org/source/config/mh-darwin 2016-06-15 20:58:17.000000000 +0200
++++ icu/source/config/mh-darwin 2017-04-21 21:30:23.584568210 +0200
+@@ -30,11 +30,7 @@
+ SHLIB.cc= $(CXX) -dynamiclib -dynamic $(CXXFLAGS) $(LDFLAGS) $(LD_SOOPTIONS)
+
+ ## Compiler switches to embed a library name and version information
+-ifeq ($(ENABLE_RPATH),YES)
+-LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name $(libdir)/$(notdir $(MIDDLE_SO_TARGET))
+-else
+-LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name $(notdir $(MIDDLE_SO_TARGET)) $(PKGDATA_TRAILING_SPACE)
+-endif
++LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name @__________________________________________________URELIB/$(notdir $(MIDDLE_SO_TARGET))
+
+ ## Compiler switch to embed a runtime search path
+ LD_RPATH=
+@@ -50,10 +46,6 @@
+ ## Non-shared intermediate object suffix
+ STATIC_O = ao
+
+-## Override Versioned target for a shared library.
+-FINAL_SO_TARGET= $(basename $(SO_TARGET)).$(SO_TARGET_VERSION).$(SO)
+-MIDDLE_SO_TARGET= $(basename $(SO_TARGET)).$(SO_TARGET_VERSION_MAJOR).$(SO)
+-
+ ## Compilation and dependency rules
+ %.$(STATIC_O): $(srcdir)/%.c
+ $(call SILENT_COMPILE,$(strip $(COMPILE.c) $(STATICCPPFLAGS) $(STATICCFLAGS)) -MMD -MT "$*.d $*.o $*.$(STATIC_O)" -o $@ $<)
+@@ -67,16 +59,10 @@
+
+ ## Versioned libraries rules
+
+-%.$(SO_TARGET_VERSION_MAJOR).$(SO): %.$(SO_TARGET_VERSION).$(SO)
++%.$(SO).$(SO_TARGET_VERSION_MAJOR): %.$(SO).$(SO_TARGET_VERSION)
+ $(RM) $@ && ln -s ${<F} $@
+-%.$(SO): %.$(SO_TARGET_VERSION_MAJOR).$(SO)
+- $(RM) $@ && ln -s ${*F}.$(SO_TARGET_VERSION).$(SO) $@
+-
+-# tzcode option
+-TZORIG_EXTRA_CFLAGS=-DSTD_INSPIRED
+-
+-# genren opts
+-GENREN_PL_OPTS=-x Mach-O -n '-g' -p '| c++filt'
++%.$(SO): %.$(SO).$(SO_TARGET_VERSION_MAJOR)
++ $(RM) $@ && ln -s ${*F}.$(SO).$(SO_TARGET_VERSION) $@
+
+ ## Remove shared library 's'
+ STATIC_PREFIX_WHEN_USED =
+diff -ur icu.org/source/tools/toolutil/pkg_genc.cpp icu/source/tools/toolutil/pkg_genc.cpp
+--- icu.org/source/tools/toolutil/pkg_genc.cpp 2017-04-13 11:46:02.000000000 +0200
++++ icu/source/tools/toolutil/pkg_genc.cpp 2017-04-21 21:30:23.583568212 +0200
+@@ -160,6 +160,28 @@
+
+ ".long ","",HEX_0X
+ },
++ {"gcc-android-arm",
++ "\t.arch armv5te\n"
++ "\t.fpu softvfp\n"
++ "\t.eabi_attribute 20, 1\n"
++ "\t.eabi_attribute 21, 1\n"
++ "\t.eabi_attribute 23, 3\n"
++ "\t.eabi_attribute 24, 1\n"
++ "\t.eabi_attribute 25, 1\n"
++ "\t.eabi_attribute 26, 2\n"
++ "\t.eabi_attribute 30, 6\n"
++ "\t.eabi_attribute 18, 4\n"
++ "\t.file \"%s.s\"\n"
++ "\t.global %s\n"
++ "\t.section .rodata\n"
++ "\t.align 2\n"
++ "\t.type %s, %%object\n"
++ "%s:\n",
++
++ "\t.word ",
++ "\t.section .note.GNU-stack,\"\",%%progbits\n",
++ HEX_0X
++ },
+ /* 16 bytes alignment. */
+ /* http://docs.oracle.com/cd/E19641-01/802-1947/802-1947.pdf */
+ {"sun",
+diff -ur icu.org/source/tools/toolutil/pkg_genc.h icu/source/tools/toolutil/pkg_genc.h
+--- icu.org/source/tools/toolutil/pkg_genc.h 2017-01-20 01:20:31.000000000 +0100
++++ icu/source/tools/toolutil/pkg_genc.h 2017-04-21 21:30:23.582568215 +0200
+@@ -60,7 +60,7 @@
+ #endif
+
+ #define LARGE_BUFFER_MAX_SIZE 2048
+-#define SMALL_BUFFER_MAX_SIZE 512
++#define SMALL_BUFFER_MAX_SIZE 2048
+ #define SMALL_BUFFER_FLAG_NAMES 32
+ #define BUFFER_PADDING_SIZE 20
+
diff --git a/external/icu/icu4c-clang-cl.patch.1 b/external/icu/icu4c-clang-cl.patch.1
new file mode 100644
index 000000000..a111a0df9
--- /dev/null
+++ b/external/icu/icu4c-clang-cl.patch.1
@@ -0,0 +1,28 @@
+diff -ur icu.org/source/config/mh-cygwin-msvc icu/source/config/mh-cygwin-msvc
+--- icu.org/source/config/mh-cygwin-msvc 2017-01-23 01:38:28.000000000 +0100
++++ icu/source/config/mh-cygwin-msvc 2017-04-21 23:07:28.482892025 +0200
+@@ -55,8 +55,8 @@
+ LDFLAGS+=-nologo
+
+ # Commands to compile
+-COMPILE.c= $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c
+-COMPILE.cc= $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c
++COMPILE.c= true && $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c
++COMPILE.cc= true && $(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c
+
+ # Commands to link
+ LINK.c= LINK.EXE -subsystem:console $(LDFLAGS)
+diff -ur icu.org/source/runConfigureICU icu/source/runConfigureICU
+--- icu.org/source/runConfigureICU 2017-01-23 01:38:28.000000000 +0100
++++ icu/source/runConfigureICU 2017-04-21 23:07:28.482892025 +0200
+@@ -261,8 +261,8 @@
+ Cygwin/MSVC)
+ THE_OS="Windows with Cygwin"
+ THE_COMP="Microsoft Visual C++"
+- CC=cl; export CC
+- CXX=cl; export CXX
++ CC=${CC-cl}; export CC
++ CXX=${CXX-cl}; export CXX
+ RELEASE_CFLAGS='-Gy -MD'
+ RELEASE_CXXFLAGS='-Gy -MD'
+ DEBUG_CFLAGS='-FS -Zi -MDd'
diff --git a/external/icu/icu4c-emscripten-cross.patch.1 b/external/icu/icu4c-emscripten-cross.patch.1
new file mode 100644
index 000000000..84c88a68a
--- /dev/null
+++ b/external/icu/icu4c-emscripten-cross.patch.1
@@ -0,0 +1,99 @@
+--- icu/source/acinclude.m4.orig 2020-04-22 22:04:20.000000000 +0200
++++ icu/source/acinclude.m4 2020-11-04 06:10:29.993070072 +0100
+@@ -84,6 +84,7 @@
+ *-dec-osf*) icu_cv_host_frag=mh-alpha-osf ;;
+ *-*-nto*) icu_cv_host_frag=mh-qnx ;;
+ *-ncr-*) icu_cv_host_frag=mh-mpras ;;
++wasm*-*-emscripten*) icu_cv_host_frag=mh-emscripten ;;
+ *) icu_cv_host_frag=mh-unknown ;;
+ esac
+ ]
+--- /dev/null
++++ icu/source/config/mh-emscripten 2015-10-06 12:01:00.497972406 +0200
+@@ -0,0 +1,86 @@
++## Emscripten-specific setup
++## Copyright (c) 1999-2013, International Business Machines Corporation and
++## others. All Rights Reserved.
++## Commands to generate dependency files
++GEN_DEPS.c= $(CC) -E -MM $(DEFS) $(CPPFLAGS)
++GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS) $(CXXFLAGS)
++
++## Flags for position independent code
++SHAREDLIBCFLAGS = -fPIC
++SHAREDLIBCXXFLAGS = -fPIC
++SHAREDLIBCPPFLAGS = -DPIC
++
++## Additional flags when building libraries and with threads
++THREADSCPPFLAGS = -D_REENTRANT
++LIBCPPFLAGS =
++
++## Compiler switch to embed a runtime search path
++LD_RPATH= -Wl,-zorigin,-rpath,'$$'ORIGIN
++LD_RPATH_PRE = -Wl,-rpath,
++
++## Force RPATH=$ORIGIN to locate own dependencies w/o need for LD_LIBRARY_PATH:
++ENABLE_RPATH=YES
++RPATHLDFLAGS=${LD_RPATH_PRE}'$$ORIGIN'
++
++## These are the library specific LDFLAGS
++#LDFLAGSICUDT=-nodefaultlibs -nostdlib
++# Debian change: linking icudata as data only causes too many problems.
++LDFLAGSICUDT=
++
++## Compiler switch to embed a library name
++# The initial tab in the next line is to prevent icu-config from reading it.
++ LD_SONAME = -Wl,-soname -Wl,$(notdir $(MIDDLE_SO_TARGET))
++#SH# # We can't depend on MIDDLE_SO_TARGET being set.
++#SH# LD_SONAME=
++
++## Shared library options
++LD_SOOPTIONS= -Wl,-Bsymbolic-functions
++
++## Shared object suffix
++SO = so
++## Non-shared intermediate object suffix
++STATIC_O = o
++
++## Compilation rules
++# WASM needs -pthread for atomics support
++%.$(STATIC_O): $(srcdir)/%.c
++ $(call SILENT_COMPILE,$(strip $(COMPILE.c) $(STATICCPPFLAGS) $(STATICCFLAGS)) -pthread -o $@ $<)
++
++%.$(STATIC_O): $(srcdir)/%.cpp
++ $(call SILENT_COMPILE,$(strip $(COMPILE.cc) $(STATICCPPFLAGS) $(STATICCXXFLAGS)) -pthread -o $@ $<)
++
++
++## Dependency rules
++%.d: $(srcdir)/%.c
++ $(call ICU_MSG,(deps)) $<
++ @$(SHELL) -ec '$(GEN_DEPS.c) $< \
++ | sed '\''s%\($*\)\.o[ :]*%\1.o $@ : %g'\'' > $@; \
++ [ -s $@ ] || rm -f $@'
++
++%.d: $(srcdir)/%.cpp
++ $(call ICU_MSG,(deps)) $<
++ @$(SHELL) -ec '$(GEN_DEPS.cc) $< \
++ | sed '\''s%\($*\)\.o[ :]*%\1.o $@ : %g'\'' > $@; \
++ [ -s $@ ] || rm -f $@'
++
++## Versioned libraries rules
++
++%.$(SO).$(SO_TARGET_VERSION_MAJOR): %.$(SO).$(SO_TARGET_VERSION)
++ $(RM) $@ && ln -s ${<F} $@
++%.$(SO): %.$(SO).$(SO_TARGET_VERSION_MAJOR)
++ $(RM) $@ && ln -s ${*F}.$(SO).$(SO_TARGET_VERSION) $@
++
++## Bind internal references
++
++# LDflags that pkgdata will use
++BIR_LDFLAGS= -Wl,-Bsymbolic
++
++# Dependencies [i.e. map files] for the final library
++BIR_DEPS=
++
++## Remove shared library 's'
++STATIC_PREFIX_WHEN_USED =
++STATIC_PREFIX =
++
++## without assembly
++PKGDATA_OPTS = -O $(top_builddir)/data/icupkg.inc -w
diff --git a/external/icu/icu4c-icudata-stdlibs.patch.1 b/external/icu/icu4c-icudata-stdlibs.patch.1
new file mode 100644
index 000000000..c8d66c6ed
--- /dev/null
+++ b/external/icu/icu4c-icudata-stdlibs.patch.1
@@ -0,0 +1,14 @@
+diff -ur icu.org/source/config/mh-linux icu/source/config/mh-linux
+--- icu.org/source/config/mh-linux 2017-04-21 23:09:57.588533707 +0200
++++ icu/source/config/mh-linux 2017-04-21 23:11:38.075292226 +0200
+@@ -27,7 +27,9 @@
+ RPATHLDFLAGS=${LD_RPATH_PRE}'$$ORIGIN'
+
+ ## These are the library specific LDFLAGS
+-LDFLAGSICUDT=-nodefaultlibs -nostdlib
++#LDFLAGSICUDT=-nodefaultlibs -nostdlib
++# Debian change: linking icudata as data only causes too many problems.
++LDFLAGSICUDT=
+
+ ## Compiler switch to embed a library name
+ # The initial tab in the next line is to prevent icu-config from reading it.
diff --git a/external/icu/icu4c-khmerbreakengine.patch.1 b/external/icu/icu4c-khmerbreakengine.patch.1
new file mode 100644
index 000000000..ea8f20f44
--- /dev/null
+++ b/external/icu/icu4c-khmerbreakengine.patch.1
@@ -0,0 +1,836 @@
+diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
+--- icu.org/source/common/dictbe.cpp 2022-04-08 00:41:55.000000000 +0200
++++ icu/source/common/dictbe.cpp 2022-05-16 13:56:43.426870900 +0200
+@@ -35,7 +35,19 @@
+ ******************************************************************
+ */
+
+-DictionaryBreakEngine::DictionaryBreakEngine() {
++DictionaryBreakEngine::DictionaryBreakEngine()
++ : fTypes(0), clusterLimit(0) {
++}
++
++DictionaryBreakEngine::DictionaryBreakEngine(uint32_t breakTypes)
++ : fTypes(breakTypes), clusterLimit(3) {
++ UErrorCode status = U_ZERO_ERROR;
++ fViramaSet.applyPattern(UnicodeString(u"[[:ccc=VR:]]"), status);
++
++ // note Skip Sets contain fIgnoreSet characters too.
++ fSkipStartSet.applyPattern(UnicodeString(u"[[:lb=OP:][:lb=QU:]\\u200C\\u200D\\u2060]"), status);
++ fSkipEndSet.applyPattern(UnicodeString(u"[[:lb=CP:][:lb=QU:][:lb=EX:][:lb=CL:]\\u200C\\u200D\\u2060]"), status);
++ fNBeforeSet.applyPattern(UnicodeString(u"[[:lb=CR:][:lb=LF:][:lb=NL:][:lb=SP:][:lb=ZW:][:lb=IS:][:lb=BA:][:lb=NS:]]"), status);
+ }
+
+ DictionaryBreakEngine::~DictionaryBreakEngine() {
+@@ -85,6 +97,169 @@
+ fSet.compact();
+ }
+
++bool
++DictionaryBreakEngine::scanBeforeStart(UText *text, int32_t& start, bool &doBreak) const {
++ UErrorCode status = U_ZERO_ERROR;
++ UText* ut = utext_clone(NULL, text, false, true, &status);
++ utext_setNativeIndex(ut, start);
++ UChar32 c = utext_current32(ut);
++ bool res = false;
++ doBreak = true;
++ while (start >= 0) {
++ if (!fSkipStartSet.contains(c)) {
++ res = (c == ZWSP);
++ break;
++ }
++ --start;
++ c = utext_previous32(ut);
++ doBreak = false;
++ }
++ utext_close(ut);
++ return res;
++}
++
++bool
++DictionaryBreakEngine::scanAfterEnd(UText *text, int32_t textEnd, int32_t& end, bool &doBreak) const {
++ UErrorCode status = U_ZERO_ERROR;
++ UText* ut = utext_clone(NULL, text, false, true, &status);
++ utext_setNativeIndex(ut, end);
++ UChar32 c = utext_current32(ut);
++ bool res = false;
++ doBreak = !fNBeforeSet.contains(c);
++ while (end < textEnd) {
++ if (!fSkipEndSet.contains(c)) {
++ res = (c == ZWSP);
++ break;
++ }
++ ++end;
++ c = utext_next32(ut);
++ doBreak = false;
++ }
++ utext_close(ut);
++ return res;
++}
++
++void
++DictionaryBreakEngine::scanBackClusters(UText *text, int32_t textStart, int32_t& start) const {
++ UChar32 c = 0;
++ start = utext_getNativeIndex(text);
++ while (start > textStart) {
++ c = utext_previous32(text);
++ --start;
++ if (!fSkipEndSet.contains(c))
++ break;
++ }
++ for (int i = 0; i < clusterLimit; ++i) { // scan backwards clusterLimit clusters
++ while (start > textStart) {
++ while (fIgnoreSet.contains(c))
++ c = utext_previous32(text);
++ if (!fMarkSet.contains(c)) {
++ if (fBaseSet.contains(c)) {
++ c = utext_previous32(text);
++ if (!fViramaSet.contains(c)) { // Virama (e.g. coeng) preceding base. Treat sequence as a mark
++ utext_next32(text);
++ c = utext_current32(text);
++ break;
++ } else {
++ --start;
++ }
++ } else {
++ break;
++ }
++ }
++ c = utext_previous32(text);
++ --start;
++ }
++ if (!fBaseSet.contains(c) || start < textStart) { // not a cluster start so finish
++ break;
++ }
++ c = utext_previous32(text);
++ --start; // go round again
++ } // ignore hitting previous inhibitor since scanning for it should have found us!
++ ++start; // counteract --before
++}
++
++void
++DictionaryBreakEngine::scanFwdClusters(UText *text, int32_t textEnd, int32_t& end) const {
++ UChar32 c = utext_current32(text);
++ end = utext_getNativeIndex(text);
++ while (end < textEnd) {
++ if (!fSkipStartSet.contains(c))
++ break;
++ utext_next32(text);
++ c = utext_current32(text);
++ ++end;
++ }
++ for (int i = 0; i < clusterLimit; ++i) { // scan forwards clusterLimit clusters
++ while (fIgnoreSet.contains(c)) {
++ utext_next32(text);
++ c = utext_current32(text);
++ }
++ if (fBaseSet.contains(c)) {
++ while (end < textEnd) {
++ utext_next32(text);
++ c = utext_current32(text);
++ ++end;
++ if (!fMarkSet.contains(c))
++ break;
++ else if (fViramaSet.contains(c)) { // handle coeng + base as mark
++ utext_next32(text);
++ c = utext_current32(text);
++ ++end;
++ if (!fBaseSet.contains(c))
++ break;
++ }
++ }
++ } else {
++ --end; // bad char so break after char before it
++ break;
++ }
++ }
++}
++
++bool
++DictionaryBreakEngine::scanWJ(UText *text, int32_t &start, int32_t end, int32_t &before, int32_t &after) const {
++ UErrorCode status = U_ZERO_ERROR;
++ UText* ut = utext_clone(NULL, text, false, true, &status);
++ int32_t nat = start;
++ utext_setNativeIndex(ut, nat);
++ bool foundFirst = true;
++ int32_t curr = start;
++ while (nat < end) {
++ UChar32 c = utext_current32(ut);
++ if (c == ZWSP || c == WJ) {
++ curr = nat + 1;
++ if (foundFirst) // only scan backwards for first inhibitor
++ scanBackClusters(ut, start, before);
++ foundFirst = false; // don't scan backwards if we go around again. Also marks found something
++
++ utext_next32(ut);
++ scanFwdClusters(ut, end, after);
++ nat = after + 1;
++
++ if (c == ZWSP || c == WJ) { // did we hit another one?
++ continue;
++ } else {
++ break;
++ }
++ }
++
++ ++nat; // keep hunting
++ utext_next32(ut);
++ }
++
++ utext_close(ut);
++
++ if (nat >= end && foundFirst) {
++ start = before = after = nat;
++ return false; // failed to find anything
++ }
++ else {
++ start = curr;
++ }
++ return true; // yup hit one
++}
++
+ /*
+ ******************************************************************
+ * PossibleWord
+@@ -114,7 +289,7 @@
+ ~PossibleWord() {}
+
+ // Fill the list of candidates if needed, select the longest, and return the number found
+- int32_t candidates( UText *text, DictionaryMatcher *dict, int32_t rangeEnd );
++ int32_t candidates( UText *text, DictionaryMatcher *dict, int32_t rangeEnd, UnicodeSet const *ignoreSet = NULL, int32_t minLength = 0 );
+
+ // Select the currently marked candidate, point after it in the text, and invalidate self
+ int32_t acceptMarked( UText *text );
+@@ -135,12 +310,12 @@
+ };
+
+
+-int32_t PossibleWord::candidates( UText *text, DictionaryMatcher *dict, int32_t rangeEnd ) {
++int32_t PossibleWord::candidates( UText *text, DictionaryMatcher *dict, int32_t rangeEnd, UnicodeSet const *ignoreSet, int32_t minLength) {
+ // TODO: If getIndex is too slow, use offset < 0 and add discardAll()
+ int32_t start = (int32_t)utext_getNativeIndex(text);
+ if (start != offset) {
+ offset = start;
+- count = dict->matches(text, rangeEnd-start, UPRV_LENGTHOF(cuLengths), cuLengths, cpLengths, NULL, &prefix);
++ count = dict->matches(text, rangeEnd-start, UPRV_LENGTHOF(cuLengths), cuLengths, cpLengths, NULL, &prefix, ignoreSet, minLength);
+ // Dictionary leaves text after longest prefix, not longest word. Back up.
+ if (count <= 0) {
+ utext_setNativeIndex(text, start);
+@@ -814,53 +989,30 @@
+ * KhmerBreakEngine
+ */
+
+-// How many words in a row are "good enough"?
+-static const int32_t KHMER_LOOKAHEAD = 3;
+-
+-// Will not combine a non-word with a preceding dictionary word longer than this
+-static const int32_t KHMER_ROOT_COMBINE_THRESHOLD = 3;
+-
+-// Will not combine a non-word that shares at least this much prefix with a
+-// dictionary word, with a preceding word
+-static const int32_t KHMER_PREFIX_COMBINE_THRESHOLD = 3;
+-
+-// Minimum word size
+-static const int32_t KHMER_MIN_WORD = 2;
+-
+-// Minimum number of characters for two words
+-static const int32_t KHMER_MIN_WORD_SPAN = KHMER_MIN_WORD * 2;
+-
+ KhmerBreakEngine::KhmerBreakEngine(DictionaryMatcher *adoptDictionary, UErrorCode &status)
+- : DictionaryBreakEngine(),
++ : DictionaryBreakEngine((1 << UBRK_WORD) | (1 << UBRK_LINE)),
+ fDictionary(adoptDictionary)
+ {
+ UTRACE_ENTRY(UTRACE_UBRK_CREATE_BREAK_ENGINE);
+ UTRACE_DATA1(UTRACE_INFO, "dictbe=%s", "Khmr");
+- UnicodeSet khmerWordSet(UnicodeString(u"[[:Khmr:]&[:LineBreak=SA:]]"), status);
++
++ clusterLimit = 3;
++
++ UnicodeSet khmerWordSet(UnicodeString(u"[[:Khmr:]\\u2060\\u200C\\u200D]"), status);
+ if (U_SUCCESS(status)) {
+ setCharacters(khmerWordSet);
+ }
+ fMarkSet.applyPattern(UnicodeString(u"[[:Khmr:]&[:LineBreak=SA:]&[:M:]]"), status);
+- fMarkSet.add(0x0020);
+- fEndWordSet = khmerWordSet;
+- fBeginWordSet.add(0x1780, 0x17B3);
+- //fBeginWordSet.add(0x17A3, 0x17A4); // deprecated vowels
+- //fEndWordSet.remove(0x17A5, 0x17A9); // Khmer independent vowels that can't end a word
+- //fEndWordSet.remove(0x17B2); // Khmer independent vowel that can't end a word
+- fEndWordSet.remove(0x17D2); // KHMER SIGN COENG that combines some following characters
+- //fEndWordSet.remove(0x17B6, 0x17C5); // Remove dependent vowels
+-// fEndWordSet.remove(0x0E31); // MAI HAN-AKAT
+-// fEndWordSet.remove(0x0E40, 0x0E44); // SARA E through SARA AI MAIMALAI
+-// fBeginWordSet.add(0x0E01, 0x0E2E); // KO KAI through HO NOKHUK
+-// fBeginWordSet.add(0x0E40, 0x0E44); // SARA E through SARA AI MAIMALAI
+-// fSuffixSet.add(THAI_PAIYANNOI);
+-// fSuffixSet.add(THAI_MAIYAMOK);
++ fIgnoreSet.add(0x2060); // WJ
++ fIgnoreSet.add(0x200C, 0x200D); // ZWJ, ZWNJ
++ fBaseSet.applyPattern(UnicodeString(u"[[:Khmr:]&[:lb=SA:]&[:^M:]]"), status);
++ fPuncSet.applyPattern(UnicodeString(u"[\\u17D4\\u17D5\\u17D6\\u17D7\\u17D9:]"), status);
+
+ // Compact for caching.
+ fMarkSet.compact();
+- fEndWordSet.compact();
+- fBeginWordSet.compact();
+-// fSuffixSet.compact();
++ fIgnoreSet.compact();
++ fBaseSet.compact();
++ fPuncSet.compact();
+ UTRACE_EXIT_STATUS(status);
+ }
+
+@@ -876,175 +1028,205 @@
+ UBool /* isPhraseBreaking */,
+ UErrorCode& status ) const {
+ if (U_FAILURE(status)) return 0;
+- if ((rangeEnd - rangeStart) < KHMER_MIN_WORD_SPAN) {
+- return 0; // Not enough characters for two words
++ uint32_t wordsFound = foundBreaks.size();
++ int32_t before = 0;
++ int32_t after = 0;
++ int32_t finalBefore = 0;
++ int32_t initAfter = 0;
++ int32_t scanStart = rangeStart;
++ int32_t scanEnd = rangeEnd;
++
++ bool startZwsp = false;
++ bool breakStart = false;
++ bool breakEnd = false;
++
++ if (rangeStart > 0) {
++ --scanStart;
++ startZwsp = scanBeforeStart(text, scanStart, breakStart);
+ }
+
+- uint32_t wordsFound = 0;
+- int32_t cpWordLength = 0;
+- int32_t cuWordLength = 0;
+- int32_t current;
+- PossibleWord words[KHMER_LOOKAHEAD];
+-
+ utext_setNativeIndex(text, rangeStart);
++ scanFwdClusters(text, rangeEnd, initAfter);
++ bool endZwsp = scanAfterEnd(text, utext_nativeLength(text), scanEnd, breakEnd);
++ utext_setNativeIndex(text, rangeEnd - 1);
++ scanBackClusters(text, rangeStart, finalBefore);
++ if (finalBefore < initAfter) { // the whole run is tented so no breaks
++ if (breakStart || fTypes < UBRK_LINE)
++ foundBreaks.push(rangeStart, status);
++ if (breakEnd || fTypes < UBRK_LINE)
++ foundBreaks.push(rangeEnd, status);
++ return foundBreaks.size() - wordsFound;
++ }
+
+- while (U_SUCCESS(status) && (current = (int32_t)utext_getNativeIndex(text)) < rangeEnd) {
+- cuWordLength = 0;
+- cpWordLength = 0;
+-
+- // Look for candidate words at the current position
+- int32_t candidates = words[wordsFound%KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
+-
+- // If we found exactly one, use that
+- if (candidates == 1) {
+- cuWordLength = words[wordsFound % KHMER_LOOKAHEAD].acceptMarked(text);
+- cpWordLength = words[wordsFound % KHMER_LOOKAHEAD].markedCPLength();
+- wordsFound += 1;
+- }
++ scanStart = rangeStart;
++ scanWJ(text, scanStart, rangeEnd, before, after);
++ if (startZwsp || initAfter >= before) {
++ after = initAfter;
++ before = 0;
++ }
++ if (!endZwsp && after > finalBefore && after < rangeEnd)
++ endZwsp = true;
++ if (endZwsp && before > finalBefore)
++ before = finalBefore;
+
+- // If there was more than one, see which one can take us forward the most words
+- else if (candidates > 1) {
+- // If we're already at the end of the range, we're done
+- if ((int32_t)utext_getNativeIndex(text) >= rangeEnd) {
+- goto foundBest;
+- }
+- do {
+- if (words[(wordsFound + 1) % KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd) > 0) {
+- // Followed by another dictionary word; mark first word as a good candidate
+- words[wordsFound % KHMER_LOOKAHEAD].markCurrent();
++ utext_setNativeIndex(text, rangeStart);
++ int32_t numCodePts = rangeEnd - rangeStart;
++ // bestSnlp[i] is the snlp of the best segmentation of the first i
++ // code points in the range to be matched.
++ UVector32 bestSnlp(numCodePts + 1, status);
++ bestSnlp.addElement(0, status);
++ for(int32_t i = 1; i <= numCodePts; i++) {
++ bestSnlp.addElement(kuint32max, status);
++ }
+
+- // If we're already at the end of the range, we're done
+- if ((int32_t)utext_getNativeIndex(text) >= rangeEnd) {
+- goto foundBest;
+- }
++ // prev[i] is the index of the last code point in the previous word in
++ // the best segmentation of the first i characters. Note negative implies
++ // that the code point is part of an unknown word.
++ UVector32 prev(numCodePts + 1, status);
++ for(int32_t i = 0; i <= numCodePts; i++) {
++ prev.addElement(kuint32max, status);
++ }
+
+- // See if any of the possible second words is followed by a third word
+- do {
+- // If we find a third word, stop right away
+- if (words[(wordsFound + 2) % KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd)) {
+- words[wordsFound % KHMER_LOOKAHEAD].markCurrent();
+- goto foundBest;
+- }
+- }
+- while (words[(wordsFound + 1) % KHMER_LOOKAHEAD].backUp(text));
+- }
++ const int32_t maxWordSize = 20;
++ UVector32 values(maxWordSize, status);
++ values.setSize(maxWordSize);
++ UVector32 lengths(maxWordSize, status);
++ lengths.setSize(maxWordSize);
++
++ // Dynamic programming to find the best segmentation.
++
++ // In outer loop, i is the code point index,
++ // ix is the corresponding string (code unit) index.
++ // They differ when the string contains supplementary characters.
++ int32_t ix = rangeStart;
++ for (int32_t i = 0; i < numCodePts; ++i, utext_setNativeIndex(text, ++ix)) {
++ if ((uint32_t)bestSnlp.elementAti(i) == kuint32max) {
++ continue;
++ }
++
++ int32_t count;
++ count = fDictionary->matches(text, numCodePts - i, maxWordSize,
++ NULL, lengths.getBuffer(), values.getBuffer(), NULL, &fIgnoreSet, 2);
++ // Note: lengths is filled with code point lengths
++ // The NULL parameter is the ignored code unit lengths.
++
++ for (int32_t j = 0; j < count; j++) {
++ int32_t ln = lengths.elementAti(j);
++ if (ln + i >= numCodePts)
++ continue;
++ utext_setNativeIndex(text, ln+ix);
++ int32_t c = utext_current32(text);
++ if (fMarkSet.contains(c) || c == 0x17D2) { // Coeng
++ lengths.removeElementAt(j);
++ values.removeElementAt(j);
++ --j;
++ --count;
+ }
+- while (words[wordsFound % KHMER_LOOKAHEAD].backUp(text));
+-foundBest:
+- cuWordLength = words[wordsFound % KHMER_LOOKAHEAD].acceptMarked(text);
+- cpWordLength = words[wordsFound % KHMER_LOOKAHEAD].markedCPLength();
+- wordsFound += 1;
+ }
+-
+- // We come here after having either found a word or not. We look ahead to the
+- // next word. If it's not a dictionary word, we will combine it with the word we
+- // just found (if there is one), but only if the preceding word does not exceed
+- // the threshold.
+- // The text iterator should now be positioned at the end of the word we found.
+- if ((int32_t)utext_getNativeIndex(text) < rangeEnd && cpWordLength < KHMER_ROOT_COMBINE_THRESHOLD) {
+- // if it is a dictionary word, do nothing. If it isn't, then if there is
+- // no preceding word, or the non-word shares less than the minimum threshold
+- // of characters with a dictionary word, then scan to resynchronize
+- if (words[wordsFound % KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd) <= 0
+- && (cuWordLength == 0
+- || words[wordsFound % KHMER_LOOKAHEAD].longestPrefix() < KHMER_PREFIX_COMBINE_THRESHOLD)) {
+- // Look for a plausible word boundary
+- int32_t remaining = rangeEnd - (current+cuWordLength);
+- UChar32 pc;
+- UChar32 uc;
+- int32_t chars = 0;
+- for (;;) {
+- int32_t pcIndex = (int32_t)utext_getNativeIndex(text);
+- pc = utext_next32(text);
+- int32_t pcSize = (int32_t)utext_getNativeIndex(text) - pcIndex;
+- chars += pcSize;
+- remaining -= pcSize;
+- if (remaining <= 0) {
++ if (count == 0) {
++ utext_setNativeIndex(text, ix);
++ int32_t c = utext_current32(text);
++ if (fPuncSet.contains(c) || fIgnoreSet.contains(c) || c == ZWSP) {
++ values.setElementAt(0, count);
++ lengths.setElementAt(1, count++);
++ } else if (fBaseSet.contains(c)) {
++ int32_t currix = utext_getNativeIndex(text);
++ do {
++ utext_next32(text);
++ c = utext_current32(text);
++ if (utext_getNativeIndex(text) >= rangeEnd)
+ break;
+- }
+- uc = utext_current32(text);
+- if (fEndWordSet.contains(pc) && fBeginWordSet.contains(uc)) {
+- // Maybe. See if it's in the dictionary.
+- int32_t num_candidates = words[(wordsFound + 1) % KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
+- utext_setNativeIndex(text, current+cuWordLength+chars);
+- if (num_candidates > 0) {
++ if (c == 0x17D2) { // Coeng
++ utext_next32(text);
++ c = utext_current32(text);
++ if (!fBaseSet.contains(c) || utext_getNativeIndex(text) >= rangeEnd) {
+ break;
++ } else {
++ utext_next32(text);
++ c = utext_current32(text);
++ if (utext_getNativeIndex(text) >= rangeEnd)
++ break;
+ }
+ }
+- }
+-
+- // Bump the word count if there wasn't already one
+- if (cuWordLength <= 0) {
+- wordsFound += 1;
+- }
++ } while (fMarkSet.contains(c) || fIgnoreSet.contains(c));
++ values.setElementAt(BADSNLP, count);
++ lengths.setElementAt(utext_getNativeIndex(text) - currix, count++);
++ } else {
++ values.setElementAt(BADSNLP, count);
++ lengths.setElementAt(1, count++);
++ }
++ }
+
+- // Update the length with the passed-over characters
+- cuWordLength += chars;
++ for (int32_t j = 0; j < count; j++) {
++ uint32_t v = values.elementAti(j);
++ int32_t newSnlp = bestSnlp.elementAti(i) + v;
++ int32_t ln = lengths.elementAti(j);
++ utext_setNativeIndex(text, ln+ix);
++ int32_t c = utext_current32(text);
++ while ((fPuncSet.contains(c) || fIgnoreSet.contains(c)) && ln + i < numCodePts) {
++ ++ln;
++ utext_next32(text);
++ c = utext_current32(text);
+ }
+- else {
+- // Back up to where we were for next iteration
+- utext_setNativeIndex(text, current+cuWordLength);
++ int32_t ln_j_i = ln + i; // yes really i!
++ if (newSnlp < bestSnlp.elementAti(ln_j_i)) {
++ if (v == BADSNLP) {
++ int32_t p = prev.elementAti(i);
++ if (p < 0)
++ prev.setElementAt(p, ln_j_i);
++ else
++ prev.setElementAt(-i, ln_j_i);
++ }
++ else
++ prev.setElementAt(i, ln_j_i);
++ bestSnlp.setElementAt(newSnlp, ln_j_i);
+ }
+ }
+-
+- // Never stop before a combining mark.
+- int32_t currPos;
+- while ((currPos = (int32_t)utext_getNativeIndex(text)) < rangeEnd && fMarkSet.contains(utext_current32(text))) {
+- utext_next32(text);
+- cuWordLength += (int32_t)utext_getNativeIndex(text) - currPos;
++ }
++ // Start pushing the optimal offset index into t_boundary (t for tentative).
++ // prev[numCodePts] is guaranteed to be meaningful.
++ // We'll first push in the reverse order, i.e.,
++ // t_boundary[0] = numCodePts, and afterwards do a swap.
++ UVector32 t_boundary(numCodePts+1, status);
++
++ int32_t numBreaks = 0;
++ // No segmentation found, set boundary to end of range
++ while (numCodePts >= 0 && (uint32_t)bestSnlp.elementAti(numCodePts) == kuint32max) {
++ --numCodePts;
++ }
++ if (numCodePts < 0) {
++ t_boundary.addElement(numCodePts, status);
++ numBreaks++;
++ } else {
++ for (int32_t i = numCodePts; (uint32_t)i != kuint32max; i = prev.elementAti(i)) {
++ if (i < 0) i = -i;
++ t_boundary.addElement(i, status);
++ numBreaks++;
+ }
++ // U_ASSERT(prev.elementAti(t_boundary.elementAti(numBreaks - 1)) == 0);
++ }
+
+- // Look ahead for possible suffixes if a dictionary word does not follow.
+- // We do this in code rather than using a rule so that the heuristic
+- // resynch continues to function. For example, one of the suffix characters
+- // could be a typo in the middle of a word.
+-// if ((int32_t)utext_getNativeIndex(text) < rangeEnd && wordLength > 0) {
+-// if (words[wordsFound%KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd) <= 0
+-// && fSuffixSet.contains(uc = utext_current32(text))) {
+-// if (uc == KHMER_PAIYANNOI) {
+-// if (!fSuffixSet.contains(utext_previous32(text))) {
+-// // Skip over previous end and PAIYANNOI
+-// utext_next32(text);
+-// utext_next32(text);
+-// wordLength += 1; // Add PAIYANNOI to word
+-// uc = utext_current32(text); // Fetch next character
+-// }
+-// else {
+-// // Restore prior position
+-// utext_next32(text);
+-// }
+-// }
+-// if (uc == KHMER_MAIYAMOK) {
+-// if (utext_previous32(text) != KHMER_MAIYAMOK) {
+-// // Skip over previous end and MAIYAMOK
+-// utext_next32(text);
+-// utext_next32(text);
+-// wordLength += 1; // Add MAIYAMOK to word
+-// }
+-// else {
+-// // Restore prior position
+-// utext_next32(text);
+-// }
+-// }
+-// }
+-// else {
+-// utext_setNativeIndex(text, current+wordLength);
+-// }
+-// }
+-
+- // Did we find a word on this iteration? If so, push it on the break stack
+- if (cuWordLength > 0) {
+- foundBreaks.push((current+cuWordLength), status);
++ // Now that we're done, convert positions in t_boundary[] (indices in
++ // the normalized input string) back to indices in the original input UText
++ // while reversing t_boundary and pushing values to foundBreaks.
++ for (int32_t i = numBreaks-1; i >= 0; i--) {
++ int32_t cpPos = t_boundary.elementAti(i);
++ if (cpPos == 0 && !breakStart && fTypes >= UBRK_LINE) continue;
++ int32_t utextPos = cpPos + rangeStart;
++ while (utextPos > after && scanWJ(text, utextPos, scanEnd, before, after));
++ if (utextPos < before) {
++ // Boundaries are added to foundBreaks output in ascending order.
++ U_ASSERT(foundBreaks.size() == 0 ||foundBreaks.peeki() < utextPos);
++ foundBreaks.push(utextPos, status);
+ }
+ }
+-
++
+ // Don't return a break for the end of the dictionary range if there is one there.
+- if (foundBreaks.peeki() >= rangeEnd) {
++ if (!breakEnd && fTypes >= UBRK_LINE && foundBreaks.peeki() >= rangeEnd) {
+ (void) foundBreaks.popi();
+- wordsFound -= 1;
+ }
+
+- return wordsFound;
++ return foundBreaks.size() - wordsFound;
+ }
+
+ #if !UCONFIG_NO_NORMALIZATION
+diff -ur icu.org/source/common/dictbe.h icu/source/common/dictbe.h
+--- icu.org/source/common/dictbe.h 2022-04-08 00:41:55.000000000 +0200
++++ icu/source/common/dictbe.h 2022-05-16 13:49:33.820459894 +0200
+@@ -35,7 +35,8 @@
+ * threads without synchronization.</p>
+ */
+ class DictionaryBreakEngine : public LanguageBreakEngine {
+- private:
++ protected:
++
+ /**
+ * The set of characters handled by this engine
+ * @internal
+@@ -43,14 +44,84 @@
+
+ UnicodeSet fSet;
+
++ const int32_t WJ = 0x2060;
++ const int32_t ZWSP = 0x200B;
++
++ /**
++ * The break types it was constructed with
++ * @internal
++ */
++ uint32_t fTypes;
++
++ /**
++ * A Unicode set of all viramas
++ * @internal
++ */
++ UnicodeSet fViramaSet;
++
++ /**
++ * A Unicode set of all base characters
++ * @internal
++ */
++ UnicodeSet fBaseSet;
++
++ /**
++ * A Unicode set of all marks
++ * @internal
++ */
++ UnicodeSet fMarkSet;
++
++ /**
++ * A Unicode set of all characters ignored ignored in dictionary matching
++ * @internal
++ */
++ UnicodeSet fIgnoreSet;
++
++ /**
++ * A Unicode set of all characters ignored ignored in dictionary matching
++ * @internal
++ */
++ UnicodeSet fSkipStartSet;
++
++ /**
++ * A Unicode set of all characters ignored ignored in dictionary matching
++ * @internal
++ */
++ UnicodeSet fSkipEndSet;
++
++ /**
++ * A Unicode set of all characters that should not be broken before
++ * @internal
++ */
++ UnicodeSet fNBeforeSet;
++
++ /**
++ * The number of clusters within which breaks are inhibited
++ * @internal
++ */
++ int32_t clusterLimit;
++
++ bool scanWJ(UText *text, int32_t &start, int32_t end, int32_t &before, int32_t &after) const;
++
++ bool scanBeforeStart(UText *text, int32_t& start, bool &doBreak) const;
++ bool scanAfterEnd(UText *text, int32_t rangeEnd, int32_t& end, bool &doBreak) const;
++ void scanBackClusters(UText *text, int32_t textStart, int32_t& start) const;
++ void scanFwdClusters(UText *text, int32_t textEnd, int32_t& end) const;
++
+ public:
+
+ /**
+- * <p>Constructor </p>
++ * <p>Default constructor.</p>
++ *
+ */
+ DictionaryBreakEngine();
+
+ /**
++ * <p>Constructor with break types.</p>
++ */
++ explicit DictionaryBreakEngine(uint32_t breakTypes);
++
++ /**
+ * <p>Virtual destructor.</p>
+ */
+ virtual ~DictionaryBreakEngine();
+@@ -305,10 +376,12 @@
+ * @internal
+ */
+
+- UnicodeSet fEndWordSet;
+ UnicodeSet fBeginWordSet;
+- UnicodeSet fMarkSet;
+- DictionaryMatcher *fDictionary;
++ UnicodeSet fPuncSet;
++ DictionaryMatcher *fDictionary;
++
++ const uint32_t BADSNLP = 256 * 20;
++ const uint32_t kuint32max = 0x7FFFFFFF;
+
+ public:
+
+diff -ur icu.org/source/common/dictionarydata.cpp icu/source/common/dictionarydata.cpp
+--- icu.org/source/common/dictionarydata.cpp 2022-04-08 00:41:55.000000000 +0200
++++ icu/source/common/dictionarydata.cpp 2022-05-16 13:49:33.821459892 +0200
+@@ -44,7 +44,7 @@
+
+ int32_t UCharsDictionaryMatcher::matches(UText *text, int32_t maxLength, int32_t limit,
+ int32_t *lengths, int32_t *cpLengths, int32_t *values,
+- int32_t *prefix) const {
++ int32_t *prefix, UnicodeSet const* ignoreSet, int32_t minLength) const {
+
+ UCharsTrie uct(characters);
+ int32_t startingTextIndex = (int32_t)utext_getNativeIndex(text);
+@@ -55,7 +55,13 @@
+ UStringTrieResult result = (codePointsMatched == 0) ? uct.first(c) : uct.next(c);
+ int32_t lengthMatched = (int32_t)utext_getNativeIndex(text) - startingTextIndex;
+ codePointsMatched += 1;
++ if (ignoreSet != NULL && ignoreSet->contains(c)) {
++ continue;
++ }
+ if (USTRINGTRIE_HAS_VALUE(result)) {
++ if (codePointsMatched < minLength) {
++ continue;
++ }
+ if (wordCount < limit) {
+ if (values != NULL) {
+ values[wordCount] = uct.getValue();
+@@ -112,7 +118,7 @@
+
+ int32_t BytesDictionaryMatcher::matches(UText *text, int32_t maxLength, int32_t limit,
+ int32_t *lengths, int32_t *cpLengths, int32_t *values,
+- int32_t *prefix) const {
++ int32_t *prefix, UnicodeSet const* ignoreSet, int32_t minLength) const {
+ BytesTrie bt(characters);
+ int32_t startingTextIndex = (int32_t)utext_getNativeIndex(text);
+ int32_t wordCount = 0;
+@@ -122,7 +128,13 @@
+ UStringTrieResult result = (codePointsMatched == 0) ? bt.first(transform(c)) : bt.next(transform(c));
+ int32_t lengthMatched = (int32_t)utext_getNativeIndex(text) - startingTextIndex;
+ codePointsMatched += 1;
++ if (ignoreSet != NULL && ignoreSet->contains(c)) {
++ continue;
++ }
+ if (USTRINGTRIE_HAS_VALUE(result)) {
++ if (codePointsMatched < minLength) {
++ continue;
++ }
+ if (wordCount < limit) {
+ if (values != NULL) {
+ values[wordCount] = bt.getValue();
+diff -ur icu.org/source/common/dictionarydata.h icu/source/common/dictionarydata.h
+--- icu.org/source/common/dictionarydata.h 2022-04-08 00:41:55.000000000 +0200
++++ icu/source/common/dictionarydata.h 2022-05-16 13:49:33.822459891 +0200
+@@ -21,6 +21,7 @@
+ #include "unicode/utext.h"
+ #include "unicode/udata.h"
+ #include "udataswp.h"
++#include "unicode/uniset.h"
+ #include "unicode/uobject.h"
+ #include "unicode/ustringtrie.h"
+
+@@ -92,7 +93,7 @@
+ */
+ virtual int32_t matches(UText *text, int32_t maxLength, int32_t limit,
+ int32_t *lengths, int32_t *cpLengths, int32_t *values,
+- int32_t *prefix) const = 0;
++ int32_t *prefix, UnicodeSet const* ignoreSet = NULL, int32_t minLength = 0) const = 0;
+
+ /** @return DictionaryData::TRIE_TYPE_XYZ */
+ virtual int32_t getType() const = 0;
+@@ -107,7 +108,7 @@
+ virtual ~UCharsDictionaryMatcher();
+ virtual int32_t matches(UText *text, int32_t maxLength, int32_t limit,
+ int32_t *lengths, int32_t *cpLengths, int32_t *values,
+- int32_t *prefix) const override;
++ int32_t *prefix, UnicodeSet const* ignoreSet = NULL, int32_t minLength = 0) const override;
+ virtual int32_t getType() const override;
+ private:
+ const UChar *characters;
+@@ -125,7 +126,7 @@
+ virtual ~BytesDictionaryMatcher();
+ virtual int32_t matches(UText *text, int32_t maxLength, int32_t limit,
+ int32_t *lengths, int32_t *cpLengths, int32_t *values,
+- int32_t *prefix) const override;
++ int32_t *prefix, UnicodeSet const* ignoreSet = NULL, int32_t minLength = 0) const override;
+ virtual int32_t getType() const override;
+ private:
+ UChar32 transform(UChar32 c) const;
diff --git a/external/icu/icu4c-macosx.patch.1 b/external/icu/icu4c-macosx.patch.1
new file mode 100644
index 000000000..fee08eb05
--- /dev/null
+++ b/external/icu/icu4c-macosx.patch.1
@@ -0,0 +1,20 @@
+diff -ur icu.org/source/common/putil.cpp icu/source/common/putil.cpp
+--- icu.org/source/common/putil.cpp 2017-04-10 16:22:16.000000000 +0200
++++ icu/source/common/putil.cpp 2017-04-21 22:14:09.940217733 +0200
+@@ -1198,8 +1198,16 @@
+ static const time_t decemberSolstice=1198332540; /*2007-12-22 06:09 UT*/
+
+ /* This probing will tell us when daylight savings occurs. */
++#if U_PLATFORM_IS_DARWIN_BASED
++ struct tm *tmp;
++ tmp = localtime(&juneSolstice);
++ juneSol = *tmp;
++ tmp = localtime(&decemberSolstice);
++ decemberSol = *tmp;
++#else
+ localtime_r(&juneSolstice, &juneSol);
+ localtime_r(&decemberSolstice, &decemberSol);
++#endif
+ if(decemberSol.tm_isdst > 0) {
+ daylightType = U_DAYLIGHT_DECEMBER;
+ } else if(juneSol.tm_isdst > 0) {
diff --git a/external/icu/icu4c-mkdir.patch.1 b/external/icu/icu4c-mkdir.patch.1
new file mode 100644
index 000000000..0cdcf2b07
--- /dev/null
+++ b/external/icu/icu4c-mkdir.patch.1
@@ -0,0 +1,17 @@
+diff -ur icu.org/source/data/Makefile.in icu/source/data/Makefile.in
+--- icu.org/source/data/Makefile.in 2020-10-28 22:21:12.000000000 +0100
++++ icu/source/data/Makefile.in 2020-11-17 10:18:37.960032668 +0100
+@@ -239,6 +239,13 @@
+
+ ifeq ($(ENABLE_SO_VERSION_DATA),1)
+ ifeq ($(PKGDATA_MODE),dll)
++
++# This should be in the included rules.mk but that is generated empty by
++# configure because we have no data/locales/root.txt with prebuilt data/in/
++$(TMP_DIR)/dirs.timestamp:
++ $(MKINSTALLDIRS) $(OUTTMPDIR) $(TMP_DIR)
++ echo timestamp > $@
++
+ SO_VERSION_DATA = $(OUTTMPDIR)/icudata.res
+ $(SO_VERSION_DATA) : $(MISCSRCDIR)/icudata.rc | $(TMP_DIR)/dirs.timestamp
+ ifeq ($(MSYS_RC_MODE),1)
diff --git a/external/icu/icu4c-rpath.patch.1 b/external/icu/icu4c-rpath.patch.1
new file mode 100644
index 000000000..35a545778
--- /dev/null
+++ b/external/icu/icu4c-rpath.patch.1
@@ -0,0 +1,36 @@
+diff -ur icu.org/source/config/mh-linux icu/source/config/mh-linux
+--- icu.org/source/config/mh-linux 2016-06-15 20:58:17.000000000 +0200
++++ icu/source/config/mh-linux 2017-04-21 22:38:18.893927819 +0200
+@@ -22,6 +22,10 @@
+ LD_RPATH= -Wl,-zorigin,-rpath,'$$'ORIGIN
+ LD_RPATH_PRE = -Wl,-rpath,
+
++## Force RPATH=$ORIGIN to locate own dependencies w/o need for LD_LIBRARY_PATH:
++ENABLE_RPATH=YES
++RPATHLDFLAGS=${LD_RPATH_PRE}'$$ORIGIN'
++
+ ## These are the library specific LDFLAGS
+ LDFLAGSICUDT=-nodefaultlibs -nostdlib
+
+diff -ur icu.org/source/data/pkgdataMakefile.in icu/source/data/pkgdataMakefile.in
+--- icu.org/source/data/pkgdataMakefile.in 2016-06-15 20:58:17.000000000 +0200
++++ icu/source/data/pkgdataMakefile.in 2017-04-21 22:38:18.892927822 +0200
+@@ -18,6 +18,9 @@
+ MIDDLE_SO_TARGET=
+ PKGDATA_TRAILING_SPACE=" "
+
++# escape $ with \ when passing to echo; needed to preserve $ORIGIN
++SHLIB.c.shell := $(subst $$,\$$,$(SHLIB.c))
++
+ all : clean
+ @echo GENCCODE_ASSEMBLY_TYPE=$(GENCCODE_ASSEMBLY) >> $(OUTPUTFILE)
+ @echo SO=$(SO) >> $(OUTPUTFILE)
+@@ -26,7 +29,7 @@
+ @echo LIB_EXT_ORDER=$(FINAL_SO_TARGET) >> $(OUTPUTFILE)
+ @echo COMPILE="$(COMPILE.c)" >> $(OUTPUTFILE)
+ @echo LIBFLAGS="-I$(top_srcdir)/common -I$(top_builddir)/common $(SHAREDLIBCPPFLAGS) $(SHAREDLIBCFLAGS)" >> $(OUTPUTFILE)
+- @echo GENLIB="$(SHLIB.c)" >> $(OUTPUTFILE)
++ @echo GENLIB="$(SHLIB.c.shell)" >> $(OUTPUTFILE)
+ @echo LDICUDTFLAGS=$(LDFLAGSICUDT) >> $(OUTPUTFILE)
+ @echo LD_SONAME=$(LD_SONAME) >> $(OUTPUTFILE)
+ @echo RPATH_FLAGS=$(RPATH_FLAGS) >> $(OUTPUTFILE)
diff --git a/external/icu/icu4c-rtti.patch.1 b/external/icu/icu4c-rtti.patch.1
new file mode 100644
index 000000000..c058c7f3c
--- /dev/null
+++ b/external/icu/icu4c-rtti.patch.1
@@ -0,0 +1,12 @@
+diff -ur icu.org/source/config/mh-linux icu/source/config/mh-linux
+--- icu.org/source/config/mh-linux 2017-04-21 23:01:23.257769703 +0200
++++ icu/source/config/mh-linux 2017-04-21 23:03:23.166481552 +0200
+@@ -36,7 +36,7 @@
+ #SH# LD_SONAME=
+
+ ## Shared library options
+-LD_SOOPTIONS= -Wl,-Bsymbolic
++LD_SOOPTIONS= -Wl,-Bsymbolic-functions
+
+ ## Shared object suffix
+ SO = so
diff --git a/external/icu/icu4c-scriptrun.patch.1 b/external/icu/icu4c-scriptrun.patch.1
new file mode 100644
index 000000000..f2f2cf9f3
--- /dev/null
+++ b/external/icu/icu4c-scriptrun.patch.1
@@ -0,0 +1,60 @@
+diff -ur icu.org/source/extra/scrptrun/scrptrun.cpp icu/source/extra/scrptrun/scrptrun.cpp
+--- icu.org/source/extra/scrptrun/scrptrun.cpp 2017-01-20 01:20:31.000000000 +0100
++++ icu/source/extra/scrptrun/scrptrun.cpp 2017-04-21 22:59:31.708037770 +0200
+@@ -151,7 +151,11 @@
+ // characters above it on the stack will be poped.
+ if (pairIndex >= 0) {
+ if ((pairIndex & 1) == 0) {
+- parenStack[++parenSP].pairIndex = pairIndex;
++ ++parenSP;
++ int32_t nVecSize = parenStack.size();
++ if (parenSP == nVecSize)
++ parenStack.resize(nVecSize + 128);
++ parenStack[parenSP].pairIndex = pairIndex;
+ parenStack[parenSP].scriptCode = scriptCode;
+ } else if (parenSP >= 0) {
+ int32_t pi = pairIndex & ~1;
+@@ -185,7 +189,14 @@
+ // pop it from the stack
+ if (pairIndex >= 0 && (pairIndex & 1) != 0 && parenSP >= 0) {
+ parenSP -= 1;
+- startSP -= 1;
++ /* decrement startSP only if it is >= 0,
++ decrementing it unnecessarily will lead to memory corruption
++ while processing the above while block.
++ e.g. startSP = -4 , parenSP = -1
++ */
++ if (startSP >= 0) {
++ startSP -= 1;
++ }
+ }
+ } else {
+ // if the run broke on a surrogate pair,
+diff -ur icu.org/source/extra/scrptrun/scrptrun.h icu/source/extra/scrptrun/scrptrun.h
+--- icu.org/source/extra/scrptrun/scrptrun.h 2017-01-20 01:20:31.000000000 +0100
++++ icu/source/extra/scrptrun/scrptrun.h 2017-04-21 22:59:31.708037770 +0200
+@@ -19,6 +19,7 @@
+ #include "unicode/utypes.h"
+ #include "unicode/uobject.h"
+ #include "unicode/uscript.h"
++#include <vector>
+
+ U_NAMESPACE_BEGIN
+
+@@ -81,7 +82,7 @@
+ int32_t scriptEnd;
+ UScriptCode scriptCode;
+
+- ParenStackEntry parenStack[128];
++ std::vector<ParenStackEntry> parenStack;
+ int32_t parenSP;
+
+ static int8_t highBit(int32_t value);
+@@ -135,6 +136,7 @@
+ scriptEnd = charStart;
+ scriptCode = USCRIPT_INVALID_CODE;
+ parenSP = -1;
++ parenStack.resize(128);
+ }
+
+ inline void ScriptRun::reset(int32_t start, int32_t length)
diff --git a/external/icu/icu4c-solarisgcc.patch.1 b/external/icu/icu4c-solarisgcc.patch.1
new file mode 100644
index 000000000..6000ed0cb
--- /dev/null
+++ b/external/icu/icu4c-solarisgcc.patch.1
@@ -0,0 +1,12 @@
+diff -ur icu.org/source/common/uposixdefs.h icu/source/common/uposixdefs.h
+--- icu.org/source/common/uposixdefs.h 2017-03-09 03:12:45.000000000 +0100
++++ icu/source/common/uposixdefs.h 2017-04-21 22:23:11.857926971 +0200
+@@ -54,7 +54,7 @@
+ *
+ * z/OS needs this definition for timeval and to get usleep.
+ */
+-#if !defined(_XOPEN_SOURCE_EXTENDED) && defined(__TOS_MVS__)
++#if !defined(_XOPEN_SOURCE_EXTENDED) && (defined(__TOS_MVS__) || defined(__IBMC__) || defined(__IBMCPP__))
+ # define _XOPEN_SOURCE_EXTENDED 1
+ #endif
+
diff --git a/external/icu/icu4c-ubsan.patch.1 b/external/icu/icu4c-ubsan.patch.1
new file mode 100644
index 000000000..7b0c2efc9
--- /dev/null
+++ b/external/icu/icu4c-ubsan.patch.1
@@ -0,0 +1,14 @@
+diff -ur icu.org/source/common/ubidiimp.h icu/source/common/ubidiimp.h
+--- icu.org/source/common/ubidiimp.h 2019-10-03 13:16:41.000000000 +0200
++++ icu/source/common/ubidiimp.h 2019-10-28 19:08:13.533284618 +0100
+@@ -198,8 +198,8 @@
+ /* in a Run, logicalStart will get this bit set if the run level is odd */
+ #define INDEX_ODD_BIT (1UL<<31)
+
+-#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)((level)&1)<<31))
+-#define ADD_ODD_BIT_FROM_LEVEL(x, level) ((x)|=((int32_t)((level)&1)<<31))
++#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((uint32_t)((level)&1)<<31))
++#define ADD_ODD_BIT_FROM_LEVEL(x, level) ((x)|=((uint32_t)((level)&1)<<31))
+ #define REMOVE_ODD_BIT(x) ((x)&=~INDEX_ODD_BIT)
+
+ #define GET_INDEX(x) ((x)&~INDEX_ODD_BIT)
diff --git a/external/icu/icu4c-use-pkgdata-single-ccode-file-mode.patch.1 b/external/icu/icu4c-use-pkgdata-single-ccode-file-mode.patch.1
new file mode 100644
index 000000000..237e554b8
--- /dev/null
+++ b/external/icu/icu4c-use-pkgdata-single-ccode-file-mode.patch.1
@@ -0,0 +1,12 @@
+--- icu/source/tools/toolutil/pkg_genc.h.orig 2022-01-11 06:02:29.694678787 +0100
++++ icu/source/tools/toolutil/pkg_genc.h 2022-01-11 06:02:41.602640965 +0100
+@@ -48,9 +48,7 @@
+ * the data to generate the final data library. This can
+ * increase the performance of the pkdata tool.
+ */
+-#if U_PLATFORM == U_PF_OS400
+ #define USE_SINGLE_CCODE_FILE
+-#endif
+
+ /* Need to fix the file seperator character when using MinGW. */
+ #if defined(WINDOWS_WITH_GNUC) || defined(USING_CYGWIN)
diff --git a/external/icu/icu4c-warnings.patch.1 b/external/icu/icu4c-warnings.patch.1
new file mode 100644
index 000000000..d8df0e14e
--- /dev/null
+++ b/external/icu/icu4c-warnings.patch.1
@@ -0,0 +1,11 @@
+diff -ur icu.org/source/common/unicode/utf16.h icu/source/common/unicode/utf16.h
+--- icu.org/source/common/unicode/utf16.h 2020-10-28 22:21:12.000000000 +0100
++++ icu/source/common/unicode/utf16.h 2020-11-16 19:31:03.356478154 +0100
+@@ -398,6 +398,7 @@
+ (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
+ } else /* c>0x10ffff or not enough space */ { \
+ (isError)=true; \
++ (void)(isError); \
+ } \
+ } UPRV_BLOCK_MACRO_END
+
diff --git a/external/icu/icu4c-windows-cygwin-cross.patch.1 b/external/icu/icu4c-windows-cygwin-cross.patch.1
new file mode 100644
index 000000000..dd6b47c17
--- /dev/null
+++ b/external/icu/icu4c-windows-cygwin-cross.patch.1
@@ -0,0 +1,131 @@
+diff -ur icu.org/source/acinclude.m4 icu/source/acinclude.m4
+--- icu.org/source/acinclude.m4 2020-04-10 16:22:16.000000000 +0200
++++ icu/source/acinclude.m4 2020-04-21 22:14:09.940217733 +0200
+@@ -52,6 +52,12 @@
+ else
+ icu_cv_host_frag=mh-cygwin-msvc
+ fi ;;
++aarch64-*-cygwin)
++ if test "$GCC" = yes; then
++ icu_cv_host_frag=mh-cygwin64
++ else
++ icu_cv_host_frag=mh-cygwin-msvc
++ fi ;;
+ *-*-mingw*)
+ if test "$GCC" = yes; then
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+--- icu/source/configure.ac.orig 2020-04-22 22:04:20.000000000 +0200
++++ icu/source/configure.ac 2020-10-01 09:39:05.570900400 +0200
+@@ -213,23 +213,33 @@
+ [cross_buildroot="${withval}"],
+ [cross_buildroot=""])
+
++cross_mixed_buildroot="$cross_buildroot"
++cross_unix_buildroot="$cross_buildroot"
+ if test "X$cross_buildroot" = "X"; then
+ if test "$cross_compiling" = "yes"; then
+ AC_MSG_ERROR([Error! Cross compiling but no --with-cross-build option specified - please supply the path to an executable ICU's build root])
+ dnl '
+ fi
+ else
+- if test -f "${cross_buildroot}/config/icucross.mk"; then
++ case "${host}" in
++ *-*-cygwin*)
++ #M# -m isn't used because it doesn't work on Win98
++ cross_mixed_buildroot=$(cygpath -ad "$cross_buildroot" | tr '\\' '/')
++ cross_unix_buildroot=$(cygpath -au "$cross_buildroot")
++ ;;
++ esac
++ if test -f "${cross_mixed_buildroot}/config/icucross.mk"; then
+ AC_MSG_RESULT([Using cross buildroot: $cross_buildroot])
+ else
+- if test -d "${cross_buildroot}"; then
+- AC_MSG_ERROR([${cross_buildroot}/config/icucross.mk not found. Please build ICU in ${cross_buildroot} first.])
++ if test -d "${cross_mixed_buildroot}"; then
++ AC_MSG_ERROR([${cross_mixed_buildroot}/config/icucross.mk not found. Please build ICU in ${cross_mixed_buildroot} first.])
+ else
+- AC_MSG_ERROR([No such directory ${cross_buildroot} supplied as the argument to --with-cross-build. Use an absolute path.])
++ AC_MSG_ERROR([No such directory ${cross_mixed_buildroot} supplied as the argument to --with-cross-build. Use an absolute path.])
+ fi
+ fi
+ fi
+-AC_SUBST(cross_buildroot)
++AC_SUBST(cross_mixed_buildroot)
++AC_SUBST(cross_unix_buildroot)
+
+ # Check for doxygen to generate documentation
+ AC_PATH_PROG(DOXYGEN,doxygen,,$PATH:/usr/local/bin:/usr/bin)
+--- icu/source/test/testdata/Makefile.in.orig 2020-10-01 09:37:25.847888900 +0200
++++ icu/source/test/testdata/Makefile.in 2020-10-01 09:36:41.859996500 +0200
+@@ -82,7 +82,7 @@
+ # relative lib links from pkgdata are the same as for tmp
+ GENRBOPTS=-k
+ # use the cross root, in case we are cross compiling. Otherwise it is equal to top_builddir
+-TOOLDIR=$(cross_buildroot)/tools
++TOOLDIR=$(cross_mixed_buildroot)/tools
+ SRCDATADIR=$(top_srcdir)/data
+ UNICODEDATADIR=$(SRCDATADIR)/unidata
+ OUTDIR=$(top_builddir)/data/out
+--- icu/source/Makefile.in.orig 2020-04-22 22:04:20.000000000 +0200
++++ icu/source/Makefile.in 2020-10-01 09:29:36.642364000 +0200
+@@ -255,16 +255,16 @@
+ @(echo "CROSS_ICU_VERSION=$(VERSION)" ;\
+ echo "TOOLEXEEXT=$(EXEEXT)" \
+ ) > $@
+- @(echo 'TOOLBINDIR=$$(cross_buildroot)/bin' ;\
+- echo 'TOOLLIBDIR=$$(cross_buildroot)/lib' ;\
+- echo "INVOKE=$(LDLIBRARYPATH_ENVVAR)=$(LIBRARY_PATH_PREFIX)"'$$(TOOLLIBDIR):$$(cross_buildroot)/stubdata:$$(cross_buildroot)/tools/ctestfw:$$$$'"$(LDLIBRARYPATH_ENVVAR)" ;\
+- echo "PKGDATA_INVOKE=$(LDLIBRARYPATH_ENVVAR)=$(LIBRARY_PATH_PREFIX)"'$$(cross_buildroot)/stubdata:$$(cross_buildroot)/tools/ctestfw:$$(TOOLLIBDIR):$$$$'"$(LDLIBRARYPATH_ENVVAR) " ;\
++ @(echo 'TOOLBINDIR=$$(cross_mixed_buildroot)/bin' ;\
++ echo 'TOOLLIBDIR=$$(cross_mixed_buildroot)/lib' ;\
++ echo "INVOKE=$(LDLIBRARYPATH_ENVVAR)=$(LIBRARY_PATH_PREFIX)"'$$(cross_unix_buildroot)/lib:$$(cross_unix_buildroot)/stubdata:$$(cross_unix_buildroot)/tools/ctestfw:$$$$'"$(LDLIBRARYPATH_ENVVAR)" ;\
++ echo "PKGDATA_INVOKE=$(LDLIBRARYPATH_ENVVAR)=$(LIBRARY_PATH_PREFIX)"'$$(cross_unix_buildroot)/stubdata:$$(cross_unix_buildroot)/tools/ctestfw:$$(cross_unix_buildroot)/lib:$$$$'"$(LDLIBRARYPATH_ENVVAR) " ;\
+ echo ) >> $@
+
+ config/icucross.inc: $(top_builddir)/icudefs.mk $(top_builddir)/Makefile @platform_make_fragment@
+ @echo rebuilding $@
+- @(grep '^CURR_FULL_DIR' $(top_builddir)/icudefs.mk ; \
+- grep '^CURR_FULL_DIR' @platform_make_fragment@ || echo ""; \
++ @(grep '^CURR_FULL_DIR' @platform_make_fragment@ || echo ""; \
++ grep '^CURR_FULL_DIR' $(top_builddir)/icudefs.mk ; \
+ ) > $@
+
+ config/icu.pc: $(srcdir)/config/icu.pc.in
+--- icu/source/icudefs.mk.in.orig 2020-04-22 22:04:20.000000000 +0200
++++ icu/source/icudefs.mk.in 2020-10-01 09:35:54.418128800 +0200
+@@ -35,7 +35,8 @@
+ sysconfdir = @sysconfdir@
+ # controls the include of $(top_builddir)/icucross.mk at bottom of file
+ cross_compiling = @cross_compiling@
+-cross_buildroot = @cross_buildroot@
++cross_mixed_buildroot = @cross_mixed_buildroot@
++cross_unix_buildroot = @cross_unix_buildroot@
+
+ # Package information
+
+@@ -303,8 +304,8 @@
+ INSTALLED_INVOKE = $(LDLIBRARYPATH_ENVVAR)=$(libdir):$$$(LDLIBRARYPATH_ENVVAR)
+
+ # Current full path directory for cross compilation
+-ifneq ($(strip $(cross_buildroot)),)
+-include $(cross_buildroot)/config/icucross.inc
++ifneq ($(strip $(cross_mixed_buildroot)),)
++include $(cross_mixed_buildroot)/config/icucross.inc
+ endif
+
+ # Platform-specific setup
+@@ -323,10 +324,11 @@
+
+ # some imported things from the cross env
+ TOOLEXEEXT = $(EXEEXT)
+-ifneq ($(strip $(cross_buildroot)),)
+-include $(cross_buildroot)/config/icucross.mk
++ifneq ($(strip $(cross_mixed_buildroot)),)
++include $(cross_mixed_buildroot)/config/icucross.mk
+ else
+-cross_buildroot = $(top_builddir)
++cross_mixed_buildroot = $(top_builddir)
++cross_unix_buildroot = $(top_builddir)
+ endif
+
+ # for tests
diff --git a/external/icu/khmerdict.dict b/external/icu/khmerdict.dict
new file mode 100644
index 000000000..52605b654
--- /dev/null
+++ b/external/icu/khmerdict.dict
Binary files differ
diff --git a/external/icu/strict_ansi.patch b/external/icu/strict_ansi.patch
new file mode 100644
index 000000000..972f0e65b
--- /dev/null
+++ b/external/icu/strict_ansi.patch
@@ -0,0 +1,15 @@
+--- source/io/ufile.cpp
++++ source/io/ufile.cpp
+@@ -21,12 +21,6 @@
+ */
+
+ #include "unicode/platform.h"
+-#if defined(__GNUC__) && !defined(__clang__) && defined(__STRICT_ANSI__)
+-// g++, fileno isn't defined if __STRICT_ANSI__ is defined.
+-// clang fails to compile the <string> header unless __STRICT_ANSI__ is defined.
+-// __GNUC__ is set by both gcc and clang.
+-#undef __STRICT_ANSI__
+-#endif
+
+ #include "locmap.h"
+ #include "unicode/ustdio.h"
diff --git a/external/icu/ubsan.patch.1 b/external/icu/ubsan.patch.1
new file mode 100644
index 000000000..1c10f8cef
--- /dev/null
+++ b/external/icu/ubsan.patch.1
@@ -0,0 +1,31 @@
+diff -ur icu.org/source/tools/genrb/rbutil.c icu/source/tools/genrb/rbutil.c
+--- icu.org/source/tools/genrb/rbutil.c 2020-10-28 22:21:12.000000000 +0100
++++ icu/source/tools/genrb/rbutil.c 2020-11-16 19:50:44.005119253 +0100
+@@ -30,7 +30,12 @@
+ get_dirname(char *dirname,
+ const char *filename)
+ {
+- const char *lastSlash = uprv_strrchr(filename, U_FILE_SEP_CHAR) + 1;
++ const char *lastSlash = uprv_strrchr(filename, U_FILE_SEP_CHAR);
++ if(lastSlash == NULL) {
++ lastSlash = filename;
++ } else {
++ ++lastSlash;
++ }
+
+ if(lastSlash>filename) {
+ uprv_strncpy(dirname, filename, (lastSlash - filename));
+@@ -46,7 +51,12 @@
+ const char *filename)
+ {
+ /* strip off any leading directory portions */
+- const char *lastSlash = uprv_strrchr(filename, U_FILE_SEP_CHAR) + 1;
++ const char *lastSlash = uprv_strrchr(filename, U_FILE_SEP_CHAR);
++ if(lastSlash == NULL) {
++ lastSlash = filename;
++ } else {
++ ++lastSlash;
++ }
+ char *lastDot;
+
+ if(lastSlash>filename) {
diff --git a/external/jfreereport/ExternalPackage_jfreereport_flow_engine.mk b/external/jfreereport/ExternalPackage_jfreereport_flow_engine.mk
new file mode 100644
index 000000000..9b1ecf64d
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_flow_engine.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_flow_engine,jfreereport_flow_engine))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_flow_engine,jfreereport_flow_engine))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_flow_engine,$(LIBO_SHARE_JAVA_FOLDER)/flow-engine.jar,build/lib/flow-engine.jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_flute.mk b/external/jfreereport/ExternalPackage_jfreereport_flute.mk
new file mode 100644
index 000000000..bdc08a06b
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_flute.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_flute,jfreereport_flute))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_flute,jfreereport_flute))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_flute,$(LIBO_SHARE_JAVA_FOLDER)/flute-$(FLUTE_VERSION).jar,dist/flute-$(FLUTE_VERSION).jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_libbase.mk b/external/jfreereport/ExternalPackage_jfreereport_libbase.mk
new file mode 100644
index 000000000..e3329d186
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_libbase.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_libbase,jfreereport_libbase))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_libbase,jfreereport_libbase))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_libbase,$(LIBO_SHARE_JAVA_FOLDER)/libbase-$(LIBBASE_VERSION).jar,dist/libbase-$(LIBBASE_VERSION).jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_libfonts.mk b/external/jfreereport/ExternalPackage_jfreereport_libfonts.mk
new file mode 100644
index 000000000..910f15ffb
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_libfonts.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_libfonts,jfreereport_libfonts))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_libfonts,jfreereport_libfonts))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_libfonts,$(LIBO_SHARE_JAVA_FOLDER)/libfonts-$(LIBFONTS_VERSION).jar,dist/libfonts-$(LIBFONTS_VERSION).jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_libformula.mk b/external/jfreereport/ExternalPackage_jfreereport_libformula.mk
new file mode 100644
index 000000000..8fb9ca99e
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_libformula.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_libformula,jfreereport_libformula))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_libformula,jfreereport_libformula))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_libformula,$(LIBO_SHARE_JAVA_FOLDER)/libformula-$(LIBFORMULA_VERSION).jar,dist/libformula-$(LIBFORMULA_VERSION).jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_liblayout.mk b/external/jfreereport/ExternalPackage_jfreereport_liblayout.mk
new file mode 100644
index 000000000..0a5307cb8
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_liblayout.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_liblayout,jfreereport_liblayout))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_liblayout,jfreereport_liblayout))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_liblayout,$(LIBO_SHARE_JAVA_FOLDER)/liblayout.jar,build/lib/liblayout.jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_libloader.mk b/external/jfreereport/ExternalPackage_jfreereport_libloader.mk
new file mode 100644
index 000000000..6cec115b8
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_libloader.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_libloader,jfreereport_libloader))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_libloader,jfreereport_libloader))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_libloader,$(LIBO_SHARE_JAVA_FOLDER)/libloader-$(LIBLOADER_VERSION).jar,dist/libloader-$(LIBLOADER_VERSION).jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_librepository.mk b/external/jfreereport/ExternalPackage_jfreereport_librepository.mk
new file mode 100644
index 000000000..63662ad1b
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_librepository.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_librepository,jfreereport_librepository))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_librepository,jfreereport_librepository))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_librepository,$(LIBO_SHARE_JAVA_FOLDER)/librepository-$(LIBREPOSITORY_VERSION).jar,dist/librepository-$(LIBREPOSITORY_VERSION).jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_libserializer.mk b/external/jfreereport/ExternalPackage_jfreereport_libserializer.mk
new file mode 100644
index 000000000..f12d6882d
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_libserializer.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_libserializer,jfreereport_libserializer))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_libserializer,jfreereport_libserializer))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_libserializer,$(LIBO_SHARE_JAVA_FOLDER)/libserializer-$(LIBBASE_VERSION).jar,dist/libserializer-$(LIBBASE_VERSION).jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_libxml.mk b/external/jfreereport/ExternalPackage_jfreereport_libxml.mk
new file mode 100644
index 000000000..13c207815
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_libxml.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_libxml,jfreereport_libxml))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_libxml,jfreereport_libxml))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_libxml,$(LIBO_SHARE_JAVA_FOLDER)/libxml-$(LIBXML_VERSION).jar,dist/libxml-$(LIBXML_VERSION).jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalPackage_jfreereport_sac.mk b/external/jfreereport/ExternalPackage_jfreereport_sac.mk
new file mode 100644
index 000000000..cfdf31ab6
--- /dev/null
+++ b/external/jfreereport/ExternalPackage_jfreereport_sac.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,jfreereport_sac,jfreereport_sac))
+
+$(eval $(call gb_ExternalPackage_use_external_project,jfreereport_sac,jfreereport_sac))
+
+$(eval $(call gb_ExternalPackage_add_file,jfreereport_sac,$(LIBO_SHARE_JAVA_FOLDER)/sac.jar,build/lib/sac.jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_flow_engine.mk b/external/jfreereport/ExternalProject_jfreereport_flow_engine.mk
new file mode 100644
index 000000000..55868ea9b
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_flow_engine.mk
@@ -0,0 +1,40 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_flow_engine))
+
+$(eval $(call gb_ExternalProject_use_external_projects,jfreereport_flow_engine,\
+ jfreereport_liblayout \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_flow_engine,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_flow_engine,build) :
+ $(call gb_Trace_StartRange,jfreereport_flow_engine,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dlibbase.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libbase)/dist/libbase-$(LIBBASE_VERSION).jar \
+ -Dlibformula.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libformula)/dist/libformula-$(LIBFORMULA_VERSION).jar \
+ -Dliblayout.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_liblayout)/build/lib/liblayout.jar \
+ -Dlibloader.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libloader)/dist/libloader-$(LIBLOADER_VERSION).jar \
+ -Dlibserializer.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libserializer)/dist/libserializer-$(LIBBASE_VERSION).jar \
+ -Dlibxml.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libxml)/dist/libxml-$(LIBXML_VERSION).jar \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_flow_engine,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_flute.mk b/external/jfreereport/ExternalProject_jfreereport_flute.mk
new file mode 100644
index 000000000..120c98cbd
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_flute.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_flute))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_flute,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_flute,build) :
+ $(call gb_Trace_StartRange,jfreereport_flute,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ -Dbuild.id="10682" \
+ -Dproject.revision="$(FLUTE_VERSION)" \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_flute,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_libbase.mk b/external/jfreereport/ExternalProject_jfreereport_libbase.mk
new file mode 100644
index 000000000..6d97ffa57
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_libbase.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_libbase))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_libbase,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_libbase,build) :
+ $(call gb_Trace_StartRange,jfreereport_libbase,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ -Dbuild.id="10682" \
+ -Dproject.revision="$(LIBBASE_VERSION)" \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_libbase,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_libfonts.mk b/external/jfreereport/ExternalProject_jfreereport_libfonts.mk
new file mode 100644
index 000000000..9a6edf0b8
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_libfonts.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_libfonts))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_libfonts,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_libfonts,build) :
+ $(call gb_Trace_StartRange,jfreereport_libfonts,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ -Dbuild.id="10682" \
+ -Dproject.revision="$(LIBFONTS_VERSION)" \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_libfonts,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_libformula.mk b/external/jfreereport/ExternalProject_jfreereport_libformula.mk
new file mode 100644
index 000000000..1182873e6
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_libformula.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_libformula))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_libformula,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_libformula,build) :
+ $(call gb_Trace_StartRange,jfreereport_libformula,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ -Dbuild.id="10682" \
+ -Dproject.revision="$(LIBFORMULA_VERSION)" \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_libformula,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_liblayout.mk b/external/jfreereport/ExternalProject_jfreereport_liblayout.mk
new file mode 100644
index 000000000..7c7478e07
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_liblayout.mk
@@ -0,0 +1,53 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_liblayout))
+
+$(eval $(call gb_ExternalProject_use_external_projects,jfreereport_liblayout,\
+ jfreereport_sac \
+ jfreereport_libbase \
+ jfreereport_flute \
+ jfreereport_libloader \
+ jfreereport_libxml \
+ jfreereport_libformula \
+ jfreereport_libfonts \
+ jfreereport_librepository \
+ jfreereport_libserializer \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_liblayout,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_liblayout,build) :
+ $(call gb_Trace_StartRange,jfreereport_liblayout,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dflute.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_flute)/dist/flute-$(FLUTE_VERSION).jar \
+ -Dlibbase.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libbase)/dist/libbase-$(LIBBASE_VERSION).jar \
+ -Dlibformula.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libformula)/dist/libformula-$(LIBFORMULA_VERSION).jar \
+ -Dlibfonts.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libfonts)/dist/libfonts-$(LIBFONTS_VERSION).jar \
+ -Dlibloader.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libloader)/dist/libloader-$(LIBLOADER_VERSION).jar \
+ -Dlibrepository.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_librepository)/dist/librepository-$(LIBREPOSITORY_VERSION).jar \
+ -Dlibserializer.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libserializer)/dist/libserializer-$(LIBBASE_VERSION).jar \
+ -Dlibxml.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_libxml)/dist/libxml-$(LIBXML_VERSION).jar \
+ -Dsac.jar=$(call gb_UnpackedTarball_get_dir,jfreereport_sac)/build/lib/sac.jar \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ -Dbuild.id="10682" \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_liblayout,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_libloader.mk b/external/jfreereport/ExternalProject_jfreereport_libloader.mk
new file mode 100644
index 000000000..ddb34e3d8
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_libloader.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_libloader))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_libloader,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_libloader,build) :
+ $(call gb_Trace_StartRange,jfreereport_libloader,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ -Dbuild.id="10682" \
+ -Dproject.revision="$(LIBLOADER_VERSION)" \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_libloader,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_librepository.mk b/external/jfreereport/ExternalProject_jfreereport_librepository.mk
new file mode 100644
index 000000000..59fa203fb
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_librepository.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_librepository))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_librepository,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_librepository,build) :
+ $(call gb_Trace_StartRange,jfreereport_librepository,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ -Dbuild.id="10682" \
+ -Dproject.revision="$(LIBREPOSITORY_VERSION)" \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_librepository,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_libserializer.mk b/external/jfreereport/ExternalProject_jfreereport_libserializer.mk
new file mode 100644
index 000000000..1226e1420
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_libserializer.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_libserializer))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_libserializer,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_libserializer,build) :
+ $(call gb_Trace_StartRange,jfreereport_libserializer,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)." \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ -Dbuild.id="10682" \
+ -Dproject.revision="$(LIBSERIALIZER_VERSION)" \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_libserializer,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_libxml.mk b/external/jfreereport/ExternalProject_jfreereport_libxml.mk
new file mode 100644
index 000000000..295573ec6
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_libxml.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_libxml))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_libxml,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_libxml,build) :
+ $(call gb_Trace_StartRange,jfreereport_libxml,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ -Dbuild.id="10682" \
+ -Dproject.revision="$(LIBXML_VERSION)" \
+ $(if $(debug),-Dbuild.debug="on") jar \
+ )
+ $(call gb_Trace_EndRange,jfreereport_libxml,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/ExternalProject_jfreereport_sac.mk b/external/jfreereport/ExternalProject_jfreereport_sac.mk
new file mode 100644
index 000000000..a33186183
--- /dev/null
+++ b/external/jfreereport/ExternalProject_jfreereport_sac.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,jfreereport_sac))
+
+$(eval $(call gb_ExternalProject_register_targets,jfreereport_sac,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,jfreereport_sac,build) :
+ $(call gb_Trace_StartRange,jfreereport_sac,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ -Dantcontrib.available="true" \
+ $(if $(debug),-Dbuild.debug="on") all \
+ )
+ $(call gb_Trace_EndRange,jfreereport_sac,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/Makefile b/external/jfreereport/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/jfreereport/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/Module_jfreereport.mk b/external/jfreereport/Module_jfreereport.mk
new file mode 100644
index 000000000..5a4431ecc
--- /dev/null
+++ b/external/jfreereport/Module_jfreereport.mk
@@ -0,0 +1,48 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,jfreereport))
+
+$(eval $(call gb_Module_add_targets,jfreereport,\
+ ExternalPackage_jfreereport_flow_engine \
+ ExternalPackage_jfreereport_flute \
+ ExternalPackage_jfreereport_libbase \
+ ExternalPackage_jfreereport_libfonts \
+ ExternalPackage_jfreereport_libformula \
+ ExternalPackage_jfreereport_liblayout \
+ ExternalPackage_jfreereport_libloader \
+ ExternalPackage_jfreereport_librepository \
+ ExternalPackage_jfreereport_libserializer \
+ ExternalPackage_jfreereport_libxml \
+ ExternalPackage_jfreereport_sac \
+ ExternalProject_jfreereport_flow_engine \
+ ExternalProject_jfreereport_flute \
+ ExternalProject_jfreereport_libbase \
+ ExternalProject_jfreereport_libfonts \
+ ExternalProject_jfreereport_libformula \
+ ExternalProject_jfreereport_liblayout \
+ ExternalProject_jfreereport_libloader \
+ ExternalProject_jfreereport_librepository \
+ ExternalProject_jfreereport_libserializer \
+ ExternalProject_jfreereport_libxml \
+ ExternalProject_jfreereport_sac \
+ UnpackedTarball_jfreereport_flow_engine \
+ UnpackedTarball_jfreereport_flute \
+ UnpackedTarball_jfreereport_libbase \
+ UnpackedTarball_jfreereport_libfonts \
+ UnpackedTarball_jfreereport_libformula \
+ UnpackedTarball_jfreereport_liblayout \
+ UnpackedTarball_jfreereport_libloader \
+ UnpackedTarball_jfreereport_librepository \
+ UnpackedTarball_jfreereport_libserializer \
+ UnpackedTarball_jfreereport_libxml \
+ UnpackedTarball_jfreereport_sac \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/README b/external/jfreereport/README
new file mode 100644
index 000000000..228577060
--- /dev/null
+++ b/external/jfreereport/README
@@ -0,0 +1 @@
+Java library providing basic functionality for the report builder, from [http://www.object-refinery.com/jfreereport/]
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_flow_engine.mk b/external/jfreereport/UnpackedTarball_jfreereport_flow_engine.mk
new file mode 100644
index 000000000..42e90e1e0
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_flow_engine.mk
@@ -0,0 +1,24 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_flow_engine))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_flow_engine,$(JFREEREPORT_FLOW_ENGINE_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_flow_engine,\
+ build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_flow_engine,\
+ external/jfreereport/patches/flow-engine.patch \
+ external/jfreereport/patches/flow-engine_date_is_datetime.patch.1 \
+ external/jfreereport/patches/pentaho-reporting-flow-engine-0.9.4-remove-commons-logging.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_flute.mk b/external/jfreereport/UnpackedTarball_jfreereport_flute.mk
new file mode 100644
index 000000000..a972e21aa
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_flute.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_flute))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_flute,$(JFREEREPORT_FLUTE_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_flute,\
+ common_build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_flute,\
+ external/jfreereport/patches/common_build.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_libbase.mk b/external/jfreereport/UnpackedTarball_jfreereport_libbase.mk
new file mode 100644
index 000000000..46bb438aa
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_libbase.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_libbase))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_libbase,$(JFREEREPORT_LIBBASE_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_libbase,\
+ common_build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_libbase,\
+ external/jfreereport/patches/common_build.patch \
+ external/jfreereport/patches/libbase-$(LIBBASE_VERSION)-deprecated.patch \
+ external/jfreereport/patches/libbase-1.1.3-remove-commons-logging.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_libfonts.mk b/external/jfreereport/UnpackedTarball_jfreereport_libfonts.mk
new file mode 100644
index 000000000..c45958505
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_libfonts.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_libfonts))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_libfonts,$(JFREEREPORT_LIBFONTS_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_libfonts,\
+ common_build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_libfonts,\
+ external/jfreereport/patches/common_build.patch \
+ external/jfreereport/patches/libfonts-$(LIBFONTS_VERSION)-deprecated.patch \
+ external/jfreereport/patches/libfonts-1.1.3-remove-commons-logging.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_libformula.mk b/external/jfreereport/UnpackedTarball_jfreereport_libformula.mk
new file mode 100644
index 000000000..13e8fcfaf
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_libformula.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_libformula))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_libformula,$(JFREEREPORT_LIBFORMULA_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_libformula,\
+ common_build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_libformula,\
+ external/jfreereport/patches/common_build.patch \
+ external/jfreereport/patches/libformula-time-notz.patch \
+ external/jfreereport/patches/libformula-seconds_rounding.patch.1 \
+ external/jfreereport/patches/libformula-minutes_truncation.patch.1 \
+ external/jfreereport/patches/libformula-datevalue_truncation.patch.1 \
+ external/jfreereport/patches/libformula-1.1.3-remove-commons-logging.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_liblayout.mk b/external/jfreereport/UnpackedTarball_jfreereport_liblayout.mk
new file mode 100644
index 000000000..a2538c378
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_liblayout.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_liblayout))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_liblayout,$(JFREEREPORT_LIBLAYOUT_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_liblayout,\
+ build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_liblayout,\
+ external/jfreereport/patches/liblayout.patch \
+ external/jfreereport/patches/liblayout-0.2.10-remove-commons-logging.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_libloader.mk b/external/jfreereport/UnpackedTarball_jfreereport_libloader.mk
new file mode 100644
index 000000000..6221dfa52
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_libloader.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_libloader))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_libloader,$(JFREEREPORT_LIBLOADER_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_libloader,\
+ common_build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_libloader,\
+ external/jfreereport/patches/common_build.patch \
+ external/jfreereport/patches/libloader-$(LIBLOADER_VERSION)-deprecated.patch \
+ external/jfreereport/patches/libloader-1.1.3-remove-commons-logging.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_librepository.mk b/external/jfreereport/UnpackedTarball_jfreereport_librepository.mk
new file mode 100644
index 000000000..e1db29d02
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_librepository.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# for VERSION
+include $(SRCDIR)/external/jfreereport/version.mk
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_librepository))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_librepository,$(JFREEREPORT_LIBREPOSITORY_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_librepository,\
+ common_build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_librepository,\
+ external/jfreereport/patches/common_build.patch \
+ external/jfreereport/patches/librepository-$(LIBREPOSITORY_VERSION)-deprecated.patch \
+ external/jfreereport/patches/librepository-1.1.3-remove-commons-logging.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_libserializer.mk b/external/jfreereport/UnpackedTarball_jfreereport_libserializer.mk
new file mode 100644
index 000000000..fb6f3d60c
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_libserializer.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_libserializer))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_libserializer,$(JFREEREPORT_LIBSERIALIZER_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_libserializer,\
+ common_build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_libserializer,\
+ external/jfreereport/patches/common_build.patch \
+ external/jfreereport/patches/libserializer-1.1.2-remove-commons-logging.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_libxml.mk b/external/jfreereport/UnpackedTarball_jfreereport_libxml.mk
new file mode 100644
index 000000000..7a920a873
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_libxml.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_libxml))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_libxml,$(JFREEREPORT_LIBXML_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,jfreereport_libxml,\
+ common_build.xml \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,jfreereport_libxml,\
+ external/jfreereport/patches/common_build.patch \
+ external/jfreereport/patches/libxml-1.1.3-remove-commons-logging.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/UnpackedTarball_jfreereport_sac.mk b/external/jfreereport/UnpackedTarball_jfreereport_sac.mk
new file mode 100644
index 000000000..eb951663d
--- /dev/null
+++ b/external/jfreereport/UnpackedTarball_jfreereport_sac.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,jfreereport_sac))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,jfreereport_sac,$(JFREEREPORT_SAC_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_add_file,jfreereport_sac,build.xml,external/jfreereport/java/sac/build.xml))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/jfreereport/java/sac/build.xml b/external/jfreereport/java/sac/build.xml
new file mode 100644
index 000000000..0e85dff04
--- /dev/null
+++ b/external/jfreereport/java/sac/build.xml
@@ -0,0 +1,64 @@
+<project name="sac" default="all" basedir=".">
+
+ <!-- Properties -->
+
+ <property name="name" value="sac"/>
+ <property name="src" value="src"/>
+ <property name="build" value="build"/>
+ <property name="build.classes" value="${build}/classes"/>
+ <property name="build.doc" value="${build}/api"/>
+ <property name="build.lib" value="${build}/lib"/>
+ <property name="packagenames" value="org.w3c.css.sac.*"/>
+
+ <!-- Targets -->
+
+ <!-- Prepare build directories -->
+ <target name="prepare">
+ <mkdir dir="${src}"/>
+ <mkdir dir="${build}"/>
+ <mkdir dir="${build.classes}"/>
+ <mkdir dir="${build.lib}"/>
+ <mkdir dir="${build.doc}"/>
+ <copy todir="${src}/org">
+ <fileset dir="org"/>
+ </copy>
+ </target>
+
+ <!-- Kill all the created directories -->
+ <target name="clean">
+ <delete dir="${build}"/>
+ <delete dir="${src}"/>
+ </target>
+
+ <!-- Build classes -->
+ <target name="classes" depends="prepare">
+ <javac srcdir="${src}" destdir="${build.classes}" debug="off" optimize="on"/>
+ <copy todir="${build.classes}">
+ <fileset dir="${src}">
+ <include name="**/*.properties"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <!-- Build jar archives -->
+ <target name="jar" depends="classes">
+ <jar jarfile="${build.lib}/${name}.jar" basedir="${build.classes}"/>
+ </target>
+
+ <!-- Build the full JavaDocs -->
+ <target name="javadoc" depends="prepare">
+ <javadoc sourcepath="${src}"
+ destdir="${build.doc}"
+ doctitle="${name} JavaDoc"
+ windowtitle="${name} JavaDoc"
+ package="true"
+ author="true"
+ version="true"
+ packagenames="${packagenames}"
+ />
+ </target>
+
+ <!-- Build everything -->
+ <target name="all" depends="jar,javadoc"/>
+
+</project> \ No newline at end of file
diff --git a/external/jfreereport/nbprojects/flute/nbproject/project.xml b/external/jfreereport/nbprojects/flute/nbproject/project.xml
new file mode 100644
index 000000000..4280b9102
--- /dev/null
+++ b/external/jfreereport/nbprojects/flute/nbproject/project.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.ant.freeform</type>
+ <configuration>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <!-- Do not use Project Properties customizer when editing this file manually. -->
+ <name>flute-13a</name>
+ <properties>
+ <property name="project.dir">../../wntmsci10/misc/build/flute</property>
+ <property name="ant.script">${project.dir}/ant/build.xml</property>
+ </properties>
+ <folders>
+ <source-folder>
+ <label>flute</label>
+ <location>${project.dir}</location>
+ </source-folder>
+ </folders>
+ <ide-actions>
+ <action name="build">
+ <script>${ant.script}</script>
+ <target>all</target>
+ </action>
+ <action name="javadoc">
+ <script>${ant.script}</script>
+ <target>javadoc</target>
+ </action>
+ </ide-actions>
+ <view>
+ <items>
+ <source-file>
+ <location>${ant.script}</location>
+ </source-file>
+ </items>
+ <context-menu>
+ <ide-action name="build"/>
+ <ide-action name="javadoc"/>
+ </context-menu>
+ </view>
+ </general-data>
+ <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+ </configuration>
+</project>
diff --git a/external/jfreereport/nbprojects/jcommon-serializer/nbproject/project.xml b/external/jfreereport/nbprojects/jcommon-serializer/nbproject/project.xml
new file mode 100644
index 000000000..f7a14ae87
--- /dev/null
+++ b/external/jfreereport/nbprojects/jcommon-serializer/nbproject/project.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.ant.freeform</type>
+ <configuration>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <!-- Do not use Project Properties customizer when editing this file manually. -->
+ <name>jcommon-serializer</name>
+ <properties>
+ <property name="project.dir">../../wntmsci10/misc/build/jcommon-serializer</property>
+ <property name="ant.script">${project.dir}/ant/build.xml</property>
+ </properties>
+ <folders>
+ <source-folder>
+ <label>jcommon-serializer</label>
+ <location>${project.dir}</location>
+ </source-folder>
+ </folders>
+ <ide-actions>
+ <action name="build">
+ <script>${ant.script}</script>
+ <target>all</target>
+ </action>
+ <action name="javadoc">
+ <script>${ant.script}</script>
+ <target>javadoc</target>
+ </action>
+ </ide-actions>
+ <view>
+ <items>
+ <source-file>
+ <location>${ant.script}</location>
+ </source-file>
+ </items>
+ <context-menu>
+ <ide-action name="build"/>
+ <ide-action name="javadoc"/>
+ </context-menu>
+ </view>
+ </general-data>
+ <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+ </configuration>
+</project>
diff --git a/external/jfreereport/nbprojects/jfreereport/nbproject/project.xml b/external/jfreereport/nbprojects/jfreereport/nbproject/project.xml
new file mode 100644
index 000000000..8f6074cfb
--- /dev/null
+++ b/external/jfreereport/nbprojects/jfreereport/nbproject/project.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.ant.freeform</type>
+ <configuration>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <!-- Do not use Project Properties customizer when editing this file manually. -->
+ <name>jfreereport</name>
+ <properties>
+ <property name="project.dir">../../wntmsci10/misc/build/jfreereport</property>
+ <property name="ant.script">${project.dir}/ant/build.xml</property>
+ </properties>
+ <folders>
+ <source-folder>
+ <label>jfreereport</label>
+ <location>${project.dir}</location>
+ </source-folder>
+ </folders>
+ <ide-actions>
+ <action name="build">
+ <script>${ant.script}</script>
+ <target>all</target>
+ </action>
+ <action name="javadoc">
+ <script>${ant.script}</script>
+ <target>javadoc</target>
+ </action>
+ </ide-actions>
+ <view>
+ <items>
+ <source-file>
+ <location>${ant.script}</location>
+ </source-file>
+ </items>
+ <context-menu>
+ <ide-action name="build"/>
+ <ide-action name="javadoc"/>
+ </context-menu>
+ </view>
+ </general-data>
+ <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+ </configuration>
+</project>
diff --git a/external/jfreereport/nbprojects/libfonts/nbproject/project.xml b/external/jfreereport/nbprojects/libfonts/nbproject/project.xml
new file mode 100644
index 000000000..d84bfb7f8
--- /dev/null
+++ b/external/jfreereport/nbprojects/libfonts/nbproject/project.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.ant.freeform</type>
+ <configuration>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <!-- Do not use Project Properties customizer when editing this file manually. -->
+ <name>libfonts</name>
+ <properties>
+ <property name="project.dir">../../wntmsci10/misc/build/libfonts</property>
+ <property name="ant.script">${project.dir}/ant/build.xml</property>
+ </properties>
+ <folders>
+ <source-folder>
+ <label>libfonts</label>
+ <location>${project.dir}</location>
+ </source-folder>
+ </folders>
+ <ide-actions>
+ <action name="build">
+ <script>${ant.script}</script>
+ <target>all</target>
+ </action>
+ <action name="javadoc">
+ <script>${ant.script}</script>
+ <target>javadoc</target>
+ </action>
+ </ide-actions>
+ <view>
+ <items>
+ <source-file>
+ <location>${ant.script}</location>
+ </source-file>
+ </items>
+ <context-menu>
+ <ide-action name="build"/>
+ <ide-action name="javadoc"/>
+ </context-menu>
+ </view>
+ </general-data>
+ <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+ </configuration>
+</project>
diff --git a/external/jfreereport/nbprojects/libformula/nbproject/project.xml b/external/jfreereport/nbprojects/libformula/nbproject/project.xml
new file mode 100644
index 000000000..e056200ee
--- /dev/null
+++ b/external/jfreereport/nbprojects/libformula/nbproject/project.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.ant.freeform</type>
+ <configuration>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <!-- Do not use Project Properties customizer when editing this file manually. -->
+ <name>libformula</name>
+ <properties>
+ <property name="project.dir">../../wntmsci10/misc/build/libformula</property>
+ <property name="ant.script">${project.dir}/ant/build.xml</property>
+ </properties>
+ <folders>
+ <source-folder>
+ <label>libformula</label>
+ <location>${project.dir}</location>
+ </source-folder>
+ </folders>
+ <ide-actions>
+ <action name="build">
+ <script>${ant.script}</script>
+ <target>all</target>
+ </action>
+ <action name="javadoc">
+ <script>${ant.script}</script>
+ <target>javadoc</target>
+ </action>
+ </ide-actions>
+ <view>
+ <items>
+ <source-file>
+ <location>${ant.script}</location>
+ </source-file>
+ </items>
+ <context-menu>
+ <ide-action name="build"/>
+ <ide-action name="javadoc"/>
+ </context-menu>
+ </view>
+ </general-data>
+ <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+ </configuration>
+</project>
diff --git a/external/jfreereport/nbprojects/liblayout/nbproject/project.xml b/external/jfreereport/nbprojects/liblayout/nbproject/project.xml
new file mode 100644
index 000000000..63ad9ef3f
--- /dev/null
+++ b/external/jfreereport/nbprojects/liblayout/nbproject/project.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.ant.freeform</type>
+ <configuration>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <!-- Do not use Project Properties customizer when editing this file manually. -->
+ <name>liblayout</name>
+ <properties>
+ <property name="project.dir">../../wntmsci10/misc/build/liblayout</property>
+ <property name="ant.script">${project.dir}/ant/build.xml</property>
+ </properties>
+ <folders>
+ <source-folder>
+ <label>liblayout</label>
+ <location>${project.dir}</location>
+ </source-folder>
+ </folders>
+ <ide-actions>
+ <action name="build">
+ <script>${ant.script}</script>
+ <target>all</target>
+ </action>
+ <action name="javadoc">
+ <script>${ant.script}</script>
+ <target>javadoc</target>
+ </action>
+ </ide-actions>
+ <view>
+ <items>
+ <source-file>
+ <location>${ant.script}</location>
+ </source-file>
+ </items>
+ <context-menu>
+ <ide-action name="build"/>
+ <ide-action name="javadoc"/>
+ </context-menu>
+ </view>
+ </general-data>
+ <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+ </configuration>
+</project>
diff --git a/external/jfreereport/nbprojects/libloader/nbproject/project.xml b/external/jfreereport/nbprojects/libloader/nbproject/project.xml
new file mode 100644
index 000000000..6b06d5686
--- /dev/null
+++ b/external/jfreereport/nbprojects/libloader/nbproject/project.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.ant.freeform</type>
+ <configuration>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <!-- Do not use Project Properties customizer when editing this file manually. -->
+ <name>libloader</name>
+ <properties>
+ <property name="project.dir">../../wntmsci10/misc/build/libloader</property>
+ <property name="ant.script">${project.dir}/ant/build.xml</property>
+ </properties>
+ <folders>
+ <source-folder>
+ <label>libloader</label>
+ <location>${project.dir}</location>
+ </source-folder>
+ </folders>
+ <ide-actions>
+ <action name="build">
+ <script>${ant.script}</script>
+ <target>all</target>
+ </action>
+ <action name="javadoc">
+ <script>${ant.script}</script>
+ <target>javadoc</target>
+ </action>
+ </ide-actions>
+ <view>
+ <items>
+ <source-file>
+ <location>${ant.script}</location>
+ </source-file>
+ </items>
+ <context-menu>
+ <ide-action name="build"/>
+ <ide-action name="javadoc"/>
+ </context-menu>
+ </view>
+ </general-data>
+ <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+ </configuration>
+</project>
diff --git a/external/jfreereport/nbprojects/librepository/nbproject/project.xml b/external/jfreereport/nbprojects/librepository/nbproject/project.xml
new file mode 100644
index 000000000..c1b92593d
--- /dev/null
+++ b/external/jfreereport/nbprojects/librepository/nbproject/project.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.ant.freeform</type>
+ <configuration>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <!-- Do not use Project Properties customizer when editing this file manually. -->
+ <name>librepository</name>
+ <properties>
+ <property name="project.dir">../../wntmsci10/misc/build/librepository</property>
+ <property name="ant.script">${project.dir}/ant/build.xml</property>
+ </properties>
+ <folders>
+ <source-folder>
+ <label>librepository</label>
+ <location>${project.dir}</location>
+ </source-folder>
+ </folders>
+ <ide-actions>
+ <action name="build">
+ <script>${ant.script}</script>
+ <target>all</target>
+ </action>
+ <action name="javadoc">
+ <script>${ant.script}</script>
+ <target>javadoc</target>
+ </action>
+ </ide-actions>
+ <view>
+ <items>
+ <source-file>
+ <location>${ant.script}</location>
+ </source-file>
+ </items>
+ <context-menu>
+ <ide-action name="build"/>
+ <ide-action name="javadoc"/>
+ </context-menu>
+ </view>
+ </general-data>
+ <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+ </configuration>
+</project>
diff --git a/external/jfreereport/nbprojects/libxml/nbproject/project.xml b/external/jfreereport/nbprojects/libxml/nbproject/project.xml
new file mode 100644
index 000000000..6b966c904
--- /dev/null
+++ b/external/jfreereport/nbprojects/libxml/nbproject/project.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.ant.freeform</type>
+ <configuration>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <!-- Do not use Project Properties customizer when editing this file manually. -->
+ <name>libxml</name>
+ <properties>
+ <property name="project.dir">../../wntmsci10/misc/build/libxml</property>
+ <property name="ant.script">${project.dir}/ant/build.xml</property>
+ </properties>
+ <folders>
+ <source-folder>
+ <label>libxml</label>
+ <location>${project.dir}</location>
+ </source-folder>
+ </folders>
+ <ide-actions>
+ <action name="build">
+ <script>${ant.script}</script>
+ <target>all</target>
+ </action>
+ <action name="javadoc">
+ <script>${ant.script}</script>
+ <target>javadoc</target>
+ </action>
+ </ide-actions>
+ <view>
+ <items>
+ <source-file>
+ <location>${ant.script}</location>
+ </source-file>
+ </items>
+ <context-menu>
+ <ide-action name="build"/>
+ <ide-action name="javadoc"/>
+ </context-menu>
+ </view>
+ </general-data>
+ <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1"/>
+ </configuration>
+</project>
diff --git a/external/jfreereport/patches/common_build.patch b/external/jfreereport/patches/common_build.patch
new file mode 100644
index 000000000..b197f494e
--- /dev/null
+++ b/external/jfreereport/patches/common_build.patch
@@ -0,0 +1,119 @@
+--- misc/libloader-1.1.3/common_build.xml 2009-11-16 10:25:34.000000000 +0100
++++ misc/build/libloader-1.1.3/common_build.xml 2009-12-04 10:22:24.277647200 +0100
+@@ -136,8 +136,6 @@
+ <property name="javac.deprecation"
+ value="true"
+ description="Indicates whether source should be compiled with deprecation information" />
+- <property name="javac.source" value="1.5" description="Provide source compatibility with specified release" />
+- <property name="javac.target" value="1.5" description="Generate class files for specific VM version" />
+
+ <!-- Build Cache properties -->
+ <property name="build.cache.dir"
+@@ -261,7 +261,7 @@ TYPICAL TARGET SEQUENCE
+ <property name="project.revision" value="${Implementation-Version}" description="Sets the version number of the project based on the Implementation-Version found in the manifest file (if one is supplied and nothing is specified in the build.properties)" />
+ <fail message="A project revision number has not been determined!">
+ <condition>
+- <matches string="${project.revision}" pattern="\$\{.*\}" />
++ <contains string="${project.revision}" substring="\$\{" />
+ </condition>
+ </fail>
+
+@@ -270,7 +270,7 @@ TYPICAL TARGET SEQUENCE
+ <property name="impl.title" value="${Implementation-Title}" description="Sets the title of the project based on the Implementation-Title found in the manifest file (if one is supplied and nothing is specified in the build.properties)" />
+ <fail message="A project title has not been determined!">
+ <condition>
+- <matches string="${impl.title}" pattern="\$\{.*\}" />
++ <contains string="${impl.title}" substring="\$\{" />
+ </condition>
+ </fail>
+
+@@ -497,7 +497,7 @@
+ Sets a property build.id to the either "development" or the svn revision
+ if in release mode
+ ====================================================================-->
+- <target name="set-build.id" unless="build.id" depends="install-antcontrib">
++ <target name="set-build.id" unless="build.id" >
+ <if>
+ <istrue value="${release}" />
+ <then>
+@@ -1061,12 +1061,17 @@
+ Performs the actual compile
+ ====================================================================-->
+ <target name="compile.compile" depends="init">
++ <copy todir="${classes.dir}">
++ <fileset dir="source">
++ <include name="**/*.properties"/>
++ </fileset>
++ </copy>
+ <javac destdir="${classes.dir}"
+ debug="${javac.debug}"
+ deprecation="${javac.deprecation}"
+ fork="true"
+- source="${javac.source}"
+- target="${javac.target}">
++ source="${ant.build.javac.source}"
++ target="${ant.build.javac.target}">
+ <classpath>
+ <path refid="classpath" />
+ </classpath>
+@@ -1082,27 +1087,32 @@
+ duplicate copying of resources from src tree (handled by compile.src_copy
+ if jar.include.source is set.
+ ====================================================================-->
+- <target name="compile.res_copy" depends="install-antcontrib">
+- <if>
+- <available file="${res.dir}" />
+- <then>
+- <copy todir="${classes.dir}">
+- <fileset dir="${res.dir}" />
+- </copy>
+- </then>
+- </if>
++ <target name="compile.res_copy" >
++ <condition property="copy.res.available">
++ <available file="$(res.dir)" type="dir" />
++ </condition>
++ <antcall target="copy.res" />
+
+- <if>
+- <not>
+- <isset property="jar.include.source" />
+- </not>
+- <then>
+- <copy todir="${classes.dir}" flatten="false">
+- <fileset dir="${src.dir}" excludes="**/*.java" />
+- </copy>
+- </then>
+- </if>
+- </target>
++ <condition property="copy.res.class.available">
++ <not>
++ <isset property="jar.include.source" />
++ </not>
++ </condition>
++ <antcall target="copy.res.class" />
++ </target>
++
++ <target name="copy.res" if="copy.res.available" >
++ <copy todir="${classes.dir}">
++ <fileset dir="${res.dir}"/>
++ </copy>
++ </target>
++
++ <target name="copy.res.class" if="copy.res.class.available" >
++ <uptodate targetfile="${classes.dir}" property="s">
++ <srcfiles dir= "${src.dir}" excludes="**/*.java" />
++ <flattenmapper/>
++ </uptodate>
++ </target>
+
+
+ <!--=======================================================================
+@@ -1167,7 +1177,6 @@
+ <target name="generate.manifest" depends="init,set-build.id">
+ <delete file="${dist.manifest.file}" />
+ <touch file="${dist.manifest.file}" />
+- <copy file="${manifest.file}" tofile="${dist.manifest.file}" overwrite="true" failonerror="false" />
+
+ <manifest file="${dist.manifest.file}" mode="update">
+ <attribute name="Implementation-Title" value="${impl.title}" />
diff --git a/external/jfreereport/patches/flow-engine.patch b/external/jfreereport/patches/flow-engine.patch
new file mode 100644
index 000000000..5cf834994
--- /dev/null
+++ b/external/jfreereport/patches/flow-engine.patch
@@ -0,0 +1,18 @@
+--- misc/flow-engine-0.9.4/build.xml (Revision 6728)
++++ misc/build/flow-engine-0.9.4/build.xml (Arbeitskopie)
+@@ -24,9 +24,12 @@
+
+ <!-- Setup the compile classpath -->
+ <path id="classpath">
+- <fileset dir="lib">
+- <include name="*.jar" />
+- </fileset>
++ <pathelement path="${libbase.jar}"/>
++ <pathelement path="${libformula.jar}"/>
++ <pathelement path="${liblayout.jar}"/>
++ <pathelement path="${libloader.jar}"/>
++ <pathelement path="${libserializer.jar}"/>
++ <pathelement path="${libxml.jar}"/>
+ </path>
+
+ <!-- Kill all the created directories -->
diff --git a/external/jfreereport/patches/flow-engine_date_is_datetime.patch.1 b/external/jfreereport/patches/flow-engine_date_is_datetime.patch.1
new file mode 100644
index 000000000..3ed23ee58
--- /dev/null
+++ b/external/jfreereport/patches/flow-engine_date_is_datetime.patch.1
@@ -0,0 +1,13 @@
+diff -ur jfreereport_flow_engine.org/source/org/jfree/report/expressions/ReportFormulaContext.java jfreereport_flow_engine/source/org/jfree/report/expressions/ReportFormulaContext.java
+--- jfreereport_flow_engine.org/source/org/jfree/report/expressions/ReportFormulaContext.java 2015-07-14 17:24:51.924156060 +0200
++++ jfreereport_flow_engine/source/org/jfree/report/expressions/ReportFormulaContext.java 2015-07-14 17:27:56.669270298 +0200
+@@ -120,7 +120,7 @@
+ {
+ if (flags.isDate())
+ {
+- return DateTimeType.DATE_TYPE;
++ return DateTimeType.DATETIME_TYPE;
+ }
+ if (flags.isNumeric())
+ {
+Only in jfreereport_flow_engine/source/org/jfree/report/expressions: ReportFormulaContext.java~
diff --git a/external/jfreereport/patches/libbase-1.1.3-remove-commons-logging.patch.1 b/external/jfreereport/patches/libbase-1.1.3-remove-commons-logging.patch.1
new file mode 100644
index 000000000..8d0df70a9
--- /dev/null
+++ b/external/jfreereport/patches/libbase-1.1.3-remove-commons-logging.patch.1
@@ -0,0 +1,903 @@
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/boot/AbstractBoot.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/boot/AbstractBoot.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/boot/AbstractBoot.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/boot/AbstractBoot.java 2021-02-23 12:11:46.680967049 +0000
+@@ -24,8 +24,7 @@
+ import java.util.ArrayList;
+ import java.util.Enumeration;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.config.Configuration;
+ import org.pentaho.reporting.libraries.base.config.ExtendedConfiguration;
+ import org.pentaho.reporting.libraries.base.config.ExtendedConfigurationWrapper;
+@@ -52,7 +51,7 @@
+ /**
+ * The logger for this class.
+ */
+- private static final Log LOGGER = LogFactory.getLog(AbstractBoot.class);
++ private static final Logger LOGGER = Logger.getLogger(AbstractBoot.class.getName());
+
+ /**
+ * The configuration wrapper around the plain configuration.
+@@ -163,7 +162,7 @@
+ }
+ if (isBootFailed())
+ {
+- LOGGER.error(getClass() + " failed to boot: " + bootFailed.getMessage());
++ LOGGER.severe(getClass() + " failed to boot: " + bootFailed.getMessage());
+ }
+ while (isBootInProgress())
+ {
+@@ -206,7 +205,7 @@
+ }
+ catch (Exception e)
+ {
+- LOGGER.error(getClass() + " failed to boot: ", e);
++ LOGGER.severe(getClass() + " failed to boot: " + e);
+ this.bootFailed = e;
+ }
+ finally
+@@ -265,8 +264,8 @@
+ if (boot.isBootFailed())
+ {
+ this.bootFailed = boot.getBootFailureReason();
+- LOGGER.error("Dependent project failed to boot up: " +
+- projectInformation.getBootClass() + " failed to boot: ", this.bootFailed);
++ LOGGER.severe("Dependent project failed to boot up: " +
++ projectInformation.getBootClass() + " failed to boot: " + this.bootFailed);
+ return;
+ }
+ }
+@@ -419,7 +418,7 @@
+ }
+ catch (IOException ioe)
+ {
+- LOGGER.warn("Failed to load the user configuration at " + url, ioe);
++ LOGGER.warning("Failed to load the user configuration at " + url + " : " + ioe);
+ }
+ }
+
+@@ -431,7 +430,7 @@
+ }
+ catch (IOException e)
+ {
+- LOGGER.warn("Failed to lookup the user configurations.", e);
++ LOGGER.warning("Failed to lookup the user configurations: " + e);
+ }
+ }
+ if (addSysProps)
+@@ -455,4 +454,4 @@
+ }
+ return extWrapper;
+ }
+-}
+\ No newline at end of file
++}
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/boot/PackageManager.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/boot/PackageManager.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/boot/PackageManager.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/boot/PackageManager.java 2021-02-23 12:18:45.836952221 +0000
+@@ -23,8 +23,8 @@
+ import java.util.HashMap;
+ import java.util.Iterator;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.config.Configuration;
+ import org.pentaho.reporting.libraries.base.config.PropertyFileConfiguration;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+@@ -63,7 +63,7 @@
+ }
+ }
+
+- private static final Log LOGGER = LogFactory.getLog(PackageManager.class);
++ private static final Logger LOGGER = Logger.getLogger(PackageManager.class.getName());
+
+ /**
+ * An internal constant declaring that the specified module was already loaded.
+@@ -201,7 +201,7 @@
+ }
+ }
+ }
+- LOGGER.debug("Loaded a total of " + count + " modules under prefix: " + modulePrefix);
++ LOGGER.config("Loaded a total of " + count + " modules under prefix: " + modulePrefix);
+ }
+
+ /**
+@@ -224,9 +224,9 @@
+
+ if (mod.configure(this.booter))
+ {
+- if (LOGGER.isDebugEnabled())
++ if (LOGGER.isLoggable(Level.CONFIG))
+ {
+- LOGGER.debug("Conf: " +
++ LOGGER.config("Conf: " +
+ new PadMessage(mod.getModule().getModuleClass(), 70) +
+ " [" + mod.getModule().getSubSystem() + ']');
+ }
+@@ -244,9 +244,9 @@
+
+ if (mod.initialize(this.booter))
+ {
+- if (LOGGER.isDebugEnabled())
++ if (LOGGER.isLoggable(Level.CONFIG))
+ {
+- LOGGER.debug("Init: " +
++ LOGGER.config("Init: " +
+ new PadMessage(mod.getModule().getModuleClass(), 70) +
+ " [" + mod.getModule().getSubSystem() + ']');
+ }
+@@ -271,12 +271,12 @@
+ final PackageState dependentState = (PackageState) modulesByClass.get(key);
+ if (dependentState == null)
+ {
+- LOGGER.warn("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not found.");
++ LOGGER.warning("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not found.");
+ return false;
+ }
+ if (dependentState.getState() != PackageState.STATE_CONFIGURED)
+ {
+- LOGGER.warn("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not configured.");
++ LOGGER.warning("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not configured.");
+ return false;
+ }
+ }
+@@ -300,12 +300,12 @@
+ final PackageState dependentState = (PackageState) modulesByClass.get(key);
+ if (dependentState == null)
+ {
+- LOGGER.warn("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not found.");
++ LOGGER.warning("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not found.");
+ return false;
+ }
+ if (dependentState.getState() != PackageState.STATE_INITIALIZED)
+ {
+- LOGGER.warn("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not initializable.");
++ LOGGER.warning("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not initializable.");
+ return false;
+ }
+ }
+@@ -418,15 +418,15 @@
+ {
+ if (fatal)
+ {
+- LOGGER.warn("Unresolved dependency for package: " + moduleInfo.getModuleClass());
++ LOGGER.warning("Unresolved dependency for package: " + moduleInfo.getModuleClass());
+ }
+- LOGGER.debug("Module class referenced, but not in classpath: " + moduleInfo.getModuleClass());
++ LOGGER.config("Module class referenced, but not in classpath: " + moduleInfo.getModuleClass());
+ }
+
+ if (acceptVersion(moduleInfo, module) == false)
+ {
+ // module conflict!
+- LOGGER.warn("Module " + module.getName() + ": required version: "
++ LOGGER.warning("Module " + module.getName() + ": required version: "
+ + moduleInfo + ", but found Version: \n" + module);
+ final PackageState state = new PackageState(module, PackageState.STATE_ERROR);
+ dropFailedModule(state);
+@@ -437,7 +437,7 @@
+ if (moduleContained == RETURN_MODULE_ERROR)
+ {
+ // the module caused harm before ...
+- LOGGER.debug("Indicated failure for module: " + module.getModuleClass());
++ LOGGER.config("Indicated failure for module: " + module.getModuleClass());
+ final PackageState state = new PackageState(module, PackageState.STATE_ERROR);
+ dropFailedModule(state);
+ return false;
+@@ -447,7 +447,7 @@
+ if (incompleteModules.contains(module))
+ {
+ // we assume that loading will continue ...
+- LOGGER.error
++ LOGGER.severe
+ ("Circular module reference: This module definition is invalid: " +
+ module.getClass());
+ final PackageState state = new PackageState(module, PackageState.STATE_ERROR);
+@@ -460,7 +460,7 @@
+ {
+ if (loadModule(required[i], incompleteModules, modules, true) == false)
+ {
+- LOGGER.debug("Indicated failure for module: " + module.getModuleClass());
++ LOGGER.config("Indicated failure for module: " + module.getModuleClass());
+ final PackageState state = new PackageState(module, PackageState.STATE_ERROR);
+ dropFailedModule(state);
+ return false;
+@@ -472,7 +472,7 @@
+ {
+ if (loadModule(optional[i], incompleteModules, modules, true) == false)
+ {
+- LOGGER.debug("Optional module: " + optional[i].getModuleClass() + " was not loaded.");
++ LOGGER.config("Optional module: " + optional[i].getModuleClass() + " was not loaded.");
+ }
+ }
+ // maybe a dependent module defined the same base module ...
+@@ -486,7 +486,7 @@
+ }
+ catch (Exception e)
+ {
+- LOGGER.warn("Exception while loading module: " + moduleInfo, e);
++ LOGGER.warning("Exception while loading module: " + moduleInfo + " : " + e);
+ return false;
+ }
+ }
+@@ -506,7 +506,7 @@
+ }
+ if (module.getMajorVersion() == null)
+ {
+- LOGGER.warn("Module " + module.getName() + " does not define a major version.");
++ LOGGER.warning("Module " + module.getName() + " does not define a major version.");
+ }
+ else
+ {
+@@ -528,7 +528,7 @@
+ }
+ if (module.getMinorVersion() == null)
+ {
+- LOGGER.warn("Module " + module.getName() + " does not define a minor version.");
++ LOGGER.warning("Module " + module.getName() + " does not define a minor version.");
+ }
+ else
+ {
+@@ -550,14 +550,14 @@
+ }
+ if (module.getPatchLevel() == null)
+ {
+- LOGGER.debug("Module " + module.getName() + " does not define a patch level.");
++ LOGGER.config("Module " + module.getName() + " does not define a patch level.");
+ }
+ else
+ {
+ if (acceptVersion(moduleRequirement.getPatchLevel(),
+ module.getPatchLevel()) > 0)
+ {
+- LOGGER.debug("Did not accept patchlevel: "
++ LOGGER.config("Did not accept patchlevel: "
+ + moduleRequirement.getPatchLevel() + " - "
+ + module.getPatchLevel());
+ return false;
+@@ -699,4 +699,4 @@
+ p.println(mod.getDescription());
+ }
+ }
+-}
+\ No newline at end of file
++}
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/boot/PackageSorter.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/boot/PackageSorter.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/boot/PackageSorter.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/boot/PackageSorter.java 2021-02-23 12:19:11.752198616 +0000
+@@ -23,8 +23,7 @@
+ import java.util.Iterator;
+ import java.util.List;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+
+ /**
+@@ -180,7 +179,7 @@
+ }
+
+ /** A logger for debug-messages. */
+- private static final Log LOGGER = LogFactory.getLog(PackageSorter.class);
++ private static final Logger LOGGER = Logger.getLogger(PackageSorter.class.getName());
+
+ /**
+ * DefaultConstructor.
+@@ -313,7 +312,7 @@
+ final SortModule reqMod = (SortModule) moduleMap.get(moduleName);
+ if (reqMod == null)
+ {
+- LOGGER.warn("Invalid state: Required dependency of '" + moduleName + "' had an error.");
++ LOGGER.warning("Invalid state: Required dependency of '" + moduleName + "' had an error.");
+ continue;
+ }
+ if (reqMod.getPosition() >= position)
+@@ -415,7 +414,7 @@
+ moduleMap.get(requiredModules[i].getModuleClass());
+ if (dependentModule == null)
+ {
+- LOGGER.warn
++ LOGGER.warning
+ ("A dependent module was not found in the list of known modules." +
+ requiredModules[i].getModuleClass());
+ continue;
+@@ -431,11 +430,11 @@
+ moduleMap.get(optionalModules[i].getModuleClass());
+ if (dependentModule == null)
+ {
+- LOGGER.warn("A dependent module was not found in the list of known modules.");
++ LOGGER.warning("A dependent module was not found in the list of known modules.");
+ continue;
+ }
+ collector.add(dependentModule.getSubSystem());
+ }
+ return collector;
+ }
+-}
+\ No newline at end of file
++}
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/boot/PackageState.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/boot/PackageState.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/boot/PackageState.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/boot/PackageState.java 2021-02-23 12:22:15.204942814 +0000
+@@ -17,8 +17,8 @@
+
+ package org.pentaho.reporting.libraries.base.boot;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+
+ /**
+ * The package state class is used by the package manager to keep track of
+@@ -31,7 +31,7 @@
+ public class PackageState
+ {
+ /** A logger. */
+- private static final Log LOGGER = LogFactory.getLog(PackageState.class);
++ private static final Logger LOGGER = Logger.getLogger(PackageState.class.getName());
+
+ /**
+ * A constant defining that the package is new.
+@@ -119,20 +119,20 @@
+ }
+ catch (NoClassDefFoundError noClassDef)
+ {
+- LOGGER.warn("Unable to load module classes for " +
++ LOGGER.warning("Unable to load module classes for " +
+ this.module.getName() + ':' + noClassDef.getMessage());
+ this.state = STATE_ERROR;
+ }
+ catch (Exception e)
+ {
+- if (LOGGER.isDebugEnabled())
++ if (LOGGER.isLoggable(Level.CONFIG))
+ {
+ // its still worth a warning, but now we are more verbose ...
+- LOGGER.warn("Unable to configure the module " + this.module.getName(), e);
++ LOGGER.warning("Unable to configure the module " + this.module.getName() + " : " + e);
+ }
+- else if (LOGGER.isWarnEnabled())
++ else if (LOGGER.isLoggable(Level.WARNING))
+ {
+- LOGGER.warn("Unable to configure the module " + this.module.getName());
++ LOGGER.warning("Unable to configure the module " + this.module.getName());
+ }
+ this.state = STATE_ERROR;
+ }
+@@ -187,32 +187,32 @@
+ }
+ catch (NoClassDefFoundError noClassDef)
+ {
+- LOGGER.warn("Unable to load module classes for " + this.module.getName() + ':' + noClassDef.getMessage());
++ LOGGER.warning("Unable to load module classes for " + this.module.getName() + ':' + noClassDef.getMessage());
+ this.state = STATE_ERROR;
+ }
+ catch (ModuleInitializeException me)
+ {
+- if (LOGGER.isDebugEnabled())
++ if (LOGGER.isLoggable(Level.CONFIG))
+ {
+ // its still worth a warning, but now we are more verbose ...
+- LOGGER.warn("Unable to initialize the module " + this.module.getName(), me);
++ LOGGER.warning("Unable to initialize the module " + this.module.getName() + " : " + me);
+ }
+- else if (LOGGER.isWarnEnabled())
++ else if (LOGGER.isLoggable(Level.WARNING))
+ {
+- LOGGER.warn("Unable to initialize the module " + this.module.getName());
++ LOGGER.warning("Unable to initialize the module " + this.module.getName());
+ }
+ this.state = STATE_ERROR;
+ }
+ catch (Exception e)
+ {
+- if (LOGGER.isDebugEnabled())
++ if (LOGGER.isLoggable(Level.CONFIG))
+ {
+ // its still worth a warning, but now we are more verbose ...
+- LOGGER.warn("Unable to initialize the module " + this.module.getName(), e);
++ LOGGER.warning("Unable to initialize the module " + this.module.getName() + " : " + e);
+ }
+- else if (LOGGER.isWarnEnabled())
++ else if (LOGGER.isLoggable(Level.WARNING))
+ {
+- LOGGER.warn("Unable to initialize the module " + this.module.getName());
++ LOGGER.warning("Unable to initialize the module " + this.module.getName());
+ }
+ this.state = STATE_ERROR;
+ }
+@@ -267,4 +267,4 @@
+ {
+ this.state = STATE_ERROR;
+ }
+-}
+\ No newline at end of file
++}
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/config/PropertyFileConfiguration.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/config/PropertyFileConfiguration.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/config/PropertyFileConfiguration.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/config/PropertyFileConfiguration.java 2021-02-23 12:13:55.788194558 +0000
+@@ -22,8 +22,7 @@
+ import java.io.InputStream;
+ import java.util.Properties;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+
+ /**
+@@ -34,7 +33,7 @@
+ public class PropertyFileConfiguration extends HierarchicalConfiguration
+ {
+ /** A logger for debug-messages. */
+- private static final Log LOGGER = LogFactory.getLog(PropertyFileConfiguration.class);
++ private static final Logger LOGGER = Logger.getLogger(PropertyFileConfiguration.class.getName());
+ /** A serialization related constant. */
+ private static final long serialVersionUID = 2423181637547944866L;
+
+@@ -89,7 +88,7 @@
+ }
+ else
+ {
+- LOGGER.debug("Configuration file not found in the classpath: " + resourceName);
++ LOGGER.config("Configuration file not found in the classpath: " + resourceName);
+ }
+
+ }
+@@ -118,9 +117,9 @@
+ }
+ catch (IOException ioe)
+ {
+- LOGGER.warn("Unable to read configuration", ioe);
++ LOGGER.warning("Unable to read configuration:" + ioe);
+ }
+
+ }
+
+-}
+\ No newline at end of file
++}
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/ClassQueryTool.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/ClassQueryTool.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/ClassQueryTool.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/ClassQueryTool.java 2021-02-23 12:24:05.460991092 +0000
+@@ -26,8 +26,7 @@
+ import java.util.zip.ZipEntry;
+ import java.util.zip.ZipInputStream;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * The class-query tool loads classes using a classloader and calls "processClass" for each class encountered. This is
+@@ -41,7 +40,7 @@
+ public abstract class ClassQueryTool
+ {
+ /** A logger. */
+- private static final Log logger = LogFactory.getLog(ClassQueryTool.class);
++ private static final Logger logger = Logger.getLogger(ClassQueryTool.class.getName());
+
+ /**
+ * The default constructor.
+@@ -89,7 +88,7 @@
+ catch (Throwable e)
+ {
+ // ignore ..
+- logger.debug("At class '" + className + "': " + e);
++ logger.config("At class '" + className + "': " + e);
+ }
+ }
+
+@@ -137,7 +136,7 @@
+ }
+ catch (final IOException e1)
+ {
+- logger.debug("Caught IO-Exception while processing file " + jarFile, e1);
++ logger.config("Caught IO-Exception while processing file " + jarFile + " : " + e1);
+ }
+ }
+
+@@ -225,7 +224,7 @@
+ for (int i = 0; i < allArray.length; i++)
+ {
+ final URL url = allArray[i];
+- logger.debug(url);
++ logger.config(url.toString());
+ }
+ for (int i = 0; i < urlsArray.length; i++)
+ {
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/DebugLog.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/DebugLog.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/DebugLog.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/DebugLog.java 2021-02-23 12:26:00.488084723 +0000
+@@ -17,8 +17,7 @@
+
+ package org.pentaho.reporting.libraries.base.util;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * This class provides static log messages for on-going bug-hunting efforts. This removes the need to create
+@@ -29,7 +28,7 @@
+ public final class DebugLog
+ {
+ /** A logger. */
+- private static final Log logger = LogFactory.getLog(DebugLog.class);
++ private static final Logger logger = Logger.getLogger(DebugLog.class.getName());
+
+ /**
+ * Logs a message using the debug-logger. By channeling all temporary log messages through this method,
+@@ -39,7 +38,7 @@
+ */
+ public static void log(final Object message)
+ {
+- logger.info(message);
++ logger.info(message.toString());
+ }
+
+ /**
+@@ -51,7 +50,7 @@
+ */
+ public static void log(final Object message, final Throwable t)
+ {
+- logger.info(message, t);
++ logger.info(message + " : " + t);
+ }
+
+ /**
+@@ -68,7 +67,7 @@
+ public static void logHereWE()
+ {
+ //noinspection ThrowableInstanceNeverThrown
+- logger.info("HERE: Debug point reached", new Exception("Debug-Point reached"));
++ logger.info("HERE: Debug point reached");
+ }
+
+ /**
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/ObjectUtilities.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/ObjectUtilities.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/ObjectUtilities.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/ObjectUtilities.java 2021-02-23 12:30:11.253468898 +0000
+@@ -29,8 +29,8 @@
+ import java.util.Arrays;
+ import java.util.StringTokenizer;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+
+ /**
+ * A collection of useful static utility methods for handling classes and object instantiation.
+@@ -39,7 +39,7 @@
+ */
+ public final class ObjectUtilities
+ {
+- private static final Log LOGGER = LogFactory.getLog(ObjectUtilities.class);
++ private static final Logger LOGGER = Logger.getLogger(ObjectUtilities.class.getName());
+
+ /**
+ * A constant for using the TheadContext as source for the classloader.
+@@ -180,15 +180,15 @@
+ }
+ catch (NoSuchMethodException e)
+ {
+- LOGGER.warn("Object without clone() method is impossible on class " + aClass, e);
++ LOGGER.warning("Object without clone() method is impossible on class " + aClass + " : " + e);
+ }
+ catch (IllegalAccessException e)
+ {
+- LOGGER.warn("Object.clone(): unable to call method 'clone()' on class " + aClass, e);
++ LOGGER.warning("Object.clone(): unable to call method 'clone()' on class " + aClass + " : " + e);
+ }
+ catch (InvocationTargetException e)
+ {
+- LOGGER.warn("Object without clone() method is impossible on class " + aClass, e);
++ LOGGER.warning("Object without clone() method is impossible on class " + aClass + " : " + e);
+ }
+ throw new CloneNotSupportedException
+ ("Failed to clone: Clone caused an Exception while cloning type " + aClass);
+@@ -424,32 +424,32 @@
+ if (type != null && type.isAssignableFrom(c) == false)
+ {
+ // this is unacceptable and means someone messed up the configuration
+- LOGGER.warn("Specified class " + className + " is not of expected type " + type);
++ LOGGER.warning("Specified class " + className + " is not of expected type " + type);
+ return null;
+ }
+ return c.newInstance();
+ }
+ catch (ClassNotFoundException e)
+ {
+- if (LOGGER.isDebugEnabled())
++ if (LOGGER.isLoggable(Level.CONFIG))
+ {
+- LOGGER.debug("Specified class " + className + " does not exist.");
++ LOGGER.config("Specified class " + className + " does not exist.");
+ }
+ // sometimes, this one is expected.
+ }
+ catch (NoClassDefFoundError e)
+ {
+- if (LOGGER.isDebugEnabled())
++ if (LOGGER.isLoggable(Level.CONFIG))
+ {
+- LOGGER.debug("Specified class " + className + " cannot be loaded [NOCLASSDEFERROR].");
++ LOGGER.config("Specified class " + className + " cannot be loaded [NOCLASSDEFERROR].");
+ }
+ }
+ catch (Throwable e)
+ {
+ // this is more severe than a class not being found at all
+- if (LOGGER.isDebugEnabled())
++ if (LOGGER.isLoggable(Level.CONFIG))
+ {
+- LOGGER.info("Specified class " + className + " failed to instantiate correctly.", e);
++ LOGGER.info("Specified class " + className + " failed to instantiate correctly." + " : " + e);
+ }
+ else
+ {
+@@ -615,4 +615,4 @@
+ }
+ return hashCode;
+ }
+-}
+\ No newline at end of file
++}
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/PngEncoder.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/PngEncoder.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/PngEncoder.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/PngEncoder.java 2021-02-23 12:27:15.484797751 +0000
+@@ -27,8 +27,7 @@
+ import java.util.zip.Deflater;
+ import java.util.zip.DeflaterOutputStream;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.encoder.ImageEncoder;
+ import org.pentaho.reporting.libraries.base.encoder.UnsupportedEncoderException;
+
+@@ -66,7 +65,7 @@
+ public class PngEncoder implements ImageEncoder
+ {
+ /** A logger for debug-messages. */
+- private static final Log logger = LogFactory.getLog(PngEncoder.class);
++ private static final Logger logger = Logger.getLogger(PngEncoder.class.getName());
+
+ /**
+ * Constant specifying that alpha channel should be encoded.
+@@ -622,12 +621,12 @@
+ }
+ catch (Exception e)
+ {
+- logger.error("interrupted waiting for pixels!", e);
++ logger.severe("interrupted waiting for pixels: " + e);
+ return false;
+ }
+ if ((pg.getStatus() & ImageObserver.ABORT) != 0)
+ {
+- logger.error("image fetch aborted or errored");
++ logger.severe("image fetch aborted or errored");
+ return false;
+ }
+
+@@ -709,7 +708,7 @@
+ }
+ catch (IOException e)
+ {
+- logger.error("Failed to write PNG Data", e);
++ logger.severe("Failed to write PNG Data:" + e);
+ return false;
+ }
+ }
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/ResourceBundleSupport.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/ResourceBundleSupport.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/ResourceBundleSupport.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/ResourceBundleSupport.java 2021-02-23 12:27:45.015078518 +0000
+@@ -36,8 +36,7 @@
+ import javax.swing.JMenu;
+ import javax.swing.KeyStroke;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * An utility class to ease up using property-file resource bundles.
+@@ -60,7 +59,7 @@
+ /**
+ * A logger for debug-messages.
+ */
+- private static final Log logger = LogFactory.getLog(ResourceBundleSupport.class);
++ private static final Logger logger = Logger.getLogger(ResourceBundleSupport.class.getName());
+
+ /**
+ * The resource bundle that will be used for local lookups.
+@@ -259,7 +258,7 @@
+ }
+ catch (Exception e)
+ {
+- logger.error("Error during global lookup", e);
++ logger.severe("Error during global lookup: " + e);
+ throw new MissingResourceException("Error during global lookup", getResourceBase(), key);
+ }
+ }
+@@ -643,7 +642,7 @@
+ final URL in = ObjectUtilities.getResource(name, ResourceBundleSupport.class);
+ if (in == null)
+ {
+- logger.warn("Unable to find file in the class path: " + name + "; key=" + key);
++ logger.warning("Unable to find file in the class path: " + name + "; key=" + key);
+ }
+ return in;
+ }
+@@ -668,13 +667,13 @@
+
+ if (in == null)
+ {
+- logger.warn("Unable to find file in the class path: " + resourceName);
++ logger.warning("Unable to find file in the class path: " + resourceName);
+ return new ImageIcon(createTransparentImage(1, 1));
+ }
+ final Image img = Toolkit.getDefaultToolkit().createImage(in);
+ if (img == null)
+ {
+- logger.warn("Unable to instantiate the image: " + resourceName);
++ logger.warning("Unable to instantiate the image: " + resourceName);
+ return new ImageIcon(createTransparentImage(1, 1));
+ }
+ if (scale)
+@@ -808,7 +808,7 @@
+ }
+ catch (MissingResourceException mre)
+ {
+- logger.warn ("ResourceBundleSupport#getString(,,)", mre);
++ logger.warning ("ResourceBundleSupport#getString(,,): " + mre);
+ return '!' + key + '!';
+ }
+ }
+@@ -821,7 +821,7 @@
+ }
+ catch (MissingResourceException mre)
+ {
+- logger.warn ("ResourceBundleSupport#getString(,,)", mre);
++ logger.warning ("ResourceBundleSupport#getString(,,): " + mre);
+ return '!' + key + '!';
+ }
+ }
+@@ -836,7 +836,7 @@
+ }
+ catch (MissingResourceException mre)
+ {
+- logger.warn ("ResourceBundleSupport#getString(,,)", mre);
++ logger.warning ("ResourceBundleSupport#getString(,,): " + mre);
+ return '!' + key + '!';
+ }
+ }
+@@ -852,7 +852,7 @@
+ }
+ catch (MissingResourceException mre)
+ {
+- logger.warn ("ResourceBundleSupport#getString(,,)", mre);
++ logger.warning ("ResourceBundleSupport#getString(,,): " + mre);
+ return '!' + key + '!';
+ }
+ }
+diff -ru libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/WaitingImageObserver.java libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/WaitingImageObserver.java
+--- libbase-1.1.3.orig/source/org/pentaho/reporting/libraries/base/util/WaitingImageObserver.java 2009-11-16 10:14:12.000000000 +0000
++++ libbase-1.1.3/source/org/pentaho/reporting/libraries/base/util/WaitingImageObserver.java 2021-02-23 12:30:28.223630238 +0000
+@@ -22,8 +22,7 @@
+ import java.awt.image.BufferedImage;
+ import java.awt.image.ImageObserver;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * This image observer blocks until the image is completely loaded. AWT defers the loading of images until they are
+@@ -37,7 +36,7 @@
+ public class WaitingImageObserver implements ImageObserver
+ {
+ /** A logger. */
+- private static final Log LOGGER = LogFactory.getLog(WaitingImageObserver.class);
++ private static final Logger LOGGER = Logger.getLogger(WaitingImageObserver.class.getName());
+
+ /**
+ * For serialization.
+@@ -149,7 +148,7 @@
+ }
+ catch (InterruptedException e)
+ {
+- LOGGER.info("WaitingImageObserver.waitImageLoaded(): InterruptedException thrown", e);
++ LOGGER.info("WaitingImageObserver.waitImageLoaded(): InterruptedException thrown: " + e);
+ }
+
+ if (maxLoadTime > 0 && lastUpdate < (System.currentTimeMillis() - maxLoadTime))
+@@ -172,4 +171,4 @@
+ {
+ return this.error;
+ }
+-}
+\ No newline at end of file
++}
+--- a/source/org/pentaho/reporting/libraries/base/util/IOUtils.java
++++ b/source/org/pentaho/reporting/libraries/base/util/IOUtils.java
+@@ -34,8 +34,7 @@
+ import java.sql.Clob;
+ import java.sql.SQLException;
+
+-import org.apache.commons.logging.LogFactory;
+-import org.apache.commons.logging.Log;
++import java.util.logging.Logger;
+
+ /**
+ * The IOUtils provide some IO related helper methods.
+@@ -48,7 +47,7 @@
+ * the singleton instance of the utility package.
+ */
+ private static IOUtils instance;
+- private static final Log logger = LogFactory.getLog(IOUtils.class);
++ private static final Logger logger = Logger.getLogger(IOUtils.class.getName());
+ /**
+ * DefaultConstructor.
+ */
+@@ -855,7 +854,7 @@
+ final long length = clob.length();
+ if (length > Integer.MAX_VALUE)
+ {
+- logger.warn ("This CLOB contains more than 2^31 characters. We cannot handle that.");
++ logger.warning ("This CLOB contains more than 2^31 characters. We cannot handle that.");
+ return null;
+ }
+
+@@ -867,7 +866,7 @@
+ }
+ catch (IOException e)
+ {
+- logger.warn ("Copying the stream failed.", e);
++ logger.warning ("Copying the stream failed: " + e);
+ }
+ try
+ {
+@@ -875,7 +874,7 @@
+ }
+ catch (IOException e)
+ {
+- logger.warn ("Failed to close input stream. No worries, we will be alright anyway.", e);
++ logger.warning ("Failed to close input stream. No worries, we will be alright anyway: " + e);
+ }
+ return outStream.toString();
+ }
+@@ -898,7 +897,7 @@
+ final long length = clob.length();
+ if (length > Integer.MAX_VALUE)
+ {
+- logger.warn ("This CLOB contains more than 2^31 characters. We cannot handle that.");
++ logger.warning ("This CLOB contains more than 2^31 characters. We cannot handle that.");
+ return null;
+ }
+
+@@ -910,7 +909,7 @@
+ }
+ catch (IOException e)
+ {
+- logger.warn ("Copying the stream failed.", e);
++ logger.warning ("Copying the stream failed: " + e);
+ }
+ try
+ {
+@@ -918,7 +917,7 @@
+ }
+ catch (IOException e)
+ {
+- logger.warn ("Failed to close input stream. No worries, we will be alright anyway.", e);
++ logger.warning ("Failed to close input stream. No worries, we will be alright anyway: " + e);
+ }
+ return outStream.toByteArray();
+ }
diff --git a/external/jfreereport/patches/libbase-1.1.6-deprecated.patch b/external/jfreereport/patches/libbase-1.1.6-deprecated.patch
new file mode 100644
index 000000000..e5cd38bd8
--- /dev/null
+++ b/external/jfreereport/patches/libbase-1.1.6-deprecated.patch
@@ -0,0 +1,53 @@
+--- misc/libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/ModuleInitializeException.java 2010-04-27 15:58:44.000000000 +0200
++++ misc/build/libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/ModuleInitializeException.java 2011-06-13 01:28:14.000000000 +0200
+@@ -48,7 +48,7 @@
+ */
+ public ModuleInitializeException(final String s, final Exception e)
+ {
+- super(s, e);
++ super(s, (Throwable) e);
+ }
+
+ /**
+--- misc/libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/ClassQueryTool.java 2010-04-27 15:58:46.000000000 +0200
++++ misc/build/libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/ClassQueryTool.java 2014-07-22 17:53:13.000000000 +0200
+@@ -173,7 +173,7 @@
+ final File file = directoryOrJar.getAbsoluteFile();
+ if (file.isDirectory() && file.exists() && file.canRead())
+ {
+- allURLs.add(file.toURL());
++ allURLs.add(file.toURI().toURL());
+ directoryURLs.add(file);
+ continue;
+ }
+@@ -186,8 +186,8 @@
+ final String fileName = file.getName();
+ if (fileName.endsWith(".jar") || fileName.endsWith(".zip"))
+ {
+- allURLs.add(file.toURL());
+- jarURLs.add(file.toURL());
++ allURLs.add(file.toURI().toURL());
++ jarURLs.add(file.toURI().toURL());
+ }
+ }
+
+@@ -199,7 +199,7 @@
+ final File file = driverFiles[i];
+ if (file.isDirectory() && file.exists() && file.canRead())
+ {
+- allURLs.add(file.toURL());
++ allURLs.add(file.toURI().toURL());
+ directoryURLs.add(file);
+ continue;
+ }
+@@ -212,8 +212,8 @@
+ final String fileName = file.getName();
+ if (fileName.endsWith(".jar") || fileName.endsWith(".zip"))
+ {
+- allURLs.add(file.toURL());
+- jarURLs.add(file.toURL());
++ allURLs.add(file.toURI().toURL());
++ jarURLs.add(file.toURI().toURL());
+ }
+ }
+ }
diff --git a/external/jfreereport/patches/libfonts-1.1.3-remove-commons-logging.patch.1 b/external/jfreereport/patches/libfonts-1.1.3-remove-commons-logging.patch.1
new file mode 100644
index 000000000..723a732a5
--- /dev/null
+++ b/external/jfreereport/patches/libfonts-1.1.3-remove-commons-logging.patch.1
@@ -0,0 +1,506 @@
+diff -ru libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/afm/AfmFontRegistry.java libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/afm/AfmFontRegistry.java
+--- libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/afm/AfmFontRegistry.java 2021-03-12 10:15:06.215353433 +0000
++++ libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/afm/AfmFontRegistry.java 2021-03-12 10:26:44.036236575 +0000
+@@ -37,8 +37,7 @@
+ import org.pentaho.reporting.libraries.resourceloader.ResourceData;
+ import org.pentaho.reporting.libraries.base.util.StringUtils;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 21.07.2007, 20:14:05
+@@ -47,7 +46,8 @@
+ */
+ public class AfmFontRegistry extends AbstractFontFileRegistry
+ {
+- private static final Log logger = LogFactory.getLog(AfmFontRegistry.class);
++ private static final Logger logger = Logger.getLogger(AfmFontRegistry.class.getName());
++
+ /**
+ * The font path filter is used to collect font files and directories during
+ * the font path registration.
+@@ -133,7 +133,7 @@
+ filePfb.isFile() == false ||
+ filePfb.canRead() == false)
+ {
+- logger.warn("Cannot embedd font: " + filePfb + " is missing for " + font);
++ logger.warning("Cannot embedd font: " + filePfb + " is missing for " + font);
+ embedded = false;
+ }
+
+@@ -264,11 +264,11 @@
+ catch (final ClassNotFoundException cnfe)
+ {
+ // ignore the exception.
+- logger.debug("Failed to restore the cache: Cache was created by a different version of LibFonts");
++ logger.config("Failed to restore the cache: Cache was created by a different version of LibFonts");
+ }
+ catch (Exception e)
+ {
+- logger.debug("Failed to restore the cache:", e);
++ logger.config("Failed to restore the cache: " + e);
+ }
+ }
+
+@@ -311,14 +311,14 @@
+ catch (IOException e)
+ {
+ // ignore ..
+- logger.debug("Failed to store cached font data", e);
++ logger.config("Failed to store cached font data: " + e);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ // should not happen
+- logger.debug("Failed to store cached font data", e);
++ logger.config("Failed to store cached font data: " + e);
+ }
+ }
+ }
+diff -ru libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/encoding/EncodingRegistry.java libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/encoding/EncodingRegistry.java
+--- libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/encoding/EncodingRegistry.java 2021-03-12 10:15:06.228353587 +0000
++++ libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/encoding/EncodingRegistry.java 2021-03-12 10:27:11.614524616 +0000
+@@ -31,8 +31,7 @@
+ import org.pentaho.reporting.libraries.resourceloader.factory.property.PropertiesResourceFactory;
+ import org.pentaho.reporting.libraries.base.config.Configuration;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * A global registry for all supported encodings. This offers the option to fall
+@@ -42,7 +41,7 @@
+ */
+ public final class EncodingRegistry
+ {
+- private static final Log logger = LogFactory.getLog(EncodingRegistry.class);
++ private static final Logger logger = Logger.getLogger(EncodingRegistry.class.getName());
+
+ /**
+ * Implementation doc: This class uses several sources to load the encodings.
+@@ -266,7 +265,7 @@
+ catch (Exception e)
+ {
+ // fall back ...
+- logger.warn("Failed to create external-encoding instance for key " + key, e);
++ logger.warning("Failed to create external-encoding instance for key " + key + " : " + e);
+ }
+ }
+ if (isEncodingSupportedJVM(name))
+diff -ru libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/encoding/generator/EncodingGenerator.java libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/encoding/generator/EncodingGenerator.java
+--- libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/encoding/generator/EncodingGenerator.java 2021-03-12 10:15:06.218353469 +0000
++++ libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/encoding/generator/EncodingGenerator.java 2021-03-12 10:27:47.015894357 +0000
+@@ -35,8 +35,7 @@
+ import org.pentaho.reporting.libraries.fonts.encoding.External8BitEncodingData;
+ import org.pentaho.reporting.libraries.base.config.DefaultConfiguration;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * A simple sourcecode generator.
+@@ -45,7 +44,7 @@
+ */
+ public class EncodingGenerator
+ {
+- private static final Log logger = LogFactory.getLog(EncodingGenerator.class);
++ private static final Logger logger = Logger.getLogger(EncodingGenerator.class.getName());
+
+ private File targetDirectory;
+ private DefaultConfiguration propertySet;
+@@ -200,7 +199,7 @@
+ }
+ catch(Exception e)
+ {
+- logger.warn ("Failed to generate Encoding " + key, e);
++ logger.warning("Failed to generate Encoding " + key + " : " + e);
+ }
+ }
+ }
+@@ -269,7 +268,7 @@
+ }
+ catch(Exception e)
+ {
+- logger.warn ("Failed to generate Encoding " + key, e);
++ logger.warning("Failed to generate Encoding " + key + " : " + e);
+ }
+ }
+
+diff -ru libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/pfm/PfmFontRegistry.java libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/pfm/PfmFontRegistry.java
+--- libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/pfm/PfmFontRegistry.java 2021-03-12 10:15:06.217353457 +0000
++++ libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/pfm/PfmFontRegistry.java 2021-03-12 10:28:33.904384084 +0000
+@@ -37,8 +37,7 @@
+ import org.pentaho.reporting.libraries.resourceloader.ResourceData;
+ import org.pentaho.reporting.libraries.base.util.StringUtils;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 21.07.2007, 16:58:06
+@@ -47,7 +46,7 @@
+ */
+ public class PfmFontRegistry extends AbstractFontFileRegistry
+ {
+- private static final Log logger = LogFactory.getLog(PfmFontRegistry.class);
++ private static final Logger logger = Logger.getLogger(PfmFontRegistry.class.getName());
+
+ /**
+ * The font path filter is used to collect font files and directories during
+@@ -146,7 +145,7 @@
+ filePfb.isFile() == false ||
+ filePfb.canRead() == false)
+ {
+- logger.warn("Cannot embedd font: " + filePfb + " is missing for " + font);
++ logger.warning("Cannot embedd font: " + filePfb + " is missing for " + font);
+ embedded = false;
+ }
+
+@@ -155,7 +154,7 @@
+ {
+ if (pfmFont.isItextCompatible() == false)
+ {
+- logger.warn("Cannot embedd font: pfb-file for " + font + " is not valid (according to iText).");
++ logger.warning("Cannot embedd font: pfb-file for " + font + " is not valid (according to iText).");
+ }
+ }
+ registerFont (pfmFont);
+@@ -283,7 +282,7 @@
+ }
+ catch (Exception e)
+ {
+- logger.debug("Failed to restore the cache:", e);
++ logger.config("Failed to restore the cache: " + e);
+ }
+ }
+
+@@ -326,14 +325,14 @@
+ catch (IOException e)
+ {
+ // ignore ..
+- logger.debug("Failed to store cached font data", e);
++ logger.config("Failed to store cached font data: " + e);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ // should not happen
+- logger.debug("Failed to store cached font data", e);
++ logger.config("Failed to store cached font data: " + e);
+ }
+ }
+ }
+diff -ru libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/registry/AbstractFontFileRegistry.java libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/registry/AbstractFontFileRegistry.java
+--- libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/registry/AbstractFontFileRegistry.java 2021-03-12 10:15:06.229353599 +0000
++++ libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/registry/AbstractFontFileRegistry.java 2021-03-12 10:25:43.831607771 +0000
+@@ -25,8 +25,7 @@
+ import java.util.Iterator;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.fonts.LibFontBoot;
+ import org.pentaho.reporting.libraries.fonts.encoding.EncodingRegistry;
+ import org.pentaho.reporting.libraries.base.util.StringUtils;
+@@ -39,7 +38,7 @@
+ */
+ public abstract class AbstractFontFileRegistry implements FontRegistry
+ {
+- private static final Log logger = LogFactory.getLog(AbstractFontFileRegistry.class);
++ private static final Logger logger = Logger.getLogger(AbstractFontFileRegistry.class.getName());
+
+ private HashMap seenFiles;
+
+@@ -74,7 +73,7 @@
+ }
+ catch (Exception e)
+ {
+- logger.warn("Extra font path " + extraDir + " could not be fully registered.", e);
++ logger.warning("Extra font path " + extraDir + " could not be fully registered: " + e);
+ }
+ }
+ }
+@@ -98,13 +97,13 @@
+ final String jrepath = safeSystemGetProperty("java.home", ".");
+ final String fs = safeSystemGetProperty("file.separator", File.separator);
+
+- logger.debug("Running on operating system: " + osname);
+- logger.debug("Character encoding used as default: " + encoding);
++ logger.config("Running on operating system: " + osname);
++ logger.config("Character encoding used as default: " + encoding);
+
+ if (safeSystemGetProperty("mrj.version", null) != null)
+ {
+ final String userhome = safeSystemGetProperty("user.home", ".");
+- logger.debug("Detected MacOS (Property 'mrj.version' is present.");
++ logger.config("Detected MacOS (Property 'mrj.version' is present.");
+ registerFontPath(new File(userhome + "/Library/Fonts"), encoding);
+ registerFontPath(new File("/Library/Fonts"), encoding);
+ registerFontPath(new File("/Network/Library/Fonts"), encoding);
+@@ -116,7 +115,7 @@
+ }
+ else
+ {
+- logger.debug("Assuming unix like file structures");
++ logger.config("Assuming unix like file structures");
+ // Assume X11 is installed in the default location.
+ registerFontPath(new File("/usr/X11R6/lib/X11/fonts"), encoding);
+ registerFontPath(new File("/usr/share/fonts"), encoding);
+@@ -145,7 +144,7 @@
+ */
+ private void registerWindowsFontPath(final String encoding)
+ {
+- logger.debug("Found 'Windows' in the OS name, assuming DOS/Win32 structures");
++ logger.config("Found 'Windows' in the OS name, assuming DOS/Win32 structures");
+ // Assume windows
+ // If you are not using windows, ignore this. This just checks if a windows system
+ // directory exist and includes a font dir.
+@@ -182,7 +181,7 @@
+ }
+ }
+ }
+- logger.debug("Fonts located in \"" + fontPath + '\"');
++ logger.config("Fonts located in \"" + fontPath + '\"');
+ if (fontPath != null)
+ {
+ final File file = new File(fontPath);
+@@ -272,7 +271,7 @@
+ }
+ catch (Exception e)
+ {
+- logger.warn("Font " + file + " is invalid. Message:" + e.getMessage(), e);
++ logger.warning("Font " + file + " is invalid. Message: " + e);
+ }
+ }
+ }
+diff -ru libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/text/GraphemeClassifier.java libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/text/GraphemeClassifier.java
+--- libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/text/GraphemeClassifier.java 2021-03-12 10:15:06.205353315 +0000
++++ libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/text/GraphemeClassifier.java 2021-03-12 10:29:03.600694237 +0000
+@@ -22,8 +22,7 @@
+ import java.io.IOException;
+
+ import org.pentaho.reporting.libraries.fonts.tools.ByteTable;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 11.06.2006, 17:11:16
+@@ -32,7 +31,7 @@
+ */
+ public final class GraphemeClassifier
+ {
+- private static final Log logger = LogFactory.getLog(GraphemeClassifier.class);
++ private static final Logger logger = Logger.getLogger(GraphemeClassifier.class.getName());
+
+ public static final int OTHER = 0;
+
+@@ -70,7 +69,7 @@
+ }
+ catch(Exception e)
+ {
+- logger.warn ("Unable to load the pre-generated classification data.", e);
++ logger.warning("Unable to load the pre-generated classification data: " + e);
+ }
+ finally
+ {
+diff -ru libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFont.java libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFont.java
+--- libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFont.java 2021-03-12 10:15:06.214353421 +0000
++++ libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFont.java 2021-03-12 10:29:19.746862875 +0000
+@@ -24,8 +24,7 @@
+ import org.pentaho.reporting.libraries.fonts.ByteAccessUtilities;
+ import org.pentaho.reporting.libraries.fonts.io.FileFontDataInputSource;
+ import org.pentaho.reporting.libraries.fonts.io.FontDataInputSource;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 06.11.2005, 18:27:21
+@@ -34,7 +33,7 @@
+ */
+ public class TrueTypeFont
+ {
+- private static final Log logger = LogFactory.getLog(TrueTypeFont.class);
++ private static final Logger logger = Logger.getLogger(TrueTypeFont.class.getName());
+
+ private static class TrueTypeFontHeader
+ {
+@@ -327,7 +326,7 @@
+ (FontHeaderTable) getTable(FontHeaderTable.TABLE_ID);
+ if (header == null)
+ {
+- logger.warn("The font '" + filename + "' does not have a 'head' table. The font file is not valid.");
++ logger.warning("The font '" + filename + "' does not have a 'head' table. The font file is not valid.");
+ return null;
+ }
+ final byte[] buffer =
+diff -ru libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFontMetricsFactory.java libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFontMetricsFactory.java
+--- libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFontMetricsFactory.java 2021-03-12 10:15:06.213353409 +0000
++++ libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFontMetricsFactory.java 2021-03-12 10:29:38.442058137 +0000
+@@ -21,8 +21,7 @@
+ import java.io.IOException;
+ import java.util.HashMap;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.fonts.io.FileFontDataInputSource;
+ import org.pentaho.reporting.libraries.fonts.io.FontDataInputSource;
+ import org.pentaho.reporting.libraries.fonts.registry.FontContext;
+@@ -38,7 +37,7 @@
+ */
+ public class TrueTypeFontMetricsFactory implements FontMetricsFactory
+ {
+- private static final Log logger = LogFactory.getLog(TrueTypeFontMetricsFactory.class);
++ private static final Logger logger = Logger.getLogger(TrueTypeFontMetricsFactory.class.getName());
+ private HashMap fontRecords;
+
+ public TrueTypeFontMetricsFactory()
+@@ -77,7 +76,7 @@
+ }
+ catch (IOException e)
+ {
+- logger.warn("Unable to read the font.", e);
++ logger.warning("Unable to read the font: " + e);
+ // todo: We should throw a better exception instead, shouldnt we?
+ throw new IllegalStateException();
+ }
+diff -ru libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFontRegistry.java libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFontRegistry.java
+--- libfonts-1.1.3.orig/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFontRegistry.java 2021-03-12 10:15:06.214353421 +0000
++++ libfonts-1.1.3/source/org/pentaho/reporting/libraries/fonts/truetype/TrueTypeFontRegistry.java 2021-03-12 10:31:15.504071887 +0000
+@@ -28,8 +28,7 @@
+ import java.io.Serializable;
+ import java.util.HashMap;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.fonts.FontException;
+ import org.pentaho.reporting.libraries.fonts.LibFontBoot;
+ import org.pentaho.reporting.libraries.fonts.cache.FontCache;
+@@ -61,7 +60,7 @@
+ return secondLevelCache;
+ }
+
+- private static final Log logger = LogFactory.getLog(TrueTypeFontRegistry.class);
++ private static final Logger logger = Logger.getLogger(TrueTypeFontRegistry.class.getName());
+
+ /**
+ * The font path filter is used to collect font files and directories during the font path registration.
+@@ -180,7 +179,7 @@
+ }
+ catch (Exception e)
+ {
+- logger.info("Unable to register font file " + file, e);
++ logger.info("Unable to register font file " + file + " : " + e);
+ // An error must not stop us on our holy mission to find and register
+ // all fonts :)
+ return false;
+@@ -206,7 +205,7 @@
+ }
+ catch (FontException e)
+ {
+- logger.info("The font '" + font.getFilename() + "' is invalid.", e);
++ logger.info("The font '" + font.getFilename() + "' is invalid: " + e);
+ return;
+ }
+
+@@ -347,11 +346,11 @@
+ catch (final ClassNotFoundException cnfe)
+ {
+ // ignore the exception.
+- logger.debug("Failed to restore the cache: Cache was created by a different version of LibFonts");
++ logger.config("Failed to restore the cache: Cache was created by a different version of LibFonts");
+ }
+ catch (Exception e)
+ {
+- logger.debug("Non-Fatal: Failed to restore the cache. The cache will be rebuilt.", e);
++ logger.config("Non-Fatal: Failed to restore the cache. The cache will be rebuilt: " + e);
+ }
+ }
+
+@@ -394,14 +393,14 @@
+ catch (IOException e)
+ {
+ // ignore ..
+- logger.debug("Failed to store cached font data", e);
++ logger.config("Failed to store cached font data: " + e);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ // should not happen
+- logger.debug("Failed to store cached font data", e);
++ logger.config("Failed to store cached font data: " + e);
+ }
+ }
+ }
+--- a/source/org/pentaho/reporting/libraries/fonts/itext/BaseFontSupport.java
++++ b/source/org/pentaho/reporting/libraries/fonts/itext/BaseFontSupport.java
+@@ -34,8 +34,8 @@
+ import org.pentaho.reporting.libraries.fonts.merge.CompoundFontRecord;
+ import org.pentaho.reporting.libraries.base.config.ExtendedConfiguration;
+ import org.pentaho.reporting.libraries.base.util.StringUtils;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+
+ /**
+ * iText font support.
+@@ -44,7 +44,7 @@
+ */
+ public class BaseFontSupport implements FontMapper
+ {
+- private static final Log logger = LogFactory.getLog(BaseFontSupport.class);
++ private static final Logger logger = Logger.getLogger(BaseFontSupport.class.getName());
+ /**
+ * Storage for BaseFont objects created.
+ */
+@@ -235,7 +235,7 @@
+ final FontSource source = (FontSource) registryFontRecord;
+ if (source.isEmbeddable() == false)
+ {
+- logger.warn("License of font forbids embedded usage for font: " + fontKey);
++ logger.warning("License of font forbids embedded usage for font: " + fontKey);
+ // strict mode here?
+ embeddedOverride = false;
+ }
+@@ -286,13 +286,13 @@
+ }
+ catch (Exception e)
+ {
+- if (logger.isDebugEnabled())
++ if (logger.isLoggable(Level.CONFIG))
+ {
+- logger.debug("BaseFont.createFont failed. Key = " + fontKey + ": " + e.getMessage(), e);
++ logger.config("BaseFont.createFont failed. Key = " + fontKey + ": " + e);
+ }
+- else if (logger.isWarnEnabled())
++ else if (logger.isLoggable(Level.WARNING))
+ {
+- logger.warn("BaseFont.createFont failed. Key = " + fontKey + ": " + e.getMessage());
++ logger.warning("BaseFont.createFont failed. Key = " + fontKey + ": " + e.getMessage());
+ }
+ }
+ // fallback .. use BaseFont.HELVETICA as default
+@@ -322,7 +322,7 @@
+ }
+ catch (Exception e)
+ {
+- logger.warn("BaseFont.createFont for FALLBACK failed.", e);
++ logger.warning("BaseFont.createFont for FALLBACK failed: " + e);
+ throw new BaseFontCreateException("Null font = " + fontKey);
+ }
+ throw new BaseFontCreateException("BaseFont creation failed, null font: " + fontKey);
diff --git a/external/jfreereport/patches/libfonts-1.1.6-deprecated.patch b/external/jfreereport/patches/libfonts-1.1.6-deprecated.patch
new file mode 100644
index 000000000..eb2ab8c76
--- /dev/null
+++ b/external/jfreereport/patches/libfonts-1.1.6-deprecated.patch
@@ -0,0 +1,11 @@
+--- misc/libfonts-1.1.6/source/org/pentaho/reporting/libraries/fonts/FontException.java 2010-04-27 16:09:00.000000000 +0200
++++ misc/build/libfonts-1.1.6/source/org/pentaho/reporting/libraries/fonts/FontException.java 2011-06-13 02:04:51.000000000 +0200
+@@ -39,7 +39,7 @@
+ */
+ public FontException(final String message, final Exception ex)
+ {
+- super(message, ex);
++ super(message, (Throwable) ex);
+ }
+
+ /**
diff --git a/external/jfreereport/patches/libformula-1.1.3-remove-commons-logging.patch.1 b/external/jfreereport/patches/libformula-1.1.3-remove-commons-logging.patch.1
new file mode 100644
index 000000000..5a578cf56
--- /dev/null
+++ b/external/jfreereport/patches/libformula-1.1.3-remove-commons-logging.patch.1
@@ -0,0 +1,266 @@
+diff -ru libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/Formula.java libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/Formula.java
+--- libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/Formula.java 2021-02-23 14:41:06.962127389 +0000
++++ libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/Formula.java 2021-02-23 14:48:18.016328356 +0000
+@@ -19,8 +19,7 @@
+
+ import java.io.Serializable;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.formula.lvalues.LValue;
+ import org.pentaho.reporting.libraries.formula.lvalues.TypeValuePair;
+ import org.pentaho.reporting.libraries.formula.parser.FormulaParseException;
+@@ -40,7 +39,7 @@
+ */
+ public class Formula implements Serializable, Cloneable
+ {
+- private static final Log logger = LogFactory.getLog(Formula.class);
++ private static final Logger logger = Logger.getLogger(Formula.class.getName());
+ private LValue rootReference;
+ private static final long serialVersionUID = -1176925812499923546L;
+
+@@ -105,7 +104,7 @@
+ final Type type = typeValuePair.getType();
+ if (type.isFlagSet(Type.ERROR_TYPE))
+ {
+- logger.debug("Error: " + typeValuePair.getValue());
++ logger.config("Error: " + typeValuePair.getValue());
+ }
+ else if (type.isFlagSet(Type.ARRAY_TYPE))
+ {
+@@ -131,7 +130,7 @@
+ }
+ catch (Exception e)
+ {
+- logger.warn("Evaluation failed unexpectedly: ", e);
++ logger.warning("Evaluation failed unexpectedly: " + e);
+ return new TypeValuePair(ErrorType.TYPE, LibFormulaErrorValue.ERROR_UNEXPECTED_VALUE);
+ }
+ }
+diff -ru libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/function/DefaultFunctionRegistry.java libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/function/DefaultFunctionRegistry.java
+--- libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/function/DefaultFunctionRegistry.java 2021-02-23 14:41:06.980127564 +0000
++++ libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/function/DefaultFunctionRegistry.java 2021-02-23 14:48:29.995445103 +0000
+@@ -25,9 +25,7 @@
+ import org.pentaho.reporting.libraries.base.util.HashNMap;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+ import org.pentaho.reporting.libraries.base.config.Configuration;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
+-
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 02.11.2006, 12:48:32
+@@ -36,7 +34,7 @@
+ */
+ public class DefaultFunctionRegistry implements FunctionRegistry
+ {
+- private static final Log logger = LogFactory.getLog(DefaultFunctionRegistry.class);
++ private static final Logger logger = Logger.getLogger(DefaultFunctionRegistry.class.getName());
+
+ private static final String FUNCTIONS_PREFIX = "org.pentaho.reporting.libraries.formula.functions.";
+ private static final String[] EMPTY_ARRAY = new String[0];
+@@ -72,7 +70,7 @@
+ final Function function = createFunction(aName);
+ if (function == null)
+ {
+- logger.debug ("There is no such function: " + aName);
++ logger.config ("There is no such function: " + aName);
+ }
+ else
+ {
+@@ -132,7 +130,7 @@
+ (functionClass, DefaultFunctionRegistry.class, Function.class);
+ if (function == null)
+ {
+- logger.debug ("There is no such function: " + name);
++ logger.config ("There is no such function: " + name);
+ }
+ else
+ {
+diff -ru libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/function/information/IsErrFunction.java libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/function/information/IsErrFunction.java
+--- libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/function/information/IsErrFunction.java 2021-02-23 14:41:06.983127594 +0000
++++ libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/function/information/IsErrFunction.java 2021-02-23 14:48:54.904687864 +0000
+@@ -27,8 +27,7 @@
+ import org.pentaho.reporting.libraries.formula.typing.Type;
+ import org.pentaho.reporting.libraries.formula.typing.coretypes.ErrorType;
+ import org.pentaho.reporting.libraries.formula.typing.coretypes.LogicalType;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * This function returns true if the parameter is of error and not of error type NA.
+@@ -37,7 +36,7 @@
+ */
+ public class IsErrFunction implements Function
+ {
+- private static final Log logger = LogFactory.getLog(IsErrFunction.class);
++ private static final Logger logger = Logger.getLogger(IsErrFunction.class.getName());
+ private static final TypeValuePair RETURN_TRUE = new TypeValuePair(LogicalType.TYPE, Boolean.TRUE);
+ private static final TypeValuePair RETURN_FALSE = new TypeValuePair(LogicalType.TYPE, Boolean.FALSE);
+ private static final long serialVersionUID = 6749192734608313367L;
+@@ -61,7 +60,7 @@
+
+ if (ErrorType.TYPE.equals(type) && value instanceof ErrorValue)
+ {
+- logger.warn ("Passing errors around is deprecated. Throw exceptions instead.");
++ logger.warning("Passing errors around is deprecated. Throw exceptions instead.");
+ final ErrorValue na = (ErrorValue) value;
+ if (na.getErrorCode() == LibFormulaErrorValue.ERROR_NA)
+ {
+diff -ru libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/function/information/IsNaFunction.java libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/function/information/IsNaFunction.java
+--- libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/function/information/IsNaFunction.java 2021-02-23 14:41:06.984127603 +0000
++++ libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/function/information/IsNaFunction.java 2021-02-23 14:49:05.917795194 +0000
+@@ -27,8 +27,7 @@
+ import org.pentaho.reporting.libraries.formula.typing.Type;
+ import org.pentaho.reporting.libraries.formula.typing.coretypes.ErrorType;
+ import org.pentaho.reporting.libraries.formula.typing.coretypes.LogicalType;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * This function returns true if the parameter is of error type NA.
+@@ -39,7 +38,7 @@
+ {
+ private static final TypeValuePair RETURN_FALSE = new TypeValuePair(LogicalType.TYPE, Boolean.FALSE);
+ private static final TypeValuePair RETURN_TRUE = new TypeValuePair(LogicalType.TYPE, Boolean.TRUE);
+- private static final Log logger = LogFactory.getLog(IsNaFunction.class);
++ private static final Logger logger = Logger.getLogger(IsNaFunction.class.getName());
+ private static final long serialVersionUID = 1205462839536368718L;
+
+ public IsNaFunction()
+@@ -61,7 +60,7 @@
+
+ if (ErrorType.TYPE.equals(type) && value instanceof ErrorValue)
+ {
+- logger.warn ("Passing errors around is deprecated. Throw exceptions instead.");
++ logger.warning("Passing errors around is deprecated. Throw exceptions instead.");
+ final ErrorValue na = (ErrorValue) value;
+ if (na.getErrorCode() == LibFormulaErrorValue.ERROR_NA)
+ {
+diff -ru libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/lvalues/FormulaFunction.java libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/lvalues/FormulaFunction.java
+--- libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/lvalues/FormulaFunction.java 2021-02-23 14:41:06.988127642 +0000
++++ libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/lvalues/FormulaFunction.java 2021-02-23 14:50:26.354579111 +0000
+@@ -17,8 +17,8 @@
+
+ package org.pentaho.reporting.libraries.formula.lvalues;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.formula.EvaluationException;
+ import org.pentaho.reporting.libraries.formula.FormulaContext;
+ import org.pentaho.reporting.libraries.formula.LibFormulaErrorValue;
+@@ -44,7 +44,7 @@
+ */
+ public class FormulaFunction extends AbstractLValue
+ {
+- private static final Log logger = LogFactory.getLog(FormulaFunction.class);
++ private static final Logger logger = Logger.getLogger(FormulaFunction.class.getName());
+
+ private static class FormulaParameterCallback implements ParameterCallback
+ {
+@@ -74,9 +74,9 @@
+ final TypeValuePair converted = typeRegistry.convertTo(paramType, result);
+ if (converted == null)
+ {
+- if (logger.isDebugEnabled())
++ if (logger.isLoggable(Level.CONFIG))
+ {
+- logger.debug("Failed to evaluate parameter " + pos + " on function " + function);
++ logger.config("Failed to evaluate parameter " + pos + " on function " + function);
+ }
+ throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_INVALID_AUTO_ARGUMENT_VALUE);
+ }
+@@ -228,7 +228,7 @@
+ }
+ catch (Exception e)
+ {
+- logger.error("Unexpected exception while evaluating", e);
++ logger.severe("Unexpected exception while evaluating: " + e);
+ throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_UNEXPECTED_VALUE);
+ }
+ }
+diff -ru libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/typing/DefaultTypeRegistry.java libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/typing/DefaultTypeRegistry.java
+--- libformula-1.1.3.orig/source/org/pentaho/reporting/libraries/formula/typing/DefaultTypeRegistry.java 2021-02-23 14:41:06.961127380 +0000
++++ libformula-1.1.3/source/org/pentaho/reporting/libraries/formula/typing/DefaultTypeRegistry.java 2021-02-23 14:47:11.376678905 +0000
+@@ -35,8 +35,7 @@
+ import java.util.List;
+ import java.util.Locale;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.config.Configuration;
+ import org.pentaho.reporting.libraries.base.util.IOUtils;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+@@ -66,7 +65,7 @@
+ */
+ public class DefaultTypeRegistry implements TypeRegistry
+ {
+- private static final Log logger = LogFactory.getLog(DefaultTypeRegistry.class);
++ private static final Logger logger = Logger.getLogger(DefaultTypeRegistry.class.getName());
+
+ private static class ArrayConverterCallback implements ArrayCallback
+ {
+@@ -599,7 +598,7 @@
+ }
+ else
+ {
+- logger.warn("Assertation failure: Type declared to be a sequence, but no sequence found inside.");
++ logger.warning("Assertation failure: Type declared to be a sequence, but no sequence found inside.");
+ throw TypeConversionException.getInstance();
+ }
+ }
+@@ -612,7 +611,7 @@
+ }
+ else
+ {
+- logger.warn("Assertation failure: Type declared to be array, but no array callback found inside.");
++ logger.warning("Assertation failure: Type declared to be array, but no array callback found inside.");
+ throw TypeConversionException.getInstance();
+ }
+ }
+@@ -651,7 +650,7 @@
+ }
+ else
+ {
+- logger.warn("Assertation failure: Type declared to be array, but no array callback found inside.");
++ logger.warning("Assertation failure: Type declared to be array, but no array callback found inside.");
+ throw TypeConversionException.getInstance();
+ }
+ }
+--- a/source/org/pentaho/reporting/libraries/formula/function/logical/IfNaFunction.java
++++ b/source/org/pentaho/reporting/libraries/formula/function/logical/IfNaFunction.java
+@@ -17,8 +17,7 @@
+
+ package org.pentaho.reporting.libraries.formula.function.logical;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.formula.ErrorValue;
+ import org.pentaho.reporting.libraries.formula.EvaluationException;
+ import org.pentaho.reporting.libraries.formula.FormulaContext;
+@@ -37,7 +36,7 @@
+ */
+ public class IfNaFunction implements Function
+ {
+- private static final Log logger = LogFactory.getLog(IfNaFunction.class);
++ private static final Logger logger = Logger.getLogger(IfNaFunction.class.getName());
+ private static final long serialVersionUID = -7517668261071087411L;
+
+ public IfNaFunction()
+@@ -67,7 +66,7 @@
+ value = parameters.getValue(0);
+ if (ErrorType.TYPE.equals(type) && value instanceof ErrorValue)
+ {
+- logger.warn("Passing errors around is deprecated. Throw exceptions instead.");
++ logger.warning("Passing errors around is deprecated. Throw exceptions instead.");
+ final ErrorValue na = (ErrorValue) value;
+ if (na.getErrorCode() == LibFormulaErrorValue.ERROR_NA)
+ {
diff --git a/external/jfreereport/patches/libformula-datevalue_truncation.patch.1 b/external/jfreereport/patches/libformula-datevalue_truncation.patch.1
new file mode 100644
index 000000000..069c667c1
--- /dev/null
+++ b/external/jfreereport/patches/libformula-datevalue_truncation.patch.1
@@ -0,0 +1,29 @@
+diff -ur jfreereport_libformula.org/source/org/pentaho/reporting/libraries/formula/function/datetime/DateValueFunction.java jfreereport_libformula/source/org/pentaho/reporting/libraries/formula/function/datetime/DateValueFunction.java
+--- jfreereport_libformula.org/source/org/pentaho/reporting/libraries/formula/function/datetime/DateValueFunction.java 2010-06-01 17:15:50.000000000 +0200
++++ jfreereport_libformula/source/org/pentaho/reporting/libraries/formula/function/datetime/DateValueFunction.java 2015-07-14 17:24:42.503895240 +0200
+@@ -18,6 +18,7 @@
+ package org.pentaho.reporting.libraries.formula.function.datetime;
+
+ import java.util.Date;
++import java.util.Calendar;
+
+ import org.pentaho.reporting.libraries.formula.EvaluationException;
+ import org.pentaho.reporting.libraries.formula.FormulaContext;
+@@ -28,6 +29,7 @@
+ import org.pentaho.reporting.libraries.formula.typing.Type;
+ import org.pentaho.reporting.libraries.formula.typing.TypeRegistry;
+ import org.pentaho.reporting.libraries.formula.typing.coretypes.DateTimeType;
++import org.pentaho.reporting.libraries.formula.util.DateUtil;
+
+ /**
+ * This function returns
+@@ -61,7 +63,8 @@
+ final Object value = parameters.getValue(0);
+
+ final Date date1 = typeRegistry.convertToDate(type, value);
+- return new TypeValuePair(DateTimeType.DATE_TYPE, date1);
++ final Date date = DateUtil.normalizeDate(date1, DateTimeType.DATE_TYPE);
+
++ return new TypeValuePair(DateTimeType.DATE_TYPE, date);
+ }
+ }
diff --git a/external/jfreereport/patches/libformula-minutes_truncation.patch.1 b/external/jfreereport/patches/libformula-minutes_truncation.patch.1
new file mode 100644
index 000000000..71f0be2c9
--- /dev/null
+++ b/external/jfreereport/patches/libformula-minutes_truncation.patch.1
@@ -0,0 +1,14 @@
+diff -ur jfreereport_libformula.org/source/org/pentaho/reporting/libraries/formula/function/datetime/MinuteFunction.java jfreereport_libformula/source/org/pentaho/reporting/libraries/formula/function/datetime/MinuteFunction.java
+--- jfreereport_libformula.org/source/org/pentaho/reporting/libraries/formula/function/datetime/MinuteFunction.java 2015-07-13 15:55:31.752539618 +0200
++++ jfreereport_libformula/source/org/pentaho/reporting/libraries/formula/function/datetime/MinuteFunction.java 2015-07-13 15:56:27.084394065 +0200
+@@ -74,7 +74,7 @@
+
+ // Multiply the minutes with 60 to get the minutes as ints
+ final BigDecimal minutes = minutesFraction.multiply(MINUTES);
+- final BigDecimal minutesAsInt = minutes.setScale(0, BigDecimal.ROUND_HALF_UP);
++ final BigDecimal minutesAsInt = NumberUtil.performIntRounding(minutes);
+ return new TypeValuePair(NumberType.GENERIC_NUMBER, minutesAsInt);
+ }
+-}
+\ Pas de fin de ligne à la fin du fichier
++}
diff --git a/external/jfreereport/patches/libformula-seconds_rounding.patch.1 b/external/jfreereport/patches/libformula-seconds_rounding.patch.1
new file mode 100644
index 000000000..369332d1a
--- /dev/null
+++ b/external/jfreereport/patches/libformula-seconds_rounding.patch.1
@@ -0,0 +1,37 @@
+diff -ur jfreereport_libformula.org/source/org/pentaho/reporting/libraries/formula/function/datetime/SecondFunction.java jfreereport_libformula/source/org/pentaho/reporting/libraries/formula/function/datetime/SecondFunction.java
+--- jfreereport_libformula.org/source/org/pentaho/reporting/libraries/formula/function/datetime/SecondFunction.java 2016-03-05 09:43:06.121774691 +0100
++++ jfreereport_libformula/source/org/pentaho/reporting/libraries/formula/function/datetime/SecondFunction.java 2016-03-05 09:51:04.810488511 +0100
+@@ -29,7 +29,7 @@
+ import org.pentaho.reporting.libraries.formula.util.NumberUtil;
+
+ /**
+- * This function extracts the minute (0 through 59) from a time.
++ * This function extracts the seconds (0 through 59) from a time.
+ *
+ * @author Cedric Pronzato
+ */
+@@ -67,14 +67,15 @@
+
+ // time * 24 so that we get the full hours (which we remove later)
+ final BigDecimal bd = NumberUtil.getAsBigDecimal(n);
+- final BigDecimal hours = bd.multiply(MINUTES_PER_DAY);
+- final BigDecimal dayAndHoursAsInt = NumberUtil.performIntRounding(hours);
+- final BigDecimal minutesFraction = hours.subtract(dayAndHoursAsInt);
+-
+- // Multiply the minutes with 60 to get the minutes as ints
+- final BigDecimal seconds = minutesFraction.multiply(SECONDS);
+- final BigDecimal secondsAsInt = NumberUtil.performIntRounding(seconds);
++ final BigDecimal minutes = bd.multiply(MINUTES_PER_DAY);
++ final BigDecimal dayHoursAndMinutesAsInt = NumberUtil.performIntRounding(minutes);
++ final BigDecimal secondsFraction = minutes.subtract(dayHoursAndMinutesAsInt);
++
++ // Multiply the minutes with 60 to get the seconds as ints
++ final BigDecimal seconds = secondsFraction.multiply(SECONDS);
++ final BigDecimal nanoSeconds = seconds.setScale(9, BigDecimal.ROUND_HALF_UP);
++ final BigDecimal secondsAsInt = NumberUtil.performIntRounding(nanoSeconds);
+
+ return new TypeValuePair(NumberType.GENERIC_NUMBER, secondsAsInt);
+ }
+-}
+\ No newline at end of file
++}
diff --git a/external/jfreereport/patches/libformula-time-notz.patch b/external/jfreereport/patches/libformula-time-notz.patch
new file mode 100644
index 000000000..fec65b17e
--- /dev/null
+++ b/external/jfreereport/patches/libformula-time-notz.patch
@@ -0,0 +1,22 @@
+--- a/jfreereport_libformula/source/org/pentaho/reporting/libraries/formula/DefaultLocalizationContext.java 2010-06-01 17:15:52.000000000 +0200
++++ a/jfreereport_libformula.patched/source/org/pentaho/reporting/libraries/formula/DefaultLocalizationContext.java 2013-08-06 13:11:58.000000000 +0200
+@@ -162,11 +169,17 @@
+ final Locale activeLocale = getLocale();
+ datetimeFormats.add(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, activeLocale));
+ dateFormats.add(DateFormat.getDateInstance(DateFormat.FULL, activeLocale));
+- timeFormats.add(DateFormat.getTimeInstance(DateFormat.FULL, activeLocale));
++ // LEM: "FULL" does not really make sense for isolated times:
++ // in the absence of a date, it cannot know whether it is meant in the winter-timezone
++ // or in the summer (daylight saving time) timezone, and will always display the winter timezone.
++ // timeFormats.add(DateFormat.getTimeInstance(DateFormat.FULL, activeLocale));
+
+ datetimeFormats.add(DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, activeLocale));
+ dateFormats.add(DateFormat.getDateInstance(DateFormat.LONG, activeLocale));
+- timeFormats.add(DateFormat.getTimeInstance(DateFormat.LONG, activeLocale));
++ // LEM: "LONG" does not really make sense for isolated times:
++ // in the absence of a date, it cannot know whether it is meant in the winter-timezone
++ // or in the summer (daylight saving time) timezone, and will always display the winter timezone.
++ // timeFormats.add(DateFormat.getTimeInstance(DateFormat.LONG, activeLocale));
+
+ datetimeFormats.add(DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, activeLocale));
+ dateFormats.add(DateFormat.getDateInstance(DateFormat.MEDIUM, activeLocale));
diff --git a/external/jfreereport/patches/liblayout-0.2.10-remove-commons-logging.patch.1 b/external/jfreereport/patches/liblayout-0.2.10-remove-commons-logging.patch.1
new file mode 100644
index 000000000..5c71a57d2
--- /dev/null
+++ b/external/jfreereport/patches/liblayout-0.2.10-remove-commons-logging.patch.1
@@ -0,0 +1,860 @@
+diff -ru liblayout-0.2.10.orig/source/org/jfree/layouting/input/style/parser/CSSValueFactory.java liblayout-0.2.10/source/org/jfree/layouting/input/style/parser/CSSValueFactory.java
+--- liblayout-0.2.10.orig/source/org/jfree/layouting/input/style/parser/CSSValueFactory.java 2021-04-07 10:34:09.797045462 +0100
++++ liblayout-0.2.10/source/org/jfree/layouting/input/style/parser/CSSValueFactory.java 2021-04-07 10:41:20.015338056 +0100
+@@ -49,8 +49,7 @@
+ import org.jfree.layouting.input.style.values.CSSStringValue;
+ import org.jfree.layouting.input.style.values.CSSValue;
+ import org.w3c.css.sac.LexicalUnit;
+-import org.apache.commons.logging.LogFactory;
+-import org.apache.commons.logging.Log;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.config.Configuration;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+
+@@ -61,7 +60,7 @@
+ */
+ public class CSSValueFactory
+ {
+- private static final Log logger = LogFactory.getLog(CSSValueFactory.class);
++ private static final Logger logger = Logger.getLogger(CSSValueFactory.class.getName());
+ public static final String SIMPLE_PREFIX = "org.jfree.layouting.parser.handlers.";
+ public static final String COMPOUND_PREFIX = "org.jfree.layouting.parser.compoundhandlers.";
+
+@@ -99,7 +98,7 @@
+ }
+ else
+ {
+- logger.warn("Invalid module implementation: " + c);
++ logger.warning("Invalid module implementation: " + c);
+ }
+ }
+
+@@ -300,7 +299,7 @@
+ (CSSCompoundValueReadHandler) compoundHandlers.get(name);
+ if (handler == null)
+ {
+- logger.warn("Got no key for inherited value: " + name);
++ logger.warning("Got no key for inherited value: " + name);
+ return;
+ }
+
+@@ -324,7 +323,7 @@
+ (CSSCompoundValueReadHandler) compoundHandlers.get(name);
+ if (handler == null)
+ {
+- logger.warn("Got no key for compound attr function: " + name);
++ logger.warning("Got no key for compound attr function: " + name);
+ return;
+ }
+
+@@ -373,7 +372,7 @@
+ {
+ if (key == null)
+ {
+- // Log.warn("Got no key for attribute-function " + normalizedName);
++ // Log.warning("Got no key for attribute-function " + normalizedName);
+ setCompundAttrValue(normalizedName, attrFn, rule, important);
+ return;
+ }
+@@ -387,7 +386,7 @@
+ // ATTR function (extended version).
+ if (key == null)
+ {
+- logger.warn("Got no key for attribute-function " + normalizedName);
++ logger.warning("Got no key for attribute-function " + normalizedName);
+ return;
+ }
+ final CSSAttrFunction attrFn = parseComplexAttrFn(value.getParameters());
+@@ -421,7 +420,7 @@
+ return;
+ }
+
+- logger.warn("Unparsable value: Got no valid result for " + normalizedName + " (" + value + ')');
++ logger.warning("Unparsable value: Got no valid result for " + normalizedName + " (" + value + ')');
+ return; // ignore this rule ..
+ }
+ final Map map = module.createValues(value);
+diff -ru liblayout-0.2.10.orig/source/org/jfree/layouting/input/style/parser/StyleSheetHandler.java liblayout-0.2.10/source/org/jfree/layouting/input/style/parser/StyleSheetHandler.java
+--- liblayout-0.2.10.orig/source/org/jfree/layouting/input/style/parser/StyleSheetHandler.java 2021-04-07 10:34:09.798045474 +0100
++++ liblayout-0.2.10/source/org/jfree/layouting/input/style/parser/StyleSheetHandler.java 2021-04-07 10:48:18.496489721 +0100
+@@ -60,8 +60,7 @@
+ import org.pentaho.reporting.libraries.resourceloader.Resource;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceException;
+ import org.pentaho.reporting.libraries.base.util.FastStack;
+-import org.apache.commons.logging.LogFactory;
+-import org.apache.commons.logging.Log;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 23.11.2005, 13:06:06
+@@ -70,7 +69,7 @@
+ */
+ public class StyleSheetHandler implements DocumentHandler, ErrorHandler
+ {
+- private static final Log logger = LogFactory.getLog(StyleSheetHandler.class);
++ private static final Logger logger = Logger.getLogger(StyleSheetHandler.class.getName());
+ private HashMap namespaces;
+ private StyleKeyRegistry registry;
+ private StyleSheet styleSheet;
+@@ -614,7 +613,7 @@
+ catch (Exception e)
+ {
+ // we catch everything.
+- logger.warn("Error parsing style key: " + name, e);
++ logger.warning("Error parsing style key: " + name + " : " + e);
+ }
+
+ }
+@@ -639,7 +638,7 @@
+ public void warning(final CSSParseException exception)
+ throws CSSException
+ {
+- logger.warn("Warning: " + exception.getMessage());
++ logger.warning("Warning: " + exception.getMessage());
+ }
+
+ /**
+@@ -665,7 +664,7 @@
+ public void error(final CSSParseException exception)
+ throws CSSException
+ {
+- logger.warn("Error: ", exception);
++ logger.warning("Error: " + exception);
+ }
+
+ /**
+@@ -690,6 +689,6 @@
+ public void fatalError(final CSSParseException exception)
+ throws CSSException
+ {
+- logger.warn("Fatal Error: ", exception);
++ logger.warning("Fatal Error: " + exception);
+ }
+ }
+diff -ru liblayout-0.2.10.orig/source/org/jfree/layouting/normalizer/generator/PrintContentGenerator.java liblayout-0.2.10/source/org/jfree/layouting/normalizer/generator/PrintContentGenerator.java
+--- liblayout-0.2.10.orig/source/org/jfree/layouting/normalizer/generator/PrintContentGenerator.java 2021-04-07 10:34:09.766045081 +0100
++++ liblayout-0.2.10/source/org/jfree/layouting/normalizer/generator/PrintContentGenerator.java 2021-04-07 10:47:20.093770766 +0100
+@@ -38,8 +38,7 @@
+ import org.jfree.layouting.layouter.context.PageContext;
+ import org.jfree.layouting.normalizer.content.NormalizationException;
+ import org.jfree.layouting.renderer.Renderer;
+-import org.apache.commons.logging.LogFactory;
+-import org.apache.commons.logging.Log;
++import java.util.logging.Logger;
+
+ /**
+ * Simply prints each incoming call.
+@@ -48,7 +47,7 @@
+ */
+ public class PrintContentGenerator implements ContentGenerator
+ {
+- private static final Log logger = LogFactory.getLog(PrintContentGenerator.class);
++ private static final Logger logger = Logger.getLogger(PrintContentGenerator.class.getName());
+
+
+ private static class PrintContentGeneratorState implements State
+@@ -96,56 +95,56 @@
+ */
+ public void startedDocument(final PageContext pageContext)
+ {
+- logger.debug("<document>");
++ logger.config("<document>");
+ renderer.startedDocument(pageContext);
+ }
+
+ public void startedFlow(final LayoutContext element)
+ throws NormalizationException
+ {
+- logger.debug("<flow tag='" + element.getTagName() + "'>");
++ logger.config("<flow tag='" + element.getTagName() + "'>");
+ renderer.startedFlow(element);
+ }
+
+ public void startedTable(final LayoutContext element)
+ throws NormalizationException
+ {
+- logger.debug("<table>");
++ logger.config("<table>");
+ renderer.startedTable(element);
+ }
+
+ public void startedTableColumnGroup(final LayoutContext element)
+ throws NormalizationException
+ {
+- logger.debug("<table-col-group>");
++ logger.config("<table-col-group>");
+ renderer.startedTableColumnGroup(element);
+ }
+
+ public void startedTableColumn(final LayoutContext element)
+ throws NormalizationException
+ {
+- logger.debug("<table-col>");
++ logger.config("<table-col>");
+ renderer.startedTableColumn(element);
+ }
+
+ public void startedTableSection(final LayoutContext element)
+ throws NormalizationException
+ {
+- logger.debug("<table-section>");
++ logger.config("<table-section>");
+ renderer.startedTableSection(element);
+ }
+
+ public void startedTableRow(final LayoutContext element)
+ throws NormalizationException
+ {
+- logger.debug("<table-row>");
++ logger.config("<table-row>");
+ renderer.startedTableRow(element);
+ }
+
+ public void startedTableCell(final LayoutContext element)
+ throws NormalizationException
+ {
+- logger.debug("<table-cell>");
++ logger.config("<table-cell>");
+ renderer.startedTableCell(element);
+ }
+
+@@ -153,7 +152,7 @@
+ throws NormalizationException
+ {
+ final String tagName = element.getTagName();
+- logger.debug("<block tag='" + tagName + "'>");
++ logger.config("<block tag='" + tagName + "'>");
+ renderer.startedBlock(element);
+ }
+
+@@ -161,14 +160,14 @@
+ throws NormalizationException
+ {
+ final String tagName = element.getTagName();
+- logger.debug("<paragraph tag='" + tagName + "'>");
++ logger.config("<paragraph tag='" + tagName + "'>");
+ renderer.startedRootInline(element);
+ }
+
+ public void startedMarker(final LayoutContext element)
+ throws NormalizationException
+ {
+- logger.debug("<marker>");
++ logger.config("<marker>");
+ renderer.startedMarker(element);
+ }
+
+@@ -176,80 +175,80 @@
+ throws NormalizationException
+ {
+ final String tagName = element.getTagName();
+- logger.debug("<inline tag='" + tagName + "'>");
++ logger.config("<inline tag='" + tagName + "'>");
+ renderer.startedInline(element);
+ }
+
+ public void addContent(final LayoutContext node, final ContentToken token)
+ throws NormalizationException
+ {
+- logger.debug("<content>" + token + "</content>");
++ logger.config("<content>" + token + "</content>");
+ renderer.addContent(node, token);
+ }
+
+ public void finishedInline() throws NormalizationException
+ {
+- logger.debug("</inline>");
++ logger.config("</inline>");
+ renderer.finishedInline();
+ }
+
+ public void finishedMarker() throws NormalizationException
+ {
+- logger.debug("</marker>");
++ logger.config("</marker>");
+ renderer.finishedMarker();
+ }
+
+ public void finishedRootInline() throws NormalizationException
+ {
+- logger.debug("</paragraph>");
++ logger.config("</paragraph>");
+ renderer.finishedRootInline();
+ }
+
+ public void finishedBlock() throws NormalizationException
+ {
+- logger.debug("</block>");
++ logger.config("</block>");
+ renderer.finishedBlock();
+ }
+
+ public void finishedTableCell() throws NormalizationException
+ {
+- logger.debug("</table-cell>");
++ logger.config("</table-cell>");
+ renderer.finishedTableCell();
+ }
+
+ public void finishedTableRow() throws NormalizationException
+ {
+- logger.debug("</table-row>");
++ logger.config("</table-row>");
+ renderer.finishedTableRow();
+ }
+
+ public void finishedTableSection() throws NormalizationException
+ {
+- logger.debug("</table-section>");
++ logger.config("</table-section>");
+ renderer.finishedTableSection();
+ }
+
+ public void finishedTableColumn() throws NormalizationException
+ {
+- logger.debug("</table-col>");
++ logger.config("</table-col>");
+ renderer.finishedTableColumn();
+ }
+
+ public void finishedTableColumnGroup() throws NormalizationException
+ {
+- logger.debug("</table-col-group>");
++ logger.config("</table-col-group>");
+ renderer.finishedTableColumnGroup();
+ }
+
+ public void finishedTable() throws NormalizationException
+ {
+- logger.debug("</table>");
++ logger.config("</table>");
+ renderer.finishedTable();
+ }
+
+ public void finishedFlow() throws NormalizationException
+ {
+- logger.debug("</flow>");
++ logger.config("</flow>");
+ renderer.finishedFlow();
+ }
+
+@@ -259,7 +258,7 @@
+ */
+ public void finishedDocument() throws NormalizationException
+ {
+- logger.debug("</document>");
++ logger.config("</document>");
+ renderer.finishedDocument();
+ }
+
+@@ -276,7 +275,7 @@
+ public void startedPassThrough(final LayoutContext element)
+ throws NormalizationException
+ {
+- logger.debug("<pass-through>");
++ logger.config("<pass-through>");
+ renderer.startedPassThrough(element);
+ }
+
+@@ -284,26 +283,26 @@
+ final ContentToken token)
+ throws NormalizationException
+ {
+- logger.debug("<pass-through-content>" + token + "</pass-through-content>");
++ logger.config("<pass-through-content>" + token + "</pass-through-content>");
+ renderer.addPassThroughContent(node, token);
+ }
+
+ public void finishedPassThrough() throws NormalizationException
+ {
+- logger.debug("</pass-through>");
++ logger.config("</pass-through>");
+ renderer.finishedPassThrough();
+ }
+
+ public void startedTableCaption(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug("<table-caption>");
++ logger.config("<table-caption>");
+ renderer.startedTableCaption(context);
+ }
+
+ public void finishedTableCaption() throws NormalizationException
+ {
+- logger.debug("</table-caption>");
++ logger.config("</table-caption>");
+ renderer.finishedTableCaption();
+ }
+
+diff -ru liblayout-0.2.10.orig/source/org/jfree/layouting/renderer/model/RenderBox.java liblayout-0.2.10/source/org/jfree/layouting/renderer/model/RenderBox.java
+--- liblayout-0.2.10.orig/source/org/jfree/layouting/renderer/model/RenderBox.java 2021-04-07 10:34:09.779045241 +0100
++++ liblayout-0.2.10/source/org/jfree/layouting/renderer/model/RenderBox.java 2021-04-07 10:49:14.499179135 +0100
+@@ -44,8 +44,7 @@
+ import org.jfree.layouting.renderer.text.ExtendedBaselineInfo;
+ import org.jfree.layouting.renderer.text.TextUtility;
+ import org.pentaho.reporting.libraries.fonts.registry.FontMetrics;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * A render-box corresponds to elements in a DOM tree.
+@@ -62,7 +61,7 @@
+ */
+ public abstract class RenderBox extends RenderNode
+ {
+- private static final Log logger = LogFactory.getLog(RenderBox.class);
++ private static final Logger logger = Logger.getLogger(RenderBox.class.getName());
+ public static final boolean LOG_PRUNE = false;
+
+ private RenderNode firstChild;
+@@ -930,7 +929,7 @@
+ {
+ if (LOG_PRUNE)
+ {
+- logger.debug("Pruning: " + this);
++ logger.config("Pruning: " + this);
+ }
+ getParent().remove(this);
+ }
+@@ -944,7 +943,7 @@
+ {
+ if (LOG_PRUNE)
+ {
+- logger.debug("Pruning: " + lastChild);
++ logger.config("Pruning: " + lastChild);
+ }
+ remove(lastChild);
+ lastChild = getLastChild();
+diff -ru liblayout-0.2.10.orig/source/org/jfree/layouting/renderer/ModelPrinter.java liblayout-0.2.10/source/org/jfree/layouting/renderer/ModelPrinter.java
+--- liblayout-0.2.10.orig/source/org/jfree/layouting/renderer/ModelPrinter.java 2021-04-07 10:34:09.786045327 +0100
++++ liblayout-0.2.10/source/org/jfree/layouting/renderer/ModelPrinter.java 2021-04-07 10:46:12.757941838 +0100
+@@ -41,8 +41,7 @@
+ import org.jfree.layouting.renderer.model.table.cells.TableCell;
+ import org.jfree.layouting.renderer.model.table.cols.TableColumn;
+ import org.jfree.layouting.renderer.model.table.cols.TableColumnModel;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: Jan 9, 2007, 2:22:59 PM
+@@ -51,7 +50,7 @@
+ */
+ public class ModelPrinter
+ {
+- private static final Log logger = LogFactory.getLog (ModelPrinter.class);
++ private static final Logger logger = Logger.getLogger(ModelPrinter.class.getName());
+
+ private ModelPrinter()
+ {
+@@ -66,7 +65,7 @@
+ b.append('[');
+ b.append(Integer.toHexString(System.identityHashCode(node)));
+ b.append(']');
+- logger.debug (b);
++ logger.config(b.toString());
+ node = node.getParent();
+ }
+ }
+@@ -96,7 +95,7 @@
+ b.append(", height=");
+ b.append(box.getHeight());
+ b.append('}');
+- logger.debug(b.toString());
++ logger.config(b.toString());
+
+ b = new StringBuffer();
+ for (int i = 0; i < level; i++)
+@@ -105,7 +104,7 @@
+ }
+ b.append("- nodeLayoutProperties=");
+ b.append(box.getNodeLayoutProperties());
+- logger.debug(b.toString());
++ logger.config(b.toString());
+
+ b = new StringBuffer();
+ for (int i = 0; i < level; i++)
+@@ -114,7 +113,7 @@
+ }
+ b.append("- boxLayoutProperties=");
+ b.append(box.getBoxLayoutProperties());
+- logger.debug(b.toString());
++ logger.config(b.toString());
+
+ if (box instanceof TableRowRenderBox)
+ {
+@@ -124,7 +123,7 @@
+ for (int i = 0; i < rowInfoStructure.getCellCount(); i++)
+ {
+ final TableCell cell = rowInfoStructure.getCellAt(i);
+- logger.debug ("CELL: " + i + " = " + cell.getRowSpan() + ' ' + cell.getColSpan() + ' ' + cell);
++ logger.config("CELL: " + i + " = " + cell.getRowSpan() + ' ' + cell.getColSpan() + ' ' + cell);
+ }
+ }
+ else if (box instanceof TableRenderBox)
+@@ -134,7 +133,7 @@
+ for (int i = 0; i < columnModel.getColumnCount(); i++)
+ {
+ final TableColumn col = columnModel.getColumn(i);
+- logger.debug ("COLUMN: EffectiveSize: " + col.getEffectiveSize() + " Computed Max Width: " + col.getComputedMaximumWidth() + " Computed ChunkSize: " + col.getComputedMinChunkSize());
++ logger.config("COLUMN: EffectiveSize: " + col.getEffectiveSize() + " Computed Max Width: " + col.getComputedMaximumWidth() + " Computed ChunkSize: " + col.getComputedMinChunkSize());
+ // for (int cs = 1; cs < 3; cs++)
+ // {
+ // Log.debug ("* COLUMN: " + i + "(" + cs + ") " +
+@@ -149,14 +148,14 @@
+ else if (box instanceof TableCellRenderBox)
+ {
+ final TableCellRenderBox cellBox = (TableCellRenderBox) box;
+- logger.debug ("CELL: Position: " + cellBox.getColumnIndex());
++ logger.config("CELL: Position: " + cellBox.getColumnIndex());
+ }
+ else if (box instanceof ParagraphRenderBox)
+ {
+ final ParagraphRenderBox paraBox = (ParagraphRenderBox) box;
+- logger.debug ("-----------------------------------------------------");
++ logger.config("-----------------------------------------------------");
+ printBox(paraBox.getLineboxContainer(), level + 1);
+- logger.debug ("-----------------------------------------------------");
++ logger.config("-----------------------------------------------------");
+ }
+
+ printChilds(box, level);
+@@ -203,7 +202,7 @@
+ b.append(", height=");
+ b.append(node.getHeight());
+ b.append('}');
+- logger.debug(b.toString());
++ logger.config(b.toString());
+
+
+ b = new StringBuffer();
+@@ -213,7 +212,7 @@
+ }
+ b.append("- nodeLayoutProperties=");
+ b.append(node.getNodeLayoutProperties());
+- logger.debug(b.toString());
++ logger.config(b.toString());
+ }
+
+ private static void printText(final RenderableText text, final int level)
+@@ -238,7 +237,7 @@
+ b.append(", text='");
+ b.append(text.getRawText());
+ b.append("'}");
+- logger.debug(b.toString());
++ logger.config(b.toString());
+
+ b = new StringBuffer();
+ for (int i = 0; i < level; i++)
+@@ -247,7 +246,7 @@
+ }
+ b.append("- nodeLayoutProperties=");
+ b.append(text.getNodeLayoutProperties());
+- logger.debug(b.toString());
++ logger.config(b.toString());
+ }
+
+ }
+diff -ru liblayout-0.2.10.orig/source/org/jfree/layouting/renderer/PrintingRenderer.java liblayout-0.2.10/source/org/jfree/layouting/renderer/PrintingRenderer.java
+--- liblayout-0.2.10.orig/source/org/jfree/layouting/renderer/PrintingRenderer.java 2021-04-07 10:34:09.786045327 +0100
++++ liblayout-0.2.10/source/org/jfree/layouting/renderer/PrintingRenderer.java 2021-04-07 10:45:03.987095239 +0100
+@@ -37,8 +37,7 @@
+ import org.jfree.layouting.layouter.context.LayoutContext;
+ import org.jfree.layouting.layouter.context.PageContext;
+ import org.jfree.layouting.normalizer.content.NormalizationException;
+-import org.apache.commons.logging.LogFactory;
+-import org.apache.commons.logging.Log;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 17.07.2006, 17:43:21
+@@ -47,7 +46,7 @@
+ */
+ public class PrintingRenderer implements Renderer
+ {
+- private static final Log logger = LogFactory.getLog(PrintingRenderer.class);
++ private static final Logger logger = Logger.getLogger(PrintingRenderer.class.getName());
+ private static class PrintingRendererState implements State
+ {
+ private State parentState;
+@@ -89,7 +88,7 @@
+ */
+ public void startedDocument(final PageContext pageContext)
+ {
+- logger.debug ("<document>");
++ logger.config("<document>");
+ parent.startedDocument(pageContext);
+ }
+
+@@ -102,7 +101,7 @@
+ public void startedFlow(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<flow " +
++ logger.config("<flow " +
+ "tag='" + context.getTagName() + "' namespace='" + context.getNamespace() + "'>");
+ parent.startedFlow(context);
+ }
+@@ -110,7 +109,7 @@
+ public void startedTable(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<table " +
++ logger.config("<table " +
+ "tag='" + context.getTagName() + "' namespace='" + context.getNamespace() + "'>");
+ parent.startedTable(context);
+ }
+@@ -118,7 +117,7 @@
+ public void startedTableSection(final LayoutContext layoutContext)
+ throws NormalizationException
+ {
+- logger.debug ("<table-section " +
++ logger.config("<table-section " +
+ "tag='" + layoutContext.getTagName() + "' namespace='" + layoutContext.getNamespace() + "'>");
+ parent.startedTableSection(layoutContext);
+ }
+@@ -126,7 +125,7 @@
+ public void startedTableRow(final LayoutContext layoutContext)
+ throws NormalizationException
+ {
+- logger.debug ("<table-row " +
++ logger.config("<table-row " +
+ "tag='" + layoutContext.getTagName() + "' namespace='" + layoutContext.getNamespace() + "'>");
+ parent.startedTableRow(layoutContext);
+ }
+@@ -134,7 +133,7 @@
+ public void startedTableCell(final LayoutContext layoutContext)
+ throws NormalizationException
+ {
+- logger.debug ("<table-cell " +
++ logger.config("<table-cell " +
+ "tag='" + layoutContext.getTagName() + "' namespace='" + layoutContext.getNamespace() + "'>");
+ parent.startedTableCell(layoutContext);
+ }
+@@ -142,7 +141,7 @@
+ public void startedBlock(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<block " +
++ logger.config("<block " +
+ "tag='" + context.getTagName() + "' namespace='" + context.getNamespace() + "'>");
+ parent.startedBlock(context);
+ }
+@@ -150,7 +149,7 @@
+ public void startedMarker(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<marker " +
++ logger.config("<marker " +
+ "tag='" + context.getTagName() + "' namespace='" + context.getNamespace() + "'>");
+ parent.startedMarker(context);
+ }
+@@ -158,7 +157,7 @@
+ public void startedRootInline(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<paragraph " +
++ logger.config("<paragraph " +
+ "tag='" + context.getTagName() + "' namespace='" + context.getNamespace() + "'>");
+ parent.startedRootInline(context);
+ }
+@@ -166,7 +165,7 @@
+ public void startedInline(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<inline " +
++ logger.config("<inline " +
+ "tag='" + context.getTagName() + "' namespace='" + context.getNamespace() + "'>");
+ parent.startedInline(context);
+ }
+@@ -175,93 +174,93 @@
+ final ContentToken content)
+ throws NormalizationException
+ {
+- logger.debug ("<content>" + content + "</content>");
++ logger.config("<content>" + content + "</content>");
+ parent.addContent(context, content);
+ }
+
+ public void finishedInline() throws NormalizationException
+ {
+- logger.debug ("</inline>");
++ logger.config("</inline>");
+ parent.finishedInline();
+ }
+
+ public void finishedRootInline() throws NormalizationException
+ {
+- logger.debug ("</paragraph>");
++ logger.config("</paragraph>");
+ parent.finishedRootInline();
+ }
+
+ public void finishedMarker() throws NormalizationException
+ {
+- logger.debug ("</marker>");
++ logger.config("</marker>");
+ parent.finishedMarker();
+ }
+
+ public void finishedBlock() throws NormalizationException
+ {
+- logger.debug ("</block>");
++ logger.config("</block>");
+ parent.finishedBlock();
+ }
+
+ public void finishedTableCell() throws NormalizationException
+ {
+- logger.debug ("</table-cell>");
++ logger.config("</table-cell>");
+ parent.finishedTableCell();
+ }
+
+ public void finishedTableRow() throws NormalizationException
+ {
+- logger.debug ("</table-row>");
++ logger.config("</table-row>");
+ parent.finishedTableRow();
+ }
+
+ public void finishedTableSection() throws NormalizationException
+ {
+- logger.debug ("</table-section>");
++ logger.config("</table-section>");
+ parent.finishedTableSection();
+ }
+
+ public void finishedTable() throws NormalizationException
+ {
+- logger.debug ("</table>");
++ logger.config("</table>");
+ parent.finishedTable();
+ }
+
+ public void finishedFlow() throws NormalizationException
+ {
+- logger.debug ("</flow>");
++ logger.config("</flow>");
+ parent.finishedFlow();
+ }
+
+ public void finishedDocument() throws NormalizationException
+ {
+- logger.debug ("</document>");
++ logger.config("</document>");
+ parent.finishedDocument();
+ }
+
+ public void startedTableColumnGroup(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<table-column-group>");
++ logger.config("<table-column-group>");
+ parent.startedTableColumnGroup(context);
+ }
+
+ public void startedTableColumn(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<table-column>");
++ logger.config("<table-column>");
+ parent.startedTableColumn(context);
+ }
+
+ public void finishedTableColumnGroup() throws NormalizationException
+ {
+- logger.debug ("</table-column-group>");
++ logger.config("</table-column-group>");
+ parent.finishedTableColumnGroup();
+ }
+
+ public void finishedTableColumn() throws NormalizationException
+ {
+- logger.debug ("</table-column>");
++ logger.config("</table-column>");
+ parent.finishedTableColumn();
+ }
+
+@@ -274,14 +273,14 @@
+ */
+ public void handlePageBreak(final PageContext pageContext)
+ {
+- logger.debug ("<!-- PAGEBREAK ENCOUNTERED -->");
++ logger.config("<!-- PAGEBREAK ENCOUNTERED -->");
+ parent.handlePageBreak(pageContext);
+ }
+
+ public void startedPassThrough(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<pass-through>");
++ logger.config("<pass-through>");
+ parent.startedPassThrough(context);
+ }
+
+@@ -289,13 +288,13 @@
+ final ContentToken content)
+ throws NormalizationException
+ {
+- logger.debug ("<pass-through-content>" + content + "</pass-through-content>");
++ logger.config("<pass-through-content>" + content + "</pass-through-content>");
+ parent.addPassThroughContent(context, content);
+ }
+
+ public void finishedPassThrough() throws NormalizationException
+ {
+- logger.debug ("</pass-through>");
++ logger.config("</pass-through>");
+ parent.finishedPassThrough();
+ }
+
+@@ -307,13 +306,13 @@
+ public void startedTableCaption(final LayoutContext context)
+ throws NormalizationException
+ {
+- logger.debug ("<table-caption>");
++ logger.config("<table-caption>");
+ parent.startedTableCaption(context);
+ }
+
+ public void finishedTableCaption() throws NormalizationException
+ {
+- logger.debug ("</table-caption>");
++ logger.config("</table-caption>");
+ parent.finishedTableCaption();
+ }
+ }
+diff -ru liblayout-0.2.10.orig/source/org/jfree/layouting/util/AttributeMap.java liblayout-0.2.10/source/org/jfree/layouting/util/AttributeMap.java
+--- liblayout-0.2.10.orig/source/org/jfree/layouting/util/AttributeMap.java 2021-04-07 10:34:09.787045339 +0100
++++ liblayout-0.2.10/source/org/jfree/layouting/util/AttributeMap.java 2021-04-07 10:48:57.444969193 +0100
+@@ -35,8 +35,7 @@
+ import java.util.Iterator;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+
+ /**
+@@ -46,7 +45,7 @@
+ */
+ public class AttributeMap implements Serializable, Cloneable
+ {
+- private static final Log logger = LogFactory.getLog(AttributeMap.class);
++ private static final Logger logger = Logger.getLogger(AttributeMap.class.getName());
+
+ private static final long serialVersionUID = -7442871030874215436L;
+ private static final String[] EMPTY_NAMESPACES = new String[0];
+@@ -102,7 +101,7 @@
+ }
+ catch (Exception e)
+ {
+- logger.error("Clone failed for ReportAttributeMap.createUnmodifiableMap", e);
++ logger.severe("Clone failed for ReportAttributeMap.createUnmodifiableMap:" + e);
+ throw new IllegalStateException("Clone failed for ReportAttributeMap.createUnmodifiableMap");
+ }
+ }
diff --git a/external/jfreereport/patches/liblayout.patch b/external/jfreereport/patches/liblayout.patch
new file mode 100644
index 000000000..9e68986a8
--- /dev/null
+++ b/external/jfreereport/patches/liblayout.patch
@@ -0,0 +1,21 @@
+--- misc/liblayout-0.2.10/build.xml (Revision 6728)
++++ misc/build/liblayout-0.2.10/build.xml (Arbeitskopie)
+@@ -24,9 +24,15 @@
+
+ <!-- Setup the compile classpath -->
+ <path id="classpath">
+- <fileset dir="lib">
+- <include name="*.jar" />
+- </fileset>
++ <pathelement path="${flute.jar}"/>
++ <pathelement path="${libbase.jar}"/>
++ <pathelement path="${libformula.jar}"/>
++ <pathelement path="${libfonts.jar}"/>
++ <pathelement path="${libloader.jar}"/>
++ <pathelement path="${librepository.jar}"/>
++ <pathelement path="${libserializer.jar}"/>
++ <pathelement path="${libxml.jar}"/>
++ <pathelement path="${sac.jar}"/>
+ </path>
+
+ <!-- Kill all the created directories -->
diff --git a/external/jfreereport/patches/libloader-1.1.3-remove-commons-logging.patch.1 b/external/jfreereport/patches/libloader-1.1.3-remove-commons-logging.patch.1
new file mode 100644
index 000000000..fad07d59d
--- /dev/null
+++ b/external/jfreereport/patches/libloader-1.1.3-remove-commons-logging.patch.1
@@ -0,0 +1,635 @@
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/DefaultResourceManagerBackend.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/DefaultResourceManagerBackend.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/DefaultResourceManagerBackend.java 2021-04-07 10:55:58.343147414 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/DefaultResourceManagerBackend.java 2021-04-07 11:08:48.389599751 +0100
+@@ -22,8 +22,8 @@
+ import java.util.Iterator;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.config.Configuration;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+
+@@ -34,7 +34,7 @@
+ */
+ public class DefaultResourceManagerBackend implements ResourceManagerBackend
+ {
+- private static final Log logger = LogFactory.getLog(DefaultResourceManagerBackend.class);
++ private static final Logger logger = Logger.getLogger(DefaultResourceManagerBackend.class.getName());
+
+ private ArrayList resourceLoaders;
+ private ArrayList resourceBundleLoaders;
+@@ -280,9 +280,9 @@
+ {
+ // ignore it, try the next factory ...
+ exception = rex;
+- if (logger.isDebugEnabled())
++ if (logger.isLoggable(Level.CONFIG))
+ {
+- logger.debug("Failed at " + fact.getClass() + ": ", rex);
++ logger.config("Failed at " + fact.getClass() + ": " + rex);
+ }
+ }
+ }
+@@ -413,7 +413,7 @@
+ {
+ throw new UnrecognizedLoaderException("Invalid key: No resource-loader registered for schema: " + key.getSchema());
+ }
+- logger.debug("Loaded " + key);
++ logger.config("Loaded " + key);
+ return loader.load(key);
+ }
+
+@@ -451,7 +451,7 @@
+ ResourceLoader.class);
+ if (loader != null)
+ {
+- //Log.debug("Registering loader for " + loader.getSchema());
++ //Log.config("Registering loader for " + loader.getSchema());
+ registerLoader(loader);
+ }
+ }
+@@ -465,7 +465,7 @@
+ ResourceManager.class, ResourceBundleLoader.class);
+ if (loader != null)
+ {
+- //Log.debug("Registering loader for " + loader.getSchema());
++ //Log.config("Registering loader for " + loader.getSchema());
+ registerBundleLoader(loader);
+ }
+ }
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/factory/drawable/DrawableWrapper.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/factory/drawable/DrawableWrapper.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/factory/drawable/DrawableWrapper.java 2021-04-07 10:55:58.342147402 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/factory/drawable/DrawableWrapper.java 2021-04-07 11:05:40.206289803 +0100
+@@ -27,8 +27,8 @@
+ import java.util.Collections;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 05.12.2007, 19:15:56
+@@ -37,7 +37,7 @@
+ */
+ public class DrawableWrapper
+ {
+- private static final Log logger = LogFactory.getLog(DrawableWrapper.class);
++ private static final Logger logger = Logger.getLogger(DrawableWrapper.class.getName());
+ private static final Map drawables = Collections.synchronizedMap(new HashMap());
+
+ private Object backend;
+@@ -67,9 +67,9 @@
+ Modifier.isAbstract(modifiers) ||
+ Modifier.isStatic(modifiers))
+ {
+- if (logger.isWarnEnabled())
++ if (logger.isLoggable(Level.WARNING))
+ {
+- logger.warn("DrawMethod is not valid: " + aClass + '#' + drawMethod);
++ logger.warning("DrawMethod is not valid: " + aClass + '#' + drawMethod);
+ }
+ drawMethod = null;
+ }
+@@ -77,9 +77,9 @@
+ catch (NoSuchMethodException e)
+ {
+ // ignore exception
+- if (logger.isWarnEnabled())
++ if (logger.isLoggable(Level.WARNING))
+ {
+- logger.warn("The object is not a drawable: " + aClass);
++ logger.warning("The object is not a drawable: " + aClass);
+ }
+ drawMethod = null;
+ }
+@@ -141,9 +141,9 @@
+ }
+ catch (Exception e)
+ {
+- if (logger.isDebugEnabled())
++ if (logger.isLoggable(Level.CONFIG))
+ {
+- logger.warn("Invoking draw failed:", e);
++ logger.warning("Invoking draw failed: " + e);
+ }
+ }
+ }
+@@ -167,9 +167,9 @@
+ }
+ catch (Exception e)
+ {
+- if (logger.isWarnEnabled())
++ if (logger.isLoggable(Level.WARNING))
+ {
+- logger.warn("Invoking getPreferredSize failed:", e);
++ logger.warning("Invoking getPreferredSize failed: " + e);
+ }
+ return null;
+ }
+@@ -193,9 +193,9 @@
+ }
+ catch (Exception e)
+ {
+- if (logger.isWarnEnabled())
++ if (logger.isLoggable(Level.WARNING))
+ {
+- logger.warn("Invoking isKeepAspectRatio failed:", e);
++ logger.warning("Invoking isKeepAspectRatio failed: " + e);
+ }
+ return false;
+ }
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/file/FileResourceLoader.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/file/FileResourceLoader.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/file/FileResourceLoader.java 2021-04-07 10:55:58.344147426 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/file/FileResourceLoader.java 2021-04-07 11:03:22.711602044 +0100
+@@ -24,8 +24,7 @@
+ import java.util.HashMap;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceData;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceKeyCreationException;
+@@ -43,7 +42,7 @@
+ public class FileResourceLoader implements ResourceLoader
+ {
+ public static final String SCHEMA_NAME = FileResourceLoader.class.getName();
+- private static final Log logger = LogFactory.getLog(FileResourceLoader.class);
++ private static final Logger logger = Logger.getLogger(FileResourceLoader.class.getName());
+
+ public FileResourceLoader()
+ {
+@@ -210,7 +209,7 @@
+ }
+
+ // Log information
+- logger.debug("Serializing a File Resource Key...");
++ logger.config("Serializing a File Resource Key...");
+ if (key.getParent() != null)
+ {
+ throw new ResourceException
+@@ -224,7 +223,7 @@
+ final String strIdentifier = file.getCanonicalPath();
+ final String result = ResourceKeyUtils.createStringResourceKey
+ (key.getSchema().toString(), strIdentifier, key.getFactoryParameters());
+- logger.debug("Serialized File Resource Key: [" + result + "]");
++ logger.config("Serialized File Resource Key: [" + result + "]");
+ return result;
+ }
+ catch (IOException ioe)
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/raw/RawResourceLoader.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/raw/RawResourceLoader.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/raw/RawResourceLoader.java 2021-04-07 10:55:58.343147414 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/raw/RawResourceLoader.java 2021-04-07 11:01:56.064538444 +0100
+@@ -21,8 +21,7 @@
+ import java.util.HashMap;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceData;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceException;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/resource/ClassloaderResourceLoader.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/resource/ClassloaderResourceLoader.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/resource/ClassloaderResourceLoader.java 2021-04-07 10:55:58.343147414 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/resource/ClassloaderResourceLoader.java 2021-04-07 11:03:14.370499656 +0100
+@@ -21,8 +21,7 @@
+ import java.util.Map;
+ import java.net.URL;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceData;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceKeyCreationException;
+@@ -41,7 +40,7 @@
+ public class ClassloaderResourceLoader implements ResourceLoader
+ {
+ public static final String SCHEMA_NAME = ClassloaderResourceLoader.class.getName();
+- private static final Log logger = LogFactory.getLog(ClassloaderResourceLoader.class);
++ private static final Logger logger = Logger.getLogger(ClassloaderResourceLoader.class.getName());
+
+ public ClassloaderResourceLoader()
+ {
+@@ -197,7 +196,7 @@
+ }
+
+ // Log information
+- logger.debug("Serializing a Classloader Resource Key...");
++ logger.config("Serializing a Classloader Resource Key...");
+ if (key.getParent() != null)
+ {
+ throw new ResourceException
+@@ -207,7 +206,7 @@
+ // Serialize the key
+ final String result = ResourceKeyUtils.createStringResourceKey(key.getSchema().toString(),
+ (String) key.getIdentifier(), key.getFactoryParameters());
+- logger.debug("Serialized Classloader Resource Key: [" + result + "]");
++ logger.config("Serialized Classloader Resource Key: [" + result + "]");
+ return result;
+ }
+
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/URLResourceLoader.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/URLResourceLoader.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/URLResourceLoader.java 2021-04-07 10:55:58.344147426 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/URLResourceLoader.java 2021-04-07 11:03:41.998838804 +0100
+@@ -22,8 +22,7 @@
+ import java.util.HashMap;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceData;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceKeyCreationException;
+@@ -40,7 +39,7 @@
+ public class URLResourceLoader implements ResourceLoader
+ {
+ public static final String SCHEMA_NAME = URLResourceLoader.class.getName();
+- private static final Log logger = LogFactory.getLog(URLResourceLoader.class);
++ private static final Logger logger = Logger.getLogger(URLResourceLoader.class.getName());
+
+ public URLResourceLoader()
+ {
+@@ -188,10 +187,10 @@
+ }
+
+ // Log information
+- logger.debug("Serializing a Classloader Resource Key...");
++ logger.config("Serializing a Classloader Resource Key...");
+ if (key.getParent() != null)
+ {
+- logger.warn("Serializing a Classloader Resource Key which contains a parent: key=[" + bundleKey + "] parent=["
++ logger.warning("Serializing a Classloader Resource Key which contains a parent: key=[" + bundleKey + "] parent=["
+ + key.getParent() + "]");
+ }
+
+@@ -199,7 +198,7 @@
+ final URL url = (URL) key.getIdentifier();
+ final String result = ResourceKeyUtils.createStringResourceKey
+ (key.getSchema().toString(), url.toExternalForm(), key.getFactoryParameters());
+- logger.debug("Serialized Classloader Resource Key: [" + result + "]");
++ logger.config("Serialized Classloader Resource Key: [" + result + "]");
+ return result;
+ }
+
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/zip/ZipResourceLoader.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/zip/ZipResourceLoader.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/loader/zip/ZipResourceLoader.java 2021-04-07 10:55:58.344147426 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/loader/zip/ZipResourceLoader.java 2021-04-07 11:02:18.522814132 +0100
+@@ -21,8 +21,7 @@
+ import java.util.HashMap;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceData;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceException;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
+@@ -40,7 +39,7 @@
+ public class ZipResourceLoader implements ResourceLoader
+ {
+ public static final String SCHEMA_NAME = ZipResourceLoader.class.getName();
+- private static final Log logger = LogFactory.getLog(ZipResourceLoader.class);
++ private static final Logger logger = Logger.getLogger(ZipResourceLoader.class.getName());
+
+ public ZipResourceLoader()
+ {
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHCacheModule.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHCacheModule.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHCacheModule.java 2021-04-07 10:55:58.345147438 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHCacheModule.java 2021-04-07 10:58:52.758288370 +0100
+@@ -20,8 +20,7 @@
+ import org.pentaho.reporting.libraries.base.boot.AbstractModule;
+ import org.pentaho.reporting.libraries.base.boot.ModuleInitializeException;
+ import org.pentaho.reporting.libraries.base.boot.SubSystem;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 13.04.2006, 16:29:07
+@@ -30,7 +29,7 @@
+ */
+ public class EHCacheModule extends AbstractModule
+ {
+- public static final Log CACHE_MONITOR = LogFactory.getLog(EHCacheModule.class.getName() + "#CacheLog");
++ public static final Logger CACHE_MONITOR = Logger.getLogger(EHCacheModule.class.getName() + "#CacheLog");
+
+ public EHCacheModule() throws ModuleInitializeException
+ {
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHResourceFactoryCache.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHResourceFactoryCache.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHResourceFactoryCache.java 2021-04-07 10:55:58.345147438 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHResourceFactoryCache.java 2021-04-07 10:59:17.251589016 +0100
+@@ -20,8 +20,8 @@
+ import net.sf.ehcache.Cache;
+ import net.sf.ehcache.CacheException;
+ import net.sf.ehcache.Element;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.Resource;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
+ import org.pentaho.reporting.libraries.resourceloader.cache.ResourceFactoryCache;
+@@ -110,7 +109,7 @@
+ }
+ }
+
+- private static final Log logger = LogFactory.getLog(EHResourceFactoryCache.class);
++ private static final Logger logger = Logger.getLogger(EHResourceFactoryCache.class.getName());
+ private Cache factoryCache;
+
+ public EHResourceFactoryCache(final Cache factoryCache)
+@@ -128,16 +128,16 @@
+ final Resource res = getInternal(key, target[i]);
+ if (res != null)
+ {
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Res Cache Hit " + key);
++ EHCacheModule.CACHE_MONITOR.config("Res Cache Hit " + key);
+ }
+ return res;
+ }
+ }
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Res Cache Miss " + key);
++ EHCacheModule.CACHE_MONITOR.config("Res Cache Miss " + key);
+ }
+ return null;
+ }
+@@ -168,9 +168,9 @@
+ }
+ catch (CacheException e)
+ {
+- if (logger.isDebugEnabled())
++ if (logger.isLoggable(Level.CONFIG))
+ {
+- logger.debug("Failed to retrieve resource for key " + key, e);
++ logger.config("Failed to retrieve resource for key " + key + ": " + e);
+ }
+ return null;
+ }
+@@ -185,9 +185,9 @@
+ }
+ catch (Exception e)
+ {
+- if (logger.isDebugEnabled())
++ if (logger.isLoggable(Level.CONFIG))
+ {
+- logger.debug("Failed to store resource for key " + source, e);
++ logger.config("Failed to store resource for key " + source + ": " + e);
+ }
+ // ignore ... the object is not serializable ..
+ }
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/ResourceKeyUtils.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/ResourceKeyUtils.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/ResourceKeyUtils.java 2021-04-07 10:55:58.342147402 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/ResourceKeyUtils.java 2021-04-07 11:06:27.248867251 +0100
+@@ -27,8 +27,8 @@
+ import java.util.Iterator;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.util.CSVQuoter;
+ import org.pentaho.reporting.libraries.base.util.CSVTokenizer;
+ import org.pentaho.reporting.libraries.base.util.IOUtils;
+@@ -42,7 +42,7 @@
+ {
+ private static final String DELIMITER = ";";
+ private static final String SERIALIZATION_PREFIX = "resourcekey:";
+- private static final Log logger = LogFactory.getLog(ResourceManager.class);
++ private static final Logger logger = Logger.getLogger(ResourceManager.class.getName());
+
+ /**
+ * Returns a string representation of the ResourceKey based on the pieces that are passed as parameters
+@@ -169,7 +169,7 @@
+
+ sb.append(quoter.doQuoting(entrySb.toString()));
+ }
+- logger.debug("Converted ResourceKey's Factory Parameters to String: [" + sb.toString() + "]");
++ logger.config("Converted ResourceKey's Factory Parameters to String: [" + sb.toString() + "]");
+ return sb.toString();
+ }
+
+@@ -226,9 +226,9 @@
+ params.put(key, value);
+ }
+
+- if (logger.isDebugEnabled())
++ if (logger.isLoggable(Level.CONFIG))
+ {
+- logger.debug("Converted ResourceKey's Factory Parameter String to a Map: [" + factoryParameters
++ logger.config("Converted ResourceKey's Factory Parameter String to a Map: [" + factoryParameters
+ + "] -> map of size " + params.size());
+ }
+ return params;
+@@ -369,7 +369,7 @@
+ }
+ catch (IOException e)
+ {
+- logger.error("Error closing input stream", e);
++ logger.severe("Error closing input stream: " + e);
+ }
+ }
+ }
+diff -ru libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/ResourceManager.java libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/ResourceManager.java
+--- libloader-1.1.3.orig/source/org/pentaho/reporting/libraries/resourceloader/ResourceManager.java 2021-04-07 10:55:58.344147426 +0100
++++ libloader-1.1.3/source/org/pentaho/reporting/libraries/resourceloader/ResourceManager.java 2021-04-07 11:07:50.557889876 +0100
+@@ -22,8 +22,8 @@
+ import java.util.Map;
+ import java.util.Set;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.config.Configuration;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+ import org.pentaho.reporting.libraries.resourceloader.cache.BundleCacheResourceWrapper;
+@@ -57,7 +57,7 @@
+ */
+ public final class ResourceManager
+ {
+- private static final Log logger = LogFactory.getLog(ResourceManager.class);
++ private static final Logger logger = Logger.getLogger(ResourceManager.class.getName());
+ private ResourceManagerBackend backend;
+
+ public static final String BUNDLE_LOADER_PREFIX = "org.pentaho.reporting.libraries.resourceloader.bundle.loader.";
+@@ -273,7 +273,7 @@
+ final ResourceBundleData bundle = loadResourceBundle(key);
+ if (bundle != null)
+ {
+- logger.debug("Loaded bundle for key " + key);
++ logger.config("Loaded bundle for key " + key);
+ return bundle;
+ }
+ final ResourceKey parent = key.getParent();
+@@ -283,7 +283,7 @@
+ final ResourceBundleData parentData = loadResourceBundle(parent);
+ if (parentData != null)
+ {
+- logger.debug("Loaded bundle for key (derivate) " + key);
++ logger.config("Loaded bundle for key (derivate) " + key);
+ return parentData.deriveData(key);
+ }
+ }
+@@ -400,9 +400,9 @@
+ newResource = backend.create(derivedManager, resourceBundleData, context, target);
+ if (isResourceCacheable(newResource))
+ {
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Storing created bundle-resource for key: " + key);
++ EHCacheModule.CACHE_MONITOR.config("Storing created bundle-resource for key: " + key);
+ }
+ factoryCache.put(newResource);
+ if (key != newResource.getSource())
+@@ -412,9 +412,9 @@
+ }
+ else
+ {
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Created bundle-resource is not cacheable for " + key);
++ EHCacheModule.CACHE_MONITOR.config("Created bundle-resource is not cacheable for " + key);
+ }
+ }
+ }
+@@ -423,17 +423,17 @@
+ newResource = backend.create(this, loadedData, context, target);
+ if (isResourceCacheable(newResource))
+ {
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Storing created resource for key: " + key);
++ EHCacheModule.CACHE_MONITOR.config("Storing created resource for key: " + key);
+ }
+ factoryCache.put(newResource);
+ }
+ else
+ {
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Created resource is not cacheable for " + key);
++ EHCacheModule.CACHE_MONITOR.config("Created resource is not cacheable for " + key);
+ }
+ }
+ }
+@@ -556,7 +556,7 @@
+ {
+ if (failedModules.contains(dataCacheProviderClass) == false)
+ {
+- logger.warn("Failed to create data cache: " + e.getLocalizedMessage());
++ logger.warning("Failed to create data cache: " + e.getLocalizedMessage());
+ failedModules.add(dataCacheProviderClass);
+ }
+ }
+@@ -593,7 +593,7 @@
+ {
+ if (failedModules.contains(dataCacheProviderClass) == false)
+ {
+- logger.warn("Failed to create data cache: " + e.getLocalizedMessage());
++ logger.warning("Failed to create data cache: " + e.getLocalizedMessage());
+ failedModules.add(dataCacheProviderClass);
+ }
+ }
+@@ -630,7 +630,7 @@
+ {
+ if (failedModules.contains(cacheProviderClass) == false)
+ {
+- logger.warn("Failed to create factory cache: " + e.getLocalizedMessage());
++ logger.warning("Failed to create factory cache: " + e.getLocalizedMessage());
+ failedModules.add(cacheProviderClass);
+ }
+ }
+--- a/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHResourceBundleDataCache.java
++++ b/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHResourceBundleDataCache.java
+@@ -17,6 +17,7 @@
+
+ package org.pentaho.reporting.libraries.resourceloader.modules.cache.ehcache;
+
++import java.util.logging.Level;
+ import net.sf.ehcache.Cache;
+ import net.sf.ehcache.CacheException;
+ import net.sf.ehcache.Element;
+@@ -64,17 +65,17 @@
+ final Element element = dataCache.get((Object) key);
+ if (element != null)
+ {
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Bund Cache Hit " + key);
++ EHCacheModule.CACHE_MONITOR.config("Bund Cache Hit " + key);
+ }
+ return (ResourceBundleDataCacheEntry) element.getObjectValue();
+ }
+ else
+ {
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Bund Cache Miss " + key);
++ EHCacheModule.CACHE_MONITOR.config("Bund Cache Miss " + key);
+ }
+ return null;
+ }
+@@ -101,9 +102,9 @@
+ final Object keyObject = data.getBundleKey();
+ final Object valueObject = new DefaultResourceBundleDataCacheEntry(cdata, caller);
+ final Element element = new Element(keyObject, valueObject);
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Storing Bundle " + keyObject);
++ EHCacheModule.CACHE_MONITOR.config("Storing Bundle " + keyObject);
+ }
+ dataCache.put(element);
+ return cdata;
+--- a/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHResourceDataCache.java
++++ b/source/org/pentaho/reporting/libraries/resourceloader/modules/cache/ehcache/EHResourceDataCache.java
+@@ -17,6 +17,7 @@
+
+ package org.pentaho.reporting.libraries.resourceloader.modules.cache.ehcache;
+
++import java.util.logging.Level;
+ import net.sf.ehcache.Cache;
+ import net.sf.ehcache.CacheException;
+ import net.sf.ehcache.Element;
+@@ -64,15 +65,15 @@
+ final Element element = dataCache.get((Object) key);
+ if (element != null)
+ {
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Data Cache Hit " + key);
++ EHCacheModule.CACHE_MONITOR.config("Data Cache Hit " + key);
+ }
+ return (ResourceDataCacheEntry) element.getObjectValue();
+ }
+- if (EHCacheModule.CACHE_MONITOR.isDebugEnabled())
++ if (EHCacheModule.CACHE_MONITOR.isLoggable(Level.CONFIG))
+ {
+- EHCacheModule.CACHE_MONITOR.debug("Data Cache Miss " + key);
++ EHCacheModule.CACHE_MONITOR.config("Data Cache Miss " + key);
+ }
+ return null;
+ }
diff --git a/external/jfreereport/patches/libloader-1.1.6-deprecated.patch b/external/jfreereport/patches/libloader-1.1.6-deprecated.patch
new file mode 100644
index 000000000..79fa046fd
--- /dev/null
+++ b/external/jfreereport/patches/libloader-1.1.6-deprecated.patch
@@ -0,0 +1,34 @@
+--- misc/libloader-1.1.6/source/org/pentaho/reporting/libraries/resourceloader/ResourceException.java 2010-04-27 16:07:00.000000000 +0200
++++ misc/build/libloader-1.1.6/source/org/pentaho/reporting/libraries/resourceloader/ResourceException.java 2011-06-13 02:00:46.000000000 +0200
+@@ -42,7 +42,7 @@
+ */
+ public ResourceException(final String message, final Exception ex)
+ {
+- super(message, ex);
++ super(message, (Throwable) ex);
+ }
+
+ /**
+--- misc/libloader-1.1.6/source/org/pentaho/reporting/libraries/resourceloader/loader/file/FileResourceLoader.java 2010-04-27 16:07:00.000000000 +0200
++++ misc/build/libloader-1.1.6/source/org/pentaho/reporting/libraries/resourceloader/loader/file/FileResourceLoader.java 2014-07-24 15:11:26.000000000 +0200
+@@ -19,6 +19,7 @@
+
+ import java.io.File;
+ import java.io.IOException;
++import java.lang.SecurityException;
+ import java.net.MalformedURLException;
+ import java.net.URL;
+ import java.util.HashMap;
+@@ -170,7 +171,11 @@
+ final File file = (File) key.getIdentifier();
+ try
+ {
+- return file.toURL();
++ return file.toURI().toURL();
++ }
++ catch (SecurityException e)
++ {
++ return null;
+ }
+ catch (MalformedURLException e)
+ {
diff --git a/external/jfreereport/patches/librepository-1.1.3-remove-commons-logging.patch.1 b/external/jfreereport/patches/librepository-1.1.3-remove-commons-logging.patch.1
new file mode 100644
index 000000000..29acd6043
--- /dev/null
+++ b/external/jfreereport/patches/librepository-1.1.3-remove-commons-logging.patch.1
@@ -0,0 +1,117 @@
+diff -ru librepository-1.1.3.orig/source/org/pentaho/reporting/libraries/repository/zip/ZipContentLocation.java librepository-1.1.3/source/org/pentaho/reporting/libraries/repository/zip/ZipContentLocation.java
+--- librepository-1.1.3.orig/source/org/pentaho/reporting/libraries/repository/zip/ZipContentLocation.java 2021-04-07 11:16:05.369984495 +0100
++++ librepository-1.1.3/source/org/pentaho/reporting/libraries/repository/zip/ZipContentLocation.java 2021-04-07 11:17:30.417035353 +0100
+@@ -21,8 +21,7 @@
+ import java.util.HashMap;
+ import java.util.zip.ZipEntry;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.repository.ContentCreationException;
+ import org.pentaho.reporting.libraries.repository.ContentEntity;
+ import org.pentaho.reporting.libraries.repository.ContentIOException;
+@@ -35,7 +34,7 @@
+
+ public class ZipContentLocation implements ContentLocation
+ {
+- private static final Log logger = LogFactory.getLog(ZipContentLocation.class);
++ private static final Logger logger = Logger.getLogger(ZipContentLocation.class.getName());
+ private ZipRepository repository;
+ private ZipContentLocation parent;
+ private String comment;
+@@ -114,7 +113,7 @@
+ final Object entry = entries.get(path);
+ if (entry instanceof ContentItem)
+ {
+- logger.warn("Directory-Entry with the same name as a Content-Entry encountered: " + path);
++ logger.warning("Directory-Entry with the same name as a Content-Entry encountered: " + path);
+ return;
+ }
+ final ZipContentLocation location;
+@@ -164,7 +163,7 @@
+ {
+ if (entry instanceof ContentItem)
+ {
+- logger.warn("Directory-Entry with the same name as a Content-Entry encountered: " + path);
++ logger.warning("Directory-Entry with the same name as a Content-Entry encountered: " + path);
+ return;
+ }
+
+@@ -188,12 +187,12 @@
+ {
+ if (entry instanceof ContentItem)
+ {
+- logger.warn("Duplicate Content-Entry encountered: " + path);
++ logger.warning("Duplicate Content-Entry encountered: " + path);
+ return;
+ }
+ else if (entry != null)
+ {
+- logger.warn("Replacing Directory-Entry with the same name as a Content-Entry: " + path);
++ logger.warning("Replacing Directory-Entry with the same name as a Content-Entry: " + path);
+ }
+ final ZipContentItem contentItem = new ZipContentItem(repository, this, zipEntry, data);
+ entries.put(path, contentItem);
+@@ -352,4 +351,4 @@
+ {
+ return (entries.remove(entity.getName()) != null);
+ }
+-}
+\ No newline at end of file
++}
+diff -ru librepository-1.1.3.orig/source/org/pentaho/reporting/libraries/repository/zipreader/ZipReadContentLocation.java librepository-1.1.3/source/org/pentaho/reporting/libraries/repository/zipreader/ZipReadContentLocation.java
+--- librepository-1.1.3.orig/source/org/pentaho/reporting/libraries/repository/zipreader/ZipReadContentLocation.java 2021-04-07 11:16:05.365984446 +0100
++++ librepository-1.1.3/source/org/pentaho/reporting/libraries/repository/zipreader/ZipReadContentLocation.java 2021-04-07 11:17:22.342935587 +0100
+@@ -21,8 +21,7 @@
+ import java.util.HashMap;
+ import java.util.zip.ZipEntry;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.repository.ContentCreationException;
+ import org.pentaho.reporting.libraries.repository.ContentEntity;
+ import org.pentaho.reporting.libraries.repository.ContentIOException;
+@@ -39,7 +38,7 @@
+ */
+ public class ZipReadContentLocation implements ContentLocation
+ {
+- private static final Log logger = LogFactory.getLog(ZipReadContentLocation.class);
++ private static final Logger logger = Logger.getLogger(ZipReadContentLocation.class.getName());
+ private ZipReadRepository repository;
+ private ZipReadContentLocation parent;
+ private String comment;
+@@ -117,7 +116,7 @@
+ final Object entry = entries.get(path);
+ if (entry instanceof ContentItem)
+ {
+- logger.warn("Directory-Entry with the same name as a Content-Entry encountered: " + path);
++ logger.warning("Directory-Entry with the same name as a Content-Entry encountered: " + path);
+ return;
+ }
+ final ZipReadContentLocation location;
+@@ -164,7 +163,7 @@
+ {
+ if (entry instanceof ContentItem)
+ {
+- logger.warn("Directory-Entry with the same name as a Content-Entry encountered: " + path);
++ logger.warning("Directory-Entry with the same name as a Content-Entry encountered: " + path);
+ return;
+ }
+
+@@ -188,12 +187,12 @@
+ {
+ if (entry instanceof ContentItem)
+ {
+- logger.warn("Duplicate Content-Entry encountered: " + path);
++ logger.warning("Duplicate Content-Entry encountered: " + path);
+ return;
+ }
+ else if (entry != null)
+ {
+- logger.warn("Replacing Directory-Entry with the same name as a Content-Entry: " + path);
++ logger.warning("Replacing Directory-Entry with the same name as a Content-Entry: " + path);
+ }
+ final ZipReadContentItem contentItem = new ZipReadContentItem(repository, this, zipEntry, data);
+ entries.put(path, contentItem);
diff --git a/external/jfreereport/patches/librepository-1.1.6-deprecated.patch b/external/jfreereport/patches/librepository-1.1.6-deprecated.patch
new file mode 100644
index 000000000..324a8f416
--- /dev/null
+++ b/external/jfreereport/patches/librepository-1.1.6-deprecated.patch
@@ -0,0 +1,37 @@
+--- misc/librepository-1.1.6/source/org/pentaho/reporting/libraries/repository/ContentIOException.java 2010-04-27 16:04:50.000000000 +0200
++++ misc/build/librepository-1.1.6/source/org/pentaho/reporting/libraries/repository/ContentIOException.java 2011-06-13 01:44:35.000000000 +0200
+@@ -43,7 +43,7 @@
+ */
+ public ContentIOException(final String message, final Exception ex)
+ {
+- super(message, ex);
++ super(message, (Throwable) ex);
+ }
+
+ /**
+--- misc/librepository-1.1.6/source/org/pentaho/reporting/libraries/repository/file/FileRepository.java 2010-04-27 16:04:50.000000000 +0200
++++ misc/build/librepository-1.1.6/source/org/pentaho/reporting/libraries/repository/file/FileRepository.java 2014-07-25 11:21:51.000000000 +0200
+@@ -19,7 +19,9 @@
+
+ import java.io.File;
+ import java.io.Serializable;
++import java.lang.SecurityException;
+ import java.net.MalformedURLException;
++import java.net.URI;
+ import java.net.URL;
+
+ import org.pentaho.reporting.libraries.repository.ContentIOException;
+@@ -104,6 +106,11 @@
+ */
+ public URL getURL() throws MalformedURLException
+ {
+- return root.getBackend().toURL();
++ try {
++ URI uri = root.getBackend().toURI();
++ return uri.toURL();
++ } catch (SecurityException e) {
++ throw new MalformedURLException("impossible" + e);
++ }
+ }
+ }
+
diff --git a/external/jfreereport/patches/libserializer-1.1.2-remove-commons-logging.patch.1 b/external/jfreereport/patches/libserializer-1.1.2-remove-commons-logging.patch.1
new file mode 100644
index 000000000..52ee76a77
--- /dev/null
+++ b/external/jfreereport/patches/libserializer-1.1.2-remove-commons-logging.patch.1
@@ -0,0 +1,31 @@
+diff -ru libserializer-1.1.2.orig/source/org/pentaho/reporting/libraries/serializer/SerializerHelper.java libserializer-1.1.2/source/org/pentaho/reporting/libraries/serializer/SerializerHelper.java
+--- libserializer-1.1.2.orig/source/org/pentaho/reporting/libraries/serializer/SerializerHelper.java 2021-04-07 11:22:05.509434457 +0100
++++ libserializer-1.1.2/source/org/pentaho/reporting/libraries/serializer/SerializerHelper.java 2021-04-07 11:23:19.102343782 +0100
+@@ -25,8 +25,7 @@
+ import java.util.HashMap;
+ import java.util.Iterator;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.base.config.Configuration;
+ import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
+ import org.pentaho.reporting.libraries.base.util.DebugLog;
+@@ -41,7 +40,7 @@
+ */
+ public class SerializerHelper
+ {
+- private static final Log logger = LogFactory.getLog(SerializerHelper.class);
++ private static final Logger logger = Logger.getLogger(SerializerHelper.class.getName());
+ /**
+ * The singleton instance of the serialize helper.
+ */
+@@ -124,7 +123,7 @@
+ }
+ else
+ {
+- logger.warn("Invalid SerializeMethod implementation: " + c);
++ logger.warning("Invalid SerializeMethod implementation: " + c);
+ }
+ }
+ }
diff --git a/external/jfreereport/patches/libxml-1.1.3-remove-commons-logging.patch.1 b/external/jfreereport/patches/libxml-1.1.3-remove-commons-logging.patch.1
new file mode 100644
index 000000000..ecec88c48
--- /dev/null
+++ b/external/jfreereport/patches/libxml-1.1.3-remove-commons-logging.patch.1
@@ -0,0 +1,313 @@
+diff -ru pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/AbstractXmlReadHandler.java pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/AbstractXmlReadHandler.java
+--- pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/AbstractXmlReadHandler.java 2021-04-07 11:34:22.313653786 +0100
++++ pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/AbstractXmlReadHandler.java 2021-04-07 11:48:16.381234640 +0100
+@@ -20,8 +20,8 @@
+ import java.util.HashMap;
+ import java.util.Map;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.DependencyCollector;
+ import org.pentaho.reporting.libraries.resourceloader.FactoryParameterKey;
+ import org.pentaho.reporting.libraries.resourceloader.Resource;
+@@ -40,7 +40,7 @@
+ */
+ public abstract class AbstractXmlReadHandler implements XmlReadHandler
+ {
+- private static final Log logger = LogFactory.getLog(AbstractXmlReadHandler.class);
++ private static final Logger logger = Logger.getLogger(AbstractXmlReadHandler.class.getName());
+
+ /**
+ * The root handler.
+@@ -120,8 +120,8 @@
+ final XmlReadHandler childHandler = getHandlerForChild(uri, tagName, attrs);
+ if (childHandler == null)
+ {
+- logger.warn("Unknown tag <" + uri + ':' + tagName + ">: Start to ignore this element and all of its childs. " + getLocatorString());
+- logger.debug(this.getClass());
++ logger.warning("Unknown tag <" + uri + ':' + tagName + ">: Start to ignore this element and all of its childs. " + getLocatorString());
++ logger.config(this.getClass().getName());
+ final IgnoreAnyChildReadHandler ignoreAnyChildReadHandler =
+ new IgnoreAnyChildReadHandler();
+ ignoreAnyChildReadHandler.init(getRootHandler(), uri, tagName);
+diff -ru pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/AbstractXmlResourceFactory.java pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/AbstractXmlResourceFactory.java
+--- pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/AbstractXmlResourceFactory.java 2021-04-07 11:34:22.313653786 +0100
++++ pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/AbstractXmlResourceFactory.java 2021-04-07 11:44:15.729203631 +0100
+@@ -26,8 +26,7 @@
+ import javax.xml.parsers.SAXParser;
+ import javax.xml.parsers.SAXParserFactory;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.CompoundResource;
+ import org.pentaho.reporting.libraries.resourceloader.FactoryParameterKey;
+ import org.pentaho.reporting.libraries.resourceloader.Resource;
+@@ -56,7 +55,7 @@
+ */
+ public abstract class AbstractXmlResourceFactory implements ResourceFactory
+ {
+- private static final Log logger = LogFactory.getLog(AbstractXmlResourceFactory.class);
++ private static final Logger logger = Logger.getLogger(AbstractXmlResourceFactory.class.getName());
+
+ /**
+ * A key for the content base.
+@@ -115,7 +114,7 @@
+ }
+ catch (SAXException se)
+ {
+- logger.debug("Comments are not supported by this SAX implementation.");
++ logger.config("Comments are not supported by this SAX implementation.");
+ }
+
+ try
+@@ -133,7 +132,7 @@
+ }
+ catch (SAXException e)
+ {
+- logger.warn("No Namespace features will be available. (Yes, this is serious)");
++ logger.warning("No Namespace features will be available. (Yes, this is serious)");
+ }
+ }
+
+diff -ru pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/DomTreeResourceFactory.java pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/DomTreeResourceFactory.java
+--- pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/DomTreeResourceFactory.java 2021-04-07 11:34:22.314653798 +0100
++++ pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/DomTreeResourceFactory.java 2021-04-07 11:43:15.934442890 +0100
+@@ -22,8 +22,7 @@
+ import javax.xml.parsers.DocumentBuilderFactory;
+ import javax.xml.parsers.ParserConfigurationException;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.Resource;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceCreationException;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceData;
+@@ -61,7 +60,7 @@
+ }
+ }
+
+- private static final Log logger = LogFactory.getLog(DomTreeResourceFactory.class);
++ private static final Logger logger = Logger.getLogger(DomTreeResourceFactory.class.getName());
+
+ /**
+ * Creates a resource by interpreting the data given in the resource-data object. If additional datastreams need to
+diff -ru pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/LoggingErrorHandler.java pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/LoggingErrorHandler.java
+--- pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/LoggingErrorHandler.java 2021-04-07 11:34:22.313653786 +0100
++++ pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/LoggingErrorHandler.java 2021-04-07 11:49:49.117390246 +0100
+@@ -17,8 +17,8 @@
+
+ package org.pentaho.reporting.libraries.xmlns.parser;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ import org.xml.sax.ErrorHandler;
+ import org.xml.sax.SAXException;
+ import org.xml.sax.SAXParseException;
+@@ -30,9 +30,9 @@
+ */
+ public class LoggingErrorHandler implements ErrorHandler
+ {
+- private static final Log defaultLogContext = LogFactory.getLog(LoggingErrorHandler.class);
++ private static final Logger defaultLogContext = Logger.getLogger(LoggingErrorHandler.class.getName());
+ /** @noinspection NonConstantLogger*/
+- private Log logContext;
++ private Logger logContext;
+
+ /**
+ * Default-Constructor. Logs to a logger configured with this class name as category.
+@@ -47,7 +47,7 @@
+ *
+ * @param logContext the logger that should receive the messages.
+ */
+- public LoggingErrorHandler(final Log logContext)
++ public LoggingErrorHandler(final Logger logContext)
+ {
+ if (logContext == null)
+ {
+@@ -78,7 +78,7 @@
+ */
+ public void warning(final SAXParseException exception) throws SAXException
+ {
+- if (logContext.isDebugEnabled())
++ if (logContext.isLoggable(Level.CONFIG))
+ {
+ if (exception.getMessage().startsWith("URI was not reported to parser for entity"))
+ {
+@@ -86,7 +86,7 @@
+ // the GNU thing complain about it ..
+ return;
+ }
+- logContext.debug("Parser-Warning", exception);
++ logContext.severe("Parser-Warning: " + exception.getMessage());
+ }
+ }
+
+@@ -115,15 +115,15 @@
+ */
+ public void error(final SAXParseException exception) throws SAXException
+ {
+- if (logContext.isWarnEnabled())
++ if (logContext.isLoggable(Level.WARNING))
+ {
+- if (logContext.isDebugEnabled())
++ if (logContext.isLoggable(Level.CONFIG))
+ {
+- logContext.warn("Recoverable Parser-Error", exception);
++ logContext.warning("Recoverable Parser-Error:" + exception.getMessage());
+ }
+ else
+ {
+- logContext.warn("Recoverable Parser-Error:" + exception.getMessage());
++ logContext.warning("Recoverable Parser-Error:" + exception.getMessage());
+ }
+ }
+ }
+@@ -156,15 +156,15 @@
+ */
+ public void fatalError(final SAXParseException exception) throws SAXException
+ {
+- if (logContext.isErrorEnabled())
++ if (logContext.isLoggable(Level.SEVERE))
+ {
+- if (logContext.isDebugEnabled())
++ if (logContext.isLoggable(Level.CONFIG))
+ {
+- logContext.error("Fatal Parser-Error", exception);
++ logContext.severe("Fatal Parser-Error:" + exception.getMessage());
+ }
+ else
+ {
+- logContext.error("Fatal Parser-Error:" + exception.getMessage());
++ logContext.severe("Fatal Parser-Error:" + exception.getMessage());
+ }
+ }
+ }
+diff -ru pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/ParserEntityResolver.java pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/ParserEntityResolver.java
+--- pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/ParserEntityResolver.java 2021-04-07 11:34:22.314653798 +0100
++++ pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/ParserEntityResolver.java 2021-04-07 11:43:45.602820344 +0100
+@@ -22,8 +22,7 @@
+ import java.net.URL;
+ import java.util.HashMap;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.xml.sax.EntityResolver;
+ import org.xml.sax.InputSource;
+
+@@ -34,7 +33,7 @@
+ */
+ public final class ParserEntityResolver implements EntityResolver
+ {
+- private static final Log logger = LogFactory.getLog(ParserEntityResolver.class);
++ private static final Logger logger = Logger.getLogger(ParserEntityResolver.class.getName());
+
+ /**
+ * The hashtable for the known entities (deprecated DTDs).
+@@ -75,7 +74,7 @@
+ }
+ else
+ {
+- logger.warn("Validate location failed for " + publicID + " location: " + location);
++ logger.warning("Validate location failed for " + publicID + " location: " + location);
+ return false;
+ }
+ }
+@@ -101,7 +100,7 @@
+ }
+ else
+ {
+- logger.warn("Validate location failed for " + publicID + " location: " + location);
++ logger.warning("Validate location failed for " + publicID + " location: " + location);
+ return false;
+ }
+ }
+@@ -195,7 +194,7 @@
+ }
+ catch (IOException ioe)
+ {
+- logger.warn("Unable to open specified DTD", ioe);
++ logger.warning("Unable to open specified DTD: " + ioe);
+ }
+ return null;
+ }
+diff -ru pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/ResourceDataInputSource.java pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/ResourceDataInputSource.java
+--- pentaho-libxml-1.1.3.orig/source/org/pentaho/reporting/libraries/xmlns/parser/ResourceDataInputSource.java 2021-04-07 11:34:22.312653773 +0100
++++ pentaho-libxml-1.1.3/source/org/pentaho/reporting/libraries/xmlns/parser/ResourceDataInputSource.java 2021-04-07 11:44:05.484073284 +0100
+@@ -20,8 +20,7 @@
+ import java.io.InputStream;
+ import java.net.URL;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceData;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceLoadingException;
+ import org.pentaho.reporting.libraries.resourceloader.ResourceManager;
+@@ -34,7 +33,7 @@
+ */
+ public class ResourceDataInputSource extends InputSource
+ {
+- private static final Log logger = LogFactory.getLog(ResourceDataInputSource.class);
++ private static final Logger logger = Logger.getLogger(ResourceDataInputSource.class.getName());
+ private ResourceData data;
+ private long version;
+ private ResourceManager caller;
+@@ -103,7 +102,7 @@
+ }
+ catch (ResourceLoadingException e)
+ {
+- logger.error("Unable to create byte-stream: " + data.getKey());
++ logger.severe("Unable to create byte-stream: " + data.getKey());
+ return null;
+ }
+ }
+--- a/source/org/pentaho/reporting/libraries/xmlns/common/ParserUtil.java
++++ b/source/org/pentaho/reporting/libraries/xmlns/common/ParserUtil.java
+@@ -21,8 +21,7 @@
+ import org.pentaho.reporting.libraries.xmlns.LibXmlBoot;
+ import org.xml.sax.Locator;
+ import org.xml.sax.SAXException;
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * Basic helper functions to ease up the process of parsing.
+@@ -31,7 +30,7 @@
+ */
+ public class ParserUtil
+ {
+- private static final Log logger = LogFactory.getLog(ParserUtil.class);
++ private static final Logger logger = Logger.getLogger(ParserUtil.class.getName());
+ private static boolean strictParsing;
+
+ static
+@@ -243,7 +242,7 @@
+ return false;
+ }
+
+- logger.warn("Invalid value encountered: Expected 'true' or 'false', but got '" + text + "'");
++ logger.warning("Invalid value encountered: Expected 'true' or 'false', but got '" + text + "'");
+ return "true".equalsIgnoreCase(text);
+ }
+ }
+@@ -281,11 +280,11 @@
+
+ if (locator == null)
+ {
+- logger.warn("Invalid value encountered for boolean attribute.");
++ logger.warning("Invalid value encountered for boolean attribute.");
+ }
+ else
+ {
+- logger.warn("Invalid value encountered for boolean attribute. [Line: " +
++ logger.warning("Invalid value encountered for boolean attribute. [Line: " +
+ locator.getLineNumber() + " Column: " + locator.getColumnNumber() + "]");
+ }
+ return Boolean.FALSE;
diff --git a/external/jfreereport/patches/pentaho-reporting-flow-engine-0.9.4-remove-commons-logging.patch.1 b/external/jfreereport/patches/pentaho-reporting-flow-engine-0.9.4-remove-commons-logging.patch.1
new file mode 100644
index 000000000..80029e49f
--- /dev/null
+++ b/external/jfreereport/patches/pentaho-reporting-flow-engine-0.9.4-remove-commons-logging.patch.1
@@ -0,0 +1,101 @@
+diff -ru pentaho-reporting-flow-engine-0.9.4.orig/source/org/jfree/report/JFreeReportBoot.java pentaho-reporting-flow-engine-0.9.4/source/org/jfree/report/JFreeReportBoot.java
+--- pentaho-reporting-flow-engine-0.9.4.orig/source/org/jfree/report/JFreeReportBoot.java 2021-04-07 12:09:46.917336778 +0100
++++ pentaho-reporting-flow-engine-0.9.4/source/org/jfree/report/JFreeReportBoot.java 2021-04-07 12:12:04.794062296 +0100
+@@ -42,8 +42,7 @@
+ import org.pentaho.reporting.libraries.base.boot.PackageManager;
+ import org.pentaho.reporting.libraries.base.versioning.ProjectInformation;
+ import org.pentaho.reporting.libraries.base.LibBaseBoot;
+-import org.apache.commons.logging.LogFactory;
+-import org.apache.commons.logging.Log;
++import java.util.logging.Logger;
+
+ /**
+ * An utility class to safely boot and initialize the JFreeReport library. This class
+@@ -66,7 +65,7 @@
+ */
+ public class JFreeReportBoot extends AbstractBoot
+ {
+- private static final Log logger = LogFactory.getLog(JFreeReportBoot.class);
++ private static final Logger logger = Logger.getLogger(JFreeReportBoot.class.getName());
+
+ /**
+ * A wrappper around the user supplied global configuration.
+@@ -292,12 +291,12 @@
+ // make sure logging is re-initialized after we injected our configuration.
+ if (isStrictFP() == false)
+ {
+- logger.warn("The used VM seems to use a non-strict floating point arithmetics");
+- logger.warn("Layouts computed with this Java Virtual Maschine may be invalid.");
+- logger.warn("JFreeReport and the library 'iText' depend on the strict floating point rules");
+- logger.warn("of Java1.1 as implemented by the Sun Virtual Maschines.");
+- logger.warn("If you are using the BEA JRockit VM, start the Java VM with the option");
+- logger.warn("'-Xstrictfp' to restore the default behaviour.");
++ logger.warning("The used VM seems to use a non-strict floating point arithmetics");
++ logger.warning("Layouts computed with this Java Virtual Maschine may be invalid.");
++ logger.warning("JFreeReport and the library 'iText' depend on the strict floating point rules");
++ logger.warning("of Java1.1 as implemented by the Sun Virtual Maschines.");
++ logger.warning("If you are using the BEA JRockit VM, start the Java VM with the option");
++ logger.warning("'-Xstrictfp' to restore the default behaviour.");
+ }
+
+ final PackageManager mgr = getPackageManager();
+@@ -338,8 +337,8 @@
+ }
+ catch (Exception se)
+ {
+- logger.error
+- ("An error occured while checking the system properties for extension modules.", se);
++ logger.severe
++ ("An error occured while checking the system properties for extension modules: " + se);
+ }
+ }
+
+diff -ru pentaho-reporting-flow-engine-0.9.4.orig/source/org/jfree/report/util/ComponentDrawable.java pentaho-reporting-flow-engine-0.9.4/source/org/jfree/report/util/ComponentDrawable.java
+--- pentaho-reporting-flow-engine-0.9.4.orig/source/org/jfree/report/util/ComponentDrawable.java 2021-04-07 12:09:46.916336765 +0100
++++ pentaho-reporting-flow-engine-0.9.4/source/org/jfree/report/util/ComponentDrawable.java 2021-04-07 12:11:25.530570919 +0100
+@@ -42,8 +42,7 @@
+ import javax.swing.RepaintManager;
+ import javax.swing.SwingUtilities;
+
+-import org.apache.commons.logging.Log;
+-import org.apache.commons.logging.LogFactory;
++import java.util.logging.Logger;
+
+ /**
+ * Creation-Date: 11.10.2005, 14:03:15
+@@ -52,7 +51,7 @@
+ */
+ public class ComponentDrawable
+ {
+- private static final Log logger = LogFactory.getLog (ComponentDrawable.class);
++ private static final Logger logger = Logger.getLogger(ComponentDrawable.class.getName());
+
+ /**
+ * A runnable that executes the drawing operation on the event-dispatcher thread.
+@@ -443,7 +442,7 @@
+ }
+ catch (Exception e)
+ {
+- ComponentDrawable.logger.warn("Failed to compute the preferred size.");
++ ComponentDrawable.logger.warning("Failed to compute the preferred size.");
+ }
+ return new Dimension(0, 0);
+ }
+@@ -475,7 +474,7 @@
+ }
+ catch (Exception e)
+ {
+- ComponentDrawable.logger.warn("Failed to compute the defined size.");
++ ComponentDrawable.logger.warning("Failed to compute the defined size.");
+ }
+ return new Dimension(0, 0);
+ }
+@@ -563,7 +562,7 @@
+ }
+ catch (Exception e)
+ {
+- ComponentDrawable.logger.warn("Failed to redraw the component.");
++ ComponentDrawable.logger.warning("Failed to redraw the component.");
+ }
+ }
+ }
diff --git a/external/jfreereport/patches/sac.patch b/external/jfreereport/patches/sac.patch
new file mode 100644
index 000000000..77db8511a
--- /dev/null
+++ b/external/jfreereport/patches/sac.patch
@@ -0,0 +1,73 @@
+*** misc/sac-1.3/build.xml Thu Oct 18 09:22:24 2007
+--- misc/build/sac-1.3/build.xml Thu Oct 18 08:53:59 2007
+***************
+*** 1 ****
+! dummy
+--- 1,66 ----
+! <!-- simple generic build file -->
+!
+! <project name="sac" default="all" basedir=".">
+!
+! <!-- Properties -->
+!
+! <property name="name" value="sac"/>
+! <property name="src" value="src"/>
+! <property name="build" value="build"/>
+! <property name="build.classes" value="${build}/classes"/>
+! <property name="build.doc" value="${build}/api"/>
+! <property name="build.lib" value="${build}/lib"/>
+! <property name="packagenames" value="org.w3c.css.sac.*"/>
+!
+! <!-- Targets -->
+!
+! <!-- Prepare build directories -->
+! <target name="prepare">
+! <mkdir dir="${src}"/>
+! <mkdir dir="${build}"/>
+! <mkdir dir="${build.classes}"/>
+! <mkdir dir="${build.lib}"/>
+! <mkdir dir="${build.doc}"/>
+! <copy todir="${src}/org">
+! <fileset dir="org"/>
+! </copy>
+! </target>
+!
+! <!-- Kill all the created directories -->
+! <target name="clean">
+! <delete dir="${build}"/>
+! <delete dir="${src}"/>
+! </target>
+!
+! <!-- Build classes -->
+! <target name="classes" depends="prepare">
+! <javac srcdir="${src}" destdir="${build.classes}" debug="off" optimize="on"/>
+! <copy todir="${build.classes}">
+! <fileset dir="${src}">
+! <include name="**/*.properties"/>
+! </fileset>
+! </copy>
+! </target>
+!
+! <!-- Build jar archives -->
+! <target name="jar" depends="classes">
+! <jar jarfile="${build.lib}/${name}.jar" basedir="${build.classes}"/>
+! </target>
+!
+! <!-- Build the full JavaDocs -->
+! <target name="javadoc" depends="prepare">
+! <javadoc sourcepath="${src}"
+! destdir="${build.doc}"
+! doctitle="${name} JavaDoc"
+! windowtitle="${name} JavaDoc"
+! package="true"
+! author="true"
+! version="true"
+! packagenames="${packagenames}"
+! />
+! </target>
+!
+! <!-- Build everything -->
+! <target name="all" depends="jar,javadoc"/>
+!
+! </project>
+\ No newline at end of file
diff --git a/external/jfreereport/version.mk b/external/jfreereport/version.mk
new file mode 100644
index 000000000..af5980f4a
--- /dev/null
+++ b/external/jfreereport/version.mk
@@ -0,0 +1,10 @@
+FLUTE_VERSION=1.1.6
+LIBBASE_VERSION=1.1.6
+LIBFONTS_VERSION=1.1.6
+LIBFORMAT_VERSION=1.1.6
+LIBFORMULA_VERSION=1.1.7
+LIBLOADER_VERSION=1.1.6
+LIBREPOSITORY_VERSION=1.1.6
+LIBSERIALIZER_VERSION=1.1.6
+LIBXML_VERSION=1.1.7
+
diff --git a/external/lcms2/ExternalPackage_lcms2.mk b/external/lcms2/ExternalPackage_lcms2.mk
new file mode 100644
index 000000000..ede9e66ac
--- /dev/null
+++ b/external/lcms2/ExternalPackage_lcms2.mk
@@ -0,0 +1,28 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,lcms2,lcms2))
+
+$(eval $(call gb_ExternalPackage_use_external_project,lcms2,lcms2))
+
+ifeq ($(DISABLE_DYNLOADING),)
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,lcms2,$(LIBO_LIB_FOLDER)/liblcms2.2.dylib,src/.libs/liblcms2.2.dylib))
+else ifeq ($(OS),WNT)
+ifeq ($(COM),GCC)
+$(eval $(call gb_ExternalPackage_add_file,lcms2,$(LIBO_LIB_FOLDER)/liblcms2-2.dll,src/.libs/liblcms2-2.dll))
+else ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalPackage_add_file,lcms2,$(LIBO_LIB_FOLDER)/lcms2.dll,bin/lcms2.dll))
+endif # $(COM)
+else # $(OS) != WNT/MACOSX
+$(eval $(call gb_ExternalPackage_add_file,lcms2,$(LIBO_LIB_FOLDER)/liblcms2.so.2,src/.libs/liblcms2.so.2.0.12))
+endif # $(OS)
+endif # $(DISABLE_DYNLOADING)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lcms2/ExternalProject_lcms2.mk b/external/lcms2/ExternalProject_lcms2.mk
new file mode 100644
index 000000000..47d9089dc
--- /dev/null
+++ b/external/lcms2/ExternalProject_lcms2.mk
@@ -0,0 +1,46 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,lcms2))
+
+$(eval $(call gb_ExternalProject_register_targets,lcms2,\
+ build \
+))
+
+ifeq ($(COM),MSC)
+$(call gb_ExternalProject_get_state_target,lcms2,build):
+ $(call gb_Trace_StartRange,lcms2,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ MSBuild.exe lcms2_DLL.vcxproj \
+ $(gb_MSBUILD_CONFIG_AND_PLATFORM) /p:TargetName=lcms2 \
+ /p:PlatformToolset=$(VCTOOLSET) /p:VisualStudioVersion=$(VCVER) /ToolsVersion:Current \
+ $(if $(filter 10,$(WINDOWS_SDK_VERSION)),/p:WindowsTargetPlatformVersion=$(UCRTVERSION)) \
+ ,Projects/VC2019/lcms2_DLL)
+ $(call gb_Trace_EndRange,lcms2,EXTERNAL)
+else
+$(call gb_ExternalProject_get_state_target,lcms2,build):
+ $(call gb_Trace_StartRange,lcms2,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure --without-jpeg --without-tiff --with-pic \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),$(if $(filter INTEL ARM,$(CPUNAME)),ac_cv_c_bigendian=no)) \
+ CPPFLAGS=" $(SOLARINC)" \
+ CFLAGS='$(CFLAGS) $(call gb_ExternalProject_get_build_flags,lcms2)' \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ && cd src \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,lcms2,EXTERNAL)
+endif
+# vim: set noet sw=4 ts=4:
diff --git a/external/lcms2/Makefile b/external/lcms2/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/lcms2/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lcms2/Module_lcms2.mk b/external/lcms2/Module_lcms2.mk
new file mode 100644
index 000000000..807dbae43
--- /dev/null
+++ b/external/lcms2/Module_lcms2.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,lcms2))
+
+$(eval $(call gb_Module_add_targets,lcms2,\
+ UnpackedTarball_lcms2 \
+ ExternalPackage_lcms2 \
+ ExternalProject_lcms2 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lcms2/README b/external/lcms2/README
new file mode 100644
index 000000000..10b18a5ad
--- /dev/null
+++ b/external/lcms2/README
@@ -0,0 +1,3 @@
+lcms2 (little cms engine)
+lcms2: Little cms is a small, speed optimized color management engine.
+with the new libcdr, writerperfect will depend on lcms2 \ No newline at end of file
diff --git a/external/lcms2/UnpackedTarball_lcms2.mk b/external/lcms2/UnpackedTarball_lcms2.mk
new file mode 100644
index 000000000..932f8c63c
--- /dev/null
+++ b/external/lcms2/UnpackedTarball_lcms2.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,lcms2))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,lcms2,$(LCMS2_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,lcms2))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,lcms2,3))
+
+$(eval $(call gb_UnpackedTarball_add_patches,lcms2,\
+ external/lcms2/lcms2-2.4-windows.patch \
+ external/lcms2/c++17.patch.1 \
+ external/lcms2/lcms2-win-arm64.patch.1 \
+))
+
+# Can't include in ARM64 patch, as diff fails to detect text in it
+$(eval $(call gb_UnpackedTarball_add_file,lcms2,Projects/VC2019/lcms2.sln,external/lcms2/lcms2_sln))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lcms2/c++17.patch.1 b/external/lcms2/c++17.patch.1
new file mode 100644
index 000000000..dc5b2ccde
--- /dev/null
+++ b/external/lcms2/c++17.patch.1
@@ -0,0 +1,13 @@
+diff --git a/include/lcms2.h b/include/lcms2.h
+index cf52014..926e2a0 100644
+--- a/include/lcms2.h
++++ b/include/lcms2.h
+@@ -62,7 +62,7 @@
+ // #define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
+
+ // Uncomment this to remove the "register" storage class
+-// #define CMS_NO_REGISTER_KEYWORD 1
++#define CMS_NO_REGISTER_KEYWORD 1
+
+ // ********** End of configuration toggles ******************************
+
diff --git a/external/lcms2/lcms2-2.4-windows.patch b/external/lcms2/lcms2-2.4-windows.patch
new file mode 100644
index 000000000..749a81200
--- /dev/null
+++ b/external/lcms2/lcms2-2.4-windows.patch
@@ -0,0 +1,20 @@
+TODO: Is this still needed?
+
+--- misc/lcms2-2.4/include/lcms2.h 2011-12-15 16:45:47.000000000 +0100
++++ misc/build/lcms2-2.4/include/lcms2.h 2012-03-17 22:53:28.731585981 +0100
+@@ -192,6 +192,15 @@ typedef int cmsBool;
+ #endif // CMS_USE_BIG_ENDIAN
+
+
++// LibreOffice always builds this as DLL and with the stdcall calling
++// convention, so make this usable from outside without having to
++// specify CMS_DLL manually whenever the library is used.
++#ifndef CMS_DLL_BUILD
++#ifndef CMS_DLL
++#define CMS_DLL
++#endif
++#endif
++
+ // Calling convention -- this is hardly platform and compiler dependent
+ #ifdef CMS_IS_WINDOWS_
+ # if defined(CMS_DLL) || defined(CMS_DLL_BUILD)
diff --git a/external/lcms2/lcms2-win-arm64.patch.1 b/external/lcms2/lcms2-win-arm64.patch.1
new file mode 100644
index 000000000..fc9f0c374
--- /dev/null
+++ b/external/lcms2/lcms2-win-arm64.patch.1
@@ -0,0 +1,1537 @@
+diff -urbaN lcms2-2.11.orig/Projects/VC2019/jpegicc/jpegicc.vcxproj lcms2-2.11/Projects/VC2019/jpegicc/jpegicc.vcxproj
+--- lcms2-2.11.orig/Projects/VC2019/jpegicc/jpegicc.vcxproj 2020-06-16 19:10:37.000000000 +0200
++++ lcms2-2.11/Projects/VC2019/jpegicc/jpegicc.vcxproj 2020-07-09 18:28:37.881727697 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -37,6 +45,12 @@
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+@@ -47,6 +61,11 @@
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -56,12 +75,18 @@
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+@@ -71,32 +96,44 @@
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\bin\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IncludePath);;C:\code\jpeg-9a</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IncludePath);;C:\code\jpeg-9a</IncludePath>
++ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(IncludePath);;C:\code\jpeg-9a</IncludePath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(LibraryPath);;C:\code\jpeg-9a</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(LibraryPath);;C:\code\jpeg-9a</LibraryPath>
++ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(LibraryPath);;C:\code\jpeg-9a</LibraryPath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IncludePath);;C:\code\jpeg-9a</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IncludePath);;C:\code\jpeg-9a</IncludePath>
++ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(IncludePath);;C:\code\jpeg-9a</IncludePath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(LibraryPath);;C:\code\jpeg-9a</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(LibraryPath);;C:\code\jpeg-9a</LibraryPath>
++ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(LibraryPath);;C:\code\jpeg-9a</LibraryPath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+@@ -140,6 +177,26 @@
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <AdditionalDependencies>libjpeg.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+@@ -197,6 +254,32 @@
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <Optimization>Full</Optimization>
++ <IntrinsicFunctions>true</IntrinsicFunctions>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
++ <OmitFramePointers>true</OmitFramePointers>
++ <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <AdditionalDependencies>libjpeg.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\utils\common\vprf.c" />
+ <ClCompile Include="..\..\..\utils\common\xgetopt.c" />
+diff -urbaN lcms2-2.11.orig/Projects/VC2019/lcms2_DLL/lcms2_DLL.vcxproj lcms2-2.11/Projects/VC2019/lcms2_DLL/lcms2_DLL.vcxproj
+--- lcms2-2.11.orig/Projects/VC2019/lcms2_DLL/lcms2_DLL.vcxproj 2020-06-16 19:10:37.000000000 +0200
++++ lcms2-2.11/Projects/VC2019/lcms2_DLL/lcms2_DLL.vcxproj 2020-07-09 18:28:38.049726437 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -37,6 +45,12 @@
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+@@ -47,6 +61,11 @@
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>DynamicLibrary</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -56,12 +75,18 @@
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+@@ -69,28 +94,40 @@
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\bin\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\bin\</OutDir>
++ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\bin\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\bin\</OutDir>
++ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>lcms2</TargetName>
+@@ -99,9 +134,15 @@
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>lcms2</TargetName>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <TargetName>lcms2</TargetName>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>lcms2</TargetName>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <TargetName>lcms2</TargetName>
++ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+@@ -144,6 +185,27 @@
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CMS_DLL_BUILD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ <StringPooling>false</StringPooling>
++ </ClCompile>
++ <Link>
++ <ModuleDefinitionFile>
++ </ModuleDefinitionFile>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Windows</SubSystem>
++ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+@@ -203,6 +265,34 @@
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <Optimization>Full</Optimization>
++ <IntrinsicFunctions>true</IntrinsicFunctions>
++ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
++ <OmitFramePointers>true</OmitFramePointers>
++ <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CMS_DLL_BUILD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <StringPooling>true</StringPooling>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <ModuleDefinitionFile>
++ </ModuleDefinitionFile>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Windows</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\src\cmsalpha.c" />
+ <ClCompile Include="..\..\..\src\cmscam02.c" />
+@@ -234,7 +324,9 @@
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\src\lcms2.def">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
++ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
++ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+diff -urbaN lcms2-2.11.orig/Projects/VC2019/lcms2_static/lcms2_static.vcxproj lcms2-2.11/Projects/VC2019/lcms2_static/lcms2_static.vcxproj
+--- lcms2-2.11.orig/Projects/VC2019/lcms2_static/lcms2_static.vcxproj 2020-06-16 19:10:37.000000000 +0200
++++ lcms2-2.11/Projects/VC2019/lcms2_static/lcms2_static.vcxproj 2020-07-09 18:28:38.173725507 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -37,6 +45,12 @@
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+@@ -47,6 +61,11 @@
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>StaticLibrary</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -56,12 +75,18 @@
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+@@ -69,22 +94,30 @@
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\Lib\MS\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\Lib\MS\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\Lib\MS\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+@@ -120,6 +153,23 @@
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <FunctionLevelLinking>
++ </FunctionLevelLinking>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ <CompileAs>Default</CompileAs>
++ </ClCompile>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+@@ -169,6 +219,28 @@
+ <StringPooling>true</StringPooling>
+ </ClCompile>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <IntrinsicFunctions>true</IntrinsicFunctions>
++ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
++ <OmitFramePointers>true</OmitFramePointers>
++ <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
++ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
++ <ExceptionHandling>false</ExceptionHandling>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
++ <StringPooling>true</StringPooling>
++ </ClCompile>
++ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\src\cmsalpha.c" />
+ <ClCompile Include="..\..\..\src\cmscam02.c" />
+diff -urbaN lcms2-2.11.orig/Projects/VC2019/linkicc/linkicc.vcxproj lcms2-2.11/Projects/VC2019/linkicc/linkicc.vcxproj
+--- lcms2-2.11.orig/Projects/VC2019/linkicc/linkicc.vcxproj 2020-06-16 19:10:37.000000000 +0200
++++ lcms2-2.11/Projects/VC2019/linkicc/linkicc.vcxproj 2020-07-09 18:28:38.297724577 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -37,6 +45,12 @@
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+@@ -47,6 +61,11 @@
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -56,12 +75,18 @@
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+@@ -69,26 +94,36 @@
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\bin\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+@@ -128,6 +163,24 @@
+ <SubSystem>Console</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+@@ -175,6 +228,27 @@
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <IntrinsicFunctions>true</IntrinsicFunctions>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\utils\linkicc\linkicc.c" />
+ <ClCompile Include="..\..\..\utils\common\vprf.c" />
+diff -urbaN lcms2-2.11.orig/Projects/VC2019/psicc/psicc.vcxproj lcms2-2.11/Projects/VC2019/psicc/psicc.vcxproj
+--- lcms2-2.11.orig/Projects/VC2019/psicc/psicc.vcxproj 2020-06-16 19:10:37.000000000 +0200
++++ lcms2-2.11/Projects/VC2019/psicc/psicc.vcxproj 2020-07-09 18:28:38.421723648 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -37,6 +45,12 @@
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+@@ -47,6 +61,11 @@
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -56,12 +75,18 @@
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+@@ -69,26 +94,36 @@
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\bin\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+@@ -128,6 +163,24 @@
+ <SubSystem>Console</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+@@ -175,6 +228,27 @@
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <IntrinsicFunctions>true</IntrinsicFunctions>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\utils\psicc\psicc.c" />
+ <ClCompile Include="..\..\..\utils\common\vprf.c" />
+diff -urbaN lcms2-2.11.orig/Projects/VC2019/testbed/testbed.vcxproj lcms2-2.11/Projects/VC2019/testbed/testbed.vcxproj
+--- lcms2-2.11.orig/Projects/VC2019/testbed/testbed.vcxproj 2020-06-16 19:10:37.000000000 +0200
++++ lcms2-2.11/Projects/VC2019/testbed/testbed.vcxproj 2020-07-09 18:28:38.577722478 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -37,6 +45,12 @@
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+@@ -47,6 +61,11 @@
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -56,37 +75,53 @@
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\testbed\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\testbed\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\..\testbed\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\testbed\</OutDir>
+ </PropertyGroup>
+@@ -130,6 +165,25 @@
+ <Profile>false</Profile>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>../../../include;../../../src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <Profile>false</Profile>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+@@ -191,6 +245,34 @@
+ <Profile>false</Profile>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <Optimization>Full</Optimization>
++ <IntrinsicFunctions>true</IntrinsicFunctions>
++ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
++ <OmitFramePointers>true</OmitFramePointers>
++ <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
++ <AdditionalIncludeDirectories>../../../include;../../../src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
++ <BufferSecurityCheck>false</BufferSecurityCheck>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <CallingConvention>Cdecl</CallingConvention>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ <Profile>false</Profile>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\lcms2_static\lcms2_static.vcxproj">
+ <Project>{71dede59-3f1e-486b-a899-4283000f76b5}</Project>
+diff -urbaN lcms2-2.11.orig/Projects/VC2019/tiffdiff/tiffdiff.vcxproj lcms2-2.11/Projects/VC2019/tiffdiff/tiffdiff.vcxproj
+--- lcms2-2.11.orig/Projects/VC2019/tiffdiff/tiffdiff.vcxproj 2020-06-16 19:10:37.000000000 +0200
++++ lcms2-2.11/Projects/VC2019/tiffdiff/tiffdiff.vcxproj 2020-07-09 18:28:38.701721548 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -37,6 +45,12 @@
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+@@ -47,6 +61,11 @@
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -56,12 +75,18 @@
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+@@ -69,34 +94,48 @@
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\bin\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\jpeg-8d;$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\jpeg-8d;$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
++ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">C:\jpeg-8d;$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\jpeg-8d;$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\jpeg-8d;$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
++ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">C:\jpeg-8d;$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\jpeg-8d;$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\jpeg-8d;$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
++ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">C:\jpeg-8d;$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\jpeg-8d;$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\jpeg-8d;$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
++ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">C:\jpeg-8d;$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+@@ -140,6 +179,26 @@
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <AdditionalDependencies>libtiff.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+@@ -193,6 +252,30 @@
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <IntrinsicFunctions>true</IntrinsicFunctions>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <AdditionalDependencies>libtiff.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
++ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\utils\common\vprf.c" />
+ <ClCompile Include="..\..\..\utils\common\xgetopt.c" />
+@@ -207,4 +290,4 @@
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+-</Project>
+\ No newline at end of file
++</Project>
+diff -urbaN lcms2-2.11.orig/Projects/VC2019/tifficc/tifficc.vcxproj lcms2-2.11/Projects/VC2019/tifficc/tifficc.vcxproj
+--- lcms2-2.11.orig/Projects/VC2019/tifficc/tifficc.vcxproj 2020-06-16 19:10:37.000000000 +0200
++++ lcms2-2.11/Projects/VC2019/tifficc/tifficc.vcxproj 2020-07-09 18:28:38.821720648 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -37,6 +45,12 @@
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+@@ -47,6 +61,11 @@
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -56,12 +75,18 @@
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+@@ -69,34 +94,48 @@
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\bin\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
++ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
++ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
++ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(IncludePath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</IncludePath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
+ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
++ <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(LibraryPath);E:\liteCommons\3rdparty\tiff-4.1.0\libtiff</LibraryPath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+@@ -140,6 +179,26 @@
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level3</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <AdditionalDependencies>libtiff.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+@@ -191,6 +250,29 @@
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <IntrinsicFunctions>true</IntrinsicFunctions>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <AdditionalDependencies>libtiff.lib;%(AdditionalDependencies)</AdditionalDependencies>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\utils\common\vprf.c" />
+ <ClCompile Include="..\..\..\utils\common\xgetopt.c" />
+@@ -208,4 +290,4 @@
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+-</Project>
+\ No newline at end of file
++</Project>
+diff -urbaN lcms2-2.11.orig/Projects/VC2019/transicc/transicc.vcxproj lcms2-2.11/Projects/VC2019/transicc/transicc.vcxproj
+--- lcms2-2.11.orig/Projects/VC2019/transicc/transicc.vcxproj 2020-06-16 19:10:37.000000000 +0200
++++ lcms2-2.11/Projects/VC2019/transicc/transicc.vcxproj 2020-07-09 18:28:38.945719719 +0200
+@@ -1,6 +1,10 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
++ <ProjectConfiguration Include="Debug|ARM64">
++ <Configuration>Debug</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+@@ -9,6 +13,10 @@
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
++ <ProjectConfiguration Include="Release|ARM64">
++ <Configuration>Release</Configuration>
++ <Platform>ARM64</Platform>
++ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+@@ -37,6 +45,12 @@
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <WholeProgramOptimization>true</WholeProgramOptimization>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+@@ -47,6 +61,11 @@
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
++ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
++ <ConfigurationType>Application</ConfigurationType>
++ <CharacterSet>Unicode</CharacterSet>
++ <PlatformToolset>v142</PlatformToolset>
++ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+@@ -56,12 +75,18 @@
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
++ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
++ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
++ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.21006.1</_ProjectFileVersion>
+@@ -69,26 +94,36 @@
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\..\bin\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\bin\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)_$(Platform)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)_$(Platform)\</IntDir>
++ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
++ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
++ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
++ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+@@ -128,6 +163,24 @@
+ <SubSystem>Console</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
++ <ClCompile>
++ <Optimization>Disabled</Optimization>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
++ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+@@ -175,9 +228,31 @@
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
++ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
++ <ClCompile>
++ <Optimization>MaxSpeed</Optimization>
++ <IntrinsicFunctions>true</IntrinsicFunctions>
++ <AdditionalIncludeDirectories>../../../include;../../../utils/common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
++ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
++ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
++ <FunctionLevelLinking>true</FunctionLevelLinking>
++ <PrecompiledHeader>
++ </PrecompiledHeader>
++ <WarningLevel>Level4</WarningLevel>
++ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
++ <MultiProcessorCompilation>true</MultiProcessorCompilation>
++ </ClCompile>
++ <Link>
++ <GenerateDebugInformation>true</GenerateDebugInformation>
++ <SubSystem>Console</SubSystem>
++ <OptimizeReferences>true</OptimizeReferences>
++ <EnableCOMDATFolding>true</EnableCOMDATFolding>
++ </Link>
++ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\utils\transicc\transicc.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
++ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\utils\common\vprf.c" />
+ <ClCompile Include="..\..\..\utils\common\xgetopt.c" />
diff --git a/external/lcms2/lcms2_sln b/external/lcms2/lcms2_sln
new file mode 100644
index 000000000..6a3d35afa
--- /dev/null
+++ b/external/lcms2/lcms2_sln
Binary files differ
diff --git a/external/libabw/ExternalProject_libabw.mk b/external/libabw/ExternalProject_libabw.mk
new file mode 100644
index 000000000..48edebf6a
--- /dev/null
+++ b/external/libabw/ExternalProject_libabw.mk
@@ -0,0 +1,47 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libabw))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libabw,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libabw,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libabw,\
+ boost_headers \
+ libxml2 \
+ revenge \
+ zlib \
+))
+
+$(call gb_ExternalProject_get_state_target,libabw,build) :
+ $(call gb_Trace_StartRange,libabw,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ --disable-tools \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-werror \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(gb_FULLDEPS),,--disable-dependency-tracking) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libabw)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libabw)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libabw,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libabw/Makefile b/external/libabw/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libabw/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libabw/Module_libabw.mk b/external/libabw/Module_libabw.mk
new file mode 100644
index 000000000..096150613
--- /dev/null
+++ b/external/libabw/Module_libabw.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libabw))
+
+$(eval $(call gb_Module_add_targets,libabw,\
+ ExternalProject_libabw \
+ UnpackedTarball_libabw \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libabw/README b/external/libabw/README
new file mode 100644
index 000000000..ce209901f
--- /dev/null
+++ b/external/libabw/README
@@ -0,0 +1,3 @@
+AbiWord file word processor format import library from
+
+[https://wiki.documentfoundation.org/DLP/Libraries/libabw]
diff --git a/external/libabw/UnpackedTarball_libabw.mk b/external/libabw/UnpackedTarball_libabw.mk
new file mode 100644
index 000000000..6860e0905
--- /dev/null
+++ b/external/libabw/UnpackedTarball_libabw.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libabw))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libabw,$(ABW_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libabw))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libassuan/ExternalPackage_libassuan.mk b/external/libassuan/ExternalPackage_libassuan.mk
new file mode 100644
index 000000000..0f24e5e2d
--- /dev/null
+++ b/external/libassuan/ExternalPackage_libassuan.mk
@@ -0,0 +1,28 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libassuan,libassuan))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libassuan,libassuan))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+
+ifeq ($(OS),LINUX)
+
+$(eval $(call gb_ExternalPackage_add_file,libassuan,$(LIBO_LIB_FOLDER)/libassuan.so.0,src/.libs/libassuan.so.0.8.5))
+
+else ifeq ($(OS),MACOSX)
+
+$(eval $(call gb_ExternalPackage_add_file,libassuan,$(LIBO_LIB_FOLDER)/libassuan.0.dylib,src/.libs/libassuan.0.dylib))
+
+endif
+
+endif # $(DISABLE_DYNLOADING)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libassuan/ExternalProject_libassuan.mk b/external/libassuan/ExternalProject_libassuan.mk
new file mode 100644
index 000000000..9b972a55f
--- /dev/null
+++ b/external/libassuan/ExternalProject_libassuan.mk
@@ -0,0 +1,67 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libassuan))
+
+$(eval $(call gb_ExternalProject_register_targets,libassuan,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libassuan,build))
+
+$(eval $(call gb_ExternalProject_use_externals,libassuan,\
+ libgpg-error \
+))
+
+
+ifeq ($(COM),MSC)
+$(call gb_ExternalProject_get_state_target,libassuan,build): $(call gb_Executable_get_target_for_build,cpp)
+ $(call gb_Trace_StartRange,libassuan,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_WIN_GPG_cross_setup_exports) \
+ && autoreconf \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --enable-static \
+ --disable-shared \
+ --disable-doc \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CFLAGS="$(CFLAGS) -D__STDC__=1 $(call gb_ExternalProject_get_build_flags,libassuan)" \
+ GPG_ERROR_CFLAGS="$(GPG_ERROR_CFLAGS)" \
+ GPG_ERROR_LIBS="$(GPG_ERROR_LIBS)" \
+ $(gb_WIN_GPG_platform_switches) \
+ MAKE=$(MAKE) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libassuan,EXTERNAL)
+else
+$(call gb_ExternalProject_get_state_target,libassuan,build):
+ $(call gb_Trace_StartRange,libassuan,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ autoreconf \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --disable-doc \
+ CFLAGS="$(CFLAGS) $(call gb_ExternalProject_get_build_flags,libassuan)" \
+ GPG_ERROR_CFLAGS="$(GPG_ERROR_CFLAGS)" \
+ GPG_ERROR_LIBS="$(GPG_ERROR_LIBS)" \
+ $(if $(filter LINUX,$(OS)), \
+ 'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN') \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),--disable-shared,--disable-static) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/.libs/libassuan.0.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,libassuan,EXTERNAL)
+
+endif
+# vim: set noet sw=4 ts=4:
diff --git a/external/libassuan/Makefile b/external/libassuan/Makefile
new file mode 100644
index 000000000..569ad8a0b
--- /dev/null
+++ b/external/libassuan/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libassuan/Module_libassuan.mk b/external/libassuan/Module_libassuan.mk
new file mode 100644
index 000000000..45ada66ee
--- /dev/null
+++ b/external/libassuan/Module_libassuan.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libassuan))
+
+$(eval $(call gb_Module_add_targets,libassuan,\
+ ExternalProject_libassuan \
+ ExternalPackage_libassuan \
+ UnpackedTarball_libassuan \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libassuan/README b/external/libassuan/README
new file mode 100644
index 000000000..cd35103a1
--- /dev/null
+++ b/external/libassuan/README
@@ -0,0 +1,3 @@
+A small library implementing Assuan protocol which is used as IPC
+between most of the newer GnuPG components
+[https://www.gnupg.org/related_software/libassuan/index.html]
diff --git a/external/libassuan/UnpackedTarball_libassuan.mk b/external/libassuan/UnpackedTarball_libassuan.mk
new file mode 100644
index 000000000..3604fa36a
--- /dev/null
+++ b/external/libassuan/UnpackedTarball_libassuan.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libassuan))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libassuan,$(LIBASSUAN_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libassuan,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libassuan, \
+ external/libassuan/find-libgpg-error.patch \
+ external/libassuan/fix-autoconf-macros.patch \
+ $(if $(filter MSC,$(COM)),external/libassuan/w32-build-fixes.patch.1) \
+ external/libassuan/w32-build-fixes-2.patch \
+ $(if $(filter LINUX,$(OS)),external/libassuan/rpath.patch) \
+ external/libassuan/w32-stdc.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libassuan/find-libgpg-error.patch b/external/libassuan/find-libgpg-error.patch
new file mode 100644
index 000000000..57361ab5e
--- /dev/null
+++ b/external/libassuan/find-libgpg-error.patch
@@ -0,0 +1,18 @@
+--- configure.ac 2017-02-13 14:34:06.983449082 +0100
++++ configure.ac 2017-02-13 15:36:50.944653536 +0100
+@@ -355,7 +355,14 @@
+
+
+ # Checking for libgpg-error.
+-AM_PATH_GPG_ERROR(1.17,, AC_MSG_ERROR([libgpg-error was not found]))
++if test "${GPG_ERROR_CFLAGS+set}" != "set"; then
++ AM_PATH_GPG_ERROR(1.17,, AC_MSG_ERROR([libgpg-error was not found]))
++else
++ GPG_ERROR_CFLAGS="$GPG_ERROR_CFLAGS"
++ GPG_ERROR_LIBS="$GPG_ERROR_LIBS"
++ AC_SUBST(GPG_ERROR_CFLAGS)
++ AC_SUBST(GPG_ERROR_LIBS)
++fi
+
+ #
+ # Checks for library functions.
diff --git a/external/libassuan/fix-autoconf-macros.patch b/external/libassuan/fix-autoconf-macros.patch
new file mode 100644
index 000000000..743ca460b
--- /dev/null
+++ b/external/libassuan/fix-autoconf-macros.patch
@@ -0,0 +1,27 @@
+diff -ur libassuan.org/configure.ac libassuan/configure.ac
+--- configure.ac 2017-02-16 18:32:51.549527554 +0100
++++ configure.ac~ 2017-02-16 18:32:59.893497890 +0100
+@@ -75,7 +80,22 @@
+ AC_SUBST(LIBASSUAN_LT_REVISION)
+
+ AC_CONFIG_AUX_DIR([build-aux])
+-AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip])
++
++dnl Initialize automake. automake < 1.12 didn't have serial-tests and
++dnl gives an error if it sees this, but for automake >= 1.13
++dnl serial-tests is required so we have to include it. Solution is to
++dnl test for the version of automake (by running an external command)
++dnl and provide it if necessary. Note we have to do this entirely using
++dnl m4 macros since automake queries this macro by running
++dnl 'autoconf --trace ...'.
++m4_define([serial_tests], [
++ m4_esyscmd([automake --version |
++ head -1 |
++ awk '{split ($NF,a,"."); if (a[1] == 1 && a[2] >= 12) { print "serial-tests" }}'
++ ])
++])
++AM_INIT_AUTOMAKE(foreign serial_tests dist-bzip2 no-dist-gzip) dnl NB: Do not [quote] this parameter.
++
+ AM_MAINTAINER_MODE
+ AC_CONFIG_SRCDIR(src/assuan.h.in)
+ AC_CONFIG_MACRO_DIR(m4)
diff --git a/external/libassuan/rpath.patch b/external/libassuan/rpath.patch
new file mode 100644
index 000000000..73c10e342
--- /dev/null
+++ b/external/libassuan/rpath.patch
@@ -0,0 +1,11 @@
+--- configure.ac
++++ configure.ac
+@@ -127,6 +127,8 @@
+ LT_INIT([win32-dll disable-static])
+ LT_LANG([Windows Resource])
+
++hardcode_libdir_flag_spec=
++
+ # For now we hardcode the use of version scripts. It would be better
+ # to write a test for this or even implement this within libtool.
+ have_ld_version_script=no
diff --git a/external/libassuan/w32-build-fixes-2.patch b/external/libassuan/w32-build-fixes-2.patch
new file mode 100644
index 000000000..918405d15
--- /dev/null
+++ b/external/libassuan/w32-build-fixes-2.patch
@@ -0,0 +1,12 @@
+Avoid MFC dependency - can go with very basic includes instead
+
+--- src/versioninfo.rc.in~ 2015-10-16 15:40:36.000000000 +0200
++++ src/versioninfo.rc.in 2017-11-29 04:19:57.870117200 +0100
+@@ -14,7 +14,6 @@
+
+ #line __LINE__ "versioninfo.rc.in"
+
+-#include <afxres.h>
+
+
+ VS_VERSION_INFO VERSIONINFO
diff --git a/external/libassuan/w32-build-fixes.patch.1 b/external/libassuan/w32-build-fixes.patch.1
new file mode 100644
index 000000000..ebf98c5f5
--- /dev/null
+++ b/external/libassuan/w32-build-fixes.patch.1
@@ -0,0 +1,73 @@
+--- libassuan.orig/src/mkheader.c 2013-03-15 20:26:09.000000000 +0100
++++ libassuan/src/mkheader.c 2017-09-24 14:17:33.584583300 +0200
+@@ -99,7 +99,7 @@
+ "# include <unistd.h>\n"
+ "#endif\n", stdout);
+ else
+- fputs ("#include <unistd.h>\n", stdout);
++ fputs ("#include <io.h>\n", stdout);
+ }
+ else if (!strcmp (tag, "include:types"))
+ {
+diff -ru libassuan.orig/src/Makefile.in libassuan/src/Makefile.in
+--- libassuan.orig/src/Makefile.in 2020-06-10 17:26:08.699728800 +0200
++++ libassuan/src/Makefile.in 2020-06-10 17:22:11.066865300 +0200
+@@ -462,7 +462,7 @@
+ assuan-pipe-connect.c assuan-socket-connect.c assuan-uds.c \
+ assuan-logging.c assuan-socket.c $(am__append_2) \
+ $(am__append_3) $(am__append_4)
++@HAVE_W32_SYSTEM_TRUE@LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RC) \
+-@HAVE_W32_SYSTEM_TRUE@LTRCCOMPILE = $(LIBTOOL) --mode=compile $(RC) \
+ @HAVE_W32_SYSTEM_TRUE@ `echo $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) | \
+ @HAVE_W32_SYSTEM_TRUE@ sed -e 's/-I/--include-dir /g;s/-D/--define /g'`
+
+diff -ru libassuan.orig/src/Makefile.am libassuan/src/Makefile.am
+--- libassuan.orig/src/Makefile.am 2017-09-24 14:20:05.906065400 +0200
++++ libassuan/src/Makefile.am 2017-09-24 14:40:59.038850200 +0200
+@@ -87,7 +87,7 @@
+
+ if HAVE_W32_SYSTEM
+
++LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RC) \
+-LTRCCOMPILE = $(LIBTOOL) --mode=compile $(RC) \
+ `echo $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) | \
+ sed -e 's/-I/--include-dir /g;s/-D/--define /g'`
+
+@@ -148,10 +148,10 @@
+ $(DESTDIR)$(bindir)/gpgcedev.dll
+ endif
+
++mkheader$(EXEEXT): mkheader.c Makefile
+-mkheader: mkheader.c Makefile
+ $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) \
+ $(LDFLAGS_FOR_BUILD) -I. -I$(srcdir) -o $@ $(srcdir)/mkheader.c
+
++assuan.h: assuan.h.in mkheader$(EXEEXT) $(parts_of_assuan_h)
++ ./mkheader$(EXEEXT) $(host_os) $(srcdir)/assuan.h.in \
+-assuan.h: assuan.h.in mkheader $(parts_of_assuan_h)
+- ./mkheader $(host_os) $(srcdir)/assuan.h.in \
+ $(PACKAGE_VERSION) $(VERSION_NUMBER) >$@
+diff -ru libassuan.orig/src/assuan-handler.c libassuan/src/assuan-handler.c
+--- libassuan.orig/src/assuan-handler.c 2016-06-25 16:27:49.000000000 +0200
++++ libassuan/src/assuan-handler.c 2017-09-24 15:32:51.200956200 +0200
+@@ -395,7 +395,7 @@
+
+ { "INPUT", std_handler_input, std_help_input, 0 },
+ { "OUTPUT", std_handler_output, std_help_output, 0 },
+- { } };
++};
+
+
+ /**
+diff -ru libassuan.orig/Makefile.am libassuan/Makefile.am
+--- libassuan.orig/Makefile.am 2016-07-14 10:09:22.000000000 +0200
++++ libassuan/Makefile.am 2017-09-25 21:20:19.928317500 +0200
+@@ -35,7 +35,7 @@
+ doc =
+ endif
+
+-SUBDIRS = m4 src $(doc) tests
++SUBDIRS = m4 src $(doc)
+
+
+ dist-hook: gen-ChangeLog
diff --git a/external/libassuan/w32-stdc.patch b/external/libassuan/w32-stdc.patch
new file mode 100644
index 000000000..def3dea83
--- /dev/null
+++ b/external/libassuan/w32-stdc.patch
@@ -0,0 +1,74 @@
+--- src/assuan-handler.c
++++ src/assuan-handler.c
+@@ -938,7 +938,7 @@
+ #if defined(HAVE_W32CE_SYSTEM)
+ fdarray[n++] = (void*)fileno (ctx->outbound.data.fp);
+ #elif defined(HAVE_W32_SYSTEM)
+- fdarray[n++] = (void*)_get_osfhandle (fileno (ctx->outbound.data.fp));
++ fdarray[n++] = (void*)_get_osfhandle (_fileno (ctx->outbound.data.fp));
+ #else
+ fdarray[n++] = fileno (ctx->outbound.data.fp);
+ #endif
+--- src/assuan-logging.c
++++ src/assuan-logging.c
+@@ -30,10 +30,15 @@
+ # ifdef HAVE_WINSOCK2_H
+ # include <winsock2.h>
+ # endif
++# include <process.h>
++# define getpid _getpid
+ # include <windows.h>
+ #endif /*HAVE_W32_SYSTEM*/
+ #include <errno.h>
+ #include <ctype.h>
++#if defined HAVE_W32_SYSTEM
++#define isascii __isascii
++#endif
+
+ #include "assuan-defs.h"
+
+--- src/assuan-pipe-connect.c
++++ src/assuan-pipe-connect.c
+@@ -47,6 +47,8 @@
+ # ifdef HAVE_WINSOCK2_H
+ # include <winsock2.h>
+ # endif
++# include <process.h>
++# define getpid _getpid
+ # include <windows.h>
+ #endif
+
+--- src/assuan-socket.c
++++ src/assuan-socket.c
+@@ -27,6 +27,8 @@
+ #include <stdlib.h>
+ #ifdef HAVE_W32_SYSTEM
+ # define WIN32_LEAN_AND_MEAN
++# include <process.h>
++# define getpid _getpid
+ # include <windows.h>
+ # include <wincrypt.h>
+ #ifndef HAVE_W32CE_SYSTEM
+--- src/conversion.c
++++ src/conversion.c
+@@ -27,6 +27,9 @@
+ #include <string.h>
+ #include <errno.h>
+ #include <ctype.h>
++#if defined HAVE_W32_SYSTEM
++#define isascii __isascii
++#endif
+
+ #include "assuan-defs.h"
+ #include "debug.h"
+--- src/system-w32.c
++++ src/system-w32.c
+@@ -453,7 +453,7 @@
+
+ /* Dup stderr to /dev/null unless it is in the list of FDs to be
+ passed to the child. */
+- fd = assuan_fd_from_posix_fd (fileno (stderr));
++ fd = assuan_fd_from_posix_fd (_fileno (stderr));
+ fdp = fd_child_list;
+ if (fdp)
+ {
diff --git a/external/libatomic_ops/ExternalProject_libatomic_ops.mk b/external/libatomic_ops/ExternalProject_libatomic_ops.mk
new file mode 100644
index 000000000..143eed2c0
--- /dev/null
+++ b/external/libatomic_ops/ExternalProject_libatomic_ops.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libatomic_ops))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libatomic_ops,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libatomic_ops,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,libatomic_ops,build) :
+ $(call gb_Trace_StartRange,libatomic_ops,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(if $(filter TRUE, \
+ $(DISABLE_DYNLOADING)) \
+ , \
+ CFLAGS="$(CFLAGS) $(gb_VISIBILITY_FLAGS) $(call gb_ExternalProject_get_build_flags,libatomic_ops)" \
+ CXXFLAGS="$(CXXFLAGS) $(gb_VISIBILITY_FLAGS) $(gb_VISIBILITY_FLAGS_CXX) $(call gb_ExternalProject_get_build_flags,libatomic_ops)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libatomic_ops)") \
+ $(gb_RUN_CONFIGURE) ./configure \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libatomic_ops,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libatomic_ops/Makefile b/external/libatomic_ops/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libatomic_ops/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libatomic_ops/Module_libatomic_ops.mk b/external/libatomic_ops/Module_libatomic_ops.mk
new file mode 100644
index 000000000..7dca6703c
--- /dev/null
+++ b/external/libatomic_ops/Module_libatomic_ops.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libatomic_ops))
+
+$(eval $(call gb_Module_add_targets,libatomic_ops,\
+ ExternalProject_libatomic_ops \
+ UnpackedTarball_libatomic_ops \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libatomic_ops/README b/external/libatomic_ops/README
new file mode 100644
index 000000000..3dcb7ef7a
--- /dev/null
+++ b/external/libatomic_ops/README
@@ -0,0 +1,4 @@
+From [https://github.com/ivmai/libatomic_ops/].
+
+Note that some files (linked into libatomic_ops_gpl) are GPL'd, the portion
+needed for Firebird (libatomic_ops) is however MIT licensed.
diff --git a/external/libatomic_ops/UnpackedTarball_libatomic_ops.mk b/external/libatomic_ops/UnpackedTarball_libatomic_ops.mk
new file mode 100644
index 000000000..652b8381a
--- /dev/null
+++ b/external/libatomic_ops/UnpackedTarball_libatomic_ops.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libatomic_ops))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libatomic_ops,$(LIBATOMIC_OPS_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libatomic_ops))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libcdr/ExternalProject_libcdr.mk b/external/libcdr/ExternalProject_libcdr.mk
new file mode 100644
index 000000000..c9f5401ac
--- /dev/null
+++ b/external/libcdr/ExternalProject_libcdr.mk
@@ -0,0 +1,49 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libcdr))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libcdr,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libcdr,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libcdr,\
+ boost_headers \
+ icu \
+ lcms2 \
+ revenge \
+ zlib \
+))
+
+$(call gb_ExternalProject_get_state_target,libcdr,build) :
+ $(call gb_Trace_StartRange,libcdr,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ --disable-tools \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-werror \
+ --disable-weffc \
+ $(if $(gb_FULLDEPS),,--disable-dependency-tracking) \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libcdr)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libcdr)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libcdr,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libcdr/Makefile b/external/libcdr/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libcdr/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libcdr/Module_libcdr.mk b/external/libcdr/Module_libcdr.mk
new file mode 100644
index 000000000..5f8acd374
--- /dev/null
+++ b/external/libcdr/Module_libcdr.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libcdr))
+
+$(eval $(call gb_Module_add_targets,libcdr,\
+ ExternalProject_libcdr \
+ UnpackedTarball_libcdr \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libcdr/README b/external/libcdr/README
new file mode 100644
index 000000000..4337b722b
--- /dev/null
+++ b/external/libcdr/README
@@ -0,0 +1,3 @@
+Library parsing the Corel cdr documents.
+
+[https://wiki.documentfoundation.org/DLP/Libraries/libcdr]
diff --git a/external/libcdr/UnpackedTarball_libcdr.mk b/external/libcdr/UnpackedTarball_libcdr.mk
new file mode 100644
index 000000000..f0e80f06f
--- /dev/null
+++ b/external/libcdr/UnpackedTarball_libcdr.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libcdr))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libcdr,$(CDR_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libcdr,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libcdr))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libcdr, \
+ external/libcdr/libcdr-visibility-win.patch \
+ external/libcdr/ax_gcc_func_attribute.m4.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libcdr/ax_gcc_func_attribute.m4.patch b/external/libcdr/ax_gcc_func_attribute.m4.patch
new file mode 100644
index 000000000..37f4edf0b
--- /dev/null
+++ b/external/libcdr/ax_gcc_func_attribute.m4.patch
@@ -0,0 +1,11 @@
+--- configure
++++ configure
+@@ -19167,7 +19167,7 @@
+
+ _ACEOF
+ if ac_fn_cxx_try_link "$LINENO"; then :
+- if test -s conftest.err; then :
++ if grep -- -Wattributes conftest.err; then :
+ ax_cv_have_func_attribute_visibility=no
+ else
+ ax_cv_have_func_attribute_visibility=yes
diff --git a/external/libcdr/libcdr-visibility-win.patch b/external/libcdr/libcdr-visibility-win.patch
new file mode 100644
index 000000000..7700cfd32
--- /dev/null
+++ b/external/libcdr/libcdr-visibility-win.patch
@@ -0,0 +1,11 @@
+--- configure.dt 2018-12-29 16:23:02.355271146 +0100
++++ configure 2018-12-29 16:23:21.644060142 +0100
+@@ -19116,6 +19116,8 @@
+
+
+ if test $platform_win32 = yes; then :
++ HAVE_VISIBILITY_TRUE='#'
++ HAVE_VISIBILITY_FALSE=
+
+ else
+
diff --git a/external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch b/external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch
new file mode 100644
index 000000000..f82c82f81
--- /dev/null
+++ b/external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch
@@ -0,0 +1,69 @@
+From 219e6d6586c8280dfd9c4851cee0d14d68b6ad65 Mon Sep 17 00:00:00 2001
+From: David Tardon <dtardon@redhat.com>
+Date: Fri, 28 Dec 2018 15:26:28 +0100
+Subject: [PATCH] rename class GetObject to avoid name clash on Windows
+
+---
+ src/libcmis/ws-objectservice.cxx | 2 +-
+ src/libcmis/ws-requests.cxx | 2 +-
+ src/libcmis/ws-requests.hxx | 7 +++----
+ 3 files changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/src/libcmis/ws-objectservice.cxx b/src/libcmis/ws-objectservice.cxx
+index 9e40085..d57f3cc 100644
+--- a/src/libcmis/ws-objectservice.cxx
++++ b/src/libcmis/ws-objectservice.cxx
+@@ -71,7 +71,7 @@ libcmis::ObjectPtr ObjectService::getObject( string repoId, string id )
+ {
+ libcmis::ObjectPtr object;
+
+- class GetObject request( repoId, id );
++ GetObjectRequest request( repoId, id );
+ vector< SoapResponsePtr > responses = m_session->soapRequest( m_url, request );
+ if ( responses.size( ) == 1 )
+ {
+diff --git a/src/libcmis/ws-requests.cxx b/src/libcmis/ws-requests.cxx
+index f8bc245..408d053 100644
+--- a/src/libcmis/ws-requests.cxx
++++ b/src/libcmis/ws-requests.cxx
+@@ -269,7 +269,7 @@ SoapResponsePtr GetTypeChildrenResponse::create( xmlNodePtr node, RelatedMultipa
+ return SoapResponsePtr( response );
+ }
+
+-void GetObject::toXml( xmlTextWriterPtr writer )
++void GetObjectRequest::toXml( xmlTextWriterPtr writer )
+ {
+ xmlTextWriterStartElement( writer, BAD_CAST( "cmism:getObject" ) );
+ xmlTextWriterWriteAttribute( writer, BAD_CAST( "xmlns:cmis" ), BAD_CAST( NS_CMIS_URL ) );
+diff --git a/src/libcmis/ws-requests.hxx b/src/libcmis/ws-requests.hxx
+index 2c4ae92..534d9a4 100644
+--- a/src/libcmis/ws-requests.hxx
++++ b/src/libcmis/ws-requests.hxx
+@@ -203,21 +203,20 @@ class GetTypeChildrenResponse : public SoapResponse
+ std::vector< libcmis::ObjectTypePtr > getChildren( ) { return m_children; }
+ };
+
+-#undef GetObject
+-class GetObject : public SoapRequest
++class GetObjectRequest : public SoapRequest
+ {
+ private:
+ std::string m_repositoryId;
+ std::string m_id;
+
+ public:
+- GetObject( std::string repoId, std::string id ) :
++ GetObjectRequest( std::string repoId, std::string id ) :
+ m_repositoryId( repoId ),
+ m_id( id )
+ {
+ }
+
+- ~GetObject( ) { }
++ ~GetObjectRequest( ) { }
+
+ void toXml( xmlTextWriterPtr writer );
+ };
+--
+2.19.2
+
diff --git a/external/libcmis/Makefile b/external/libcmis/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libcmis/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libcmis/Module_libcmis.mk b/external/libcmis/Module_libcmis.mk
new file mode 100644
index 000000000..78ab61c51
--- /dev/null
+++ b/external/libcmis/Module_libcmis.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libcmis))
+
+$(eval $(call gb_Module_add_targets,libcmis,\
+ StaticLibrary_libcmis \
+ UnpackedTarball_libcmis \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libcmis/README b/external/libcmis/README
new file mode 100644
index 000000000..8065e7c76
--- /dev/null
+++ b/external/libcmis/README
@@ -0,0 +1,8 @@
+A C++ client library for the CMIS interface.
+
+From:
+[https://github.com/tdf/libcmis]
+
+Wikipedia (CMIS):
+Content Management Interoperability Services (CMIS) is an open standard that defines an
+abstraction layer for controlling diverse document management systems and repositories using web protocols.
diff --git a/external/libcmis/StaticLibrary_libcmis.mk b/external/libcmis/StaticLibrary_libcmis.mk
new file mode 100644
index 000000000..ebcd16607
--- /dev/null
+++ b/external/libcmis/StaticLibrary_libcmis.mk
@@ -0,0 +1,104 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,libcmis))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,libcmis))
+
+$(eval $(call gb_StaticLibrary_set_precompiled_header,libcmis,external/libcmis/inc/pch/precompiled_libcmis))
+
+ifeq ($(COM_IS_CLANG),TRUE)
+# Avoid narrowing conversion error (even though the option is technically a warning)
+# caused by boost
+$(eval $(call gb_StaticLibrary_add_cxxflags,libcmis,\
+ -Wno-error=c++11-narrowing \
+))
+endif
+
+$(eval $(call gb_StaticLibrary_add_defs,libcmis, \
+ -DBOOST_ALL_NO_LIB \
+))
+
+$(eval $(call gb_StaticLibrary_set_include,libcmis, \
+ -I$(call gb_UnpackedTarball_get_dir,libcmis/inc) \
+ -I$(call gb_UnpackedTarball_get_dir,libcmis/src/libcmis) \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,libcmis,libcmis))
+
+$(eval $(call gb_StaticLibrary_use_externals,libcmis,\
+ boost_headers \
+ curl \
+ libxml2 \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,libcmis,\
+ UnpackedTarball/libcmis/src/libcmis/allowable-actions \
+ UnpackedTarball/libcmis/src/libcmis/atom-document \
+ UnpackedTarball/libcmis/src/libcmis/atom-folder \
+ UnpackedTarball/libcmis/src/libcmis/atom-object-type \
+ UnpackedTarball/libcmis/src/libcmis/atom-object \
+ UnpackedTarball/libcmis/src/libcmis/atom-session \
+ UnpackedTarball/libcmis/src/libcmis/atom-workspace \
+ UnpackedTarball/libcmis/src/libcmis/base-session \
+ UnpackedTarball/libcmis/src/libcmis/document \
+ UnpackedTarball/libcmis/src/libcmis/folder \
+ UnpackedTarball/libcmis/src/libcmis/gdrive-document \
+ UnpackedTarball/libcmis/src/libcmis/gdrive-folder \
+ UnpackedTarball/libcmis/src/libcmis/gdrive-object \
+ UnpackedTarball/libcmis/src/libcmis/gdrive-object-type \
+ UnpackedTarball/libcmis/src/libcmis/gdrive-property \
+ UnpackedTarball/libcmis/src/libcmis/gdrive-repository \
+ UnpackedTarball/libcmis/src/libcmis/gdrive-session \
+ UnpackedTarball/libcmis/src/libcmis/gdrive-utils \
+ UnpackedTarball/libcmis/src/libcmis/http-session \
+ UnpackedTarball/libcmis/src/libcmis/json-utils \
+ UnpackedTarball/libcmis/src/libcmis/oauth2-data \
+ UnpackedTarball/libcmis/src/libcmis/oauth2-handler \
+ UnpackedTarball/libcmis/src/libcmis/oauth2-providers \
+ UnpackedTarball/libcmis/src/libcmis/object \
+ UnpackedTarball/libcmis/src/libcmis/object-type \
+ UnpackedTarball/libcmis/src/libcmis/onedrive-document \
+ UnpackedTarball/libcmis/src/libcmis/onedrive-folder \
+ UnpackedTarball/libcmis/src/libcmis/onedrive-object \
+ UnpackedTarball/libcmis/src/libcmis/onedrive-object-type \
+ UnpackedTarball/libcmis/src/libcmis/onedrive-property \
+ UnpackedTarball/libcmis/src/libcmis/onedrive-repository \
+ UnpackedTarball/libcmis/src/libcmis/onedrive-session \
+ UnpackedTarball/libcmis/src/libcmis/onedrive-utils \
+ UnpackedTarball/libcmis/src/libcmis/property \
+ UnpackedTarball/libcmis/src/libcmis/property-type \
+ UnpackedTarball/libcmis/src/libcmis/rendition \
+ UnpackedTarball/libcmis/src/libcmis/repository \
+ UnpackedTarball/libcmis/src/libcmis/session-factory \
+ UnpackedTarball/libcmis/src/libcmis/sharepoint-document \
+ UnpackedTarball/libcmis/src/libcmis/sharepoint-folder \
+ UnpackedTarball/libcmis/src/libcmis/sharepoint-object \
+ UnpackedTarball/libcmis/src/libcmis/sharepoint-object-type \
+ UnpackedTarball/libcmis/src/libcmis/sharepoint-property \
+ UnpackedTarball/libcmis/src/libcmis/sharepoint-repository \
+ UnpackedTarball/libcmis/src/libcmis/sharepoint-session \
+ UnpackedTarball/libcmis/src/libcmis/sharepoint-utils \
+ UnpackedTarball/libcmis/src/libcmis/ws-document \
+ UnpackedTarball/libcmis/src/libcmis/ws-folder \
+ UnpackedTarball/libcmis/src/libcmis/ws-navigationservice \
+ UnpackedTarball/libcmis/src/libcmis/ws-object \
+ UnpackedTarball/libcmis/src/libcmis/ws-object-type \
+ UnpackedTarball/libcmis/src/libcmis/ws-objectservice \
+ UnpackedTarball/libcmis/src/libcmis/ws-relatedmultipart \
+ UnpackedTarball/libcmis/src/libcmis/ws-repositoryservice \
+ UnpackedTarball/libcmis/src/libcmis/ws-requests \
+ UnpackedTarball/libcmis/src/libcmis/ws-session \
+ UnpackedTarball/libcmis/src/libcmis/ws-soap \
+ UnpackedTarball/libcmis/src/libcmis/ws-versioningservice \
+ UnpackedTarball/libcmis/src/libcmis/xml-utils \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libcmis/UnpackedTarball_libcmis.mk b/external/libcmis/UnpackedTarball_libcmis.mk
new file mode 100644
index 000000000..f48201d31
--- /dev/null
+++ b/external/libcmis/UnpackedTarball_libcmis.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libcmis))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libcmis,$(LIBCMIS_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libcmis,1))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libcmis, \
+ external/libcmis/libcmis-libxml2_compatibility.patch \
+ external/libcmis/0001-rename-class-GetObject-to-avoid-name-clash-on-Window.patch \
+ external/libcmis/libcmis_onedrive.patch \
+ external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1 \
+ external/libcmis/libcmis_gdrive.patch.1 \
+ external/libcmis/libcmis-boost-string.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libcmis/inc/pch/precompiled_libcmis.cxx b/external/libcmis/inc/pch/precompiled_libcmis.cxx
new file mode 100644
index 000000000..13668b837
--- /dev/null
+++ b/external/libcmis/inc/pch/precompiled_libcmis.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_libcmis.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libcmis/inc/pch/precompiled_libcmis.hxx b/external/libcmis/inc/pch/precompiled_libcmis.hxx
new file mode 100644
index 000000000..a8a4b979f
--- /dev/null
+++ b/external/libcmis/inc/pch/precompiled_libcmis.hxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2019-05-18 14:55:22 using:
+ ./bin/update_pch external/libcmis libcmis --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/libcmis/inc/pch/precompiled_libcmis.hxx "make external/libcmis.build" --find-conflicts
+*/
+
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <cctype>
+#include <errno.h>
+#include <locale>
+#include <memory>
+#include <sstream>
+#include <stdlib.h>
+#include <string>
+#include <boost/algorithm/string.hpp>
+#include <boost/date_time.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include <boost/version.hpp>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <curl/curl.h>
+#include <libcmis/allowable-actions.hxx>
+#include <libcmis/document.hxx>
+#include <libcmis/exception.hxx>
+#include <libcmis/folder.hxx>
+#include <libcmis/oauth2-data.hxx>
+#include <libcmis/object-type.hxx>
+#include <libcmis/object.hxx>
+#include <libcmis/property-type.hxx>
+#include <libcmis/property.hxx>
+#include <libcmis/rendition.hxx>
+#include <libcmis/repository.hxx>
+#include <libcmis/session-factory.hxx>
+#include <libcmis/session.hxx>
+#include <libcmis/xml-utils.hxx>
+#include <libxml/HTMLparser.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlreader.h>
+#include <libxml/xmlstring.h>
+#include <libxml/xpath.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libcmis/libcmis-boost-string.patch b/external/libcmis/libcmis-boost-string.patch
new file mode 100644
index 000000000..247d38a19
--- /dev/null
+++ b/external/libcmis/libcmis-boost-string.patch
@@ -0,0 +1,11 @@
+--- a/src/libcmis/oauth2-handler.cxx
++++ b/src/libcmis/oauth2-handler.cxx
+@@ -26,6 +26,8 @@
+ * instead of those above.
+ */
+
++#include <boost/algorithm/string.hpp>
++
+ #include "oauth2-handler.hxx"
+
+ #include <libcmis/session-factory.hxx>
diff --git a/external/libcmis/libcmis-libxml2_compatibility.patch b/external/libcmis/libcmis-libxml2_compatibility.patch
new file mode 100644
index 000000000..240b85b4d
--- /dev/null
+++ b/external/libcmis/libcmis-libxml2_compatibility.patch
@@ -0,0 +1,14 @@
+# -*- Mode: Diff -*-
+--- a/src/libcmis/oauth2-providers.cxx
++++ b/src/libcmis/oauth2-providers.cxx
+@@ -34,6 +34,10 @@
+
+ using namespace std;
+
++#if LIBXML_VERSION < 20621
++#define HTML_PARSE_RECOVER 0
++#endif
++
+ namespace {
+
+ // Encodes the given data according to the application/x-www-form-urlencoded format, see
diff --git a/external/libcmis/libcmis_gdrive.patch.1 b/external/libcmis/libcmis_gdrive.patch.1
new file mode 100644
index 000000000..24ff65d1e
--- /dev/null
+++ b/external/libcmis/libcmis_gdrive.patch.1
@@ -0,0 +1,702 @@
+diff -ur libcmis.org/src/libcmis/gdrive-document.cxx libcmis/src/libcmis/gdrive-document.cxx
+--- libcmis.org/src/libcmis/gdrive-document.cxx 2021-07-27 19:11:02.679247008 +0200
++++ libcmis/src/libcmis/gdrive-document.cxx 2021-07-27 19:11:18.873246420 +0200
+@@ -145,23 +145,17 @@
+ {
+ if ( !os.get( ) )
+ throw libcmis::Exception( "Missing stream" );
+- if ( !isImmutable( ) )
+- throw libcmis::Exception( string ( "Document " + getId( )+
+- " is not editable" ) );
+- string putUrl = getUploadUrl( ) + getId( );
+- putUrl += "?uploadType=media";
+-
+- // If it's a Google document, convert it
+- if ( isGoogleDoc( ) )
+- putUrl += "&convert=true";
++
++ string putUrl = GDRIVE_UPLOAD_LINK + getId( ) + "?uploadType=media";
+
+ // Upload stream
+ boost::shared_ptr< istream> is ( new istream ( os->rdbuf( ) ) );
+ vector <string> headers;
+ headers.push_back( string( "Content-Type: " ) + contentType );
++ string res;
+ try
+ {
+- getSession()->httpPutRequest( putUrl, *is, headers );
++ res = getSession()->httpPatchRequest( putUrl, *is, headers )->getStream()->str();
+ }
+ catch ( const CurlException& e )
+ {
+@@ -181,35 +175,10 @@
+ {
+ if ( !os.get( ) )
+ throw libcmis::Exception( "Missing stream" );
+-
+- if ( !isImmutable( ) )
+- throw libcmis::Exception( string ( "Document " + getId( )+
+- " is not editable" ) );
+- string metaUrl = getUrl( );
+-
+- // If it's a Google document, convert it
+- if ( isGoogleDoc( ) )
+- metaUrl += "?convert=true";
+-
+- // Update file name meta information
+- if ( !fileName.empty( ) && fileName != getContentFilename( ) )
+- {
+- Json metaJson;
+- Json fileJson( fileName.c_str( ) );
+- metaJson.add("title", fileJson );
+-
+- std::istringstream is( metaJson.toString( ) );
+- vector<string> headers;
+- headers.push_back( "Content-Type: application/json" );
+- try
+- {
+- getSession()->httpPutRequest( metaUrl, is, headers );
+- }
+- catch ( const CurlException& e )
+- {
+- throw e.getCmisException( );
+- }
+- }
++
++ // TODO: when would the filename need an update?
++ if (!fileName.empty() && fileName != getContentFilename())
++ std::cout << "filename change is not implemented in setContentStream" << std::endl;
+
+ // Upload stream
+ uploadStream( os, contentType );
+@@ -251,7 +220,7 @@
+ vector< libcmis::DocumentPtr > GDriveDocument::getAllVersions( )
+ {
+ vector< libcmis::DocumentPtr > revisions;
+- string versionUrl = getUrl( ) + "/revisions";
++ string versionUrl = GDRIVE_METADATA_LINK + getId( ) + "/revisions";
+ // Run the http request to get the properties definition
+ string res;
+ try
+@@ -263,7 +232,7 @@
+ throw e.getCmisException( );
+ }
+ Json jsonRes = Json::parse( res );
+- Json::JsonVector objs = jsonRes["items"].getList( );
++ Json::JsonVector objs = jsonRes["revisions"].getList( );
+
+ string parentId = getStringProperty( "cmis:parentId" );
+
+diff -ur libcmis.org/src/libcmis/gdrive-folder.cxx libcmis/src/libcmis/gdrive-folder.cxx
+--- libcmis.org/src/libcmis/gdrive-folder.cxx 2021-07-27 19:11:02.678247008 +0200
++++ libcmis/src/libcmis/gdrive-folder.cxx 2021-07-27 19:11:18.874246420 +0200
+@@ -62,8 +62,8 @@
+ // Instead of sending multiple queries for children,
+ // we send a single query to search for objects where parents
+ // include the folderID.
+- string query = getSession( )->getBindingUrl( ) +
+- "/files?q=\"" + getId( ) + "\"+in+parents+and+trashed+=+false";
++ string query = GDRIVE_METADATA_LINK + "?q=\"" + getId( ) + "\"+in+parents+and+trashed+=+false" +
++ "&fields=files(kind,id,name,parents,mimeType,createdTime,modifiedTime,thumbnailLink,size)";
+
+ string res;
+ try
+@@ -76,7 +76,7 @@
+ }
+
+ Json jsonRes = Json::parse( res );
+- Json::JsonVector objs = jsonRes["items"].getList( );
++ Json::JsonVector objs = jsonRes["files"].getList( );
+
+ // Create children objects from Json objects
+ for(unsigned int i = 0; i < objs.size(); i++)
+@@ -95,7 +95,7 @@
+ string GDriveFolder::uploadProperties( Json properties )
+ {
+ // URL for uploading meta data
+- string metaUrl = getSession()->getBindingUrl() + "/files/";
++ string metaUrl = GDRIVE_METADATA_LINK + "?fields=kind,id,name,parents,mimeType,createdTime,modifiedTime";
+
+ // add parents to the properties
+ properties.add( "parents", GdriveUtils::createJsonFromParentId( getId( ) ) );
+@@ -147,9 +147,15 @@
+
+ Json propsJson = GdriveUtils::toGdriveJson( properties );
+
+- // Add filename to properties
+- Json jsonFilename( fileName.c_str( ) );
+- propsJson.add( "title", jsonFilename );
++ if(!fileName.empty()) {
++ // use provided filename
++ Json jsonFilename( fileName.c_str( ) );
++
++ propsJson.add( "name", jsonFilename );
++ }
++ if(!contentType.empty()) {
++ propsJson.add( "mimeType", Json(contentType.c_str()));
++ }
+
+ // Upload meta-datas
+ string res = uploadProperties( propsJson);
+@@ -171,12 +177,9 @@
+ libcmis::UnfileObjects::Type /*unfile*/,
+ bool /*continueOnError*/ )
+ {
+- // Object remove doesn't work with folder
+- // Using trash instead
+ try
+ {
+- istringstream is( "" );
+- getSession( )->httpPostRequest( getUrl( ) + "/trash", is, "" );
++ getSession( )->httpDeleteRequest( GDRIVE_METADATA_LINK + getId( ) );
+ }
+ catch ( const CurlException& e )
+ {
+diff -ur libcmis.org/src/libcmis/gdrive-object.cxx libcmis/src/libcmis/gdrive-object.cxx
+--- libcmis.org/src/libcmis/gdrive-object.cxx 2021-07-27 19:11:02.675247009 +0200
++++ libcmis/src/libcmis/gdrive-object.cxx 2021-07-27 19:11:18.874246420 +0200
+@@ -89,8 +89,8 @@
+ property.reset( new GDriveProperty( it->first, it->second ) );
+ m_properties[ property->getPropertyType( )->getId()] = property;
+
+- // we map "title" to both "cmis:name" and "cmis:getContentStreamFileName"
+- if ( it->first == "title" )
++ // we map "name" to both "cmis:name" and "cmis:getContentStreamFileName"
++ if ( it->first == "name" )
+ {
+ property.reset( new GDriveProperty( "cmis:name", it->second) );
+ m_properties[ property->getPropertyType( )->getId()] = property;
+@@ -142,16 +142,13 @@
+ {
+ if ( m_renditions.empty( ) )
+ {
+- string downloadUrl = getStringProperty( "downloadUrl" );
+- if ( !downloadUrl.empty( ) )
+- {
+- string mimeType = getStringProperty( "cmis:contentStreamMimeType" );
+- if ( !mimeType.empty( ) )
+- {
+- RenditionPtr rendition(
+- new Rendition( mimeType, mimeType, mimeType, downloadUrl ));
+- m_renditions.push_back( rendition );
+- }
++ string downloadUrl = GDRIVE_METADATA_LINK + getId( ) + "?alt=media";
++ string mimeType = getStringProperty( "cmis:contentStreamMimeType" );
++ if ( !mimeType.empty( ) )
++ {
++ RenditionPtr rendition(
++ new Rendition( mimeType, mimeType, mimeType, downloadUrl ));
++ m_renditions.push_back( rendition );
+ }
+
+ vector< string > exportLinks = getMultiStringProperty( "exportLinks" );
+@@ -192,7 +189,7 @@
+ {
+ vector< string > headers;
+ headers.push_back( "Content-Type: application/json" );
+- response = getSession( )->httpPutRequest( getUrl( ), is, headers );
++ response = getSession( )->httpPatchRequest( getUrl( ), is, headers );
+ }
+ catch ( const CurlException& e )
+ {
+@@ -228,7 +225,7 @@
+ {
+ try
+ {
+- getSession( )->httpDeleteRequest( getUrl( ) );
++ getSession( )->httpDeleteRequest( GDRIVE_METADATA_LINK + getId( ) );
+ }
+ catch ( const CurlException& e )
+ {
+@@ -239,8 +236,8 @@
+ void GDriveObject::move( FolderPtr /*source*/, FolderPtr destination )
+ {
+ Json parentsJson;
+- Json parentsValue = GdriveUtils::createJsonFromParentId( destination->getId( ) );
+- parentsJson.add( "parents", parentsValue );
++ parentsJson.add( "addParents", Json(destination->getId( ).c_str()) );
++ parentsJson.add( "removeParents", Json(getStringProperty( "cmis:parentId" ).c_str()) );
+
+ istringstream is( parentsJson.toString( ) );
+ libcmis::HttpResponsePtr response;
+@@ -248,7 +245,7 @@
+ {
+ vector< string > headers;
+ headers.push_back( "Content-Type: application/json" );
+- response = getSession( )->httpPutRequest( getUrl( ), is, headers );
++ response = getSession( )->httpPatchRequest( getUrl( ), is, headers );
+ }
+ catch ( const CurlException& e )
+ {
+@@ -262,12 +259,10 @@
+
+ string GDriveObject::getUrl( )
+ {
+- return getSession( )->getBindingUrl( ) + "/files/" + getId( );
+-}
+-
+-string GDriveObject::getUploadUrl( )
+-{
+- return GDRIVE_UPLOAD_LINKS;
++ // thumbnailLink causes some operations to fail with internal server error,
++ // see https://issuetracker.google.com/issues/36760667
++ return GDRIVE_METADATA_LINK + getId( ) +
++ "?fields=kind,id,name,parents,mimeType,createdTime,modifiedTime,size";
+ }
+
+ vector< string> GDriveObject::getMultiStringProperty( const string& propertyName )
+diff -ur libcmis.org/src/libcmis/gdrive-repository.cxx libcmis/src/libcmis/gdrive-repository.cxx
+--- libcmis.org/src/libcmis/gdrive-repository.cxx 2021-07-27 19:11:02.676247009 +0200
++++ libcmis/src/libcmis/gdrive-repository.cxx 2021-07-27 19:11:18.874246420 +0200
+@@ -35,7 +35,7 @@
+ m_name = "Google Drive";
+ m_description = "Google Drive repository";
+ m_productName = "Google Drive";
+- m_productVersion = "v2";
++ m_productVersion = "v3";
+ m_rootId = "root";
+
+ m_capabilities[ ACL ] = "discover";
+diff -ur libcmis.org/src/libcmis/gdrive-session.cxx libcmis/src/libcmis/gdrive-session.cxx
+--- libcmis.org/src/libcmis/gdrive-session.cxx 2021-07-27 19:11:02.675247009 +0200
++++ libcmis/src/libcmis/gdrive-session.cxx 2021-07-27 19:11:18.874246420 +0200
+@@ -124,9 +124,13 @@
+
+ libcmis::ObjectPtr GDriveSession::getObject( string objectId )
+ {
++ if(objectId == "root") {
++ return getRootFolder();
++ }
+ // Run the http request to get the properties definition
+ string res;
+- string objectLink = m_bindingUrl + "/files/" + objectId;
++ string objectLink = GDRIVE_METADATA_LINK + objectId +
++ "?fields=kind,id,name,parents,mimeType,createdTime,modifiedTime,thumbnailLink,size";
+ try
+ {
+ res = httpGetRequest( objectLink )->getStream()->str();
+@@ -188,9 +192,10 @@
+ {
+ // Normal child case
+ // Ask for the ID of the child if there is any
+- string childIdUrl = m_bindingUrl + "/files/" + objectId +
+- "/children/?q=title+=+'" + segment +
+- "'&fields=items:id";
++ // somewhat flawed as names are not necessarily unique in GDrive...
++ string query = libcmis::escape("'" + objectId + "' in parents and trashed = false and name='" + segment + "'");
++
++ string childIdUrl = m_bindingUrl + "/files/?q=" + query + "&fields=files(id)";
+
+ string res;
+ try
+@@ -204,7 +209,7 @@
+ Json jsonRes = Json::parse( res );
+
+ // Did we get an id?
+- Json::JsonVector items = jsonRes["items"].getList();
++ Json::JsonVector items = jsonRes["files"].getList();
+ if ( items.empty( ) )
+ throw libcmis::Exception( "Object not found: " + path, "objectNotFound" );
+
+@@ -219,6 +224,27 @@
+ return getObject( objectId );
+ }
+
++libcmis::FolderPtr GDriveSession::getRootFolder()
++{
++ // permissions/scope with just drive.file don't allow to get it with the "root" alias/by its actual object-ID
++ Json propsJson;
++
++ // GDrive folder is a file with a different mime type.
++ string mimeType = GDRIVE_FOLDER_MIME_TYPE;
++
++ // Add mimetype to the propsJson
++ Json jsonMimeType( mimeType.c_str( ) );
++ propsJson.add( "mimeType", jsonMimeType );
++ propsJson.add( "id", "root" );
++
++ // Upload meta-datas
++ propsJson.add("cmis:name", "VirtualRoot");
++
++ libcmis::FolderPtr folderPtr( new GDriveFolder( this, propsJson ) );
++
++ return folderPtr;
++}
++
+ libcmis::ObjectTypePtr GDriveSession::getType( string id )
+ {
+ libcmis::ObjectTypePtr type( new GdriveObjectType( id ) );
+diff -ur libcmis.org/src/libcmis/gdrive-session.hxx libcmis/src/libcmis/gdrive-session.hxx
+--- libcmis.org/src/libcmis/gdrive-session.hxx 2021-07-27 19:11:02.675247009 +0200
++++ libcmis/src/libcmis/gdrive-session.hxx 2021-07-27 19:11:18.875246420 +0200
+@@ -57,6 +57,8 @@
+
+ virtual std::vector< libcmis::ObjectTypePtr > getBaseTypes( );
+
++ virtual libcmis::FolderPtr getRootFolder();
++
+ virtual std::string getRefreshToken();
+
+ private:
+diff -ur libcmis.org/src/libcmis/gdrive-utils.cxx libcmis/src/libcmis/gdrive-utils.cxx
+--- libcmis.org/src/libcmis/gdrive-utils.cxx 2021-07-27 19:11:02.677247008 +0200
++++ libcmis/src/libcmis/gdrive-utils.cxx 2021-07-27 19:11:18.875246420 +0200
+@@ -44,17 +44,17 @@
+ convertedKey = "cmis:createdBy";
+ else if ( key == "description" )
+ convertedKey = "cmis:description";
+- else if ( key == "createdDate" )
++ else if ( key == "createdTime" )
+ convertedKey = "cmis:creationDate";
+ else if ( key == "lastModifyingUserName" )
+ convertedKey = "cmis:lastModifiedBy";
+- else if ( key == "modifiedDate" )
++ else if ( key == "modifiedTime" )
+ convertedKey = "cmis:lastModificationDate";
+- else if ( key == "title" )
++ else if ( key == "name" )
+ convertedKey = "cmis:contentStreamFileName";
+ else if ( key == "mimeType" )
+ convertedKey = "cmis:contentStreamMimeType";
+- else if ( key == "fileSize" )
++ else if ( key == "size" )
+ convertedKey = "cmis:contentStreamLength";
+ else if ( key == "editable" )
+ convertedKey = "cmis:isImmutable";
+@@ -72,21 +72,21 @@
+ else if ( key == "cmis:createdBy" )
+ convertedKey = "ownerNames";
+ else if ( key == "cmis:creationDate" )
+- convertedKey = "createdDate";
++ convertedKey = "createdTime";
+ else if ( key == "cmis:description" )
+ convertedKey = "description";
+ else if ( key == "cmis:lastModifiedBy" )
+ convertedKey = "lastModifyingUserName";
+ else if ( key == "cmis:lastModificationDate" )
+- convertedKey = "modifiedDate";
++ convertedKey = "modifiedTime";
+ else if ( key == "cmis:contentStreamFileName" )
+- convertedKey = "title";
++ convertedKey = "name";
+ else if ( key == "cmis:name" )
+- convertedKey = "title";
++ convertedKey = "name";
+ else if ( key == "cmis:contentStreamMimeType" )
+ convertedKey = "mimeType";
+ else if ( key == "cmis:contentStreamLength" )
+- convertedKey = "fileSize";
++ convertedKey = "size";
+ else if ( key == "cmis:isImmutable" )
+ convertedKey = "editable";
+ else if ( key == "cmis:parentId" )
+@@ -124,9 +124,9 @@
+ bool GdriveUtils::checkUpdatable( const string& key )
+ {
+ // taken from https://developers.google.com/drive/v2/reference/files
+- bool updatable = ( key == "title" ||
++ bool updatable = ( key == "name" ||
+ key == "description" ||
+- key == "modifiedDate" ||
++ key == "modifiedTime" ||
+ key == "lastViewedByMeDate" );
+ return updatable;
+ }
+@@ -143,18 +143,11 @@
+
+ Json GdriveUtils::createJsonFromParentId( const string& parentId )
+ {
+- Json parentValue( parentId.c_str( ) );
+-
+ // parents is a Json array
+ Json firstParent;
+- firstParent.add( "id", parentValue );
+-
+- Json::JsonVector parents;
+- parents.insert( parents.begin( ), firstParent );
++ firstParent.add( Json( parentId.c_str() ) );
+
+- Json parentsValue( parents );
+-
+- return parentsValue;
++ return firstParent;
+ }
+
+ vector< string > GdriveUtils::parseGdriveProperty( string key, Json json )
+diff -ur libcmis.org/src/libcmis/gdrive-utils.hxx libcmis/src/libcmis/gdrive-utils.hxx
+--- libcmis.org/src/libcmis/gdrive-utils.hxx 2021-07-27 19:11:02.677247008 +0200
++++ libcmis/src/libcmis/gdrive-utils.hxx 2021-07-27 19:11:18.875246420 +0200
+@@ -35,7 +35,8 @@
+ #include "json-utils.hxx"
+
+ static const std::string GDRIVE_FOLDER_MIME_TYPE = "application/vnd.google-apps.folder" ;
+-static const std::string GDRIVE_UPLOAD_LINKS = "https://www.googleapis.com/upload/drive/v2/files/";
++static const std::string GDRIVE_UPLOAD_LINK = "https://www.googleapis.com/upload/drive/v3/files/";
++static const std::string GDRIVE_METADATA_LINK = "https://www.googleapis.com/drive/v3/files/";
+
+ class GdriveUtils
+ {
+diff -ur libcmis.org/src/libcmis/oauth2-handler.cxx libcmis/src/libcmis/oauth2-handler.cxx
+--- libcmis.org/src/libcmis/oauth2-handler.cxx 2021-07-27 19:11:02.676247009 +0200
++++ libcmis/src/libcmis/oauth2-handler.cxx 2021-07-27 19:11:18.875246420 +0200
+@@ -92,8 +92,11 @@
+ "code=" + authCode +
+ "&client_id=" + m_data->getClientId() +
+ "&redirect_uri=" + m_data->getRedirectUri() +
+- "&scope=" + libcmis::escape( m_data->getScope() ) +
+ "&grant_type=authorization_code" ;
++ if(boost::starts_with(m_data->getTokenUrl(), "https://oauth2.googleapis.com/"))
++ post += "&client_secret=" + m_data->getClientSecret();
++ else
++ post += "&scope=" + libcmis::escape( m_data->getScope() );
+
+ istringstream is( post );
+
+@@ -104,7 +107,7 @@
+ resp = m_session->httpPostRequest ( m_data->getTokenUrl(), is,
+ "application/x-www-form-urlencoded" );
+ }
+- catch ( const CurlException& )
++ catch ( const CurlException& e)
+ {
+ throw libcmis::Exception(
+ "Couldn't get tokens from the authorization code ");
+@@ -122,6 +125,8 @@
+ "refresh_token=" + m_refresh +
+ "&client_id=" + m_data->getClientId() +
+ "&grant_type=refresh_token" ;
++ if(boost::starts_with(m_data->getTokenUrl(), "https://oauth2.googleapis.com/"))
++ post += "&client_secret=" + m_data->getClientSecret();
+
+ istringstream is( post );
+ libcmis::HttpResponsePtr resp;
+@@ -130,7 +135,7 @@
+ resp = m_session->httpPostRequest( m_data->getTokenUrl( ), is,
+ "application/x-www-form-urlencoded" );
+ }
+- catch (const CurlException& )
++ catch (const CurlException& e )
+ {
+ throw libcmis::Exception( "Couldn't refresh token ");
+ }
+diff -ur libcmis.org/src/libcmis/oauth2-providers.cxx libcmis/src/libcmis/oauth2-providers.cxx
+--- libcmis.org/src/libcmis/oauth2-providers.cxx 2021-07-27 19:11:02.679247008 +0200
++++ libcmis/src/libcmis/oauth2-providers.cxx 2021-07-27 19:11:18.886246420 +0200
+@@ -80,172 +80,8 @@
+
+ }
+
+-string OAuth2Providers::OAuth2Gdrive( HttpSession* session, const string& authUrl,
+- const string& username, const string& password )
+-{
+- /* This member function implements 'Google OAuth 2.0'
+- *
+- * The interaction is carried out by libcmis, with no web browser involved.
+- *
+- * Normal sequence (without 2FA) is:
+- * 1) a get to activate login page
+- * receive first login page, html format
+- * 2) subsequent post to sent email
+- * receive html page for password input
+- * 3) subsequent post to send password
+- * receive html page for application consent
+- * 4) subsequent post to send a consent for the application
+- * receive a single-use authorization code
+- * this code is returned as a string
+- *
+- * Sequence with 2FA is:
+- * 1) a get to activate login page
+- * receive first login page, html format
+- * 2) subsequent post to sent email
+- * receive html page for password input
+- * 3) subsequent post to send password
+- * receive html page for pin input
+- * 3b) subsequent post to send pin number
+- * receive html page for application consent
+- * 4) subsequent post to send a consent for the application
+- * receive a single-use authorization code
+- * this code is returned as a string
+- */
+-
+- static const string CONTENT_TYPE( "application/x-www-form-urlencoded" );
+- // STEP 1: get login page
+- string res;
+- try
+- {
+- // send the first get, receive the html login page
+- res = session->httpGetRequest( authUrl )->getStream( )->str( );
+- }
+- catch ( const CurlException& )
+- {
+- return string( );
+- }
+-
+- // STEP 2: send email
+-
+- string loginEmailPost, loginEmailLink;
+- if ( !parseResponse( res.c_str( ), loginEmailPost, loginEmailLink ) )
+- return string( );
+-
+- loginEmailPost += "Email=";
+- loginEmailPost += escapeForm( username );
+-
+- istringstream loginEmailIs( loginEmailPost );
+- string loginEmailRes;
+- try
+- {
+- // send a post with user email, receive the html page for password input
+- loginEmailRes = session->httpPostRequest ( loginEmailLink, loginEmailIs, CONTENT_TYPE )
+- ->getStream( )->str( );
+- }
+- catch ( const CurlException& )
+- {
+- return string( );
+- }
+-
+- // STEP 3: password page
+-
+- string loginPasswdPost, loginPasswdLink;
+- if ( !parseResponse( loginEmailRes.c_str( ), loginPasswdPost, loginPasswdLink ) )
+- return string( );
+-
+- loginPasswdPost += "Passwd=";
+- loginPasswdPost += escapeForm( password );
+-
+- istringstream loginPasswdIs( loginPasswdPost );
+- string loginPasswdRes;
+- try
+- {
+- // send a post with user password, receive the application consent page
+- loginPasswdRes = session->httpPostRequest ( loginPasswdLink, loginPasswdIs, CONTENT_TYPE )
+- ->getStream( )->str( );
+- }
+- catch ( const CurlException& )
+- {
+- return string( );
+- }
+-
+- string approvalPost, approvalLink;
+- if ( !parseResponse( loginPasswdRes. c_str( ), approvalPost, approvalLink) )
+- return string( );
+-
+- // when 2FA is enabled, link doesn't start with 'http'
+- if ( approvalLink.compare(0, 4, "http") != 0 )
+- {
+- // STEP 3b: 2 Factor Authentication, pin code request
+-
+- string loginChallengePost( approvalPost );
+- string loginChallengeLink( approvalLink );
+-
+- libcmis::OAuth2AuthCodeProvider fallbackProvider = libcmis::SessionFactory::getOAuth2AuthCodeProvider( );
+- unique_ptr< char, void (*)( void * ) > pin{ fallbackProvider( "", "", "" ), free };
+-
+- if( !pin )
+- {
+- // unset OAuth2AuthCode Provider to avoid showing pin request again in the HttpSession::oauth2Authenticate
+- libcmis::SessionFactory::setOAuth2AuthCodeProvider( NULL );
+- return string( );
+- }
+-
+- loginChallengeLink = "https://accounts.google.com" + loginChallengeLink;
+- loginChallengePost += string( PIN_INPUT_NAME ) + "=";
+- loginChallengePost += string( pin.get() );
+-
+- istringstream loginChallengeIs( loginChallengePost );
+- string loginChallengeRes;
+- try
+- {
+- // send a post with pin, receive the application consent page
+- loginChallengeRes = session->httpPostRequest ( loginChallengeLink, loginChallengeIs, CONTENT_TYPE )
+- ->getStream( )->str( );
+- }
+- catch ( const CurlException& )
+- {
+- return string( );
+- }
+-
+- approvalPost = string();
+- approvalLink = string();
+-
+- if ( !parseResponse( loginChallengeRes. c_str( ), approvalPost, approvalLink) )
+- return string( );
+- }
+- else if( approvalLink.compare( "https://accounts.google.com/ServiceLoginAuth" ) == 0 )
+- {
+- // wrong password,
+- // unset OAuth2AuthCode Provider to avoid showing pin request again in the HttpSession::oauth2Authenticate
+- libcmis::SessionFactory::setOAuth2AuthCodeProvider( NULL );
+- return string( );
+- }
+-
+- // STEP 4: allow libcmis to access google drive
+- approvalPost += "submit_access=true";
+-
+- istringstream approvalIs( approvalPost );
+- string approvalRes;
+- try
+- {
+- // send a post with application consent
+- approvalRes = session->httpPostRequest ( approvalLink, approvalIs,
+- CONTENT_TYPE) ->getStream( )->str( );
+- }
+- catch ( const CurlException& e )
+- {
+- throw e.getCmisException( );
+- }
+-
+- // Take the authentication code from the text bar
+- string code = parseCode( approvalRes.c_str( ) );
+-
+- return code;
+-}
+-
+-string OAuth2Providers::OAuth2Onedrive( HttpSession* /*session*/, const string& /*authUrl*/,
+- const string& /*username*/, const string& /*password*/ )
++string OAuth2Providers::OAuth2Dummy( HttpSession* /*session*/, const string& /*authUrl*/,
++ const string& /*username*/, const string& /*password*/ )
+ {
+ return string( );
+ }
+@@ -314,12 +150,8 @@
+ // For Alfresco in the cloud, only match the hostname as there can be several
+ // binding URLs created with it.
+ return OAuth2Alfresco;
+- else if ( boost::starts_with( url, "https://www.googleapis.com/drive/v2" ) )
+- return OAuth2Gdrive;
+- else if ( boost::starts_with( url, "https://graph.microsoft.com/v1.0" ) )
+- return OAuth2Onedrive;
+
+- return OAuth2Gdrive;
++ return OAuth2Dummy;
+ }
+
+ int OAuth2Providers::parseResponse ( const char* response, string& post, string& link )
+diff -ur libcmis.org/src/libcmis/oauth2-providers.hxx libcmis/src/libcmis/oauth2-providers.hxx
+--- libcmis.org/src/libcmis/oauth2-providers.hxx 2021-07-27 19:11:02.678247008 +0200
++++ libcmis/src/libcmis/oauth2-providers.hxx 2021-07-27 19:11:18.886246420 +0200
+@@ -39,12 +39,8 @@
+ class OAuth2Providers
+ {
+ public :
+- static std::string OAuth2Gdrive( HttpSession* session, const std::string& authUrl,
++ static std::string OAuth2Dummy( HttpSession* session, const std::string& authUrl,
+ const std::string& username, const std::string& password );
+-
+- static std::string OAuth2Onedrive( HttpSession* session, const std::string& authUrl,
+- const std::string& username, const std::string& password );
+-
+ static std::string OAuth2Alfresco( HttpSession* session, const std::string& authUrl,
+ const std::string& username, const std::string& password );
+
+diff -ur libcmis.org/src/libcmis/session-factory.cxx libcmis/src/libcmis/session-factory.cxx
+--- libcmis.org/src/libcmis/session-factory.cxx 2021-07-27 19:11:02.679247008 +0200
++++ libcmis/src/libcmis/session-factory.cxx 2021-07-27 19:11:18.886246420 +0200
+@@ -66,7 +66,7 @@
+ if ( !bindingUrl.empty( ) )
+ {
+ // Try the special cases based on the binding URL
+- if ( bindingUrl == "https://www.googleapis.com/drive/v2" )
++ if ( bindingUrl == "https://www.googleapis.com/drive/v3" )
+ {
+ session = new GDriveSession( bindingUrl, username, password,
+ oauth2, verbose );
diff --git a/external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1 b/external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1
new file mode 100644
index 000000000..a8cb06509
--- /dev/null
+++ b/external/libcmis/libcmis_oauth_pw_as_refreshtoken.patch.1
@@ -0,0 +1,185 @@
+diff -ur libcmis.org/inc/libcmis/session.hxx libcmis/inc/libcmis/session.hxx
+--- libcmis.org/inc/libcmis/session.hxx 2021-07-27 19:09:42.580249917 +0200
++++ libcmis/inc/libcmis/session.hxx 2021-07-27 19:10:02.368249199 +0200
+@@ -95,6 +95,8 @@
+ certificate exception feature available on common web browser.
+ */
+ virtual void setNoSSLCertificateCheck( bool noCheck ) = 0;
++
++ virtual std::string getRefreshToken() { return ""; };
+ };
+ }
+
+diff -ur libcmis.org/src/libcmis/gdrive-session.cxx libcmis/src/libcmis/gdrive-session.cxx
+--- libcmis.org/src/libcmis/gdrive-session.cxx 2021-07-27 19:09:42.581249917 +0200
++++ libcmis/src/libcmis/gdrive-session.cxx 2021-07-27 19:10:02.369249198 +0200
+@@ -70,6 +70,46 @@
+ {
+ }
+
++
++void GDriveSession::setOAuth2Data( libcmis::OAuth2DataPtr oauth2 )
++{
++ m_oauth2Handler = new OAuth2Handler( this, oauth2 );
++ m_oauth2Handler->setOAuth2Parser( OAuth2Providers::getOAuth2Parser( getBindingUrl( ) ) );
++
++ oauth2Authenticate( );
++}
++
++void GDriveSession::oauth2Authenticate()
++{
++ // treat the supplied password as refresh token
++ if (!m_password.empty())
++ {
++ try
++ {
++ m_inOAuth2Authentication = true;
++
++ m_oauth2Handler->setRefreshToken(m_password);
++ // Try to get new access tokens using the stored refreshtoken
++ m_oauth2Handler->refresh();
++ m_inOAuth2Authentication = false;
++ }
++ catch (const CurlException &e)
++ {
++ m_inOAuth2Authentication = false;
++ // refresh token expired or invalid, trigger initial auth (that in turn will hit the fallback with copy'n'paste method)
++ BaseSession::oauth2Authenticate();
++ }
++ }
++ else
++ {
++ BaseSession::oauth2Authenticate();
++ }
++}
++
++string GDriveSession::getRefreshToken() {
++ return HttpSession::getRefreshToken();
++}
++
+ libcmis::RepositoryPtr GDriveSession::getRepository( )
+ {
+ // Return a dummy repository since GDrive doesn't have that notion
+diff -ur libcmis.org/src/libcmis/gdrive-session.hxx libcmis/src/libcmis/gdrive-session.hxx
+--- libcmis.org/src/libcmis/gdrive-session.hxx 2021-07-27 19:09:42.583249917 +0200
++++ libcmis/src/libcmis/gdrive-session.hxx 2021-07-27 19:10:02.369249198 +0200
+@@ -57,8 +57,14 @@
+
+ virtual std::vector< libcmis::ObjectTypePtr > getBaseTypes( );
+
++ virtual std::string getRefreshToken();
++
+ private:
+ GDriveSession( );
++
++ virtual void setOAuth2Data( libcmis::OAuth2DataPtr oauth2 );
++
++ void oauth2Authenticate( );
+ };
+
+ #endif /* _GDRIVE_SESSION_HXX_ */
+diff -ur libcmis.org/src/libcmis/http-session.hxx libcmis/src/libcmis/http-session.hxx
+--- libcmis.org/src/libcmis/http-session.hxx 2021-07-27 19:09:42.582249917 +0200
++++ libcmis/src/libcmis/http-session.hxx 2021-07-27 19:10:02.369249198 +0200
+@@ -148,7 +148,7 @@
+
+ void setNoSSLCertificateCheck( bool noCheck );
+
+- std::string getRefreshToken( );
++ virtual std::string getRefreshToken( );
+
+ protected:
+ HttpSession( );
+diff -ur libcmis.org/src/libcmis/oauth2-handler.cxx libcmis/src/libcmis/oauth2-handler.cxx
+--- libcmis.org/src/libcmis/oauth2-handler.cxx 2021-07-27 19:09:42.582249917 +0200
++++ libcmis/src/libcmis/oauth2-handler.cxx 2021-07-27 19:10:02.369249198 +0200
+@@ -158,6 +158,11 @@
+ return m_refresh;
+ }
+
++void OAuth2Handler::setRefreshToken( string refreshToken )
++{
++ m_refresh = refreshToken;
++}
++
+ string OAuth2Handler::getHttpHeader( )
+ {
+ string header;
+diff -ur libcmis.org/src/libcmis/oauth2-handler.hxx libcmis/src/libcmis/oauth2-handler.hxx
+--- libcmis.org/src/libcmis/oauth2-handler.hxx 2021-07-27 19:09:42.582249917 +0200
++++ libcmis/src/libcmis/oauth2-handler.hxx 2021-07-27 19:10:02.370249198 +0200
+@@ -61,6 +61,7 @@
+
+ std::string getAccessToken( ) ;
+ std::string getRefreshToken( ) ;
++ void setRefreshToken( std::string refreshToken ) ;
+
+ // adding HTTP auth header
+ std::string getHttpHeader( ) ;
+diff -ur libcmis.org/src/libcmis/onedrive-session.cxx libcmis/src/libcmis/onedrive-session.cxx
+--- libcmis.org/src/libcmis/onedrive-session.cxx 2021-07-27 19:09:42.583249917 +0200
++++ libcmis/src/libcmis/onedrive-session.cxx 2021-07-27 19:10:02.370249198 +0200
+@@ -68,6 +68,45 @@
+ {
+ }
+
++void OneDriveSession::setOAuth2Data( libcmis::OAuth2DataPtr oauth2 )
++{
++ m_oauth2Handler = new OAuth2Handler( this, oauth2 );
++ m_oauth2Handler->setOAuth2Parser( OAuth2Providers::getOAuth2Parser( getBindingUrl( ) ) );
++
++ oauth2Authenticate( );
++}
++
++void OneDriveSession::oauth2Authenticate()
++{
++ // treat the supplied password as refresh token
++ if (!m_password.empty())
++ {
++ try
++ {
++ m_inOAuth2Authentication = true;
++
++ m_oauth2Handler->setRefreshToken(m_password);
++ // Try to get new access tokens using the stored refreshtoken
++ m_oauth2Handler->refresh();
++ m_inOAuth2Authentication = false;
++ }
++ catch (const CurlException &e)
++ {
++ m_inOAuth2Authentication = false;
++ // refresh token expired or invalid, trigger initial auth (that in turn will hit the fallback with copy'n'paste method)
++ BaseSession::oauth2Authenticate();
++ }
++ }
++ else
++ {
++ BaseSession::oauth2Authenticate();
++ }
++}
++
++string OneDriveSession::getRefreshToken() {
++ return HttpSession::getRefreshToken();
++}
++
+ libcmis::RepositoryPtr OneDriveSession::getRepository( )
+ {
+ // Return a dummy repository since OneDrive doesn't have that notion
+diff -ur libcmis.org/src/libcmis/onedrive-session.hxx libcmis/src/libcmis/onedrive-session.hxx
+--- libcmis.org/src/libcmis/onedrive-session.hxx 2021-07-27 19:09:42.583249917 +0200
++++ libcmis/src/libcmis/onedrive-session.hxx 2021-07-27 19:10:02.370249198 +0200
+@@ -62,8 +62,14 @@
+
+ bool isAPathMatch( Json objectJson, std::string path );
+
++ virtual std::string getRefreshToken();
++
+ private:
+ OneDriveSession( );
++
++ virtual void setOAuth2Data( libcmis::OAuth2DataPtr oauth2 );
++
++ void oauth2Authenticate( );
+ };
+
+ #endif /* _ONEDRIVE_SESSION_HXX_ */
diff --git a/external/libcmis/libcmis_onedrive.patch b/external/libcmis/libcmis_onedrive.patch
new file mode 100644
index 000000000..60d7e7b3b
--- /dev/null
+++ b/external/libcmis/libcmis_onedrive.patch
@@ -0,0 +1,445 @@
+diff --git a/src/libcmis/http-session.cxx b/src/libcmis/http-session.cxx
+index 2638482..227667e 100644
+--- a/src/libcmis/http-session.cxx
++++ b/src/libcmis/http-session.cxx
+@@ -293,6 +293,94 @@ libcmis::HttpResponsePtr HttpSession::httpGetRequest( string url )
+ return response;
+ }
+
++libcmis::HttpResponsePtr HttpSession::httpPatchRequest( string url, istream& is, vector< string > headers )
++{
++ checkOAuth2( url );
++
++ // Duplicate istream in case we need to retry
++ string isStr( static_cast< stringstream const&>( stringstream( ) << is.rdbuf( ) ).str( ) );
++
++ istringstream isOriginal( isStr ), isBackup( isStr );
++
++ // Reset the handle for the request
++ curl_easy_reset( m_curlHandle );
++ initProtocols( );
++
++ libcmis::HttpResponsePtr response( new libcmis::HttpResponse( ) );
++
++ curl_easy_setopt( m_curlHandle, CURLOPT_WRITEFUNCTION, lcl_bufferData );
++ curl_easy_setopt( m_curlHandle, CURLOPT_WRITEDATA, response->getData( ).get( ) );
++
++ curl_easy_setopt( m_curlHandle, CURLOPT_HEADERFUNCTION, &lcl_getHeaders );
++ curl_easy_setopt( m_curlHandle, CURLOPT_WRITEHEADER, response.get() );
++
++ curl_easy_setopt( m_curlHandle, CURLOPT_MAXREDIRS, 20);
++
++ // Get the stream length
++ is.seekg( 0, ios::end );
++ long size = is.tellg( );
++ is.seekg( 0, ios::beg );
++ curl_easy_setopt( m_curlHandle, CURLOPT_INFILESIZE, size );
++ curl_easy_setopt( m_curlHandle, CURLOPT_READDATA, &isOriginal );
++ curl_easy_setopt( m_curlHandle, CURLOPT_READFUNCTION, lcl_readStream );
++ curl_easy_setopt( m_curlHandle, CURLOPT_UPLOAD, 1 );
++ curl_easy_setopt( m_curlHandle, CURLOPT_CUSTOMREQUEST, "PATCH" );
++ curl_easy_setopt( m_curlHandle, CURLOPT_IOCTLFUNCTION, lcl_ioctlStream );
++ curl_easy_setopt( m_curlHandle, CURLOPT_IOCTLDATA, &isOriginal );
++
++ // If we know for sure that 100-Continue won't be accepted,
++ // don't even try with it to save one HTTP request.
++ if ( m_no100Continue )
++ headers.push_back( "Expect:" );
++ try
++ {
++ httpRunRequest( url, headers );
++ response->getData( )->finish();
++ }
++ catch ( const CurlException& )
++ {
++ long status = getHttpStatus( );
++ /** If we had a HTTP 417 response, this is likely to be due to some
++ HTTP 1.0 proxy / server not accepting the "Expect: 100-continue"
++ header. Try to disable this header and try again.
++ */
++ if ( status == 417 && !m_no100Continue)
++ {
++ // Remember that we don't want 100-Continue for the future requests
++ m_no100Continue = true;
++ response = httpPutRequest( url, isBackup, headers );
++ }
++
++ // If the access token is expired, we get 401 error,
++ // Need to use the refresh token to get a new one.
++ if ( status == 401 && !getRefreshToken( ).empty( ) && !m_refreshedToken )
++ {
++
++ // Refresh the token
++ oauth2Refresh();
++
++ // Resend the query
++ try
++ {
++ // Avoid infinite recursive call
++ m_refreshedToken = true;
++ response = httpPutRequest( url, isBackup, headers );
++ m_refreshedToken = false;
++ }
++ catch (const CurlException&)
++ {
++ m_refreshedToken = false;
++ throw;
++ }
++ }
++ // Has tried but failed
++ if ( ( status != 417 || m_no100Continue ) &&
++ ( status != 401 || getRefreshToken( ).empty( ) || m_refreshedToken ) ) throw;
++ }
++ m_refreshedToken = false;
++ return response;
++}
++
+ libcmis::HttpResponsePtr HttpSession::httpPutRequest( string url, istream& is, vector< string > headers )
+ {
+ checkOAuth2( url );
+diff --git a/src/libcmis/http-session.hxx b/src/libcmis/http-session.hxx
+index 851d52d..29de64d 100644
+--- a/src/libcmis/http-session.hxx
++++ b/src/libcmis/http-session.hxx
+@@ -132,6 +132,9 @@ class HttpSession
+ virtual void setOAuth2Data( libcmis::OAuth2DataPtr oauth2 );
+
+ libcmis::HttpResponsePtr httpGetRequest( std::string url );
++ libcmis::HttpResponsePtr httpPatchRequest( std::string url,
++ std::istream& is,
++ std::vector< std::string > headers );
+ libcmis::HttpResponsePtr httpPutRequest( std::string url,
+ std::istream& is,
+ std::vector< std::string > headers );
+diff --git a/src/libcmis/oauth2-handler.cxx b/src/libcmis/oauth2-handler.cxx
+index a3320e3..842769f 100644
+--- a/src/libcmis/oauth2-handler.cxx
++++ b/src/libcmis/oauth2-handler.cxx
+@@ -91,8 +91,8 @@ void OAuth2Handler::fetchTokens( string authCode )
+ string post =
+ "code=" + authCode +
+ "&client_id=" + m_data->getClientId() +
+- "&client_secret=" + m_data->getClientSecret() +
+ "&redirect_uri=" + m_data->getRedirectUri() +
++ "&scope=" + libcmis::escape( m_data->getScope() ) +
+ "&grant_type=authorization_code" ;
+
+ istringstream is( post );
+@@ -121,7 +121,6 @@ void OAuth2Handler::refresh( )
+ string post =
+ "refresh_token=" + m_refresh +
+ "&client_id=" + m_data->getClientId() +
+- "&client_secret=" + m_data->getClientSecret() +
+ "&grant_type=refresh_token" ;
+
+ istringstream is( post );
+diff --git a/src/libcmis/oauth2-providers.cxx b/src/libcmis/oauth2-providers.cxx
+index 8cf9652..654021f 100644
+--- a/src/libcmis/oauth2-providers.cxx
++++ b/src/libcmis/oauth2-providers.cxx
+@@ -312,7 +312,7 @@ OAuth2Parser OAuth2Providers::getOAuth2Parser( const std::string& url )
+ return OAuth2Alfresco;
+ else if ( boost::starts_with( url, "https://www.googleapis.com/drive/v2" ) )
+ return OAuth2Gdrive;
+- else if ( boost::starts_with( url, "https://apis.live.net/v5.0" ) )
++ else if ( boost::starts_with( url, "https://graph.microsoft.com/v1.0" ) )
+ return OAuth2Onedrive;
+
+ return OAuth2Gdrive;
+diff --git a/src/libcmis/onedrive-document.cxx b/src/libcmis/onedrive-document.cxx
+index f753b42..863a92f 100644
+--- a/src/libcmis/onedrive-document.cxx
++++ b/src/libcmis/onedrive-document.cxx
+@@ -73,7 +73,7 @@ boost::shared_ptr< istream > OneDriveDocument::getContentStream( string /*stream
+ boost::shared_ptr< istream > stream;
+ string streamUrl = getStringProperty( "source" );
+ if ( streamUrl.empty( ) )
+- throw libcmis::Exception( "can not found stream url" );
++ throw libcmis::Exception( "could not find stream url" );
+
+ try
+ {
+@@ -89,15 +89,15 @@ boost::shared_ptr< istream > OneDriveDocument::getContentStream( string /*stream
+ void OneDriveDocument::setContentStream( boost::shared_ptr< ostream > os,
+ string /*contentType*/,
+ string fileName,
+- bool /*overwrite*/ )
++ bool bReplaceExisting )
+ {
+ if ( !os.get( ) )
+ throw libcmis::Exception( "Missing stream" );
+-
++
+ string metaUrl = getUrl( );
+
+ // Update file name meta information
+- if ( !fileName.empty( ) && fileName != getContentFilename( ) )
++ if ( bReplaceExisting && !fileName.empty( ) && fileName != getContentFilename( ) )
+ {
+ Json metaJson;
+ Json fileJson( fileName.c_str( ) );
+@@ -108,7 +108,7 @@ void OneDriveDocument::setContentStream( boost::shared_ptr< ostream > os,
+ headers.push_back( "Content-Type: application/json" );
+ try
+ {
+- getSession()->httpPutRequest( metaUrl, is, headers );
++ getSession()->httpPatchRequest( metaUrl, is, headers );
+ }
+ catch ( const CurlException& e )
+ {
+@@ -117,9 +117,9 @@ void OneDriveDocument::setContentStream( boost::shared_ptr< ostream > os,
+ }
+
+ fileName = libcmis::escape( getStringProperty( "cmis:name" ) );
+- string putUrl = getSession( )->getBindingUrl( ) + "/" +
+- getStringProperty( "cmis:parentId" ) + "/files/" +
+- fileName + "?overwrite=true";
++ string putUrl = getSession( )->getBindingUrl( ) + "/me/drive/items/" +
++ getStringProperty( "cmis:parentId" ) + ":/" +
++ fileName + ":/content";
+
+ // Upload stream
+ boost::shared_ptr< istream> is ( new istream ( os->rdbuf( ) ) );
+@@ -142,6 +142,7 @@ void OneDriveDocument::setContentStream( boost::shared_ptr< ostream > os,
+ libcmis::DocumentPtr OneDriveDocument::checkOut( )
+ {
+ // OneDrive doesn't have CheckOut, so just return the same document here
++ // TODO: no longer true - onedrive now has checkout/checkin
+ libcmis::ObjectPtr obj = getSession( )->getObject( getId( ) );
+ libcmis::DocumentPtr checkout =
+ boost::dynamic_pointer_cast< libcmis::Document > ( obj );
+diff --git a/src/libcmis/onedrive-folder.cxx b/src/libcmis/onedrive-folder.cxx
+index a9ae694..c1980c8 100644
+--- a/src/libcmis/onedrive-folder.cxx
++++ b/src/libcmis/onedrive-folder.cxx
+@@ -57,7 +57,9 @@ OneDriveFolder::~OneDriveFolder( )
+ vector< libcmis::ObjectPtr > OneDriveFolder::getChildren( )
+ {
+ vector< libcmis::ObjectPtr > children;
+- string query = getSession( )->getBindingUrl( ) + "/" + getId( ) + "/files";
++ // TODO: limited to 200 items by default - to get more one would have to
++ // follow @odata.nextLink or change pagination size
++ string query = getSession( )->getBindingUrl( ) + "/me/drive/items/" + getId( ) + "/children";
+
+ string res;
+ try
+@@ -70,7 +72,7 @@ vector< libcmis::ObjectPtr > OneDriveFolder::getChildren( )
+ }
+
+ Json jsonRes = Json::parse( res );
+- Json::JsonVector objs = jsonRes["data"].getList( );
++ Json::JsonVector objs = jsonRes["value"].getList( );
+
+ // Create children objects from Json objects
+ for(unsigned int i = 0; i < objs.size(); i++)
+@@ -85,8 +87,7 @@ libcmis::FolderPtr OneDriveFolder::createFolder(
+ const PropertyPtrMap& properties )
+ {
+ Json propsJson = OneDriveUtils::toOneDriveJson( properties );
+-
+- string uploadUrl = getSession( )->getBindingUrl( ) + "/" + getId( );
++ string uploadUrl = getSession( )->getBindingUrl( ) + "/me/drive/items/" + getId( ) + "/children";
+
+ std::istringstream is( propsJson.toString( ) );
+ string response;
+@@ -126,9 +127,10 @@ libcmis::DocumentPtr OneDriveFolder::createDocument(
+ }
+ }
+
++ // TODO: limited to 4MB, larger uploads need dedicated UploadSession
+ fileName = libcmis::escape( fileName );
+- string newDocUrl = getSession( )->getBindingUrl( ) + "/" +
+- getId( ) + "/files/" + fileName;
++ string newDocUrl = getSession( )->getBindingUrl( ) + "/me/drive/items/" +
++ getId( ) + ":/" + fileName + ":/content";
+ boost::shared_ptr< istream> is ( new istream ( os->rdbuf( ) ) );
+ vector< string > headers;
+ string res;
+diff --git a/src/libcmis/onedrive-object.cxx b/src/libcmis/onedrive-object.cxx
+index 976a97b..8deb591 100644
+--- a/src/libcmis/onedrive-object.cxx
++++ b/src/libcmis/onedrive-object.cxx
+@@ -65,7 +65,7 @@ void OneDriveObject::initializeFromJson ( Json json, string /*id*/, string /*nam
+ Json::JsonObject objs = json.getObjects( );
+ Json::JsonObject::iterator it;
+ PropertyPtr property;
+- bool isFolder = json["type"].toString( ) == "folder";
++ bool isFolder = json["folder"].toString( ) != "";
+ for ( it = objs.begin( ); it != objs.end( ); ++it)
+ {
+ property.reset( new OneDriveProperty( it->first, it->second ) );
+@@ -74,7 +74,12 @@ void OneDriveObject::initializeFromJson ( Json json, string /*id*/, string /*nam
+ {
+ property.reset( new OneDriveProperty( "cmis:contentStreamFileName", it->second ) );
+ m_properties[ property->getPropertyType( )->getId()] = property;
+- }
++ } else if ( it->first == "parentReference" ) {
++ if (it->second["id"].toString() != "") {
++ property.reset( new OneDriveProperty( "cmis:parentId", it->second["id"] ) );
++ m_properties[ property->getPropertyType( )->getId()] = property;
++ }
++ }
+ }
+
+ m_refreshTimestamp = time( NULL );
+@@ -122,7 +127,7 @@ void OneDriveObject::remove( bool /*allVersions*/ )
+
+ string OneDriveObject::getUrl( )
+ {
+- return getSession( )->getBindingUrl( ) + "/" + getId( );
++ return getSession( )->getBindingUrl( ) + "/me/drive/items/" + getId( );
+ }
+
+ string OneDriveObject::getUploadUrl( )
+@@ -152,7 +157,7 @@ libcmis::ObjectPtr OneDriveObject::updateProperties(
+ {
+ vector< string > headers;
+ headers.push_back( "Content-Type: application/json" );
+- response = getSession( )->httpPutRequest( getUrl( ), is, headers );
++ response = getSession( )->httpPatchRequest( getUrl( ), is, headers );
+ }
+ catch ( const CurlException& e )
+ {
+diff --git a/src/libcmis/onedrive-repository.cxx b/src/libcmis/onedrive-repository.cxx
+index 3eaac9c..b01f5c2 100644
+--- a/src/libcmis/onedrive-repository.cxx
++++ b/src/libcmis/onedrive-repository.cxx
+@@ -35,7 +35,7 @@ OneDriveRepository::OneDriveRepository( ) :
+ m_description = "One Drive repository";
+ m_productName = "One Drive";
+ m_productVersion = "v5";
+- m_rootId = "me/skydrive";
++ m_rootId = "/me/drive/root";
+
+ m_capabilities[ ACL ] = "discover";
+ m_capabilities[ AllVersionsSearchable ] = "true";
+diff --git a/src/libcmis/onedrive-session.cxx b/src/libcmis/onedrive-session.cxx
+index c6f4270..a603278 100644
+--- a/src/libcmis/onedrive-session.cxx
++++ b/src/libcmis/onedrive-session.cxx
+@@ -79,7 +79,9 @@ libcmis::ObjectPtr OneDriveSession::getObject( string objectId )
+ {
+ // Run the http request to get the properties definition
+ string res;
+- string objectLink = m_bindingUrl + "/" + objectId;
++ string objectLink = m_bindingUrl + "/me/drive/items/" + objectId;
++ if (objectId == getRootId())
++ objectLink = m_bindingUrl + objectId;
+ try
+ {
+ res = httpGetRequest( objectLink )->getStream()->str();
+@@ -95,12 +97,11 @@ libcmis::ObjectPtr OneDriveSession::getObject( string objectId )
+ libcmis::ObjectPtr OneDriveSession::getObjectFromJson( Json& jsonRes )
+ {
+ libcmis::ObjectPtr object;
+- string kind = jsonRes["type"].toString( );
+- if ( kind == "folder" || kind == "album" )
++ if ( jsonRes["folder"].toString() != "" )
+ {
+ object.reset( new OneDriveFolder( this, jsonRes ) );
+ }
+- else if ( kind == "file" )
++ else if ( jsonRes["file"].toString() != "" )
+ {
+ object.reset( new OneDriveDocument( this, jsonRes ) );
+ }
+@@ -113,44 +114,18 @@ libcmis::ObjectPtr OneDriveSession::getObjectFromJson( Json& jsonRes )
+
+ libcmis::ObjectPtr OneDriveSession::getObjectByPath( string path )
+ {
+- string id;
+- if ( path == "/" )
+- {
+- id = "me/skydrive";
+- }
+- else
++ string res;
++ string objectQuery = m_bindingUrl + "/me/drive/root:" + libcmis::escape( path );
++ try
+ {
+- path = "/SkyDrive" + path;
+- size_t pos = path.rfind("/");
+- string name = libcmis::escape( path.substr( pos + 1, path.size( ) ) );
+- string res;
+- string objectQuery = m_bindingUrl + "/me/skydrive/search?q=" + name;
+- try
+- {
+- res = httpGetRequest( objectQuery )->getStream( )->str( );
+- }
+- catch ( const CurlException& e )
+- {
+- throw e.getCmisException( );
+- }
+- Json jsonRes = Json::parse( res );
+- Json::JsonVector objs = jsonRes["data"].getList( );
+-
+- // Searching for a match in the path to the object
+- for ( unsigned int i = 0; i < objs.size( ); i++ )
+- {
+- if ( isAPathMatch( objs[i], path ) )
+- {
+- id = objs[i]["id"].toString( );
+- break;
+- }
+- }
++ res = httpGetRequest( objectQuery )->getStream( )->str( );
+ }
+- if ( id.empty( ) )
++ catch ( const CurlException& e )
+ {
+- throw libcmis::Exception( "No file could be found" );
++ throw libcmis::Exception( "No file could be found for path " + path + ": " + e.what() );
+ }
+- return getObject( id );
++ Json jsonRes = Json::parse( res );
++ return getObjectFromJson( jsonRes );
+ }
+
+ bool OneDriveSession::isAPathMatch( Json objectJson, string path )
+diff --git a/src/libcmis/onedrive-utils.cxx b/src/libcmis/onedrive-utils.cxx
+index dc6ec5d..17ed324 100644
+--- a/src/libcmis/onedrive-utils.cxx
++++ b/src/libcmis/onedrive-utils.cxx
+@@ -44,16 +44,16 @@ string OneDriveUtils::toCmisKey( const string& key )
+ convertedKey = "cmis:createdBy";
+ else if ( key == "description" )
+ convertedKey = "cmis:description";
+- else if ( key == "created_time" )
++ else if ( key == "createdDateTime" )
+ convertedKey = "cmis:creationDate";
+- else if ( key == "updated_time" )
++ else if ( key == "lastModifiedDateTime" )
+ convertedKey = "cmis:lastModificationDate";
+ else if ( key == "name" )
+ convertedKey = "cmis:name";
+ else if ( key == "size" )
+ convertedKey = "cmis:contentStreamLength";
+- else if ( key == "parent_id" )
+- convertedKey = "cmis:parentId";
++ else if ( key == "@microsoft.graph.downloadUrl" )
++ convertedKey = "source";
+ else convertedKey = key;
+ return convertedKey;
+ }
+@@ -75,8 +75,6 @@ string OneDriveUtils::toOneDriveKey( const string& key )
+ convertedKey = "name";
+ else if ( key == "cmis:contentStreamLength" )
+ convertedKey = "file_size";
+- else if ( key == "cmis:parentId" )
+- convertedKey = "parent_id";
+ else convertedKey = key;
+ return convertedKey;
+ }
+diff --git a/src/libcmis/session-factory.cxx b/src/libcmis/session-factory.cxx
+index ba55cd9..e740afb 100644
+--- a/src/libcmis/session-factory.cxx
++++ b/src/libcmis/session-factory.cxx
+@@ -71,7 +71,7 @@ namespace libcmis
+ session = new GDriveSession( bindingUrl, username, password,
+ oauth2, verbose );
+ }
+- else if ( bindingUrl == "https://apis.live.net/v5.0" )
++ else if ( bindingUrl == "https://graph.microsoft.com/v1.0" )
+ {
+ session = new OneDriveSession( bindingUrl, username, password,
+ oauth2, verbose);
diff --git a/external/libebook/ExternalProject_libebook.mk b/external/libebook/ExternalProject_libebook.mk
new file mode 100644
index 000000000..3a3df8c71
--- /dev/null
+++ b/external/libebook/ExternalProject_libebook.mk
@@ -0,0 +1,54 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libebook))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libebook,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libebook,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libebook,\
+ boost_headers \
+ icu \
+ liblangtag \
+ libxml2 \
+ revenge \
+ zlib \
+))
+
+$(call gb_ExternalProject_get_state_target,libebook,build) :
+ $(call gb_Trace_StartRange,libebook,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ --without-tools \
+ --disable-tests \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ --disable-werror \
+ --disable-weffc \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libebook)" \
+ CPPFLAGS="$(CPPFLAGS) $(ICU_UCHAR_TYPE) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libebook)" \
+ LANGTAG_CFLAGS="$(LIBLANGTAG_CFLAGS)" \
+ LANGTAG_LIBS="$(LIBLANGTAG_LIBS)" \
+ XML_CFLAGS="$(LIBXML_CFLAGS)" \
+ XML_LIBS="$(LIBXML_LIBS)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libebook,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libebook/Makefile b/external/libebook/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libebook/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libebook/Module_libebook.mk b/external/libebook/Module_libebook.mk
new file mode 100644
index 000000000..cbc74f109
--- /dev/null
+++ b/external/libebook/Module_libebook.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libebook))
+
+$(eval $(call gb_Module_add_targets,libebook,\
+ ExternalProject_libebook \
+ UnpackedTarball_libebook \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libebook/README b/external/libebook/README
new file mode 100644
index 000000000..804de5c1b
--- /dev/null
+++ b/external/libebook/README
@@ -0,0 +1,3 @@
+Library for import of various non-HTML reflowable e-book formats.
+
+[https://sourceforge.net/projects/libebook/]
diff --git a/external/libebook/UnpackedTarball_libebook.mk b/external/libebook/UnpackedTarball_libebook.mk
new file mode 100644
index 000000000..4a6dd2bce
--- /dev/null
+++ b/external/libebook/UnpackedTarball_libebook.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libebook))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libebook,$(EBOOK_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libebook))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libebook,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libebook, \
+ external/libebook/libebook-no-icu-boolean.patch.1 \
+ external/libebook/include.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libebook/include.patch b/external/libebook/include.patch
new file mode 100644
index 000000000..fe6d8bdbe
--- /dev/null
+++ b/external/libebook/include.patch
@@ -0,0 +1,10 @@
+--- src/lib/BBeBCollector.cpp
++++ src/lib/BBeBCollector.cpp
+@@ -7,6 +7,7 @@
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
++#include <algorithm>
+ #include <unordered_map>
+
+ #include <librevenge/librevenge.h>
diff --git a/external/libebook/libebook-no-icu-boolean.patch.1 b/external/libebook/libebook-no-icu-boolean.patch.1
new file mode 100644
index 000000000..0e53546b7
--- /dev/null
+++ b/external/libebook/libebook-no-icu-boolean.patch.1
@@ -0,0 +1,12 @@
+diff -ur libebook.org/src/lib/EBOOKCharsetConverter.cpp libebook/src/lib/EBOOKCharsetConverter.cpp
+--- libebook.org/src/lib/EBOOKCharsetConverter.cpp 2018-01-01 12:16:28.000000000 +0100
++++ libebook/src/lib/EBOOKCharsetConverter.cpp 2020-11-16 21:19:46.699315299 +0100
+@@ -124,7 +124,7 @@
+ m_converterToUTF8.get(), m_converterToUnicode.get(),
+ &outText, outText + out.size(), &inText, inText + length,
+ nullptr, nullptr, nullptr, nullptr,
+- TRUE, TRUE, &status)
++ true, true, &status)
+ ;
+ if (status==U_BUFFER_OVERFLOW_ERROR)
+ {
diff --git a/external/libeot/ExternalProject_libeot.mk b/external/libeot/ExternalProject_libeot.mk
new file mode 100644
index 000000000..98c7d2eb4
--- /dev/null
+++ b/external/libeot/ExternalProject_libeot.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libeot))
+
+$(eval $(call gb_ExternalProject_register_targets,libeot,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,libeot,build) :
+ $(call gb_Trace_StartRange,libeot,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ touch Makefile.in \
+ && export PKG_CONFIG="" \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --disable-debug \
+ CFLAGS='$(filter-out -std=gnu89,$(CFLAGS))' \
+ && $(MAKE) $(if $(verbose),V=1) \
+ )
+ $(call gb_Trace_EndRange,libeot,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libeot/Makefile b/external/libeot/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libeot/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libeot/Module_libeot.mk b/external/libeot/Module_libeot.mk
new file mode 100644
index 000000000..128b255d1
--- /dev/null
+++ b/external/libeot/Module_libeot.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libeot))
+
+$(eval $(call gb_Module_add_targets,libeot,\
+ ExternalProject_libeot \
+ UnpackedTarball_libeot \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libeot/README b/external/libeot/README
new file mode 100644
index 000000000..fc317f43d
--- /dev/null
+++ b/external/libeot/README
@@ -0,0 +1,2 @@
+Library for parsing Embedded OpenType files (Microsoft embedded font
+"standard"), and converting them to other formats.
diff --git a/external/libeot/UnpackedTarball_libeot.mk b/external/libeot/UnpackedTarball_libeot.mk
new file mode 100644
index 000000000..cbd1a69aa
--- /dev/null
+++ b/external/libeot/UnpackedTarball_libeot.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libeot))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libeot,$(LIBEOT_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libepubgen/ExternalProject_libepubgen.mk b/external/libepubgen/ExternalProject_libepubgen.mk
new file mode 100644
index 000000000..f0dbf70a2
--- /dev/null
+++ b/external/libepubgen/ExternalProject_libepubgen.mk
@@ -0,0 +1,43 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libepubgen))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libepubgen,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libepubgen,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libepubgen,\
+ boost_headers \
+ revenge \
+))
+
+$(call gb_ExternalProject_get_state_target,libepubgen,build) :
+ $(call gb_Trace_StartRange,libepubgen,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-werror \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libepubgen)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libepubgen)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libepubgen,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libepubgen/Makefile b/external/libepubgen/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libepubgen/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libepubgen/Module_libepubgen.mk b/external/libepubgen/Module_libepubgen.mk
new file mode 100644
index 000000000..a0ed770be
--- /dev/null
+++ b/external/libepubgen/Module_libepubgen.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libepubgen))
+
+$(eval $(call gb_Module_add_targets,libepubgen,\
+ ExternalProject_libepubgen \
+ UnpackedTarball_libepubgen \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libepubgen/README b/external/libepubgen/README
new file mode 100644
index 000000000..4d1dca7f8
--- /dev/null
+++ b/external/libepubgen/README
@@ -0,0 +1,3 @@
+An EPUB generator library for librevenge from
+
+[https://sourceforge.net/projects/libepubgen/]
diff --git a/external/libepubgen/UnpackedTarball_libepubgen.mk b/external/libepubgen/UnpackedTarball_libepubgen.mk
new file mode 100644
index 000000000..3c505ea1b
--- /dev/null
+++ b/external/libepubgen/UnpackedTarball_libepubgen.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+epubgen_patches :=
+epubgen_patches += tdf-120491.patch
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libepubgen))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libepubgen,$(EPUBGEN_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libepubgen))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libepubgen,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libepubgen,\
+ $(foreach patch,$(epubgen_patches),external/libepubgen/$(patch)) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libepubgen/tdf-120491.patch b/external/libepubgen/tdf-120491.patch
new file mode 100644
index 000000000..2a02a66e4
--- /dev/null
+++ b/external/libepubgen/tdf-120491.patch
@@ -0,0 +1,33 @@
+From 92760e4b0b8da126029c5ff858ebec27df4acfa8 Mon Sep 17 00:00:00 2001
+Subject: [PATCH] tdf#120491 EPUBHTMLGenerator: remove not needed <meta
+ content="text/html...">
+
+IngramSpark flags this as an error, and not writing it still passes
+epubcheck.
+---
+ src/lib/EPUBHTMLGenerator.cpp | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/src/lib/EPUBHTMLGenerator.cpp b/src/lib/EPUBHTMLGenerator.cpp
+index a950ea5..f6c2527 100644
+--- src/lib/EPUBHTMLGenerator.cpp
++++ src/lib/EPUBHTMLGenerator.cpp
+@@ -579,14 +579,9 @@ void EPUBHTMLGenerator::endDocument()
+ m_impl->m_document.openElement("title", RVNGPropertyList());
+ m_impl->m_document.closeElement("title");
+ }
+- RVNGPropertyList metaAttrs;
+- metaAttrs.insert("http-equiv", "content-type");
+- metaAttrs.insert("content", "text/html; charset=UTF-8");
+- m_impl->m_document.openElement("meta", metaAttrs);
+- m_impl->m_document.closeElement("meta");
+ if (m_impl->m_version >= 30 && m_impl->m_layoutMethod == EPUB_LAYOUT_METHOD_FIXED)
+ {
+- metaAttrs.clear();
++ RVNGPropertyList metaAttrs;
+ metaAttrs.insert("name", "viewport");
+ std::stringstream content;
+ if (const librevenge::RVNGProperty *pageWidth = m_impl->m_actualPageProperties["fo:page-width"])
+--
+2.16.4
+
diff --git a/external/libetonyek/0001-allow-0-size-message.patch.1 b/external/libetonyek/0001-allow-0-size-message.patch.1
new file mode 100644
index 000000000..62e584b81
--- /dev/null
+++ b/external/libetonyek/0001-allow-0-size-message.patch.1
@@ -0,0 +1,30 @@
+From 54762245feee35ce6885f7443da8f8443fccd5b5 Mon Sep 17 00:00:00 2001
+From: David Tardon <dtardon@redhat.com>
+Date: Wed, 26 May 2021 20:39:41 +0200
+Subject: [PATCH] allow 0-size message
+
+It likely means the input is broken, but there is no need to reject it.
+Let's just produce a dummy, empty message.
+
+Change-Id: I03a1e9827f21f6a0ce69d7e16dfcf2e9a0f2d44f
+---
+ src/lib/IWAMessage.cpp | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/lib/IWAMessage.cpp b/src/lib/IWAMessage.cpp
+index c01b1b6..9456444 100644
+--- a/src/lib/IWAMessage.cpp
++++ b/src/lib/IWAMessage.cpp
+@@ -42,7 +42,8 @@ IWAMessage::IWAMessage(const RVNGInputStreamPtr_t &input, unsigned long length)
+ : m_input(input)
+ , m_fields()
+ {
+- assert(length > 0);
++ if (length == 0)
++ return;
+
+ parse(length);
+ }
+--
+2.31.1
+
diff --git a/external/libetonyek/0001-fix-build-with-MSVC.patch.1 b/external/libetonyek/0001-fix-build-with-MSVC.patch.1
new file mode 100644
index 000000000..2a72844dc
--- /dev/null
+++ b/external/libetonyek/0001-fix-build-with-MSVC.patch.1
@@ -0,0 +1,28 @@
+From 1aa22c746b41a688296f4daf4fc35710d2045a33 Mon Sep 17 00:00:00 2001
+From: David Tardon <dtardon@redhat.com>
+Date: Wed, 19 May 2021 19:43:43 +0200
+Subject: [PATCH] fix build with MSVC
+
+error C2664: 'libetonyek::IWORKFormula::IWORKFormula(const boost::optional<unsigned int> &)': cannot convert argument 1 from 'int' to 'const boost::optional<unsigned int> &'
+
+Change-Id: Iaa3de2d0ef8f960495e5d5afebb75c5063955177
+---
+ src/lib/IWAParser.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/lib/IWAParser.cpp b/src/lib/IWAParser.cpp
+index 7fd95c3..a2bd292 100644
+--- a/src/lib/IWAParser.cpp
++++ b/src/lib/IWAParser.cpp
+@@ -3403,7 +3403,7 @@ bool IWAParser::parseFormula(const IWAMessage &msg, IWORKFormulaPtr_t &formula)
+ }
+ else
+ {
+- formula.reset(new IWORKFormula(0));
++ formula.reset(new IWORKFormula(boost::make_optional(0u)));
+ formula->parse(stack[0]);
+ }
+ return ok;
+--
+2.31.1
+
diff --git a/external/libetonyek/0002-fix-build-with-MSVC.patch.1 b/external/libetonyek/0002-fix-build-with-MSVC.patch.1
new file mode 100644
index 000000000..0eadb0912
--- /dev/null
+++ b/external/libetonyek/0002-fix-build-with-MSVC.patch.1
@@ -0,0 +1,55 @@
+From 7b69af66227309e9c258beca3bc3934be454a221 Mon Sep 17 00:00:00 2001
+From: David Tardon <dtardon@redhat.com>
+Date: Wed, 19 May 2021 21:11:40 +0200
+Subject: [PATCH] fix build with MSVC
+
+C:/PROGRA~2/MIB055~1/2019/COMMUN~1/VC/Tools/MSVC/1428~1.299/Include\xutility(138): error C2668: 'libetonyek::IWORKStyle::IWORKStyle': ambiguous call to overloaded function
+C:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\UnpackedTarball\libetonyek\src\lib\IWORKStyle.h(32): note: could be 'libetonyek::IWORKStyle::IWORKStyle(const libetonyek::IWORKPropertyMap &,const boost::optional<std::string> &,const libetonyek::IWORKStylePtr_t &)'
+C:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\UnpackedTarball\libetonyek\src\lib\IWORKStyle.h(31): note: or 'libetonyek::IWORKStyle::IWORKStyle(const libetonyek::IWORKPropertyMap &,const boost::optional<std::string> &,const boost::optional<std::string> &)'
+C:/PROGRA~2/MIB055~1/2019/COMMUN~1/VC/Tools/MSVC/1428~1.299/Include\xutility(137): note: while trying to match the argument list '(libetonyek::IWORKPropertyMap, const boost::none_t, _Ty)'
+ with
+ [
+ _Ty=nullptr
+ ]
+C:/PROGRA~2/MIB055~1/2019/COMMUN~1/VC/Tools/MSVC/1428~1.299/Include\memory(2186): note: see reference to function template instantiation 'void std::_Construct_in_place<_Ty,libetonyek::IWORKPropertyMap&,const boost::none_t&,nullptr>(_Ty &,libetonyek::IWORKPropertyMap &,const boost::none_t &,nullptr &&) noexcept(false)' being compiled
+ with
+ [
+ _Ty=libetonyek::IWORKStyle
+ ]
+C:/PROGRA~2/MIB055~1/2019/COMMUN~1/VC/Tools/MSVC/1428~1.299/Include\memory(2906): note: see reference to function template instantiation 'std::_Ref_count_obj2<_Ty>::_Ref_count_obj2<libetonyek::IWORKPropertyMap&,const boost::none_t&,nullptr>(libetonyek::IWORKPropertyMap &,const boost::none_t &,nullptr &&)' being compiled
+ with
+ [
+ _Ty=libetonyek::IWORKStyle
+ ]
+C:/PROGRA~2/MIB055~1/2019/COMMUN~1/VC/Tools/MSVC/1428~1.299/Include\memory(2907): note: see reference to function template instantiation 'std::_Ref_count_obj2<_Ty>::_Ref_count_obj2<libetonyek::IWORKPropertyMap&,const boost::none_t&,nullptr>(libetonyek::IWORKPropertyMap &,const boost::none_t &,nullptr &&)' being compiled
+ with
+ [
+ _Ty=libetonyek::IWORKStyle
+ ]
+C:/cygwin/home/tdf/lode/jenkins/workspace/gerrit_windows/workdir/UnpackedTarball/libetonyek/src/lib/IWAParser.cpp(2358): note: see reference to function template instantiation 'std::shared_ptr<libetonyek::IWORKStyle> std::make_shared<libetonyek::IWORKStyle,libetonyek::IWORKPropertyMap&,const boost::none_t&,nullptr>(libetonyek::IWORKPropertyMap &,const boost::none_t &,nullptr &&)' being compiled
+
+Change-Id: Idf871474b2a20f252073846388d018cccc15bc11
+---
+ src/lib/IWAParser.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/lib/IWAParser.cpp b/src/lib/IWAParser.cpp
+index a2bd292..1fdeae7 100644
+--- a/src/lib/IWAParser.cpp
++++ b/src/lib/IWAParser.cpp
+@@ -2355,10 +2355,10 @@ void IWAParser::parseAuthorInComment(unsigned id)
+ IWORKPropertyMap props;
+ // normally yellow, but blue may be better in LO
+ props.put<property::FontColor>(IWORKColor(0,0,1,1));
+- spans[0]=std::make_shared<IWORKStyle>(props, boost::none, nullptr);
++ spans[0]=std::make_shared<IWORKStyle>(props, boost::none, IWORKStylePtr_t());
+ // reset color to default, if not, comment will be blue colored
+ props.put<property::FontColor>(IWORKColor(0,0,0,1));
+- spans[unsigned(len)]=std::make_shared<IWORKStyle>(props, boost::none, nullptr);
++ spans[unsigned(len)]=std::make_shared<IWORKStyle>(props, boost::none, IWORKStylePtr_t());
+ text.setSpans(spans);
+ text.parse(*m_currentText);
+ }
+--
+2.31.1
+
diff --git a/external/libetonyek/ExternalPackage_libetonyek.mk b/external/libetonyek/ExternalPackage_libetonyek.mk
new file mode 100644
index 000000000..98d4763c8
--- /dev/null
+++ b/external/libetonyek/ExternalPackage_libetonyek.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libetonyek,libetonyek))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libetonyek,libetonyek))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,libetonyek,$(LIBO_LIB_FOLDER)/libetonyek-0.1.1.dylib,src/lib/.libs/libetonyek-0.1.1.dylib))
+else ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,libetonyek,$(LIBO_LIB_FOLDER)/libetonyek-0.1.dll,src/lib/.libs/libetonyek-0.1.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,libetonyek,$(LIBO_LIB_FOLDER)/libetonyek-0.1-lo.so.1,src/lib/.libs/libetonyek-0.1-lo.so.1.0.$(ETONYEK_VERSION_MICRO)))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libetonyek/ExternalProject_libetonyek.mk b/external/libetonyek/ExternalProject_libetonyek.mk
new file mode 100644
index 000000000..e0f2f3e08
--- /dev/null
+++ b/external/libetonyek/ExternalProject_libetonyek.mk
@@ -0,0 +1,67 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libetonyek))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libetonyek,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libetonyek,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libetonyek,\
+ boost_headers \
+ glm_headers \
+ liblangtag \
+ libxml2 \
+ mdds_headers \
+ revenge \
+ zlib \
+))
+
+$(call gb_ExternalProject_get_state_target,libetonyek,build) :
+ $(call gb_Trace_StartRange,libetonyek,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ --without-docs \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-tests \
+ --disable-werror \
+ --disable-weffc \
+ --without-tools \
+ --with-mdds=1.0 \
+ $(if $(filter WNT,$(OS_FOR_BUILD)),MKDIR_P="$(shell cygpath -m /usr/bin/mkdir) -p") \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(filter LINUX,$(OS)), \
+ 'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN') \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libetonyek)" \
+ LANGTAG_CFLAGS="$(LIBLANGTAG_CFLAGS)" \
+ LANGTAG_LIBS="$(LIBLANGTAG_LIBS)" \
+ XML_CFLAGS="$(LIBXML_CFLAGS)" \
+ XML_LIBS="$(LIBXML_LIBS)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/lib/.libs/libetonyek-0.1.1.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,libetonyek,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libetonyek/Library_etonyek.mk b/external/libetonyek/Library_etonyek.mk
new file mode 100644
index 000000000..87e21fc4b
--- /dev/null
+++ b/external/libetonyek/Library_etonyek.mk
@@ -0,0 +1,193 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,etonyek))
+
+$(eval $(call gb_Library_use_unpacked,etonyek,libetonyek))
+
+$(eval $(call gb_Library_use_externals,etonyek,\
+ boost_headers \
+ glm_headers \
+ liblangtag \
+ libxml2 \
+ mdds_headers \
+ revenge \
+ zlib \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,etonyek))
+
+$(eval $(call gb_Library_set_precompiled_header,etonyek,external/libetonyek/inc/pch/precompiled_etonyek))
+
+$(eval $(call gb_Library_set_include,etonyek,\
+ -I$(call gb_UnpackedTarball_get_dir,libetonyek)/inc \
+ -I$(call gb_UnpackedTarball_get_dir,libetonyek)/src/lib \
+ -I$(call gb_UnpackedTarball_get_dir,libetonyek)/src/lib/contexts \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,etonyek,\
+ -DBOOST_ALL_NO_LIB \
+ -DDLL_EXPORT \
+ -DLIBETONYEK_BUILD \
+ -DNDEBUG \
+))
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,etonyek,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,etonyek,\
+ UnpackedTarball/libetonyek/src/lib/EtonyekDocument \
+ UnpackedTarball/libetonyek/src/lib/IWAField \
+ UnpackedTarball/libetonyek/src/lib/IWAMessage \
+ UnpackedTarball/libetonyek/src/lib/IWAObjectIndex \
+ UnpackedTarball/libetonyek/src/lib/IWAParser \
+ UnpackedTarball/libetonyek/src/lib/IWAReader \
+ UnpackedTarball/libetonyek/src/lib/IWASnappyStream \
+ UnpackedTarball/libetonyek/src/lib/IWAText \
+ UnpackedTarball/libetonyek/src/lib/IWORKChainedTokenizer \
+ UnpackedTarball/libetonyek/src/lib/IWORKChart \
+ UnpackedTarball/libetonyek/src/lib/IWORKCollector \
+ UnpackedTarball/libetonyek/src/lib/IWORKDictionary \
+ UnpackedTarball/libetonyek/src/lib/IWORKDiscardContext \
+ UnpackedTarball/libetonyek/src/lib/IWORKDocumentInterface \
+ UnpackedTarball/libetonyek/src/lib/IWORKFormula \
+ UnpackedTarball/libetonyek/src/lib/IWORKLanguageManager \
+ UnpackedTarball/libetonyek/src/lib/IWORKMemoryStream \
+ UnpackedTarball/libetonyek/src/lib/IWORKOutputElements \
+ UnpackedTarball/libetonyek/src/lib/IWORKOutputManager \
+ UnpackedTarball/libetonyek/src/lib/IWORKParser \
+ UnpackedTarball/libetonyek/src/lib/IWORKPath \
+ UnpackedTarball/libetonyek/src/lib/IWORKPresentationRedirector \
+ UnpackedTarball/libetonyek/src/lib/IWORKProperties \
+ UnpackedTarball/libetonyek/src/lib/IWORKPropertyHandler \
+ UnpackedTarball/libetonyek/src/lib/IWORKPropertyMap \
+ UnpackedTarball/libetonyek/src/lib/IWORKRecorder \
+ UnpackedTarball/libetonyek/src/lib/IWORKShape \
+ UnpackedTarball/libetonyek/src/lib/IWORKSpreadsheetRedirector \
+ UnpackedTarball/libetonyek/src/lib/IWORKStyle \
+ UnpackedTarball/libetonyek/src/lib/IWORKStyleStack \
+ UnpackedTarball/libetonyek/src/lib/IWORKStylesheet \
+ UnpackedTarball/libetonyek/src/lib/IWORKSubDirStream \
+ UnpackedTarball/libetonyek/src/lib/IWORKTable \
+ UnpackedTarball/libetonyek/src/lib/IWORKTableRecorder \
+ UnpackedTarball/libetonyek/src/lib/IWORKText \
+ UnpackedTarball/libetonyek/src/lib/IWORKTextRecorder \
+ UnpackedTarball/libetonyek/src/lib/IWORKTextRedirector \
+ UnpackedTarball/libetonyek/src/lib/IWORKToken \
+ UnpackedTarball/libetonyek/src/lib/IWORKTokenizer \
+ UnpackedTarball/libetonyek/src/lib/IWORKTokenizerBase \
+ UnpackedTarball/libetonyek/src/lib/IWORKTransformation \
+ UnpackedTarball/libetonyek/src/lib/IWORKTypes \
+ UnpackedTarball/libetonyek/src/lib/IWORKXMLContext \
+ UnpackedTarball/libetonyek/src/lib/IWORKXMLContextBase \
+ UnpackedTarball/libetonyek/src/lib/IWORKXMLParserState \
+ UnpackedTarball/libetonyek/src/lib/IWORKZlibStream \
+ UnpackedTarball/libetonyek/src/lib/KEY1Dictionary \
+ UnpackedTarball/libetonyek/src/lib/KEY1Parser \
+ UnpackedTarball/libetonyek/src/lib/KEY1ParserState \
+ UnpackedTarball/libetonyek/src/lib/KEY1Token \
+ UnpackedTarball/libetonyek/src/lib/KEY2Dictionary \
+ UnpackedTarball/libetonyek/src/lib/KEY2Parser \
+ UnpackedTarball/libetonyek/src/lib/KEY2ParserState \
+ UnpackedTarball/libetonyek/src/lib/KEY2Token \
+ UnpackedTarball/libetonyek/src/lib/KEY6Parser \
+ UnpackedTarball/libetonyek/src/lib/KEYCollector \
+ UnpackedTarball/libetonyek/src/lib/KEYProperties \
+ UnpackedTarball/libetonyek/src/lib/KEYTypes \
+ UnpackedTarball/libetonyek/src/lib/NUM1Dictionary \
+ UnpackedTarball/libetonyek/src/lib/NUM1Parser \
+ UnpackedTarball/libetonyek/src/lib/NUM1ParserState \
+ UnpackedTarball/libetonyek/src/lib/NUM1Token \
+ UnpackedTarball/libetonyek/src/lib/NUM3Parser \
+ UnpackedTarball/libetonyek/src/lib/NUMCollector \
+ UnpackedTarball/libetonyek/src/lib/PAG1Dictionary \
+ UnpackedTarball/libetonyek/src/lib/PAG1Parser \
+ UnpackedTarball/libetonyek/src/lib/PAG1ParserState \
+ UnpackedTarball/libetonyek/src/lib/PAG1Token \
+ UnpackedTarball/libetonyek/src/lib/PAG5Parser \
+ UnpackedTarball/libetonyek/src/lib/PAGCollector \
+ UnpackedTarball/libetonyek/src/lib/PAGProperties \
+ UnpackedTarball/libetonyek/src/lib/PAGTypes \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKBezierElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKBinaryElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKBrContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKCalcEngineContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKCellCommentDrawableInfoElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKChartInfoElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKColorElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKCoreImageFilterDescriptorElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKDataElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKFieldElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKFillElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKFilteredImageElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKFormatElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKFormulaElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKGeometryElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKGroupElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKHeaderFooterContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKImageContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKImageElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKLayoutElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKLineElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKLineEndElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKLinkElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKListLabelGeometriesProperty \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKListLabelGeometryElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKListLabelIndentsProperty \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKListLabelTypeinfoElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKListLabelTypesProperty \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKListTextIndentsProperty \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKMediaElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKMetadataElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKNumberConverter \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKPElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKPathElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKPositionElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKPropertyContextBase \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKPropertyMapElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKRefContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKShapeContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKSizeElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKSpanElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKStringElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKStrokeContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKStyleContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKStyleRefContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKStylesContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKStylesheetBase \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKTabElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKTableInfoElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKTabsElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKTabularInfoElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKTabularModelElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKTextBodyElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKTextElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKTextLabelElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKTextStorageElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKUnfilteredElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/IWORKWrapElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/KEY1ContentElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/KEY1DivElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/KEY1FillElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/KEY1SpanElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/KEY1StringConverter \
+ UnpackedTarball/libetonyek/src/lib/contexts/KEY1StylesContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/KEY1TableElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/KEY2StyleContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/PAG1AnnotationContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/PAG1AnnotationElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/PAG1FootnotesElement \
+ UnpackedTarball/libetonyek/src/lib/contexts/PAG1ShapeContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/PAG1StyleContext \
+ UnpackedTarball/libetonyek/src/lib/contexts/PAG1TextStorageElement \
+ UnpackedTarball/libetonyek/src/lib/libetonyek_utils \
+ UnpackedTarball/libetonyek/src/lib/libetonyek_xml \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libetonyek/Makefile b/external/libetonyek/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libetonyek/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libetonyek/Module_libetonyek.mk b/external/libetonyek/Module_libetonyek.mk
new file mode 100644
index 000000000..94fd6ca0d
--- /dev/null
+++ b/external/libetonyek/Module_libetonyek.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libetonyek))
+
+$(eval $(call gb_Module_add_targets,libetonyek,\
+ UnpackedTarball_libetonyek \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,libetonyek,\
+ Library_etonyek \
+))
+
+else
+
+$(eval $(call gb_Module_add_targets,libetonyek,\
+ ExternalPackage_libetonyek \
+ ExternalProject_libetonyek \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libetonyek/README b/external/libetonyek/README
new file mode 100644
index 000000000..5fe625372
--- /dev/null
+++ b/external/libetonyek/README
@@ -0,0 +1,3 @@
+Library for import of Apple Keynote presentations.
+
+[https://wiki.documentfoundation.org/DLP/Libraries/libetonyek]
diff --git a/external/libetonyek/UnpackedTarball_libetonyek.mk b/external/libetonyek/UnpackedTarball_libetonyek.mk
new file mode 100644
index 000000000..81a3fa5b8
--- /dev/null
+++ b/external/libetonyek/UnpackedTarball_libetonyek.mk
@@ -0,0 +1,38 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libetonyek))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libetonyek,$(ETONYEK_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libetonyek,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libetonyek))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libetonyek,\
+ external/libetonyek/win_build.patch.1 \
+ external/libetonyek/ubsan.patch \
+ external/libetonyek/rpath.patch \
+ external/libetonyek/warnings.patch \
+ external/libetonyek/0001-fix-build-with-MSVC.patch.1 \
+ external/libetonyek/0002-fix-build-with-MSVC.patch.1 \
+ external/libetonyek/0001-allow-0-size-message.patch.1 \
+))
+
+ifneq ($(OS),MACOSX)
+ifneq ($(OS),WNT)
+ifneq ($(OS),iOS)
+$(eval $(call gb_UnpackedTarball_add_patches,libetonyek,\
+ external/libetonyek/libetonyek-bundled-soname.patch.0 \
+))
+endif
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libetonyek/inc/pch/precompiled_etonyek.cxx b/external/libetonyek/inc/pch/precompiled_etonyek.cxx
new file mode 100644
index 000000000..56f4f6a2e
--- /dev/null
+++ b/external/libetonyek/inc/pch/precompiled_etonyek.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_etonyek.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libetonyek/inc/pch/precompiled_etonyek.hxx b/external/libetonyek/inc/pch/precompiled_etonyek.hxx
new file mode 100644
index 000000000..9af8b1c25
--- /dev/null
+++ b/external/libetonyek/inc/pch/precompiled_etonyek.hxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2019-05-18 15:09:41 using:
+ ./bin/update_pch external/libetonyek etonyek --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/libetonyek/inc/pch/precompiled_etonyek.hxx "make external/libetonyek.build" --find-conflicts
+*/
+
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <cassert>
+#include <cmath>
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <deque>
+#include <functional>
+#include <iomanip>
+#include <iterator>
+#include <libetonyek_utils.h>
+#include <libetonyek_xml.h>
+#include <limits>
+#include <map>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <stack>
+#include <stdexcept>
+#include <string>
+#include <utility>
+#include <vector>
+#include <zlib.h>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/fusion/adapted/std_pair.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/fusion/include/std_pair.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/none.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/optional.hpp>
+#include <boost/spirit/include/phoenix.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/qi_attr.hpp>
+#include <boost/spirit/include/qi_lit.hpp>
+#include <boost/spirit/include/qi_optional.hpp>
+#include <boost/spirit/include/qi_parse_attr.hpp>
+#include <boost/spirit/include/qi_sequence.hpp>
+#include <boost/spirit/include/qi_symbols.hpp>
+#include <boost/variant.hpp>
+#include <boost/variant/recursive_variant.hpp>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <glm/glm.hpp>
+#include <libetonyek/libetonyek.h>
+#include <librevenge/librevenge.h>
+#include <libxml/xmlreader.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libetonyek/libetonyek-bundled-soname.patch.0 b/external/libetonyek/libetonyek-bundled-soname.patch.0
new file mode 100644
index 000000000..15a58fa83
--- /dev/null
+++ b/external/libetonyek/libetonyek-bundled-soname.patch.0
@@ -0,0 +1,11 @@
+--- src/lib/Makefile.in.orig 2016-01-12 19:21:24.000000000 +0100
++++ src/lib/Makefile.in 2016-03-02 18:19:52.214551270 +0100
+@@ -538,7 +538,7 @@
+ $(XML_CFLAGS) $(ZLIB_CFLAGS) $(DEBUG_CXXFLAGS) $(am__append_1)
+ libetonyek_@ETONYEK_MAJOR_VERSION@_@ETONYEK_MINOR_VERSION@_la_LIBADD = libetonyek_internal.la $(REVENGE_LIBS) $(LANGTAG_LIBS) $(XML_LIBS) $(ZLIB_LIBS) @LIBETONYEK_WIN32_RESOURCE@
+ libetonyek_@ETONYEK_MAJOR_VERSION@_@ETONYEK_MINOR_VERSION@_la_DEPENDENCIES = libetonyek_internal.la @LIBETONYEK_WIN32_RESOURCE@
+-libetonyek_@ETONYEK_MAJOR_VERSION@_@ETONYEK_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined
++libetonyek_@ETONYEK_MAJOR_VERSION@_@ETONYEK_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined -release lo
+ libetonyek_@ETONYEK_MAJOR_VERSION@_@ETONYEK_MINOR_VERSION@_la_SOURCES = \
+ EtonyekDocument.cpp
+
diff --git a/external/libetonyek/rpath.patch b/external/libetonyek/rpath.patch
new file mode 100644
index 000000000..3a6280597
--- /dev/null
+++ b/external/libetonyek/rpath.patch
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -14451,6 +14451,7 @@
+ esac
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+
+ lynxos*)
diff --git a/external/libetonyek/ubsan.patch b/external/libetonyek/ubsan.patch
new file mode 100644
index 000000000..260e9f33d
--- /dev/null
+++ b/external/libetonyek/ubsan.patch
@@ -0,0 +1,11 @@
+--- src/lib/libetonyek_xml.cpp
++++ src/lib/libetonyek_xml.cpp
+@@ -35,7 +35,7 @@
+ unsigned long bytesRead = 0;
+ const unsigned char *const bytes = input->read((unsigned long)len, bytesRead);
+
+- std::memcpy(buffer, bytes, static_cast<size_t>(bytesRead));
++ if (bytesRead != 0) std::memcpy(buffer, bytes, static_cast<size_t>(bytesRead));
+ return static_cast<int>(bytesRead);
+ }
+ catch (...)
diff --git a/external/libetonyek/warnings.patch b/external/libetonyek/warnings.patch
new file mode 100644
index 000000000..841d70cb6
--- /dev/null
+++ b/external/libetonyek/warnings.patch
@@ -0,0 +1,11 @@
+--- src/lib/IWORKXMLContext.cpp
++++ src/lib/IWORKXMLContext.cpp
+@@ -18,7 +18,7 @@
+ {
+ }
+
+-void IWORKXMLContext::CDATA(const char */*value*/)
++void IWORKXMLContext::CDATA(const char * /*value*/)
+ {
+ ETONYEK_DEBUG_MSG(("IWORKXMLContext::cData: find unexpected CDATA block\n"));
+ }
diff --git a/external/libetonyek/win_build.patch.1 b/external/libetonyek/win_build.patch.1
new file mode 100644
index 000000000..a357737d8
--- /dev/null
+++ b/external/libetonyek/win_build.patch.1
@@ -0,0 +1,13 @@
+Fix the windows build - fix libtool
+
+--- libetonyek/ltmain.sh.orig 2015-05-20 00:47:55.378800000 +0200
++++ libetonyek/ltmain.sh 2015-05-20 00:47:33.648000000 +0200
+@@ -3722,6 +3722,8 @@
+ sleep 2
+ done
+ fi
++ # Cygwin ar.exe does not create directories for the objects!
++ mkdir -p $f_ex_an_ar_dir/contexts
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test yes = "$lock_old_archive_extraction"; then
diff --git a/external/libexttextcat/ExternalPackage_fingerprint.mk b/external/libexttextcat/ExternalPackage_fingerprint.mk
new file mode 100644
index 000000000..15084a21b
--- /dev/null
+++ b/external/libexttextcat/ExternalPackage_fingerprint.mk
@@ -0,0 +1,194 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libexttextcat_fingerprint,libexttextcat))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,libexttextcat_fingerprint,$(LIBO_SHARE_FOLDER)/fingerprint,\
+ langclass/fpdb.conf \
+ langclass/LM/ab.lm \
+ langclass/LM/ace.lm \
+ langclass/LM/ada.lm \
+ langclass/LM/af.lm \
+ langclass/LM/ak.lm \
+ langclass/LM/alt.lm \
+ langclass/LM/am.lm \
+ langclass/LM/ar.lm \
+ langclass/LM/arn.lm \
+ langclass/LM/ast.lm \
+ langclass/LM/ay.lm \
+ langclass/LM/az-Cyrl.lm \
+ langclass/LM/az.lm \
+ langclass/LM/ban.lm \
+ langclass/LM/be.lm \
+ langclass/LM/bem.lm \
+ langclass/LM/bg.lm \
+ langclass/LM/bho.lm \
+ langclass/LM/bi.lm \
+ langclass/LM/bik.lm \
+ langclass/LM/bm.lm \
+ langclass/LM/bn.lm \
+ langclass/LM/bo.lm \
+ langclass/LM/br.lm \
+ langclass/LM/bs.lm \
+ langclass/LM/buc.lm \
+ langclass/LM/ca.lm \
+ langclass/LM/ckb.lm \
+ langclass/LM/cs.lm \
+ langclass/LM/cv.lm \
+ langclass/LM/cy.lm \
+ langclass/LM/da.lm \
+ langclass/LM/de.lm \
+ langclass/LM/dv.lm \
+ langclass/LM/dz.lm \
+ langclass/LM/ee.lm \
+ langclass/LM/el.lm \
+ langclass/LM/emk-Latn.lm \
+ langclass/LM/en.lm \
+ langclass/LM/eo.lm \
+ langclass/LM/es.lm \
+ langclass/LM/et.lm \
+ langclass/LM/eu.lm \
+ langclass/LM/fa.lm \
+ langclass/LM/fi.lm \
+ langclass/LM/fj.lm \
+ langclass/LM/fkv.lm \
+ langclass/LM/fo.lm \
+ langclass/LM/fon.lm \
+ langclass/LM/fr.lm \
+ langclass/LM/fur.lm \
+ langclass/LM/fy.lm \
+ langclass/LM/ga.lm \
+ langclass/LM/gd.lm \
+ langclass/LM/gl.lm \
+ langclass/LM/grc.lm \
+ langclass/LM/gu.lm \
+ langclass/LM/gug.lm \
+ langclass/LM/gv.lm \
+ langclass/LM/ha-NG.lm \
+ langclass/LM/haw.lm \
+ langclass/LM/he.lm \
+ langclass/LM/hi.lm \
+ langclass/LM/hil.lm \
+ langclass/LM/hr.lm \
+ langclass/LM/hsb.lm \
+ langclass/LM/ht.lm \
+ langclass/LM/hu.lm \
+ langclass/LM/hy.lm \
+ langclass/LM/ia.lm \
+ langclass/LM/id.lm \
+ langclass/LM/is.lm \
+ langclass/LM/it.lm \
+ langclass/LM/ja.lm \
+ langclass/LM/ka.lm \
+ langclass/LM/kbd.lm \
+ langclass/LM/kk.lm \
+ langclass/LM/kl.lm \
+ langclass/LM/km.lm \
+ langclass/LM/kn.lm \
+ langclass/LM/kng.lm \
+ langclass/LM/koi.lm \
+ langclass/LM/ko.lm \
+ langclass/LM/ktu.lm \
+ langclass/LM/ky.lm \
+ langclass/LM/la.lm \
+ langclass/LM/lb.lm \
+ langclass/LM/lg.lm \
+ langclass/LM/lij.lm \
+ langclass/LM/lld.lm \
+ langclass/LM/ln.lm \
+ langclass/LM/lo.lm \
+ langclass/LM/lt.lm \
+ langclass/LM/lv.lm \
+ langclass/LM/mai.lm \
+ langclass/LM/mi.lm \
+ langclass/LM/min.lm \
+ langclass/LM/mk.lm \
+ langclass/LM/ml.lm \
+ langclass/LM/mn.lm \
+ langclass/LM/mos.lm \
+ langclass/LM/mr.lm \
+ langclass/LM/ms.lm \
+ langclass/LM/mt.lm \
+ langclass/LM/my.lm \
+ langclass/LM/nb.lm \
+ langclass/LM/nds.lm \
+ langclass/LM/ne.lm \
+ langclass/LM/nio.lm \
+ langclass/LM/nl.lm \
+ langclass/LM/nn.lm \
+ langclass/LM/nr.lm \
+ langclass/LM/nso.lm \
+ langclass/LM/ny.lm \
+ langclass/LM/oc.lm \
+ langclass/LM/om.lm \
+ langclass/LM/pa.lm \
+ langclass/LM/pap.lm \
+ langclass/LM/pl.lm \
+ langclass/LM/plt.lm \
+ langclass/LM/pt.lm \
+ langclass/LM/quh.lm \
+ langclass/LM/quz.lm \
+ langclass/LM/rm.lm \
+ langclass/LM/ro.lm \
+ langclass/LM/ru.lm \
+ langclass/LM/rue.lm \
+ langclass/LM/rw.lm \
+ langclass/LM/sa.lm \
+ langclass/LM/sc.lm \
+ langclass/LM/sco.lm \
+ langclass/LM/sd.lm \
+ langclass/LM/se.lm \
+ langclass/LM/sg.lm \
+ langclass/LM/shs.lm \
+ langclass/LM/si.lm \
+ langclass/LM/sk.lm \
+ langclass/LM/sl.lm \
+ langclass/LM/so.lm \
+ langclass/LM/sq.lm \
+ langclass/LM/sr-Cyrl.lm \
+ langclass/LM/sr-Latn.lm \
+ langclass/LM/ss.lm \
+ langclass/LM/st.lm \
+ langclass/LM/sun.lm \
+ langclass/LM/sv.lm \
+ langclass/LM/swb.lm \
+ langclass/LM/sw.lm \
+ langclass/LM/ta.lm \
+ langclass/LM/tet.lm \
+ langclass/LM/tg.lm \
+ langclass/LM/th.lm \
+ langclass/LM/ti.lm \
+ langclass/LM/tk.lm \
+ langclass/LM/tl.lm \
+ langclass/LM/tn.lm \
+ langclass/LM/tpi.lm \
+ langclass/LM/tr.lm \
+ langclass/LM/ts.lm \
+ langclass/LM/tt.lm \
+ langclass/LM/ty.lm \
+ langclass/LM/tzm-Latn.lm \
+ langclass/LM/ug.lm \
+ langclass/LM/uk.lm \
+ langclass/LM/ur.lm \
+ langclass/LM/uz-Cyrl.lm \
+ langclass/LM/uz.lm \
+ langclass/LM/vec.lm \
+ langclass/LM/ve.lm \
+ langclass/LM/vep.lm \
+ langclass/LM/vi.lm \
+ langclass/LM/wa.lm \
+ langclass/LM/xh.lm \
+ langclass/LM/yi.lm \
+ langclass/LM/yo.lm \
+ langclass/LM/zh-Hans.lm \
+ langclass/LM/zh-Hant.lm \
+ langclass/LM/zu.lm \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libexttextcat/ExternalProject_libexttextcat.mk b/external/libexttextcat/ExternalProject_libexttextcat.mk
new file mode 100644
index 000000000..8adaaee75
--- /dev/null
+++ b/external/libexttextcat/ExternalProject_libexttextcat.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libexttextcat))
+
+$(eval $(call gb_ExternalProject_register_targets,libexttextcat,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,libexttextcat,build):
+ $(call gb_Trace_StartRange,libexttextcat,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure --disable-shared --with-pic \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(ENABLE_WERROR),--enable-werror,--disable-werror) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ CFLAGS="$(CFLAGS) $(gb_VISIBILITY_FLAGS) $(gb_DEBUGINFO_FLAGS) $(call gb_ExternalProject_get_build_flags,libexttextcat) \
+ $(if $(COM_IS_CLANG),-Qunused-arguments) \
+ $(if $(filter AIX,$(OS)),-D_LINUX_SOURCE_COMPAT)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libexttextcat)" \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libexttextcat,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libexttextcat/Makefile b/external/libexttextcat/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libexttextcat/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libexttextcat/Module_libexttextcat.mk b/external/libexttextcat/Module_libexttextcat.mk
new file mode 100644
index 000000000..00f73f619
--- /dev/null
+++ b/external/libexttextcat/Module_libexttextcat.mk
@@ -0,0 +1,26 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libexttextcat))
+
+$(eval $(call gb_Module_add_targets,libexttextcat,\
+ ExternalPackage_fingerprint \
+ UnpackedTarball_libexttextcat \
+))
+ifeq ($(COM),MSC)
+$(eval $(call gb_Module_add_targets,libexttextcat,\
+ StaticLibrary_libexttextcat \
+))
+else
+$(eval $(call gb_Module_add_targets,libexttextcat,\
+ ExternalProject_libexttextcat \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libexttextcat/README b/external/libexttextcat/README
new file mode 100644
index 000000000..6204e987e
--- /dev/null
+++ b/external/libexttextcat/README
@@ -0,0 +1,6 @@
+N-Gram-Based Text Categorization library
+
+This guesses the language that input text is written in. Fundamentally
+an adaptation of wiseguys libtextcat extended to be UTF-8 aware.
+
+It is hosted at: [https://wiki.documentfoundation.org/Libexttextcat]
diff --git a/external/libexttextcat/StaticLibrary_libexttextcat.mk b/external/libexttextcat/StaticLibrary_libexttextcat.mk
new file mode 100644
index 000000000..1e70f8501
--- /dev/null
+++ b/external/libexttextcat/StaticLibrary_libexttextcat.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,libexttextcat))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,libexttextcat,libexttextcat))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,libexttextcat))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,libexttextcat,\
+ UnpackedTarball/libexttextcat/src/common \
+ UnpackedTarball/libexttextcat/src/fingerprint \
+ UnpackedTarball/libexttextcat/src/textcat \
+ UnpackedTarball/libexttextcat/src/wg_mempool \
+ UnpackedTarball/libexttextcat/src/utf8misc \
+))
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libexttextcat/UnpackedTarball_libexttextcat.mk b/external/libexttextcat/UnpackedTarball_libexttextcat.mk
new file mode 100644
index 000000000..9262d425b
--- /dev/null
+++ b/external/libexttextcat/UnpackedTarball_libexttextcat.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libexttextcat))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libexttextcat,$(LIBEXTTEXTCAT_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libexttextcat))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libffi/ExternalPackage_libffi.mk b/external/libffi/ExternalPackage_libffi.mk
new file mode 100644
index 000000000..61b0a1ca4
--- /dev/null
+++ b/external/libffi/ExternalPackage_libffi.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libffi,libffi))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libffi,libffi))
+
+ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalPackage_add_files,libffi,$(LIBO_LIB_FOLDER)/python-core-$(PYTHON_VERSION)/lib, \
+ $(HOST_PLATFORM)/.libs/libffi-7.dll \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libffi/ExternalProject_libffi.mk b/external/libffi/ExternalProject_libffi.mk
new file mode 100644
index 000000000..2e60dd480
--- /dev/null
+++ b/external/libffi/ExternalProject_libffi.mk
@@ -0,0 +1,52 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libffi))
+
+$(eval $(call gb_ExternalProject_register_targets,libffi,\
+ build \
+))
+
+# set prefix so that it ends up in libffi.pc so that pkg-config in python3 works
+# For a static Windows build, change CPPFLAGS to include -D_LIB and --disable-static
+# Also remove the ExternalPackage in that case
+
+libffi_WIN_PLATFORM := $(strip \
+ $(if $(filter INTEL,$(CPUNAME)),32) \
+ $(if $(filter X86_64,$(CPUNAME)),64) \
+ $(if $(filter AARCH64,$(CPUNAME)),arm64) \
+ )
+
+$(call gb_ExternalProject_get_state_target,libffi,build):
+ $(call gb_Trace_StartRange,libffi,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export LIB="$(ILIB)" && \
+ MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --enable-option-checking=fatal \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter LINUX,$(OS)), \
+ --disable-shared \
+ CC="$(CC) -fvisibility=hidden" \
+ --with-pic \
+ --enable-portable-binary) \
+ $(if $(filter WNT,$(OS)), \
+ --disable-static \
+ CC="$(call gb_UnpackedTarball_get_dir,libffi)/msvcc.sh -m$(libffi_WIN_PLATFORM)" \
+ CXX="$(call gb_UnpackedTarball_get_dir,libffi)/msvcc.sh -m$(libffi_WIN_PLATFORM)" \
+ LD='link' \
+ CPP='cl -nologo -EP' \
+ CXXCPP='cl -nologo -EP' \
+ CPPFLAGS="-DFFI_BUILDING_DLL $(SOLARINC)") \
+ --prefix=$(call gb_UnpackedTarball_get_dir,libffi)/$(HOST_PLATFORM) \
+ --disable-docs \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libffi,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libffi/Makefile b/external/libffi/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libffi/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libffi/Module_libffi.mk b/external/libffi/Module_libffi.mk
new file mode 100644
index 000000000..ace75480a
--- /dev/null
+++ b/external/libffi/Module_libffi.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libffi))
+
+$(eval $(call gb_Module_add_targets,libffi,\
+ UnpackedTarball_libffi \
+ ExternalProject_libffi \
+ ExternalPackage_libffi \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libffi/README b/external/libffi/README
new file mode 100644
index 000000000..cdf7fa937
--- /dev/null
+++ b/external/libffi/README
@@ -0,0 +1,3 @@
+libffi is required to build CPython's ctypes module
+
+https://sourceware.org/libffi/
diff --git a/external/libffi/UnpackedTarball_libffi.mk b/external/libffi/UnpackedTarball_libffi.mk
new file mode 100644
index 000000000..5d0582329
--- /dev/null
+++ b/external/libffi/UnpackedTarball_libffi.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libffi))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libffi,$(LIBFFI_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libfreehand/ExternalProject_libfreehand.mk b/external/libfreehand/ExternalProject_libfreehand.mk
new file mode 100644
index 000000000..554017caf
--- /dev/null
+++ b/external/libfreehand/ExternalProject_libfreehand.mk
@@ -0,0 +1,49 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libfreehand))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libfreehand,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libfreehand,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libfreehand,\
+ boost_headers \
+ icu \
+ lcms2 \
+ revenge \
+ zlib \
+))
+
+$(call gb_ExternalProject_get_state_target,libfreehand,build) :
+ $(call gb_Trace_StartRange,libfreehand,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ --disable-tests \
+ --disable-tools \
+ --disable-debug \
+ --disable-werror \
+ --disable-weffc \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libfreehand)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libfreehand)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libfreehand,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libfreehand/Makefile b/external/libfreehand/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libfreehand/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libfreehand/Module_libfreehand.mk b/external/libfreehand/Module_libfreehand.mk
new file mode 100644
index 000000000..b00efd16e
--- /dev/null
+++ b/external/libfreehand/Module_libfreehand.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libfreehand))
+
+$(eval $(call gb_Module_add_targets,libfreehand,\
+ ExternalProject_libfreehand \
+ UnpackedTarball_libfreehand \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libfreehand/README b/external/libfreehand/README
new file mode 100644
index 000000000..7403eb1a0
--- /dev/null
+++ b/external/libfreehand/README
@@ -0,0 +1,3 @@
+Library for import of FreeHand drawings.
+
+[https://wiki.documentfoundation.org/DLP/Libraries/libfreehand]
diff --git a/external/libfreehand/UnpackedTarball_libfreehand.mk b/external/libfreehand/UnpackedTarball_libfreehand.mk
new file mode 100644
index 000000000..641b470e3
--- /dev/null
+++ b/external/libfreehand/UnpackedTarball_libfreehand.mk
@@ -0,0 +1,24 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libfreehand))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libfreehand,$(FREEHAND_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libfreehand))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libfreehand,0))
+
+# icu-65-api-macros-with-semicolon.patch.1
+# See http://site.icu-project.org/download/65 Migration Issues
+$(eval $(call gb_UnpackedTarball_add_patches,libfreehand,\
+ external/libfreehand/icu-65-api-macros-with-semicolon.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libfreehand/icu-65-api-macros-with-semicolon.patch.1 b/external/libfreehand/icu-65-api-macros-with-semicolon.patch.1
new file mode 100644
index 000000000..20b0af801
--- /dev/null
+++ b/external/libfreehand/icu-65-api-macros-with-semicolon.patch.1
@@ -0,0 +1,12 @@
+diff -ur libfreehand.org/src/lib/libfreehand_utils.cpp libfreehand/src/lib/libfreehand_utils.cpp
+--- libfreehand.org/src/lib/libfreehand_utils.cpp 2017-09-16 12:28:50.000000000 +0200
++++ libfreehand/src/lib/libfreehand_utils.cpp 2019-10-28 23:02:38.581354923 +0100
+@@ -162,7 +162,7 @@
+ while (j < length)
+ {
+ UChar32 c;
+- U16_NEXT(s, j, length, c)
++ U16_NEXT(s, j, length, c);
+ unsigned char outbuf[U8_MAX_LENGTH+1];
+ int i = 0;
+ U8_APPEND_UNSAFE(&outbuf[0], i, c);
diff --git a/external/libgpg-error/ExternalPackage_libgpg-error.mk b/external/libgpg-error/ExternalPackage_libgpg-error.mk
new file mode 100644
index 000000000..7ee849d23
--- /dev/null
+++ b/external/libgpg-error/ExternalPackage_libgpg-error.mk
@@ -0,0 +1,28 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libgpg-error,libgpg-error))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libgpg-error,libgpg-error))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+
+ifeq ($(OS),LINUX)
+
+$(eval $(call gb_ExternalPackage_add_file,libgpg-error,$(LIBO_LIB_FOLDER)/libgpg-error-lo.so.0,src/.libs/libgpg-error-lo.so.0.32.1))
+
+else ifeq ($(OS),MACOSX)
+
+$(eval $(call gb_ExternalPackage_add_file,libgpg-error,$(LIBO_LIB_FOLDER)/libgpg-error.0.dylib,src/.libs/libgpg-error.0.dylib))
+
+endif
+
+endif # $(DISABLE_DYNLOADING)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libgpg-error/ExternalProject_libgpg-error.mk b/external/libgpg-error/ExternalProject_libgpg-error.mk
new file mode 100644
index 000000000..055cd3cbe
--- /dev/null
+++ b/external/libgpg-error/ExternalProject_libgpg-error.mk
@@ -0,0 +1,53 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libgpg-error))
+
+$(eval $(call gb_ExternalProject_register_targets,libgpg-error,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libgpg-error,build))
+
+ifeq ($(COM),MSC)
+$(call gb_ExternalProject_get_state_target,libgpg-error,build): $(call gb_Executable_get_target_for_build,cpp)
+ $(call gb_Trace_StartRange,libgpg-error,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_WIN_GPG_cross_setup_exports) \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --enable-static \
+ --disable-shared \
+ --disable-rpath \
+ --disable-languages \
+ --disable-doc \
+ --disable-tests \
+ $(gb_WIN_GPG_platform_switches) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libgpg-error,EXTERNAL)
+else
+$(call gb_ExternalProject_get_state_target,libgpg-error,build):
+ $(call gb_Trace_StartRange,libgpg-error,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --disable-rpath \
+ --disable-languages \
+ --disable-doc \
+ CFLAGS=" $(CFLAGS) $(call gb_ExternalProject_get_build_flags,libgpg-error)" \
+ CPPFLAGS=" $(SOLARINC)" \
+ $(if $(filter MSC,$(COM)),--force_use_syscfg=true) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),--disable-shared,--disable-static) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libgpg-error,EXTERNAL)
+
+endif
+# vim: set noet sw=4 ts=4:
diff --git a/external/libgpg-error/Makefile b/external/libgpg-error/Makefile
new file mode 100644
index 000000000..569ad8a0b
--- /dev/null
+++ b/external/libgpg-error/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libgpg-error/Module_libgpg-error.mk b/external/libgpg-error/Module_libgpg-error.mk
new file mode 100644
index 000000000..0079dcba9
--- /dev/null
+++ b/external/libgpg-error/Module_libgpg-error.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libgpg-error))
+
+$(eval $(call gb_Module_add_targets,libgpg-error,\
+ ExternalProject_libgpg-error \
+ ExternalPackage_libgpg-error \
+ UnpackedTarball_libgpg-error \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libgpg-error/README b/external/libgpg-error/README
new file mode 100644
index 000000000..84288267a
--- /dev/null
+++ b/external/libgpg-error/README
@@ -0,0 +1,2 @@
+A small library that defines common error values for GnuPG components
+[https://www.gnupg.org/related_software/libgpg-error/index.html]
diff --git a/external/libgpg-error/UnpackedTarball_libgpg-error.mk b/external/libgpg-error/UnpackedTarball_libgpg-error.mk
new file mode 100644
index 000000000..72ff13069
--- /dev/null
+++ b/external/libgpg-error/UnpackedTarball_libgpg-error.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libgpg-error))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libgpg-error,$(LIBGPGERROR_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libgpg-error,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libgpg-error, \
+ $(if $(filter MSC,$(COM)),external/libgpg-error/w32-build-fixes.patch) \
+ $(if $(filter MSC,$(COM)),external/libgpg-error/w32-build-fixes-2.patch.1) \
+ $(if $(filter MSC,$(COM)),external/libgpg-error/w32-build-fixes-3.patch.1) \
+ $(if $(filter MSC,$(COM)),external/libgpg-error/w32-disable-dllinit.patch.1) \
+ external/libgpg-error/w32-build-fixes-4.patch \
+ $(if $(filter MSC,$(COM)),external/libgpg-error/w32-build-fixes-5.patch) \
+ $(if $(filter LINUX,$(OS)),external/libgpg-error/libgpgerror-bundled-soname.patch.1) \
+ external/libgpg-error/clang-cl.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libgpg-error/clang-cl.patch b/external/libgpg-error/clang-cl.patch
new file mode 100644
index 000000000..3a635c5d8
--- /dev/null
+++ b/external/libgpg-error/clang-cl.patch
@@ -0,0 +1,11 @@
+--- src/gpg-error.h.in
++++ src/gpg-error.h.in
+@@ -152,7 +152,7 @@
+ /*
+ * GCC feature test.
+ */
+-#if __GNUC__
++#ifdef __GNUC__
+ # define _GPG_ERR_GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
diff --git a/external/libgpg-error/libgpgerror-bundled-soname.patch.1 b/external/libgpg-error/libgpgerror-bundled-soname.patch.1
new file mode 100644
index 000000000..6b5c47b4c
--- /dev/null
+++ b/external/libgpg-error/libgpgerror-bundled-soname.patch.1
@@ -0,0 +1,22 @@
+--- libgpg-error/src/Makefile.in.orig 2019-01-28 14:11:10.518425440 +0100
++++ libgpg-error/src/Makefile.in 2019-01-28 14:11:16.901414229 +0100
+@@ -540,7 +540,7 @@
+ @HAVE_LD_VERSION_SCRIPT_TRUE@libgpg_error_vers_opt = -Wl,--version-script=$(srcdir)/gpg-error.vers
+ libgpg_error_la_LDFLAGS = \
+ -no-undefined $(export_symbols) $(libgpg_error_vers_opt) \
+- $(extra_ltoptions) -version-info \
++ $(extra_ltoptions) -release lo -version-info \
+ @LIBGPG_ERROR_LT_CURRENT@:@LIBGPG_ERROR_LT_REVISION@:@LIBGPG_ERROR_LT_AGE@
+
+ libgpg_error_la_SOURCES = gettext.h $(arch_sources) \
+--- libgpg-error/src/gpg-error.vers.orig 2019-01-28 14:08:11.413740011 +0100
++++ libgpg-error/src/gpg-error.vers 2019-01-28 14:08:34.172700037 +0100
+@@ -20,7 +20,7 @@
+ # visibility.h and gpg-error.def.in as well.
+
+
+-GPG_ERROR_1.0 {
++GPG_ERROR_LIBREOFFICE {
+ global:
+ gpg_strerror;
+ gpg_strerror_r;
diff --git a/external/libgpg-error/w32-build-fixes-2.patch.1 b/external/libgpg-error/w32-build-fixes-2.patch.1
new file mode 100644
index 000000000..0f8a8b36e
--- /dev/null
+++ b/external/libgpg-error/w32-build-fixes-2.patch.1
@@ -0,0 +1,31 @@
+diff -ru libgpg-error.orig/src/Makefile.in libgpg-error/src/Makefile.in
+--- libgpg-error.orig/src/Makefile.in 2017-09-12 08:18:29.376536700 +0200
++++ libgpg-error/src/Makefile.in 2017-09-12 08:57:11.648083800 +0200
+@@ -512,8 +512,7 @@
+ @HAVE_W32_SYSTEM_TRUE@arch_sources = w32-gettext.c w32-lock.c w32-lock-obj.h w32-thread.c \
+ @HAVE_W32_SYSTEM_TRUE@ w32-iconv.c w32-estream.c w32-reg.c spawn-w32.c
+
+-@HAVE_W32_SYSTEM_TRUE@RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+-@HAVE_W32_SYSTEM_TRUE@ -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS) $(CPPFLAGS)
++@HAVE_W32_SYSTEM_TRUE@RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) -DLOCALEDIR=$(localedir) $(AM_CPPFLAGS)
+
+ @HAVE_W32_SYSTEM_TRUE@LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
+ @HAVE_W32_SYSTEM_TRUE@SUFFIXES = .rc .lo
+@@ -1242,7 +1241,7 @@
+
+
+ @HAVE_W32_SYSTEM_TRUE@.rc.lo:
+-@HAVE_W32_SYSTEM_TRUE@ $(LTRCCOMPILE) -i "$<" -o "$@"
++@HAVE_W32_SYSTEM_TRUE@ $(LTRCCOMPILE) -i $< -o $@
+
+ @HAVE_W32_SYSTEM_TRUE@versioninfo.lo : gpg-error.w32-manifest
+
+@@ -1283,7 +1282,7 @@
+ # It is correct to use $(CPP). We want the host's idea of the error codes.
+ mkerrcodes.h: Makefile mkerrcodes.awk $(gpg_extra_headers)
+ $(AWK) -f $(srcdir)/mkerrcodes1.awk $(srcdir)/errnos.in >_$@
+- $(CPP) $(CPPFLAGS) $(extra_cppflags) -P _$@ | grep GPG_ERR_ | \
++ $(CPP) $(CPPFLAGS) $(extra_cppflags) _$@ | grep GPG_ERR_ | \
+ $(AWK) -f $(srcdir)/mkerrcodes.awk >$@
+ -rm _$@
+
diff --git a/external/libgpg-error/w32-build-fixes-3.patch.1 b/external/libgpg-error/w32-build-fixes-3.patch.1
new file mode 100644
index 000000000..5883211f9
--- /dev/null
+++ b/external/libgpg-error/w32-build-fixes-3.patch.1
@@ -0,0 +1,57 @@
+diff -ru libgpg-error.orig/src/gpg-error.c libgpg-error/src/gpg-error.c
+--- libgpg-error.orig/src/gpg-error.c 2016-12-02 22:55:32.000000000 +0100
++++ libgpg-error/src/gpg-error.c 2017-09-13 22:25:10.040113800 +0200
+@@ -206,7 +206,7 @@
+ static const char src_prefix[] = "GPG_ERR_SOURCE_";
+ static const char code_prefix[] = "GPG_ERR_";
+
+- if (!strncasecmp (src_prefix, str, sizeof (src_prefix) - 1))
++ if (!_strnicmp (src_prefix, str, sizeof (src_prefix) - 1))
+ {
+ gpg_err_source_t src;
+
+@@ -220,14 +220,14 @@
+ const char *src_sym;
+
+ src_sym = gpg_strsource_sym (src << GPG_ERR_SOURCE_SHIFT);
+- if (src_sym && !strcasecmp (str, src_sym + sizeof (src_prefix) - 1))
++ if (src_sym && !_stricmp (str, src_sym + sizeof (src_prefix) - 1))
+ {
+ *err |= src << GPG_ERR_SOURCE_SHIFT;
+ return 1;
+ }
+ }
+ }
+- else if (!strncasecmp (code_prefix, str, sizeof (code_prefix) - 1))
++ else if (!_strnicmp (code_prefix, str, sizeof (code_prefix) - 1))
+ {
+ gpg_err_code_t code;
+
+@@ -240,7 +240,7 @@
+ {
+ const char *code_sym = gpg_strerror_sym (code);
+ if (code_sym
+- && !strcasecmp (str, code_sym + sizeof (code_prefix) - 1))
++ && !_stricmp (str, code_sym + sizeof (code_prefix) - 1))
+ {
+ *err |= code;
+ return 1;
+@@ -296,7 +296,7 @@
+ for (src = 0; src < GPG_ERR_SOURCE_DIM; src++)
+ {
+ const char *src_str = gpg_strsource (src << GPG_ERR_SOURCE_SHIFT);
+- if (src_str && !strcasecmp (str, src_str))
++ if (src_str && !_stricmp (str, src_str))
+ {
+ if (*have_source)
+ return 0;
+@@ -310,7 +310,7 @@
+ for (code = 0; code < GPG_ERR_CODE_DIM; code++)
+ {
+ const char *code_str = gpg_strerror (code);
+- if (code_str && !strcasecmp (str, code_str))
++ if (code_str && !_stricmp (str, code_str))
+ {
+ if (*have_code)
+ return 0;
+Nur in libgpg-error/src: gpg-error.c~.
diff --git a/external/libgpg-error/w32-build-fixes-4.patch b/external/libgpg-error/w32-build-fixes-4.patch
new file mode 100644
index 000000000..1d4e052a5
--- /dev/null
+++ b/external/libgpg-error/w32-build-fixes-4.patch
@@ -0,0 +1,13 @@
+Avoid MFC dependency - can go with very basic includes instead
+
+--- src/versioninfo.rc.in~ 2017-02-28 14:48:38.000000000 +0100
++++ src/versioninfo.rc.in 2017-11-29 01:41:47.549804600 +0100
+@@ -14,8 +14,6 @@
+
+ #line __LINE__ "versioninfo.rc.in"
+
+-#include <afxres.h>
+-
+
+ VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @BUILD_FILEVERSION@
diff --git a/external/libgpg-error/w32-build-fixes-5.patch b/external/libgpg-error/w32-build-fixes-5.patch
new file mode 100644
index 000000000..4e04e47a3
--- /dev/null
+++ b/external/libgpg-error/w32-build-fixes-5.patch
@@ -0,0 +1,145 @@
+--- src/argparse.c 2021-11-03 13:44:56.000000000 +0100
++++ src/argparse.c~ 2022-01-03 17:05:23.418077200 +0100
+@@ -33,8 +33,12 @@
+ #include <stdarg.h>
+ #include <limits.h>
+ #include <errno.h>
+-#include <unistd.h>
+ #include <time.h>
++#ifdef _WIN32
++# define R_OK 04
++# define strncasecmp _strnicmp
++# define strcasecmp _stricmp
++#endif
+
+ #include "gpgrt-int.h"
+
+--- src/gpg-error.c 2020-06-06 00:18:40.199791000 +0200
++++ src/gpg-error.c~ 2020-06-05 18:44:14.223182300 +0200
+@@ -61,6 +61,11 @@
+ #define drop_locale_dir(dir)
+ #endif
+
++#ifdef _WIN32
++# define strncasecmp _strnicmp
++# define strcasecmp _stricmp
++#endif
++
+ static void
+ i18n_init (void)
+ {
+
+--- src/spawn-w32.c~ 2022-01-03 16:33:24.000000000 +0100
++++ src/spawn-w32.c 2022-01-03 16:46:57.173841200 +0100
+@@ -56,7 +56,7 @@
+ * Previous versions interpreted X_OK as F_OK anyway, so we'll just
+ * use F_OK directly. */
+ #undef X_OK
++#define X_OK 0
+-#define X_OK F_OK
+
+ /* For HANDLE and the internal file descriptor (fd) of this module:
+ * HANDLE can be represented by an intptr_t which should be true for
+
+--- src/logging.c 2020-06-05 18:58:59.254413200 +0200
++++ src/logging.c~ 2019-12-12 15:23:37.000000000 +0100
+@@ -44,7 +44,12 @@
+ # include <netinet/in.h>
+ # include <arpa/inet.h>
+ #endif /*!HAVE_W32_SYSTEM*/
++#ifdef _WIN32
++# include <io.h>
++# include <process.h>
++#else
++# include <unistd.h>
++#endif
+-#include <unistd.h>
+ #include <fcntl.h>
+ /* #include <execinfo.h> */
+
+@@ -57,6 +53,15 @@
+
+
+ #ifdef HAVE_W32_SYSTEM
++# ifndef S_IRUSR
++# define S_IRUSR _S_IREAD
++# endif
++# ifndef S_IWUSR
++# define S_IWUSR _S_IWRITE
++# endif
++# ifndef S_IXUSR
++# define S_IXUSR 0x00400000
++# endif
+ # ifndef S_IRWXG
+ # define S_IRGRP S_IRUSR
+ # define S_IWGRP S_IWUSR
+--- src/Makefile.am 2020-06-06 01:01:31.931459300 +0200
++++ src/Makefile.am~ 2020-02-06 18:39:06.000000000 +0100
+@@ -213,7 +213,7 @@
+ # without the extra_cppflags because they may include am -idirafter
+ # which is not supported by the RC compiler.
+ libgpg_error_la_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(extra_cppflags)
++libgpg_error_la_LIBADD = $(gpg_error_res) $(intllibs) $(socklibs) -ladvapi32 $(LIBTHREAD)
+-libgpg_error_la_LIBADD = $(gpg_error_res) $(intllibs) $(socklibs) $(LIBTHREAD)
+
+ gpg_error_SOURCES = strsource-sym.c strerror-sym.c gpg-error.c
+ gpg_error_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \
+--- src/Makefile.in 2020-06-06 01:01:31.931459300 +0200
++++ src/Makefile.in~ 2020-02-06 18:39:06.000000000 +0100
+@@ -659,7 +659,7 @@
+ # without the extra_cppflags because they may include am -idirafter
+ # which is not supported by the RC compiler.
+ libgpg_error_la_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(extra_cppflags)
++libgpg_error_la_LIBADD = $(gpg_error_res) $(intllibs) $(socklibs) -ladvapi32 $(LIBTHREAD)
+-libgpg_error_la_LIBADD = $(gpg_error_res) $(intllibs) $(socklibs) $(LIBTHREAD)
+ gpg_error_SOURCES = strsource-sym.c strerror-sym.c gpg-error.c
+ gpg_error_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \
+ -DLOCALEDIR=\"$(localedir)\" $(extra_cppflags)
+--- src/sysutils.c 2020-06-06 00:23:52.457265500 +0200
++++ src/sysutils.c~ 2019-12-12 15:23:37.000000000 +0100
+@@ -22,7 +22,11 @@
+ #include <stdlib.h>
+ #include <stdint.h>
+ #include <string.h>
++#ifdef _WIN32
++# include <io.h>
++#else
++# include <unistd.h>
++#endif
+-#include <unistd.h>
+ #include <errno.h>
+ #ifdef HAVE_W32_SYSTEM
+ # include <windows.h>
+--- src/visibility.c 2020-06-05 18:54:56.410442900 +0200
++++ src/visibility.c~ 2019-01-04 12:56:54.000000000 +0100
+@@ -1067,11 +1067,7 @@
+ _gpgrt_log_assert (const char *expr, const char *file,
+ int line, const char *func)
+ {
+-#ifdef GPGRT_HAVE_MACRO_FUNCTION
+ _gpgrt__log_assert (expr, file, line, func);
+-#else
+- _gpgrt__log_assert (expr, file, line);
+-#endif
+ }
+
+
+--- src/w32-add.h 2020-06-06 00:32:38.502203300 +0200
++++ src/w32-add.h~ 2018-12-07 14:48:19.000000000 +0100
+@@ -65,3 +65,5 @@
+ char *gpgrt_w32_reg_query_string (const char *root,
+ const char *dir,
+ const char *name);
++
++wchar_t *utf8_to_wchar (const char *string, size_t length, size_t *retlen);
+--- src/w32-gettext.c 2020-06-06 00:33:24.680341900 +0200
++++ src/w32-gettext.c~ 2020-06-05 18:44:14.254481700 +0200
+@@ -1355,7 +1355,7 @@
+ is not defined. If LENGTH is zero and RETLEN NULL the fucntion
+ assumes that STRING is a nul-terminated string and returns a
+ (wchar_t)0-terminated string. */
++wchar_t *
+-static wchar_t *
+ utf8_to_wchar (const char *string, size_t length, size_t *retlen)
+ {
+ int n;
diff --git a/external/libgpg-error/w32-build-fixes.patch b/external/libgpg-error/w32-build-fixes.patch
new file mode 100644
index 000000000..1de57e424
--- /dev/null
+++ b/external/libgpg-error/w32-build-fixes.patch
@@ -0,0 +1,121 @@
+diff -ur libgpg-error.org/src/estream.c libgpg-error/src/estream.c
+--- src/estream.c 2016-11-16 13:22:03.000000000 +0100
++++ src/estream.c~ 2017-02-19 17:53:15.010869000 +0100
+@@ -74,12 +74,16 @@
+ # include <sys/time.h>
+ #endif
+ #include <sys/types.h>
+-#include <sys/file.h>
++/*#include <sys/file.h>*/
+ #include <sys/stat.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <unistd.h>
++#ifdef _WIN32
++# include <io.h>
++#else
++# include <unistd.h>
++#endif
+ #include <stdarg.h>
+ #include <fcntl.h>
+ #include <errno.h>
+@@ -109,6 +113,15 @@
+
+
+ #ifdef HAVE_W32_SYSTEM
++# ifndef S_IRUSR
++# define S_IRUSR _S_IREAD
++# endif
++# ifndef S_IWUSR
++# define S_IWUSR _S_IWRITE
++# endif
++# ifndef S_IXUSR
++# define S_IXUSR 0x00400000
++# endif
+ # ifndef S_IRGRP
+ # define S_IRGRP S_IRUSR
+ # endif
+diff -ur libgpg-error.org/src/estream-printf.c libgpg-error/src/estream-printf.c
+--- src/estream-printf.c 2016-12-02 22:51:19.000000000 +0100
++++ src/estream-printf.c~ 2017-02-19 18:02:52.239383500 +0100
+@@ -85,7 +85,11 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <unistd.h>
++#ifdef _WIN32
++# include <io.h>
++#else
++# include <unistd.h>
++#endif
+ #include <stdarg.h>
+ #include <errno.h>
+ #include <stddef.h>
+--- src/mkheader.c 2016-11-16 13:22:03.000000000 +0100
++++ src/mkheader.c~ 2017-02-19 17:35:32.172009000 +0100
+@@ -16,7 +16,11 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+-#include <unistd.h>
++#ifdef _WIN32
++# include <io.h>
++#else
++# include <unistd.h>
++#endif
+
+ #define PGM "mkheader"
+
+@@ -402,12 +406,20 @@
+
+ repl_flag = !!strchr (name, '&');
+ incfname = mk_include_name (name, repl_flag? host_triplet : NULL);
++#ifdef _WIN32
++ rc = _access (incfname, 04);
++#else
+ rc = access (incfname, R_OK);
++#endif
+ if (rc && repl_flag)
+ {
+ free (incfname);
+ incfname = mk_include_name (name, host_os);
++#ifdef _WIN32
++ rc = _access (incfname, 04);
++#else
+ rc = access (incfname, R_OK);
++#endif
+ }
+ if (!rc)
+ include_file (fname, lnr, name, outf);
+diff -ur libgpg-error.org/src/w32-estream.c libgpg-error/src/w32-estream.c
+--- src/w32-estream.c 2016-11-16 13:22:03.000000000 +0100
++++ src/w32-estream.c~ 2017-02-19 17:37:35.879037500 +0100
+@@ -42,6 +42,11 @@
+
+ #include "gpgrt-int.h"
+
++#ifdef _WIN32
++/* no ssize_t in windows std headers, emulate for native build */
++typedef SSIZE_T ssize_t;
++#endif
++
+ /*
+ * In order to support es_poll on Windows, we create a proxy shim that
+ * we use as the estream I/O functions. This shim creates reader and
+--- src/spawn-w32.c 2019-08-22 12:30:38.000000000 +0200
++++ src/spawn-w32.c~ 2020-05-26 01:37:17.759077700 +0200
+@@ -34,7 +34,11 @@
+ #ifdef HAVE_SIGNAL_H
+ # include <signal.h>
+ #endif
+-#include <unistd.h>
++#ifdef _WIN32
++# include <io.h>
++#else
++# include <unistd.h>
++#endif
+ #include <fcntl.h>
+ #ifdef HAVE_STAT
+ # include <sys/stat.h>
+
diff --git a/external/libgpg-error/w32-disable-dllinit.patch.1 b/external/libgpg-error/w32-disable-dllinit.patch.1
new file mode 100644
index 000000000..96abb3bbd
--- /dev/null
+++ b/external/libgpg-error/w32-disable-dllinit.patch.1
@@ -0,0 +1,55 @@
+Disable all DLL init functions in libgpg-error, since they're
+not actually run in statically linked libs. And libtool seems
+to unconditionally set that flag on all Windows builds.
+
+diff -ur libgpg-error.org/src/init.c libgpg-error/src/init.c
+--- libgpg-error.org/src/init.c 2017-02-28 10:11:05.000000000 +0100
++++ libgpg-error/src/init.c 2017-11-23 16:44:56.850797400 +0100
+@@ -88,7 +88,7 @@
+ _gpg_err_init (void)
+ {
+ #ifdef HAVE_W32_SYSTEM
+-# ifdef DLL_EXPORT
++# ifdef HAVE_DLL_INIT
+ /* We always have a constructor and thus this function is called
+ automatically. Due to the way the C init code of mingw works,
+ the constructors are called before our DllMain function is
+@@ -130,7 +130,7 @@
+ void
+ _gpg_err_deinit (int mode)
+ {
+-#if defined (HAVE_W32_SYSTEM) && !defined(DLL_EXPORT)
++#if defined (HAVE_W32_SYSTEM) && !defined(HAVE_DLL_INIT)
+ struct tls_space_s *tls;
+
+ tls = TlsGetValue (tls_index);
+@@ -473,7 +473,7 @@
+
+
+ /* Entry point called by the DLL loader. */
+-#ifdef DLL_EXPORT
++#ifdef HAVE_DLL_INIT
+ int WINAPI
+ DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
+ {
+diff -ur libgpg-error.org/src/w32-gettext.c libgpg-error/src/w32-gettext.c
+--- libgpg-error.org/src/w32-gettext.c 2016-12-02 22:51:19.000000000 +0100
++++ libgpg-error/src/w32-gettext.c 2017-11-23 16:43:28.450453000 +0100
+@@ -1180,7 +1180,7 @@
+ DLL. If used as a static lib we can't control the process set; for
+ example it might be used with a main module which is not build with
+ mingw and thus does not know how to call the constructors. */
+-#ifdef DLL_EXPORT
++#ifdef HAVE_DLL_INIT
+ static void module_init (void) _GPG_ERR_CONSTRUCTOR;
+ #endif
+ static void
+@@ -1195,7 +1195,7 @@
+ }
+ }
+
+-#if !defined(DLL_EXPORT) || !defined(_GPG_ERR_HAVE_CONSTRUCTOR)
++#if !defined(HAVE_DLL_INIT) || !defined(_GPG_ERR_HAVE_CONSTRUCTOR)
+ void
+ _gpg_w32__init_gettext_module (void)
+ {
diff --git a/external/libjpeg-turbo/Makefile b/external/libjpeg-turbo/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libjpeg-turbo/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libjpeg-turbo/Module_libjpeg-turbo.mk b/external/libjpeg-turbo/Module_libjpeg-turbo.mk
new file mode 100644
index 000000000..29be90155
--- /dev/null
+++ b/external/libjpeg-turbo/Module_libjpeg-turbo.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libjpeg-turbo))
+
+$(eval $(call gb_Module_add_targets,libjpeg-turbo,\
+ UnpackedTarball_libjpeg-turbo \
+ StaticLibrary_libjpeg-turbo \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libjpeg-turbo/README b/external/libjpeg-turbo/README
new file mode 100644
index 000000000..46eff7cb7
--- /dev/null
+++ b/external/libjpeg-turbo/README
@@ -0,0 +1,6 @@
+External library for reading/writing jpegs
+
+This is only used by the jpeg import filter that is provided
+for use by VCL see [[vcl/source/filter/jpeg]]
+
+From [http://www.libjpeg-turbo.org/].
diff --git a/external/libjpeg-turbo/StaticLibrary_libjpeg-turbo.mk b/external/libjpeg-turbo/StaticLibrary_libjpeg-turbo.mk
new file mode 100644
index 000000000..0b6b3044d
--- /dev/null
+++ b/external/libjpeg-turbo/StaticLibrary_libjpeg-turbo.mk
@@ -0,0 +1,214 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozillarg/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,libjpeg-turbo))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,libjpeg-turbo,libjpeg-turbo))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,libjpeg-turbo))
+
+$(eval $(call gb_StaticLibrary_set_include,libjpeg-turbo,\
+ -I$(call gb_UnpackedTarball_get_dir,libjpeg-turbo) \
+ $$(INCLUDE) \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_StaticLibrary_add_cflags,libjpeg-turbo,\
+ -DHAVE_INTRIN_H=1 \
+))
+endif
+
+$(eval $(call gb_StaticLibrary_add_cflags,libjpeg-turbo,\
+ -DSIZEOF_SIZE_T=$(SIZEOF_SIZE_T) \
+))
+
+ifeq ($(COM),GCC)
+ifneq ($(ENABLE_OPTIMIZED),)
+$(eval $(call gb_StaticLibrary_add_cflags,libjpeg-turbo,\
+ -O3 \
+))
+endif
+endif
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,libjpeg-turbo,\
+ UnpackedTarball/libjpeg-turbo/jcapimin \
+ UnpackedTarball/libjpeg-turbo/jcapistd \
+ UnpackedTarball/libjpeg-turbo/jccoefct \
+ UnpackedTarball/libjpeg-turbo/jccolor \
+ UnpackedTarball/libjpeg-turbo/jcdctmgr \
+ UnpackedTarball/libjpeg-turbo/jchuff \
+ UnpackedTarball/libjpeg-turbo/jcicc \
+ UnpackedTarball/libjpeg-turbo/jcinit \
+ UnpackedTarball/libjpeg-turbo/jcmainct \
+ UnpackedTarball/libjpeg-turbo/jcmarker \
+ UnpackedTarball/libjpeg-turbo/jcmaster \
+ UnpackedTarball/libjpeg-turbo/jcomapi \
+ UnpackedTarball/libjpeg-turbo/jcparam \
+ UnpackedTarball/libjpeg-turbo/jcphuff \
+ UnpackedTarball/libjpeg-turbo/jcprepct \
+ UnpackedTarball/libjpeg-turbo/jcsample \
+ UnpackedTarball/libjpeg-turbo/jctrans \
+ UnpackedTarball/libjpeg-turbo/jdapimin \
+ UnpackedTarball/libjpeg-turbo/jdapistd \
+ UnpackedTarball/libjpeg-turbo/jdatadst \
+ UnpackedTarball/libjpeg-turbo/jdatasrc \
+ UnpackedTarball/libjpeg-turbo/jdcoefct \
+ UnpackedTarball/libjpeg-turbo/jdcolor \
+ UnpackedTarball/libjpeg-turbo/jddctmgr \
+ UnpackedTarball/libjpeg-turbo/jdhuff \
+ UnpackedTarball/libjpeg-turbo/jdicc \
+ UnpackedTarball/libjpeg-turbo/jdinput \
+ UnpackedTarball/libjpeg-turbo/jdmainct \
+ UnpackedTarball/libjpeg-turbo/jdmarker \
+ UnpackedTarball/libjpeg-turbo/jdmaster \
+ UnpackedTarball/libjpeg-turbo/jdmerge \
+ UnpackedTarball/libjpeg-turbo/jdphuff \
+ UnpackedTarball/libjpeg-turbo/jdpostct \
+ UnpackedTarball/libjpeg-turbo/jdsample \
+ UnpackedTarball/libjpeg-turbo/jdtrans \
+ UnpackedTarball/libjpeg-turbo/jerror \
+ UnpackedTarball/libjpeg-turbo/jfdctflt \
+ UnpackedTarball/libjpeg-turbo/jfdctfst \
+ UnpackedTarball/libjpeg-turbo/jfdctint \
+ UnpackedTarball/libjpeg-turbo/jidctflt \
+ UnpackedTarball/libjpeg-turbo/jidctfst \
+ UnpackedTarball/libjpeg-turbo/jidctint \
+ UnpackedTarball/libjpeg-turbo/jidctred \
+ UnpackedTarball/libjpeg-turbo/jquant1 \
+ UnpackedTarball/libjpeg-turbo/jquant2 \
+ UnpackedTarball/libjpeg-turbo/jutils \
+ UnpackedTarball/libjpeg-turbo/jmemmgr \
+ UnpackedTarball/libjpeg-turbo/jmemnobs \
+ UnpackedTarball/libjpeg-turbo/jaricom \
+ UnpackedTarball/libjpeg-turbo/jcarith \
+ UnpackedTarball/libjpeg-turbo/jdarith \
+))
+
+ifneq ($(NASM),)
+
+$(eval $(call gb_StaticLibrary_add_nasmflags,libjpeg-turbo,\
+ -I$(call gb_UnpackedTarball_get_dir,libjpeg-turbo)/simd/nasm/ \
+ -I$(dir $(call gb_UnpackedTarball_get_dir,libjpeg-turbo)/$(1)) \
+))
+
+ifeq ($(CPUNAME),X86_64)
+
+$(eval $(call gb_StaticLibrary_add_cflags,libjpeg-turbo,\
+ -DWITH_SIMD \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,libjpeg-turbo,\
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jsimd \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_nasmobjects,libjpeg-turbo,\
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jsimdcpu.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jfdctflt-sse.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jccolor-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jcgray-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jchuff-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jcphuff-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jcsample-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jdcolor-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jdmerge-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jdsample-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jfdctfst-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jfdctint-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jidctflt-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jidctfst-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jidctint-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jidctred-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jquantf-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jquanti-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jccolor-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jcgray-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jcsample-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jdcolor-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jdmerge-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jdsample-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jfdctint-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jidctint-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/x86_64/jquanti-avx2.asm \
+))
+
+else ifeq ($(CPUNAME),INTEL)
+
+$(eval $(call gb_StaticLibrary_add_cflags,libjpeg-turbo,\
+ -DWITH_SIMD \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,libjpeg-turbo,\
+ UnpackedTarball/libjpeg-turbo/simd/i386/jsimd \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_nasmobjects,libjpeg-turbo,\
+ UnpackedTarball/libjpeg-turbo/simd/i386/jsimdcpu.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jfdctflt-3dn.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctflt-3dn.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jquant-3dn.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jccolor-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jcgray-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jcsample-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jdcolor-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jdmerge-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jdsample-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jfdctfst-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jfdctint-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctfst-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctint-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctred-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jquant-mmx.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jfdctflt-sse.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctflt-sse.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jquant-sse.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jccolor-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jcgray-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jchuff-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jcphuff-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jcsample-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jdcolor-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jdmerge-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jdsample-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jfdctfst-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jfdctint-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctflt-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctfst-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctint-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctred-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jquantf-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jquanti-sse2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jccolor-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jcgray-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jcsample-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jdcolor-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jdmerge-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jdsample-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jfdctint-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jidctint-avx2.asm \
+ UnpackedTarball/libjpeg-turbo/simd/i386/jquanti-avx2.asm \
+))
+
+else
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,libjpeg-turbo,\
+ UnpackedTarball/libjpeg-turbo/jsimd_none \
+))
+
+endif
+
+else
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,libjpeg-turbo,\
+ UnpackedTarball/libjpeg-turbo/jsimd_none \
+))
+
+endif
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libjpeg-turbo/UnpackedTarball_libjpeg-turbo.mk b/external/libjpeg-turbo/UnpackedTarball_libjpeg-turbo.mk
new file mode 100644
index 000000000..22777b863
--- /dev/null
+++ b/external/libjpeg-turbo/UnpackedTarball_libjpeg-turbo.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libjpeg-turbo))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libjpeg-turbo,$(LIBJPEG_TURBO_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libjpeg-turbo,0))
+
+# jconfigint.h and jconfig.h generated via
+# cmake -DENABLE_STATIC:BOOL=ON -DENABLE_SHARED:BOOL=NO -DWITH_JAVA:BOOL=OFF -DWITH_TURBOJPEG:BOOL=OFF -DWITH_SIMD:BOOL=ON
+# and then tweaking
+
+$(eval $(call gb_UnpackedTarball_add_file,libjpeg-turbo,jconfigint.h,external/libjpeg-turbo/jconfigint.h))
+$(eval $(call gb_UnpackedTarball_add_file,libjpeg-turbo,jconfig.h,external/libjpeg-turbo/jconfig.h))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libjpeg-turbo/jconfig.h b/external/libjpeg-turbo/jconfig.h
new file mode 100644
index 000000000..7cff68812
--- /dev/null
+++ b/external/libjpeg-turbo/jconfig.h
@@ -0,0 +1,86 @@
+/* Version ID for the JPEG library.
+ * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
+ */
+#define JPEG_LIB_VERSION 62
+
+/* libjpeg-turbo version */
+#define LIBJPEG_TURBO_VERSION 2.1.1
+
+/* libjpeg-turbo version in integer form */
+#define LIBJPEG_TURBO_VERSION_NUMBER 2001001
+
+/* Support arithmetic encoding */
+#define C_ARITH_CODING_SUPPORTED 1
+
+/* Support arithmetic decoding */
+#define D_ARITH_CODING_SUPPORTED 1
+
+/* Support in-memory source/destination managers */
+#define MEM_SRCDST_SUPPORTED 1
+
+/* Use accelerated SIMD routines. */
+/* #undef WITH_SIMD */
+
+/*
+ * Define BITS_IN_JSAMPLE as either
+ * 8 for 8-bit sample values (the usual setting)
+ * 12 for 12-bit sample values
+ * Only 8 and 12 are legal data precisions for lossy JPEG according to the
+ * JPEG standard, and the IJG code does not support anything else!
+ * We do not support run-time selection of data precision, sorry.
+ */
+
+#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
+
+/* Define to 1 if you have the <locale.h> header file. */
+/* undef HAVE_LOCALE_H */
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you need to include <sys/types.h> to get size_t. */
+#define NEED_SYS_TYPES_H 1
+
+/* Define if you have BSD-like bzero and bcopy in <strings.h> rather than
+ memset/memcpy in <string.h>. */
+/* #undef NEED_BSD_STRINGS */
+
+/* Define to 1 if the system has the type `unsigned char'. */
+#define HAVE_UNSIGNED_CHAR 1
+
+/* Define to 1 if the system has the type `unsigned short'. */
+#define HAVE_UNSIGNED_SHORT 1
+
+/* Compiler does not support pointers to undefined structures. */
+/* #undef INCOMPLETE_TYPES_BROKEN */
+
+/* Define if your (broken) compiler shifts signed values as if they were
+ unsigned. */
+/* #undef RIGHT_SHIFT_IS_UNSIGNED */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Extra Libreoffice config for windows */
+#ifdef _MSC_VER
+
+/* Define "boolean" as unsigned char, not int, per Windows custom */
+#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
+typedef unsigned char boolean;
+#endif
+#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
+
+/* Define "INT32" as int, not long, per Windows custom */
+#if !(defined(_BASETSD_H_) || defined(_BASETSD_H)) /* don't conflict if basetsd.h already read */
+typedef short INT16;
+typedef signed int INT32;
+#endif
+#define XMD_H /* prevent jmorecfg.h from redefining it */
+
+#endif /* _MSC_VER */
diff --git a/external/libjpeg-turbo/jconfigint.h b/external/libjpeg-turbo/jconfigint.h
new file mode 100644
index 000000000..478a4d338
--- /dev/null
+++ b/external/libjpeg-turbo/jconfigint.h
@@ -0,0 +1,51 @@
+#include <sal/types.h>
+
+/* libjpeg-turbo build number */
+#define BUILD "20211020"
+
+/* Compiler's inline keyword */
+#undef inline
+
+/* How to obtain function inlining. */
+#if defined _MSC_VER
+#define INLINE __forceinline
+#elif defined __GNUC__
+#define INLINE __attribute__((always_inline)) inline
+#else
+#define INLINE inline
+#endif
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libjpeg-turbo"
+
+/* Version number of package */
+#define VERSION "2.1.1"
+
+/* The size of `size_t', as computed by sizeof. */
+/* #undef SIZEOF_SIZE_T */
+
+#if defined(__GNUC__) && SAL_TYPES_SIZEOFLONG == SIZEOF_SIZE_T
+/* Define if your compiler has __builtin_ctzl() and sizeof(unsigned long) == sizeof(size_t). */
+#define HAVE_BUILTIN_CTZL
+#endif
+
+/* Define to 1 if you have the <intrin.h> header file. */
+/* #undef HAVE_INTRIN_H */
+
+#if defined(_MSC_VER) && defined(HAVE_INTRIN_H)
+#if (SIZEOF_SIZE_T == 8)
+#define HAVE_BITSCANFORWARD64
+#elif (SIZEOF_SIZE_T == 4)
+#define HAVE_BITSCANFORWARD
+#endif
+#endif
+
+#if defined(__has_attribute)
+#if __has_attribute(fallthrough)
+#define FALLTHROUGH __attribute__((fallthrough));
+#else
+#define FALLTHROUGH
+#endif
+#else
+#define FALLTHROUGH
+#endif
diff --git a/external/liblangtag/ExternalPackage_liblangtag.mk b/external/liblangtag/ExternalPackage_liblangtag.mk
new file mode 100644
index 000000000..549f5eb36
--- /dev/null
+++ b/external/liblangtag/ExternalPackage_liblangtag.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,liblangtag,liblangtag))
+
+$(eval $(call gb_ExternalPackage_use_external_project,liblangtag,liblangtag))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,liblangtag,$(LIBO_LIB_FOLDER)/liblangtag.1.dylib,liblangtag/.libs/liblangtag.1.dylib))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,liblangtag,$(LIBO_LIB_FOLDER)/liblangtag-lo.so.1,liblangtag/.libs/liblangtag-lo.so.1.4.1))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liblangtag/ExternalPackage_liblangtag_data.mk b/external/liblangtag/ExternalPackage_liblangtag_data.mk
new file mode 100644
index 000000000..fee94a1b5
--- /dev/null
+++ b/external/liblangtag/ExternalPackage_liblangtag_data.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,liblangtag_data,liblangtag))
+
+$(eval $(call gb_ExternalPackage_use_external_project,liblangtag_data,liblangtag))
+
+$(eval $(call gb_ExternalPackage_add_files,liblangtag_data,$(LIBO_SHARE_FOLDER)/liblangtag,\
+ data/language-subtag-registry.xml \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,liblangtag_data,$(LIBO_SHARE_FOLDER)/liblangtag/common/bcp47,\
+ data/common/bcp47/calendar.xml \
+ data/common/bcp47/collation.xml \
+ data/common/bcp47/currency.xml \
+ data/common/bcp47/number.xml \
+ data/common/bcp47/timezone.xml \
+ data/common/bcp47/transform.xml \
+ data/common/bcp47/transform_ime.xml \
+ data/common/bcp47/transform_keyboard.xml \
+ data/common/bcp47/transform_mt.xml \
+ data/common/bcp47/transform_private_use.xml \
+ data/common/bcp47/variant.xml \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,liblangtag_data,$(LIBO_SHARE_FOLDER)/liblangtag/common/supplemental,\
+ data/common/supplemental/likelySubtags.xml \
+ data/common/supplemental/supplementalMetadata.xml \
+))
+
+# vim: set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/external/liblangtag/ExternalProject_liblangtag.mk b/external/liblangtag/ExternalProject_liblangtag.mk
new file mode 100644
index 000000000..9e2553860
--- /dev/null
+++ b/external/liblangtag/ExternalProject_liblangtag.mk
@@ -0,0 +1,54 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,liblangtag))
+
+$(eval $(call gb_ExternalProject_use_external,liblangtag,libxml2))
+
+$(eval $(call gb_ExternalProject_use_autoconf,liblangtag,build))
+
+$(eval $(call gb_ExternalProject_register_targets,liblangtag,\
+ build \
+))
+
+# disable ccache on windows, as it doesn't cope with the quoted defines
+# liblangtag uses (-DBUILDDIR="\"$(abs_top_builddir)\"" and similar).
+# Results in "cl : Command line error D8003 : missing source filename"
+$(call gb_ExternalProject_get_state_target,liblangtag,build):
+ $(call gb_Trace_StartRange,liblangtrag,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure --disable-modules --disable-test --disable-introspection --with-pic \
+ $(if $(or $(DISABLE_DYNLOADING),$(filter MSC,$(COM))), \
+ --disable-shared --enable-static, \
+ --enable-shared --disable-static) \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(filter TRUE,$(HAVE_GCC_BUILTIN_ATOMIC)),"lt_cv_has_atomic=yes","lt_cv_has_atomic=no") \
+ CFLAGS='$(CFLAGS) -pthread \
+ $(call gb_ExternalProject_get_build_flags,liblangtag)' \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),$(if $(filter WNT,$(OS)),"lt_cv_c99_vsnprintf=yes" "ac_cv_va_copy=yes","ac_cv_va_copy=no")) \
+ LIBXML2_CFLAGS="$(LIBXML_CFLAGS)" \
+ LIBXML2_LIBS="$(if $(filter WNT,$(OS)),-L$(call gb_UnpackedTarball_get_dir,libxml2)/win32/bin.msvc -llibxml2,$(LIBXML_LIBS))" \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________URELIB) \
+ $(if $(filter-out LINUX FREEBSD,$(OS)),,LDFLAGS="-Wl$(COMMA)-z$(COMMA)origin -Wl$(COMMA)-rpath,\\"\$$\$$ORIGIN) \
+ $(if $(filter-out SOLARIS,$(OS)),,LDFLAGS="-Wl$(COMMA)-z$(COMMA)origin -Wl$(COMMA)-R$(COMMA)\\"\$$\$$ORIGIN) \
+ && $(if $(filter WNT,$(OS)),\
+ REAL_CC="$(shell cygpath -w $(lastword $(filter-out -%,$(CC))))" \
+ REAL_CC_FLAGS="$(filter -%,$(CC))") \
+ $(if $(verbose),V=1) \
+ $(MAKE) \
+ LIBO_TUNNEL_LIBRARY_PATH='$(subst ','\'',$(subst $$,$$$$,$(call gb_Helper_extend_ld_path,$(call gb_UnpackedTarball_get_dir,liblangtag)/liblangtag/.libs)))' \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl URELIB \
+ $(EXTERNAL_WORKDIR)/liblangtag/.libs/liblangtag.1.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,liblangtrag,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liblangtag/Makefile b/external/liblangtag/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/liblangtag/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liblangtag/Module_liblangtag.mk b/external/liblangtag/Module_liblangtag.mk
new file mode 100644
index 000000000..dbb7dd5f1
--- /dev/null
+++ b/external/liblangtag/Module_liblangtag.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,liblangtag))
+
+$(eval $(call gb_Module_add_targets,liblangtag,\
+ UnpackedTarball_liblangtag \
+ ExternalPackage_liblangtag_data \
+ ExternalProject_liblangtag \
+))
+
+
+ifneq ($(COM),MSC)
+$(eval $(call gb_Module_add_targets,liblangtag,\
+ ExternalPackage_liblangtag \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liblangtag/README b/external/liblangtag/README
new file mode 100644
index 000000000..254e40a22
--- /dev/null
+++ b/external/liblangtag/README
@@ -0,0 +1,10 @@
+From [https://bitbucket.org/tagoh/liblangtag]. An interface for BCP47 language tags.
+
+Updated IANA Language Subtag Registry files are available as
+[https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry]
+and per convention are stored as a data/language-subtag-registry file in a
+language-subtag-registry-YYYY-MM-DD.tar.bz2 archive, with YYYY-MM-DD being the
+File-Date entry of the file, for example
+language-subtag-registry-2015-08-04.tar.bz2, and uploaded to the external
+sources repository to be included in the build of liblangtag. See download.lst
+LANGTAGREG_TARBALL and LANGTAGREG_SHA256SUM.
diff --git a/external/liblangtag/UnpackedTarball_liblangtag.mk b/external/liblangtag/UnpackedTarball_liblangtag.mk
new file mode 100644
index 000000000..16b9ea999
--- /dev/null
+++ b/external/liblangtag/UnpackedTarball_liblangtag.mk
@@ -0,0 +1,35 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,liblangtag))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,liblangtag,$(LIBLANGTAG_TARBALL),,liblangtag))
+
+$(eval $(call gb_UnpackedTarball_set_pre_action,liblangtag,\
+ $(GNUTAR) -x -j -f $(gb_UnpackedTarget_TARFILE_LOCATION)/$(LANGTAGREG_TARBALL) \
+))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,liblangtag))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,liblangtag,0))
+
+ifneq ($(OS),MACOSX)
+ifneq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,liblangtag,\
+ external/liblangtag/liblangtag-bundled-soname.patch.0 \
+))
+endif
+endif
+
+$(eval $(call gb_UnpackedTarball_add_patches,liblangtag, \
+ $(if $(SYSTEM_LIBXML),,external/liblangtag/langtag-libtool-rpath.patch.0) \
+ external/liblangtag/clang-cl.patch.0 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liblangtag/clang-cl.patch.0 b/external/liblangtag/clang-cl.patch.0
new file mode 100644
index 000000000..94348b65f
--- /dev/null
+++ b/external/liblangtag/clang-cl.patch.0
@@ -0,0 +1,41 @@
+--- liblangtag/lt-macros.h
++++ liblangtag/lt-macros.h
+@@ -120,7 +120,7 @@
+ *
+ * See the GNU C documentation for more details.
+ */
+-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
++#if (defined __GNUC__ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4))) || defined __clang__
+ # define LT_GNUC_PRINTF(format_idx, arg_idx) \
+ __attribute__((__format__ (__printf__, format_idx, arg_idx)))
+ # define LT_GNUC_UNUSED \
+@@ -136,7 +136,7 @@
+ * explicit %NULL.
+ * See the GNU C documentation for details.
+ */
+-#if __GNUC__ >= 4
++#if (defined __GNUC__ &&__GNUC__ >= 4) || defined __clang__
+ # define LT_GNUC_NULL_TERMINATED \
+ __attribute__((__sentinel__))
+ #else /* !__GNUC__ */
+@@ -220,17 +220,17 @@
+ *
+ * See the GNU C documentation for more details.
+ */
+-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
++#if defined __GNUC__ && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+ #define LT_GNUC_DEPRECATED __attribute__((__deprecated__))
+ #else
+ #define LT_GNUC_DEPRECATED
+ #endif
+-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
++#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
+ #define LT_GNUC_DEPRECATED_FOR(f) __attribute__((deprecated("Use " #f " instead")))
+ #else
+ #define LT_GNUC_DEPRECATED_FOR(f) LT_GNUC_DEPRECATED
+ #endif
+-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
++#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+ #define LT_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
diff --git a/external/liblangtag/langtag-libtool-rpath.patch.0 b/external/liblangtag/langtag-libtool-rpath.patch.0
new file mode 100644
index 000000000..368832b8b
--- /dev/null
+++ b/external/liblangtag/langtag-libtool-rpath.patch.0
@@ -0,0 +1,23 @@
+Prevent libtool from adding annoying stuff to RPATH
+
+--- configure
++++ configure
+@@ -10730,6 +10730,7 @@
+ else
+ ld_shlibs=no
+ fi
++hardcode_libdir_flag_spec=
+ ;;
+
+ netbsd*)
+--- data/Makefile.in
++++ data/Makefile.in
+@@ -859,7 +859,7 @@
+ @CROSS_COMPILING_TRUE@language-subtag-registry.xml: language-subtag-registry reg2xml.c Makefile
+ @CROSS_COMPILING_TRUE@ @echo Warning: Unable to rebuild $@ when cross-compiling
+ @CROSS_COMPILING_FALSE@@REBUILD_DATA_TRUE@language-subtag-registry.xml: language-subtag-registry reg2xml$(EXEEXT) Makefile
+-@CROSS_COMPILING_FALSE@@REBUILD_DATA_TRUE@ $(AM_V_GEN) $(builddir)/reg2xml$(EXEEXT) $(srcdir)/language-subtag-registry $@.tmp || $(builddir)/reg2xml$(EXEEXT) $(builddir)/language-subtag-registry $@.tmp; \
++@CROSS_COMPILING_FALSE@@REBUILD_DATA_TRUE@ $(AM_V_GEN) $(LIBO_TUNNEL_LIBRARY_PATH) $(builddir)/reg2xml$(EXEEXT) $(srcdir)/language-subtag-registry $@.tmp || $(LIBO_TUNNEL_LIBRARY_PATH) $(builddir)/reg2xml$(EXEEXT) $(builddir)/language-subtag-registry $@.tmp; \
+ @CROSS_COMPILING_FALSE@@REBUILD_DATA_TRUE@ head -1 $@.tmp | grep -E '^<\?xml version'>/dev/null 2>&1 && mv $@.tmp $@ || (echo "E: $@ isn't an expected result"; rm $@.tmp)
+ @CROSS_COMPILING_FALSE@@REBUILD_DATA_FALSE@language-subtag-registry.xml:
+ @CROSS_COMPILING_FALSE@@REBUILD_DATA_FALSE@ @echo Warning: the rebuild of $@ is explicitly disabled.
diff --git a/external/liblangtag/liblangtag-bundled-soname.patch.0 b/external/liblangtag/liblangtag-bundled-soname.patch.0
new file mode 100644
index 000000000..4780d7a12
--- /dev/null
+++ b/external/liblangtag/liblangtag-bundled-soname.patch.0
@@ -0,0 +1,10 @@
+--- liblangtag/Makefile.in.orig 2015-08-07 11:57:42.256742305 +0200
++++ liblangtag/Makefile.in 2015-08-07 11:58:11.818741799 +0200
+@@ -638,6 +638,7 @@
+ liblangtag_la_LDFLAGS = \
+ $(LDFLAGS) \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
++ -release lo \
+ $(NULL)
+
+ all: $(BUILT_SOURCES)
diff --git a/external/libmspub/ExternalProject_libmspub.mk b/external/libmspub/ExternalProject_libmspub.mk
new file mode 100644
index 000000000..f84e5c9b2
--- /dev/null
+++ b/external/libmspub/ExternalProject_libmspub.mk
@@ -0,0 +1,47 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libmspub))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libmspub,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libmspub,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libmspub,\
+ boost_headers \
+ icu \
+ revenge \
+ zlib \
+))
+
+$(call gb_ExternalProject_get_state_target,libmspub,build) :
+ $(call gb_Trace_StartRange,libmspub,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ --disable-tools \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-werror \
+ --disable-weffc \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libmspub)" \
+ CPPFLAGS="$(CPPFLAGS) $(ICU_UCHAR_TYPE) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libmspub)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libmspub,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmspub/Makefile b/external/libmspub/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libmspub/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmspub/Module_libmspub.mk b/external/libmspub/Module_libmspub.mk
new file mode 100644
index 000000000..81ea7e91d
--- /dev/null
+++ b/external/libmspub/Module_libmspub.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libmspub))
+
+$(eval $(call gb_Module_add_targets,libmspub,\
+ ExternalProject_libmspub \
+ UnpackedTarball_libmspub \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmspub/README b/external/libmspub/README
new file mode 100644
index 000000000..5a6625fff
--- /dev/null
+++ b/external/libmspub/README
@@ -0,0 +1,3 @@
+Library parsing the Microsoft Publisher documents.
+
+[https://wiki.documentfoundation.org/DLP/Libraries/libmspub]
diff --git a/external/libmspub/UnpackedTarball_libmspub.mk b/external/libmspub/UnpackedTarball_libmspub.mk
new file mode 100644
index 000000000..287be540d
--- /dev/null
+++ b/external/libmspub/UnpackedTarball_libmspub.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libmspub))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libmspub,$(MSPUB_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libmspub,0))
+
+# * external/libmspub/stdint.patch is upstream at <https://gerrit.libreoffice.org/#/c/73814/>
+# "missing include":
+$(eval $(call gb_UnpackedTarball_add_patches,libmspub,\
+ external/libmspub/ubsan.patch \
+ external/libmspub/stdint.patch \
+))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libmspub))
+
+ifeq ($(ANDROID_APP_ABI),armeabi-v7a)
+$(eval $(call gb_UnpackedTarball_add_patches,libmspub, \
+ external/libmspub/libmspub_android_arm.patch.1 \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmspub/libmspub_android_arm.patch.1 b/external/libmspub/libmspub_android_arm.patch.1
new file mode 100644
index 000000000..2d7d0e12c
--- /dev/null
+++ b/external/libmspub/libmspub_android_arm.patch.1
@@ -0,0 +1,12 @@
+diff -ur libmspub.org/src/lib/libmspub_utils.cpp libmspub/src/lib/libmspub_utils.cpp
+--- libmspub.org/src/lib/libmspub_utils.cpp 2018-04-07 15:13:32.041792236 +0200
++++ libmspub/src/lib/libmspub_utils.cpp 2018-04-07 15:14:08.547790739 +0200
+@@ -29,7 +29,7 @@
+ {
+ va_list args;
+ va_start(args, format);
+- std::vfprintf(stderr, format, args);
++ vfprintf(stderr, format, args);
+ va_end(args);
+ }
+
diff --git a/external/libmspub/stdint.patch b/external/libmspub/stdint.patch
new file mode 100644
index 000000000..61f1dd122
--- /dev/null
+++ b/external/libmspub/stdint.patch
@@ -0,0 +1,10 @@
+--- src/lib/MSPUBMetaData.h
++++ src/lib/MSPUBMetaData.h
+@@ -13,6 +13,7 @@
+ #include <map>
+ #include <utility>
+ #include <vector>
++#include <stdint.h>
+
+ #include <librevenge/librevenge.h>
+
diff --git a/external/libmspub/ubsan.patch b/external/libmspub/ubsan.patch
new file mode 100644
index 000000000..b58249e18
--- /dev/null
+++ b/external/libmspub/ubsan.patch
@@ -0,0 +1,12 @@
+--- src/lib/MSPUBContentChunkType.h
++++ src/lib/MSPUBContentChunkType.h
+@@ -27,7 +27,8 @@
+ CELLS = 0x63,
+ FONT = 0x6C,
+ IMAGE_2K, //these don't exist in Pub 2k3 so their value in the enum is not used.
+- IMAGE_2K_DATA
++ IMAGE_2K_DATA,
++ MSPUBContentChunkType_dummy=0xFF // MSPUBParser.cpp:2359:9: runtime error: load of value 138, which is not a valid value for type 'libmspub::MSPUBContentChunkType'
+ };
+ } // namespace libmspub
+
diff --git a/external/libmwaw/ExternalPackage_libmwaw.mk b/external/libmwaw/ExternalPackage_libmwaw.mk
new file mode 100644
index 000000000..6f3f27ccc
--- /dev/null
+++ b/external/libmwaw/ExternalPackage_libmwaw.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libmwaw,libmwaw))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libmwaw,libmwaw))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,libmwaw,$(LIBO_LIB_FOLDER)/libmwaw-0.3.3.dylib,src/lib/.libs/libmwaw-0.3.3.dylib))
+else ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,libmwaw,$(LIBO_LIB_FOLDER)/libmwaw-0.3.dll,src/lib/.libs/libmwaw-0.3.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,libmwaw,$(LIBO_LIB_FOLDER)/libmwaw-0.3-lo.so.3,src/lib/.libs/libmwaw-0.3-lo.so.3.0.$(MWAW_VERSION_MICRO)))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmwaw/ExternalProject_libmwaw.mk b/external/libmwaw/ExternalProject_libmwaw.mk
new file mode 100644
index 000000000..7a67a067f
--- /dev/null
+++ b/external/libmwaw/ExternalProject_libmwaw.mk
@@ -0,0 +1,54 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libmwaw))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libmwaw,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libmwaw,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libmwaw,\
+ revenge \
+))
+
+$(call gb_ExternalProject_get_state_target,libmwaw,build) :
+ $(call gb_Trace_StartRange,libmwaw,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ --without-docs \
+ --disable-tools \
+ --disable-zip \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ --disable-werror \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libmwaw)" \
+ $(if $(filter LINUX,$(OS)),$(if $(SYSTEM_REVENGE),, \
+ 'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN')) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ && (cd $(EXTERNAL_WORKDIR)/src/lib && \
+ $(MAKE)) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/lib/.libs/libmwaw-0.3.3.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,libmwaw,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmwaw/Library_mwaw.mk b/external/libmwaw/Library_mwaw.mk
new file mode 100644
index 000000000..58d433f9d
--- /dev/null
+++ b/external/libmwaw/Library_mwaw.mk
@@ -0,0 +1,223 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,mwaw))
+
+$(eval $(call gb_Library_use_unpacked,mwaw,libmwaw))
+
+$(eval $(call gb_Library_use_externals,mwaw,\
+ revenge \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,mwaw))
+
+$(eval $(call gb_Library_set_precompiled_header,mwaw,external/libmwaw/inc/pch/precompiled_mwaw))
+
+$(eval $(call gb_Library_set_include,mwaw,\
+ -I$(call gb_UnpackedTarball_get_dir,libmwaw)/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,mwaw,\
+ -DBUILD_MWAW \
+ -DNDEBUG \
+ -D_WINDLL \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,mwaw,\
+ UnpackedTarball/libmwaw/src/lib/ActaParser \
+ UnpackedTarball/libmwaw/src/lib/ActaText \
+ UnpackedTarball/libmwaw/src/lib/ApplePictParser \
+ UnpackedTarball/libmwaw/src/lib/BeagleWksBMParser \
+ UnpackedTarball/libmwaw/src/lib/BeagleWksDBParser \
+ UnpackedTarball/libmwaw/src/lib/BeagleWksDRParser \
+ UnpackedTarball/libmwaw/src/lib/BeagleWksParser \
+ UnpackedTarball/libmwaw/src/lib/BeagleWksSSParser \
+ UnpackedTarball/libmwaw/src/lib/BeagleWksStructManager \
+ UnpackedTarball/libmwaw/src/lib/BeagleWksText \
+ UnpackedTarball/libmwaw/src/lib/Canvas5BMParser \
+ UnpackedTarball/libmwaw/src/lib/Canvas5Graph \
+ UnpackedTarball/libmwaw/src/lib/Canvas5Image \
+ UnpackedTarball/libmwaw/src/lib/Canvas5Parser \
+ UnpackedTarball/libmwaw/src/lib/Canvas5Structure \
+ UnpackedTarball/libmwaw/src/lib/Canvas5StyleManager \
+ UnpackedTarball/libmwaw/src/lib/CanvasGraph \
+ UnpackedTarball/libmwaw/src/lib/CanvasParser \
+ UnpackedTarball/libmwaw/src/lib/CanvasStyleManager \
+ UnpackedTarball/libmwaw/src/lib/ClarisDrawGraph \
+ UnpackedTarball/libmwaw/src/lib/ClarisDrawParser \
+ UnpackedTarball/libmwaw/src/lib/ClarisDrawStyleManager \
+ UnpackedTarball/libmwaw/src/lib/ClarisDrawText \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksBMParser \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksDatabase \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksDbaseContent \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksDocument \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksGraph \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksPRParser \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksParser \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksPresentation \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksSSParser \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksSpreadsheet \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksStruct \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksStyleManager \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksTable \
+ UnpackedTarball/libmwaw/src/lib/ClarisWksText \
+ UnpackedTarball/libmwaw/src/lib/CorelPainterParser \
+ UnpackedTarball/libmwaw/src/lib/CricketDrawParser \
+ UnpackedTarball/libmwaw/src/lib/DocMkrParser \
+ UnpackedTarball/libmwaw/src/lib/DocMkrText \
+ UnpackedTarball/libmwaw/src/lib/DrawTableParser \
+ UnpackedTarball/libmwaw/src/lib/EDocParser \
+ UnpackedTarball/libmwaw/src/lib/FreeHandParser \
+ UnpackedTarball/libmwaw/src/lib/FullWrtGraph \
+ UnpackedTarball/libmwaw/src/lib/FullWrtParser \
+ UnpackedTarball/libmwaw/src/lib/FullWrtStruct \
+ UnpackedTarball/libmwaw/src/lib/FullWrtText \
+ UnpackedTarball/libmwaw/src/lib/GreatWksBMParser \
+ UnpackedTarball/libmwaw/src/lib/GreatWksDBParser \
+ UnpackedTarball/libmwaw/src/lib/GreatWksDRParser \
+ UnpackedTarball/libmwaw/src/lib/GreatWksDocument \
+ UnpackedTarball/libmwaw/src/lib/GreatWksGraph \
+ UnpackedTarball/libmwaw/src/lib/GreatWksParser \
+ UnpackedTarball/libmwaw/src/lib/GreatWksSSParser \
+ UnpackedTarball/libmwaw/src/lib/GreatWksText \
+ UnpackedTarball/libmwaw/src/lib/HanMacWrdJGraph \
+ UnpackedTarball/libmwaw/src/lib/HanMacWrdJParser \
+ UnpackedTarball/libmwaw/src/lib/HanMacWrdJText \
+ UnpackedTarball/libmwaw/src/lib/HanMacWrdKGraph \
+ UnpackedTarball/libmwaw/src/lib/HanMacWrdKParser \
+ UnpackedTarball/libmwaw/src/lib/HanMacWrdKText \
+ UnpackedTarball/libmwaw/src/lib/JazzSSParser \
+ UnpackedTarball/libmwaw/src/lib/JazzWriterParser \
+ UnpackedTarball/libmwaw/src/lib/LightWayTxtGraph \
+ UnpackedTarball/libmwaw/src/lib/LightWayTxtParser \
+ UnpackedTarball/libmwaw/src/lib/LightWayTxtText \
+ UnpackedTarball/libmwaw/src/lib/MWAWCell \
+ UnpackedTarball/libmwaw/src/lib/MWAWChart \
+ UnpackedTarball/libmwaw/src/lib/MWAWDebug \
+ UnpackedTarball/libmwaw/src/lib/MWAWDocument \
+ UnpackedTarball/libmwaw/src/lib/MWAWEntry \
+ UnpackedTarball/libmwaw/src/lib/MWAWFont \
+ UnpackedTarball/libmwaw/src/lib/MWAWFontConverter \
+ UnpackedTarball/libmwaw/src/lib/MWAWFontSJISConverter \
+ UnpackedTarball/libmwaw/src/lib/MWAWGraphicDecoder \
+ UnpackedTarball/libmwaw/src/lib/MWAWGraphicEncoder \
+ UnpackedTarball/libmwaw/src/lib/MWAWGraphicListener \
+ UnpackedTarball/libmwaw/src/lib/MWAWGraphicShape \
+ UnpackedTarball/libmwaw/src/lib/MWAWGraphicStyle \
+ UnpackedTarball/libmwaw/src/lib/MWAWHeader \
+ UnpackedTarball/libmwaw/src/lib/MWAWInputStream \
+ UnpackedTarball/libmwaw/src/lib/MWAWList \
+ UnpackedTarball/libmwaw/src/lib/MWAWListener \
+ UnpackedTarball/libmwaw/src/lib/MWAWOLEParser \
+ UnpackedTarball/libmwaw/src/lib/MWAWPageSpan \
+ UnpackedTarball/libmwaw/src/lib/MWAWParagraph \
+ UnpackedTarball/libmwaw/src/lib/MWAWParser \
+ UnpackedTarball/libmwaw/src/lib/MWAWPict \
+ UnpackedTarball/libmwaw/src/lib/MWAWPictBitmap \
+ UnpackedTarball/libmwaw/src/lib/MWAWPictData \
+ UnpackedTarball/libmwaw/src/lib/MWAWPictMac \
+ UnpackedTarball/libmwaw/src/lib/MWAWPosition \
+ UnpackedTarball/libmwaw/src/lib/MWAWPresentationListener \
+ UnpackedTarball/libmwaw/src/lib/MWAWPrinter \
+ UnpackedTarball/libmwaw/src/lib/MWAWPropertyHandler \
+ UnpackedTarball/libmwaw/src/lib/MWAWRSRCParser \
+ UnpackedTarball/libmwaw/src/lib/MWAWSection \
+ UnpackedTarball/libmwaw/src/lib/MWAWSpreadsheetDecoder \
+ UnpackedTarball/libmwaw/src/lib/MWAWSpreadsheetEncoder \
+ UnpackedTarball/libmwaw/src/lib/MWAWSpreadsheetListener \
+ UnpackedTarball/libmwaw/src/lib/MWAWStream \
+ UnpackedTarball/libmwaw/src/lib/MWAWStringStream \
+ UnpackedTarball/libmwaw/src/lib/MWAWSubDocument \
+ UnpackedTarball/libmwaw/src/lib/MWAWTable \
+ UnpackedTarball/libmwaw/src/lib/MWAWTextListener \
+ UnpackedTarball/libmwaw/src/lib/MacDocParser \
+ UnpackedTarball/libmwaw/src/lib/MacDraft5Parser \
+ UnpackedTarball/libmwaw/src/lib/MacDraft5StyleManager \
+ UnpackedTarball/libmwaw/src/lib/MacDraftParser \
+ UnpackedTarball/libmwaw/src/lib/MacDrawParser \
+ UnpackedTarball/libmwaw/src/lib/MacDrawProParser \
+ UnpackedTarball/libmwaw/src/lib/MacDrawProStyleManager \
+ UnpackedTarball/libmwaw/src/lib/MacPaintParser \
+ UnpackedTarball/libmwaw/src/lib/MacWrtParser \
+ UnpackedTarball/libmwaw/src/lib/MacWrtProParser \
+ UnpackedTarball/libmwaw/src/lib/MacWrtProStructures \
+ UnpackedTarball/libmwaw/src/lib/MaxWrtParser \
+ UnpackedTarball/libmwaw/src/lib/MarinerWrtGraph \
+ UnpackedTarball/libmwaw/src/lib/MarinerWrtParser \
+ UnpackedTarball/libmwaw/src/lib/MarinerWrtText \
+ UnpackedTarball/libmwaw/src/lib/MindWrtParser \
+ UnpackedTarball/libmwaw/src/lib/MoreParser \
+ UnpackedTarball/libmwaw/src/lib/MoreText \
+ UnpackedTarball/libmwaw/src/lib/MouseWrtParser \
+ UnpackedTarball/libmwaw/src/lib/MsWks3Text \
+ UnpackedTarball/libmwaw/src/lib/MsWks4Text \
+ UnpackedTarball/libmwaw/src/lib/MsWks4Zone \
+ UnpackedTarball/libmwaw/src/lib/MsWksDBParser \
+ UnpackedTarball/libmwaw/src/lib/MsWksDRParser \
+ UnpackedTarball/libmwaw/src/lib/MsWksDocument \
+ UnpackedTarball/libmwaw/src/lib/MsWksGraph \
+ UnpackedTarball/libmwaw/src/lib/MsWksParser \
+ UnpackedTarball/libmwaw/src/lib/MsWksSSParser \
+ UnpackedTarball/libmwaw/src/lib/MsWksTable \
+ UnpackedTarball/libmwaw/src/lib/MsWrd1Parser \
+ UnpackedTarball/libmwaw/src/lib/MsWrdParser \
+ UnpackedTarball/libmwaw/src/lib/MsWrdStruct \
+ UnpackedTarball/libmwaw/src/lib/MsWrdText \
+ UnpackedTarball/libmwaw/src/lib/MsWrdTextStyles \
+ UnpackedTarball/libmwaw/src/lib/MultiplanParser \
+ UnpackedTarball/libmwaw/src/lib/NisusWrtGraph \
+ UnpackedTarball/libmwaw/src/lib/NisusWrtParser \
+ UnpackedTarball/libmwaw/src/lib/NisusWrtStruct \
+ UnpackedTarball/libmwaw/src/lib/NisusWrtText \
+ UnpackedTarball/libmwaw/src/lib/PixelPaintParser \
+ UnpackedTarball/libmwaw/src/lib/PowerPoint1Parser \
+ UnpackedTarball/libmwaw/src/lib/PowerPoint3OLE \
+ UnpackedTarball/libmwaw/src/lib/PowerPoint3Parser \
+ UnpackedTarball/libmwaw/src/lib/PowerPoint7Graph \
+ UnpackedTarball/libmwaw/src/lib/PowerPoint7Parser \
+ UnpackedTarball/libmwaw/src/lib/PowerPoint7Struct \
+ UnpackedTarball/libmwaw/src/lib/PowerPoint7Text \
+ UnpackedTarball/libmwaw/src/lib/RagTime5Chart \
+ UnpackedTarball/libmwaw/src/lib/RagTime5ClusterManager \
+ UnpackedTarball/libmwaw/src/lib/RagTime5Document \
+ UnpackedTarball/libmwaw/src/lib/RagTime5Formula \
+ UnpackedTarball/libmwaw/src/lib/RagTime5Graph \
+ UnpackedTarball/libmwaw/src/lib/RagTime5Layout \
+ UnpackedTarball/libmwaw/src/lib/RagTime5Parser \
+ UnpackedTarball/libmwaw/src/lib/RagTime5Pipeline \
+ UnpackedTarball/libmwaw/src/lib/RagTime5SSParser \
+ UnpackedTarball/libmwaw/src/lib/RagTime5Spreadsheet \
+ UnpackedTarball/libmwaw/src/lib/RagTime5StructManager \
+ UnpackedTarball/libmwaw/src/lib/RagTime5StyleManager \
+ UnpackedTarball/libmwaw/src/lib/RagTime5Text \
+ UnpackedTarball/libmwaw/src/lib/RagTimeParser \
+ UnpackedTarball/libmwaw/src/lib/RagTimeSpreadsheet \
+ UnpackedTarball/libmwaw/src/lib/RagTimeStruct \
+ UnpackedTarball/libmwaw/src/lib/RagTimeText \
+ UnpackedTarball/libmwaw/src/lib/ReadySetGoParser \
+ UnpackedTarball/libmwaw/src/lib/ScoopParser \
+ UnpackedTarball/libmwaw/src/lib/ScriptWriterParser \
+ UnpackedTarball/libmwaw/src/lib/StudentWritingCParser \
+ UnpackedTarball/libmwaw/src/lib/StyleParser \
+ UnpackedTarball/libmwaw/src/lib/SuperPaintParser \
+ UnpackedTarball/libmwaw/src/lib/TeachTxtParser \
+ UnpackedTarball/libmwaw/src/lib/WingzGraph \
+ UnpackedTarball/libmwaw/src/lib/WingzParser \
+ UnpackedTarball/libmwaw/src/lib/WordMakerParser \
+ UnpackedTarball/libmwaw/src/lib/WriteNowEntry \
+ UnpackedTarball/libmwaw/src/lib/WriteNowParser \
+ UnpackedTarball/libmwaw/src/lib/WriteNowText \
+ UnpackedTarball/libmwaw/src/lib/WriterPlsParser \
+ UnpackedTarball/libmwaw/src/lib/ZWrtParser \
+ UnpackedTarball/libmwaw/src/lib/ZWrtText \
+ UnpackedTarball/libmwaw/src/lib/libmwaw_internal \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmwaw/Makefile b/external/libmwaw/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libmwaw/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmwaw/Module_libmwaw.mk b/external/libmwaw/Module_libmwaw.mk
new file mode 100644
index 000000000..272ec01b4
--- /dev/null
+++ b/external/libmwaw/Module_libmwaw.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libmwaw))
+
+$(eval $(call gb_Module_add_targets,libmwaw,\
+ UnpackedTarball_libmwaw \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,libmwaw,\
+ Library_mwaw \
+))
+
+else
+
+$(eval $(call gb_Module_add_targets,libmwaw,\
+ ExternalPackage_libmwaw \
+ ExternalProject_libmwaw \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmwaw/README b/external/libmwaw/README
new file mode 100644
index 000000000..c10d26bb5
--- /dev/null
+++ b/external/libmwaw/README
@@ -0,0 +1,3 @@
+Library parsing different document file formats used on old Mac OS.
+
+https://sourceforge.net/projects/libmwaw/
diff --git a/external/libmwaw/UnpackedTarball_libmwaw.mk b/external/libmwaw/UnpackedTarball_libmwaw.mk
new file mode 100644
index 000000000..935cbc1eb
--- /dev/null
+++ b/external/libmwaw/UnpackedTarball_libmwaw.mk
@@ -0,0 +1,32 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libmwaw))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libmwaw,$(MWAW_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libmwaw,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libmwaw))
+
+ifneq ($(OS),MACOSX)
+ifneq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,libmwaw, \
+ external/libmwaw/libmwaw-bundled-soname.patch.0 \
+))
+endif
+endif
+
+ifeq ($(SYSTEM_REVENGE),)
+$(eval $(call gb_UnpackedTarball_add_patches,libmwaw, \
+ external/libmwaw/rpath.patch \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libmwaw/inc/pch/precompiled_mwaw.cxx b/external/libmwaw/inc/pch/precompiled_mwaw.cxx
new file mode 100644
index 000000000..b72c8e728
--- /dev/null
+++ b/external/libmwaw/inc/pch/precompiled_mwaw.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_mwaw.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libmwaw/inc/pch/precompiled_mwaw.hxx b/external/libmwaw/inc/pch/precompiled_mwaw.hxx
new file mode 100644
index 000000000..939d664dd
--- /dev/null
+++ b/external/libmwaw/inc/pch/precompiled_mwaw.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2020-04-25 20:55:00 using:
+ ./bin/update_pch external/libmwaw mwaw --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/libmwaw/inc/pch/precompiled_mwaw.hxx "make external/libmwaw.build" --find-conflicts
+*/
+
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <cctype>
+#include <cmath>
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <ctype.h>
+#include <iomanip>
+#include <iostream>
+#include <limits>
+#include <locale.h>
+#include <map>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <stack>
+#include <string.h>
+#include <string>
+#include <time.h>
+#include <utility>
+#include <vector>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <libmwaw/libmwaw.hxx>
+#include <librevenge-stream/librevenge-stream.h>
+#include <librevenge/librevenge.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libmwaw/libmwaw-bundled-soname.patch.0 b/external/libmwaw/libmwaw-bundled-soname.patch.0
new file mode 100644
index 000000000..31f5c75cb
--- /dev/null
+++ b/external/libmwaw/libmwaw-bundled-soname.patch.0
@@ -0,0 +1,14 @@
+--- src/lib/Makefile.in.orig 2015-08-07 14:04:47.646611627 +0200
++++ src/lib/Makefile.in 2015-08-07 14:25:49.888589996 +0200
+@@ -418,8 +418,8 @@
+ AM_CXXFLAGS = -I$(top_srcdir)/inc $(REVENGE_CFLAGS) $(DEBUG_CXXFLAGS) \
+ $(ZLIB_CFLAGS) $(am__append_1)
+ libmwaw_@MWAW_MAJOR_VERSION@_@MWAW_MINOR_VERSION@_la_LIBADD = $(REVENGE_LIBS) $(ZLIB_LIBS) @LIBMWAW_WIN32_RESOURCE@
+-libmwaw_@MWAW_MAJOR_VERSION@_@MWAW_MINOR_VERSION@_la_DEPENDENCIES = @LIBMWAW_WIN32_RESOURCE@
+-libmwaw_@MWAW_MAJOR_VERSION@_@MWAW_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined
++libmwaw_@MWAW_MAJOR_VERSION@_@MWAW_MINOR_VERSION@_la_DEPENDENCIES = @LIBMWAW_WIN32_RESOURCE@
++libmwaw_@MWAW_MAJOR_VERSION@_@MWAW_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined -release lo
+ libmwaw_@MWAW_MAJOR_VERSION@_@MWAW_MINOR_VERSION@_la_SOURCES = \
+ libmwaw_internal.cxx \
+ libmwaw_internal.hxx \
+
diff --git a/external/libmwaw/rpath.patch b/external/libmwaw/rpath.patch
new file mode 100644
index 000000000..a73d8ae22
--- /dev/null
+++ b/external/libmwaw/rpath.patch
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -15353,6 +15353,7 @@
+ esac
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+
+ lynxos*)
diff --git a/external/libnumbertext/ExternalPackage_numbertext.mk b/external/libnumbertext/ExternalPackage_numbertext.mk
new file mode 100644
index 000000000..0116627b8
--- /dev/null
+++ b/external/libnumbertext/ExternalPackage_numbertext.mk
@@ -0,0 +1,66 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libnumbertext_numbertext,libnumbertext))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,libnumbertext_numbertext,$(LIBO_SHARE_FOLDER)/numbertext,\
+ data/af.sor \
+ data/bg.sor \
+ data/ca.sor \
+ data/cs.sor \
+ data/da.sor \
+ data/de.sor \
+ data/el.sor \
+ data/en.sor \
+ data/eo.sor \
+ data/es.sor \
+ data/et.sor \
+ data/fa.sor \
+ data/fi.sor \
+ data/fr.sor \
+ data/fr.sor \
+ data/ga.sor \
+ data/gl.sor \
+ data/he.sor \
+ data/hr.sor \
+ data/hu.sor \
+ data/hu_Hung.sor \
+ data/id.sor \
+ data/is.sor \
+ data/it.sor \
+ data/ja.sor \
+ data/ko.sor \
+ data/lb.sor \
+ data/lg.sor \
+ data/lt.sor \
+ data/lv.sor \
+ data/mr.sor \
+ data/ms.sor \
+ data/mt.sor \
+ data/no.sor \
+ data/nl.sor \
+ data/pl.sor \
+ data/pt.sor \
+ data/Roman.sor \
+ data/ro.sor \
+ data/ru.sor \
+ data/sh.sor \
+ data/sl.sor \
+ data/sq.sor \
+ data/sr.sor \
+ data/Suzhou.sor \
+ data/sv.sor \
+ data/th.sor \
+ data/tr.sor \
+ data/uk.sor \
+ data/vi.sor \
+ data/zh.sor \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libnumbertext/ExternalProject_libnumbertext.mk b/external/libnumbertext/ExternalProject_libnumbertext.mk
new file mode 100644
index 000000000..bd96b162d
--- /dev/null
+++ b/external/libnumbertext/ExternalProject_libnumbertext.mk
@@ -0,0 +1,41 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libnumbertext))
+
+$(eval $(call gb_ExternalProject_use_externals,libnumbertext, \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,libnumbertext,\
+ build \
+))
+
+libnumbertext_CXXFLAGS=$(CXXFLAGS) $(CXXFLAGS_CXX11) $(gb_EMSCRIPTEN_CXXFLAGS)
+
+libnumbertext_CPPFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG) $(gb_EMSCRIPTEN_CPPFLAGS)
+
+$(call gb_ExternalProject_get_state_target,libnumbertext,build):
+ $(call gb_Trace_StartRange,libnumbertext,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ LIBS="$(gb_STDLIBS) $(LIBS)" \
+ $(SHELL) $(gb_RUN_CONFIGURE) ./configure --disable-shared --with-pic \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(ENABLE_WERROR),--enable-werror,--disable-werror) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter AIX,$(OS)),CFLAGS="-D_LINUX_SOURCE_COMPAT") \
+ $(if $(libnumbertext_CPPFLAGS),CPPFLAGS='$(libnumbertext_CPPFLAGS)') \
+ CXXFLAGS="$(libnumbertext_CXXFLAGS) \
+ $(call gb_ExternalProject_get_build_flags,libnumbertext) \
+ $(gb_VISIBILITY_FLAGS) $(gb_VISIBILITY_FLAGS_CXX)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libnumbertext)" \
+ && cd src && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libnumbertext,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libnumbertext/MSVCNonBMPBug.patch1 b/external/libnumbertext/MSVCNonBMPBug.patch1
new file mode 100644
index 000000000..8ced22165
--- /dev/null
+++ b/external/libnumbertext/MSVCNonBMPBug.patch1
@@ -0,0 +1,69 @@
+MSVC's std::codecvt_utf8 has a bug converting non-BMP codepoints like U+10CFA.
+Use MultiByteToWideChar/WideCharToMultiByte instead on Windows.
+
+diff --git a/src/Numbertext.cxx b/src/Numbertext.cxx
+index 5f05b48579af..eb83e59f366f 100755
+--- a/src/Numbertext.cxx
++++ b/src/Numbertext.cxx
+@@ -7,6 +7,10 @@
+ #include <sstream>
+ #include <fstream>
+
++#ifdef _WIN32
++#include <Windows.h>
++#endif
++
+ #include "Numbertext.hxx"
+
+ #ifdef NUMBERTEXT_BOOST
+@@ -22,6 +26,14 @@
+
+ bool readfile(const std::string& filename, std::wstring& result)
+ {
++#ifdef _WIN32
++ std::ifstream ifs(filename);
++ if (ifs.fail())
++ return false;
++ std::stringstream ss;
++ ss << ifs.rdbuf();
++ result = Numbertext::string2wstring(ss.str());
++#else
+ std::wifstream wif(filename);
+ if (wif.fail())
+ return false;
+@@ -29,6 +44,7 @@ bool readfile(const std::string& filename, std::wstring& result)
+ std::wstringstream wss;
+ wss << wif.rdbuf();
+ result = wss.str();
++#endif
+ return true;
+ }
+
+@@ -99,7 +112,12 @@
+
+ std::wstring Numbertext::string2wstring(const std::string& s)
+ {
+-#ifndef NUMBERTEXT_BOOST
++#ifdef _WIN32
++ int nSize = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0);
++ std::unique_ptr<wchar_t[]> wstr(new wchar_t[nSize]);
++ MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, wstr.get(), nSize);
++ return wstr.get();
++#elif !defined NUMBERTEXT_BOOST
+ typedef std::codecvt_utf8<wchar_t> convert_type;
+ std::wstring_convert<convert_type, wchar_t> converter;
+ return converter.from_bytes( s );
+@@ -110,7 +128,12 @@
+
+ std::string Numbertext::wstring2string(const std::wstring& s)
+ {
+-#ifndef NUMBERTEXT_BOOST
++#ifdef _WIN32
++ int nSize = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, nullptr, 0, nullptr, nullptr);
++ std::unique_ptr<char[]> str(new char[nSize]);
++ WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, str.get(), nSize, nullptr, nullptr);
++ return str.get();
++#elif !defined NUMBERTEXT_BOOST
+ typedef std::codecvt_utf8<wchar_t> convert_type;
+ std::wstring_convert<convert_type, wchar_t> converter;
+ return converter.to_bytes( s );
diff --git a/external/libnumbertext/Makefile b/external/libnumbertext/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libnumbertext/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libnumbertext/Module_libnumbertext.mk b/external/libnumbertext/Module_libnumbertext.mk
new file mode 100644
index 000000000..a48583e43
--- /dev/null
+++ b/external/libnumbertext/Module_libnumbertext.mk
@@ -0,0 +1,28 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libnumbertext))
+
+$(eval $(call gb_Module_add_targets,libnumbertext,\
+ ExternalPackage_numbertext \
+ UnpackedTarball_libnumbertext \
+))
+ifeq ($(COM),MSC)
+$(eval $(call gb_Module_add_targets,libnumbertext,\
+ StaticLibrary_libnumbertext \
+))
+else
+
+$(eval $(call gb_Module_add_targets,libnumbertext,\
+ ExternalProject_libnumbertext \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libnumbertext/README b/external/libnumbertext/README
new file mode 100644
index 000000000..922f19df1
--- /dev/null
+++ b/external/libnumbertext/README
@@ -0,0 +1,3 @@
+Number to Number Name Conversion Library
+
+It is hosted at: [https://github.com/Numbertext/libnumbertext]
diff --git a/external/libnumbertext/StaticLibrary_libnumbertext.mk b/external/libnumbertext/StaticLibrary_libnumbertext.mk
new file mode 100644
index 000000000..78b384a55
--- /dev/null
+++ b/external/libnumbertext/StaticLibrary_libnumbertext.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,libnumbertext))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,libnumbertext,libnumbertext))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,libnumbertext))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,libnumbertext,\
+ UnpackedTarball/libnumbertext/src/Soros \
+ UnpackedTarball/libnumbertext/src/Numbertext \
+))
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libnumbertext/UnpackedTarball_libnumbertext.mk b/external/libnumbertext/UnpackedTarball_libnumbertext.mk
new file mode 100644
index 000000000..48cd2a9a2
--- /dev/null
+++ b/external/libnumbertext/UnpackedTarball_libnumbertext.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libnumbertext))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libnumbertext,$(LIBNUMBERTEXT_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libnumbertext))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libnumbertext,1))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libnumbertext, \
+ external/libnumbertext/MSVCNonBMPBug.patch1 \
+ external/libnumbertext/WinUnicodePath.patch1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libnumbertext/WinUnicodePath.patch1 b/external/libnumbertext/WinUnicodePath.patch1
new file mode 100644
index 000000000..24a0bd580
--- /dev/null
+++ b/external/libnumbertext/WinUnicodePath.patch1
@@ -0,0 +1,20 @@
+To allow opening files on Unicode paths on Windpws, expect passed 8-bit
+strings to be UTF-8-encoded, and convert them to wchar_t. Fallback to
+ACP strings for backward compatibility.
+
+diff --git a/src/Numbertext.cxx b/src/Numbertext.cxx
+--- a/src/Numbertext.cxx
++++ b/src/Numbertext.cxx
+@@ -27,7 +27,11 @@
+ bool readfile(const std::string& filename, std::wstring& result)
+ {
+ #ifdef _WIN32
+- std::ifstream ifs(filename);
++ // First try to convert from UTF-8
++ std::ifstream ifs(Numbertext::string2wstring(filename));
++ // Fallback to ACP string for backward compatibility
++ if (ifs.fail())
++ ifs.open(filename);
+ if (ifs.fail())
+ return false;
+ std::stringstream ss;
diff --git a/external/libodfgen/ExternalPackage_libodfgen.mk b/external/libodfgen/ExternalPackage_libodfgen.mk
new file mode 100644
index 000000000..f2df2a623
--- /dev/null
+++ b/external/libodfgen/ExternalPackage_libodfgen.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libodfgen,libodfgen))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libodfgen,libodfgen))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,libodfgen,$(LIBO_LIB_FOLDER)/libodfgen-0.1.1.dylib,src/.libs/libodfgen-0.1.1.dylib))
+else ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,libodfgen,$(LIBO_LIB_FOLDER)/libodfgen-0.1.dll,src/.libs/libodfgen-0.1.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,libodfgen,$(LIBO_LIB_FOLDER)/libodfgen-0.1-lo.so.1,src/.libs/libodfgen-0.1-lo.so.1.0.$(ODFGEN_VERSION_MICRO)))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libodfgen/ExternalProject_libodfgen.mk b/external/libodfgen/ExternalProject_libodfgen.mk
new file mode 100644
index 000000000..c3df917c0
--- /dev/null
+++ b/external/libodfgen/ExternalProject_libodfgen.mk
@@ -0,0 +1,56 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libodfgen))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libodfgen,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libodfgen,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libodfgen,\
+ libxml2 \
+ revenge \
+))
+
+$(call gb_ExternalProject_get_state_target,libodfgen,build) :
+ $(call gb_Trace_StartRange,libodfgen,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-werror \
+ --disable-weffc \
+ --without-docs \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libodfgen)" \
+ CPPFLAGS="$(CPPFLAGS) $(if $(SYSTEM_REVENGE),,$(if $(filter-out MSC,$(COM)),-DLIBREVENGE_VISIBILITY))" \
+ XML_CFLAGS="$(LIBXML_CFLAGS)" \
+ XML_LIBS="$(LIBXML_LIBS)" \
+ $(if $(filter LINUX,$(OS)),$(if $(SYSTEM_REVENGE),, \
+ 'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN')) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/.libs/libodfgen-0.1.1.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,libodfgen,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libodfgen/Library_odfgen.mk b/external/libodfgen/Library_odfgen.mk
new file mode 100644
index 000000000..b67f5ad89
--- /dev/null
+++ b/external/libodfgen/Library_odfgen.mk
@@ -0,0 +1,57 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,odfgen))
+
+$(eval $(call gb_Library_use_unpacked,odfgen,libodfgen))
+
+$(eval $(call gb_Library_use_externals,odfgen,\
+ libxml2 \
+ revenge \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,odfgen))
+
+$(eval $(call gb_Library_set_include,odfgen,\
+ -I$(call gb_UnpackedTarball_get_dir,libodfgen)/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,odfgen,\
+ -DDLL_EXPORT \
+ -DLIBODFGEN_BUILD \
+ -DNDEBUG \
+ -DPACKAGE=\"libodfgen\" \
+ -DVERSION=\"0.1.$(ODFGEN_VERSION_MICRO)\" \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,odfgen,\
+ UnpackedTarball/libodfgen/src/DocumentElement \
+ UnpackedTarball/libodfgen/src/FillManager \
+ UnpackedTarball/libodfgen/src/FilterInternal \
+ UnpackedTarball/libodfgen/src/FontStyle \
+ UnpackedTarball/libodfgen/src/GraphicFunctions \
+ UnpackedTarball/libodfgen/src/GraphicStyle \
+ UnpackedTarball/libodfgen/src/InternalHandler \
+ UnpackedTarball/libodfgen/src/ListStyle \
+ UnpackedTarball/libodfgen/src/NumberingStyle \
+ UnpackedTarball/libodfgen/src/OdcGenerator \
+ UnpackedTarball/libodfgen/src/OdfGenerator \
+ UnpackedTarball/libodfgen/src/OdgGenerator \
+ UnpackedTarball/libodfgen/src/OdpGenerator \
+ UnpackedTarball/libodfgen/src/OdsGenerator \
+ UnpackedTarball/libodfgen/src/OdtGenerator \
+ UnpackedTarball/libodfgen/src/PageSpan \
+ UnpackedTarball/libodfgen/src/SectionStyle \
+ UnpackedTarball/libodfgen/src/SheetStyle \
+ UnpackedTarball/libodfgen/src/TableStyle \
+ UnpackedTarball/libodfgen/src/TextRunStyle \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libodfgen/Makefile b/external/libodfgen/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libodfgen/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libodfgen/Module_libodfgen.mk b/external/libodfgen/Module_libodfgen.mk
new file mode 100644
index 000000000..c10727402
--- /dev/null
+++ b/external/libodfgen/Module_libodfgen.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libodfgen))
+
+$(eval $(call gb_Module_add_targets,libodfgen,\
+ UnpackedTarball_libodfgen \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,libodfgen,\
+ Library_odfgen \
+))
+
+else
+
+$(eval $(call gb_Module_add_targets,libodfgen,\
+ ExternalPackage_libodfgen \
+ ExternalProject_libodfgen \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libodfgen/README b/external/libodfgen/README
new file mode 100644
index 000000000..01454e0d9
--- /dev/null
+++ b/external/libodfgen/README
@@ -0,0 +1 @@
+From [https://sourceforge.net/p/libwpd/wiki/libodfgen/]. Library to generate ODT and ODG documents from librevenge API calls.
diff --git a/external/libodfgen/UnpackedTarball_libodfgen.mk b/external/libodfgen/UnpackedTarball_libodfgen.mk
new file mode 100644
index 000000000..c9790e103
--- /dev/null
+++ b/external/libodfgen/UnpackedTarball_libodfgen.mk
@@ -0,0 +1,39 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libodfgen))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libodfgen,$(ODFGEN_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libodfgen,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libodfgen))
+
+# * external/libodfgen/ellipticalarc.patch reported upstream as
+# <https://sourceforge.net/p/libwpd/mailman/message/37329517/> "[Libwpd-devel] [PATCH] Avoid
+# division by zero for empty elliptical arc":
+$(eval $(call gb_UnpackedTarball_add_patches,libodfgen, \
+ external/libodfgen/ellipticalarc.patch \
+))
+
+ifeq ($(SYSTEM_REVENGE),)
+$(eval $(call gb_UnpackedTarball_add_patches,libodfgen, \
+ external/libodfgen/rpath.patch \
+))
+endif
+
+ifneq ($(OS),MACOSX)
+ifneq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,libodfgen, \
+ external/libodfgen/libodfgen-bundled-soname.patch.0 \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libodfgen/ellipticalarc.patch b/external/libodfgen/ellipticalarc.patch
new file mode 100644
index 000000000..27aaee77c
--- /dev/null
+++ b/external/libodfgen/ellipticalarc.patch
@@ -0,0 +1,13 @@
+--- src/GraphicFunctions.cxx
++++ src/GraphicFunctions.cxx
+@@ -59,6 +59,10 @@
+ double rx, double ry, double phi, bool largeArc, bool sweep, double x, double y,
+ double &xmin, double &ymin, double &xmax, double &ymax)
+ {
++ if (x0 == x && y0 == y) {
++ return;
++ }
++
+ phi *= M_PI/180;
+ if (rx < 0.0)
+ rx *= -1.0;
diff --git a/external/libodfgen/libodfgen-bundled-soname.patch.0 b/external/libodfgen/libodfgen-bundled-soname.patch.0
new file mode 100644
index 000000000..d012fe3a8
--- /dev/null
+++ b/external/libodfgen/libodfgen-bundled-soname.patch.0
@@ -0,0 +1,13 @@
+-*- Mode: Diff -*-
+diff -urN src/Makefile.in.orig src/Makefile.in
+--- src/Makefile.in.orig 2016-03-02 17:17:02.812606210 +0100
++++ src/Makefile.in 2016-03-02 17:17:25.176670151 +0100
+@@ -355,7 +355,7 @@
+ $(XML_CFLAGS) -DLIBODFGEN_BUILD $(am__append_1)
+ libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_LIBADD = @LIBODFGEN_WIN32_RESOURCE@ $(REVENGE_LIBS) $(XML_LIBS)
+ libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_DEPENDENCIES = @LIBODFGEN_WIN32_RESOURCE@
+-libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined
++libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined -release lo
+ libodfgen_@LIBODFGEN_MAJOR_VERSION@_@LIBODFGEN_MINOR_VERSION@_la_SOURCES = \
+ DocumentElement.cxx \
+ DocumentElement.hxx \
diff --git a/external/libodfgen/rpath.patch b/external/libodfgen/rpath.patch
new file mode 100644
index 000000000..698cf5dca
--- /dev/null
+++ b/external/libodfgen/rpath.patch
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -13940,6 +13940,7 @@
+ esac
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+
+ lynxos*)
diff --git a/external/liborcus/ExternalPackage_liborcus.mk b/external/liborcus/ExternalPackage_liborcus.mk
new file mode 100644
index 000000000..13d61a8fe
--- /dev/null
+++ b/external/liborcus/ExternalPackage_liborcus.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,liborcus,liborcus))
+
+$(eval $(call gb_ExternalPackage_use_external_project,liborcus,liborcus))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,liborcus,$(LIBO_LIB_FOLDER)/liborcus-0.17.0.dylib,src/liborcus/.libs/liborcus-0.17.0.dylib))
+$(eval $(call gb_ExternalPackage_add_file,liborcus,$(LIBO_LIB_FOLDER)/liborcus-parser-0.17.0.dylib,src/parser/.libs/liborcus-parser-0.17.0.dylib))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,liborcus,$(LIBO_LIB_FOLDER)/liborcus-0.17.so.0,src/liborcus/.libs/liborcus-0.17.so.0.0.0))
+$(eval $(call gb_ExternalPackage_add_file,liborcus,$(LIBO_LIB_FOLDER)/liborcus-parser-0.17.so.0,src/parser/.libs/liborcus-parser-0.17.so.0.0.0))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liborcus/ExternalProject_liborcus.mk b/external/liborcus/ExternalProject_liborcus.mk
new file mode 100644
index 000000000..e7f929a28
--- /dev/null
+++ b/external/liborcus/ExternalProject_liborcus.mk
@@ -0,0 +1,122 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,liborcus))
+
+$(eval $(call gb_ExternalProject_use_autoconf,liborcus,build))
+
+$(eval $(call gb_ExternalProject_use_externals,liborcus, \
+ boost_headers \
+ boost_filesystem \
+ boost_iostreams \
+ boost_system \
+ mdds_headers \
+ zlib \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,liborcus,\
+ build \
+))
+
+# Must be built with debug GNU C++ library if --enable-dbgutil has
+# caused the LO code to be built thus.
+
+# The LIBS setting for Android is needed to get the orcus-xml-dump
+# executable to build successfully. We obviously don't actually need
+# that executable on Android, but we don't want to bother with
+# patching out building it for Android.
+
+#$(if $(filter MSC,$(COM)),CPPFLAGS+="-DBOOST_ALL_NO_LIB") CXXFLAGS+="$(BOOST_CXXFLAGS))
+
+liborcus_LIBS=
+ifneq ($(SYSTEM_ZLIB),)
+liborcus_LIBS+=-lz
+endif
+ifneq ($(SYSTEM_BOOST),)
+liborcus_LIBS+=$(BOOST_SYSTEM_LIB) $(BOOST_IOSTREAMS_LIB) $(BOOST_FILESYSTEM_LIB)
+else
+liborcus_LIBS+=-L$(gb_StaticLibrary_WORKDIR) -lboost_system -lboost_iostreams -lboost_filesystem
+endif
+ifeq ($(OS),ANDROID)
+liborcus_LIBS+=$(gb_STDLIBS)
+endif
+
+liborcus_CPPCLAGS=$(CPPFLAGS)
+ifeq ($(SYSTEM_ZLIB),)
+liborcus_CPPFLAGS+=$(ZLIB_CFLAGS)
+endif
+#
+# OSes that use the GNU C++ library need to use -D_GLIBCXX_DEBUG in
+# sync with the rest of LibreOffice, i.e. depending on
+# --enable-dbgutil. Note that although Android doesn't use the GNU C
+# library (glibc), the NDK does offer the GNU C++ library as one of
+# the C++ libraries available, and we use it.
+#
+liborcus_CPPFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG)
+
+liborcus_CXXFLAGS=$(CXXFLAGS) $(gb_VISIBILITY_FLAGS) $(gb_VISIBILITY_FLAGS_CXX) $(CXXFLAGS_CXX11) -DBOOST_SYSTEM_NO_DEPRECATED
+liborcus_LDFLAGS=$(LDFLAGS) $(gb_LTOFLAGS)
+liborcus_CXXFLAGS+=$(call gb_ExternalProject_get_build_flags,liborcus)
+liborcus_LDFLAGS+=$(call gb_ExternalProject_get_link_flags,liborcus)
+ifeq ($(COM),MSC)
+liborcus_CXXFLAGS+=$(BOOST_CXXFLAGS)
+endif
+ifeq ($(SYSTEM_BOOST),)
+liborcus_CXXFLAGS+=${BOOST_CPPFLAGS}
+else
+liborcus_LDFLAGS+=$(BOOST_LDFLAGS)
+endif
+ifneq (,$(PTHREAD_LIBS))
+liborcus_LDFLAGS+=$(PTHREAD_LIBS)
+endif
+
+ifeq ($(OS),LINUX)
+liborcus_LDFLAGS+=-Wl,-z,origin -Wl,-rpath,\$$$$ORIGIN
+endif
+
+$(call gb_ExternalProject_get_state_target,liborcus,build) :
+ $(call gb_Trace_StartRange,liborcus,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(if $(liborcus_LIBS),LIBS='$(liborcus_LIBS)') \
+ $(if $(liborcus_CXXFLAGS),CXXFLAGS='$(liborcus_CXXFLAGS)') \
+ $(if $(liborcus_CPPFLAGS),CPPFLAGS='$(liborcus_CPPFLAGS) $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_EXCEPT)') \
+ $(if $(liborcus_LDFLAGS),LDFLAGS='$(liborcus_LDFLAGS) $(gb_EMSCRIPTEN_EXCEPT)') \
+ MDDS_CFLAGS='$(MDDS_CFLAGS)' \
+ MDDS_LIBS=' ' \
+ MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-spreadsheet-model \
+ --without-tools \
+ --disable-python \
+ --disable-werror \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(SYSTEM_BOOST),,\
+ --with-boost=$(WORKDIR)/UnpackedTarball/boost \
+ boost_cv_lib_iostreams=yes \
+ boost_cv_lib_system=yes \
+ boost_cv_lib_filesystem=yes \
+ ) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(if $(verbose),V=1) \
+ $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/liborcus/.libs/liborcus-0.17.0.dylib \
+ $(EXTERNAL_WORKDIR)/src/parser/.libs/liborcus-parser-0.17.0.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,liborcus,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liborcus/Library_orcus-parser.mk b/external/liborcus/Library_orcus-parser.mk
new file mode 100644
index 000000000..f26657756
--- /dev/null
+++ b/external/liborcus/Library_orcus-parser.mk
@@ -0,0 +1,73 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,orcus-parser))
+
+$(eval $(call gb_Library_use_unpacked,orcus-parser,liborcus))
+
+$(eval $(call gb_Library_use_externals,orcus-parser,\
+ boost_headers \
+ boost_filesystem \
+ boost_system \
+ mdds_headers \
+ zlib \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,orcus-parser))
+
+$(eval $(call gb_Library_set_precompiled_header,orcus-parser,external/liborcus/inc/pch/precompiled_orcus-parser))
+
+$(eval $(call gb_Library_set_include,orcus-parser,\
+ -I$(call gb_UnpackedTarball_get_dir,liborcus)/include \
+ -I$(call gb_UnpackedTarball_get_dir,liborcus)/src/include \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,orcus-parser,\
+ -DBOOST_ALL_NO_LIB \
+ -D__ORCUS_PSR_BUILDING_DLL \
+))
+
+# Needed when building against MSVC in C++17 mode, as
+# workdir/UnpackedTarball/liborcus/include/orcus/global.hpp uses std::unary_function:
+$(eval $(call gb_Library_add_defs,orcus-parser, \
+ -D_HAS_AUTO_PTR_ETC=1 \
+))
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,orcus-parser,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,orcus-parser,\
+ UnpackedTarball/liborcus/src/parser/base64 \
+ UnpackedTarball/liborcus/src/parser/cell_buffer \
+ UnpackedTarball/liborcus/src/parser/css_parser_base \
+ UnpackedTarball/liborcus/src/parser/css_types \
+ UnpackedTarball/liborcus/src/parser/csv_parser_base \
+ UnpackedTarball/liborcus/src/parser/exception \
+ UnpackedTarball/liborcus/src/parser/json_global \
+ UnpackedTarball/liborcus/src/parser/json_parser_base \
+ UnpackedTarball/liborcus/src/parser/json_parser_thread \
+ UnpackedTarball/liborcus/src/parser/parser_base \
+ UnpackedTarball/liborcus/src/parser/parser_global \
+ UnpackedTarball/liborcus/src/parser/pstring \
+ UnpackedTarball/liborcus/src/parser/sax_parser_base \
+ UnpackedTarball/liborcus/src/parser/sax_token_parser \
+ UnpackedTarball/liborcus/src/parser/sax_token_parser_thread \
+ UnpackedTarball/liborcus/src/parser/stream \
+ UnpackedTarball/liborcus/src/parser/string_pool \
+ UnpackedTarball/liborcus/src/parser/tokens \
+ UnpackedTarball/liborcus/src/parser/types \
+ UnpackedTarball/liborcus/src/parser/utf8 \
+ UnpackedTarball/liborcus/src/parser/xml_namespace \
+ UnpackedTarball/liborcus/src/parser/xml_writer \
+ UnpackedTarball/liborcus/src/parser/yaml_parser_base \
+ UnpackedTarball/liborcus/src/parser/zip_archive \
+ UnpackedTarball/liborcus/src/parser/zip_archive_stream \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liborcus/Library_orcus.mk b/external/liborcus/Library_orcus.mk
new file mode 100644
index 000000000..3c318797a
--- /dev/null
+++ b/external/liborcus/Library_orcus.mk
@@ -0,0 +1,148 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,orcus))
+
+$(eval $(call gb_Library_use_unpacked,orcus,liborcus))
+
+$(eval $(call gb_Library_use_externals,orcus,\
+ boost_headers \
+ boost_filesystem \
+ boost_iostreams \
+ boost_system \
+ mdds_headers \
+ zlib \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,orcus))
+
+$(eval $(call gb_Library_set_precompiled_header,orcus,external/liborcus/inc/pch/precompiled_orcus))
+
+$(eval $(call gb_Library_set_include,orcus,\
+ -I$(call gb_UnpackedTarball_get_dir,liborcus)/include \
+ -I$(call gb_UnpackedTarball_get_dir,liborcus)/src/include \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,orcus,\
+ -DBOOST_ALL_NO_LIB \
+ -D__ORCUS_BUILDING_DLL \
+ -D__ORCUS_GNUMERIC \
+ -D__ORCUS_ODS \
+ -D__ORCUS_XLSX \
+ -D__ORCUS_XLS_XML \
+))
+
+# Needed when building against MSVC in C++17 mode, as
+# workdir/UnpackedTarball/liborcus/src/liborcus/css_document_tree.cpp uses std::unary_function:
+$(eval $(call gb_Library_add_defs,orcus, \
+ -D_HAS_AUTO_PTR_ETC=1 \
+))
+
+$(eval $(call gb_Library_use_libraries,orcus,\
+ orcus-parser \
+))
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,orcus,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,orcus,\
+ UnpackedTarball/liborcus/src/liborcus/config \
+ UnpackedTarball/liborcus/src/liborcus/css_document_tree \
+ UnpackedTarball/liborcus/src/liborcus/css_selector \
+ UnpackedTarball/liborcus/src/liborcus/detection_result \
+ UnpackedTarball/liborcus/src/liborcus/dom_tree \
+ UnpackedTarball/liborcus/src/liborcus/format_detection \
+ UnpackedTarball/liborcus/src/liborcus/formula_result \
+ UnpackedTarball/liborcus/src/liborcus/global \
+ UnpackedTarball/liborcus/src/liborcus/gnumeric_cell_context \
+ UnpackedTarball/liborcus/src/liborcus/gnumeric_context \
+ UnpackedTarball/liborcus/src/liborcus/gnumeric_detection_handler \
+ UnpackedTarball/liborcus/src/liborcus/gnumeric_handler \
+ UnpackedTarball/liborcus/src/liborcus/gnumeric_helper \
+ UnpackedTarball/liborcus/src/liborcus/gnumeric_namespace_types \
+ UnpackedTarball/liborcus/src/liborcus/gnumeric_sheet_context \
+ UnpackedTarball/liborcus/src/liborcus/gnumeric_tokens \
+ UnpackedTarball/liborcus/src/liborcus/info \
+ UnpackedTarball/liborcus/src/liborcus/interface \
+ UnpackedTarball/liborcus/src/liborcus/json_document_tree \
+ UnpackedTarball/liborcus/src/liborcus/json_map_tree \
+ UnpackedTarball/liborcus/src/liborcus/json_structure_mapper \
+ UnpackedTarball/liborcus/src/liborcus/json_structure_tree \
+ UnpackedTarball/liborcus/src/liborcus/json_util \
+ UnpackedTarball/liborcus/src/liborcus/measurement \
+ UnpackedTarball/liborcus/src/liborcus/odf_helper \
+ UnpackedTarball/liborcus/src/liborcus/odf_namespace_types \
+ UnpackedTarball/liborcus/src/liborcus/odf_number_formatting_context \
+ UnpackedTarball/liborcus/src/liborcus/odf_para_context \
+ UnpackedTarball/liborcus/src/liborcus/odf_styles \
+ UnpackedTarball/liborcus/src/liborcus/odf_styles_context \
+ UnpackedTarball/liborcus/src/liborcus/odf_tokens \
+ UnpackedTarball/liborcus/src/liborcus/ods_content_xml_context \
+ UnpackedTarball/liborcus/src/liborcus/ods_content_xml_handler \
+ UnpackedTarball/liborcus/src/liborcus/ods_dde_links_context \
+ UnpackedTarball/liborcus/src/liborcus/ods_session_data \
+ UnpackedTarball/liborcus/src/liborcus/ooxml_content_types \
+ UnpackedTarball/liborcus/src/liborcus/ooxml_global \
+ UnpackedTarball/liborcus/src/liborcus/ooxml_namespace_types \
+ UnpackedTarball/liborcus/src/liborcus/ooxml_schemas \
+ UnpackedTarball/liborcus/src/liborcus/ooxml_tokens \
+ UnpackedTarball/liborcus/src/liborcus/ooxml_types \
+ UnpackedTarball/liborcus/src/liborcus/opc_context \
+ UnpackedTarball/liborcus/src/liborcus/opc_reader \
+ UnpackedTarball/liborcus/src/liborcus/orcus_csv \
+ UnpackedTarball/liborcus/src/liborcus/orcus_gnumeric \
+ UnpackedTarball/liborcus/src/liborcus/orcus_import_ods \
+ UnpackedTarball/liborcus/src/liborcus/orcus_import_xlsx \
+ UnpackedTarball/liborcus/src/liborcus/orcus_json \
+ UnpackedTarball/liborcus/src/liborcus/orcus_ods \
+ UnpackedTarball/liborcus/src/liborcus/orcus_xls_xml \
+ UnpackedTarball/liborcus/src/liborcus/orcus_xlsx \
+ UnpackedTarball/liborcus/src/liborcus/orcus_xml \
+ UnpackedTarball/liborcus/src/liborcus/orcus_xml_impl \
+ UnpackedTarball/liborcus/src/liborcus/orcus_xml_map_def \
+ UnpackedTarball/liborcus/src/liborcus/session_context \
+ UnpackedTarball/liborcus/src/liborcus/spreadsheet_iface_util \
+ UnpackedTarball/liborcus/src/liborcus/spreadsheet_impl_types \
+ UnpackedTarball/liborcus/src/liborcus/spreadsheet_interface \
+ UnpackedTarball/liborcus/src/liborcus/spreadsheet_types \
+ UnpackedTarball/liborcus/src/liborcus/string_helper \
+ UnpackedTarball/liborcus/src/liborcus/xls_xml_context \
+ UnpackedTarball/liborcus/src/liborcus/xls_xml_detection_handler \
+ UnpackedTarball/liborcus/src/liborcus/xls_xml_handler \
+ UnpackedTarball/liborcus/src/liborcus/xls_xml_namespace_types \
+ UnpackedTarball/liborcus/src/liborcus/xls_xml_tokens \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_autofilter_context \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_conditional_format_context \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_context \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_drawing_context \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_handler \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_helper \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_pivot_context \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_revision_context \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_session_data \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_sheet_context \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_table_context \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_types \
+ UnpackedTarball/liborcus/src/liborcus/xlsx_workbook_context \
+ UnpackedTarball/liborcus/src/liborcus/xml_context_base \
+ UnpackedTarball/liborcus/src/liborcus/xml_context_global \
+ UnpackedTarball/liborcus/src/liborcus/xml_element_validator \
+ UnpackedTarball/liborcus/src/liborcus/xml_empty_context \
+ UnpackedTarball/liborcus/src/liborcus/xml_map_tree \
+ UnpackedTarball/liborcus/src/liborcus/xml_simple_stream_handler \
+ UnpackedTarball/liborcus/src/liborcus/xml_stream_handler \
+ UnpackedTarball/liborcus/src/liborcus/xml_stream_parser \
+ UnpackedTarball/liborcus/src/liborcus/xml_structure_mapper \
+ UnpackedTarball/liborcus/src/liborcus/xml_structure_tree \
+ UnpackedTarball/liborcus/src/liborcus/xml_util \
+ UnpackedTarball/liborcus/src/liborcus/xpath_parser \
+ UnpackedTarball/liborcus/src/liborcus/yaml_document_tree \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liborcus/Makefile b/external/liborcus/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/liborcus/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liborcus/Module_liborcus.mk b/external/liborcus/Module_liborcus.mk
new file mode 100644
index 000000000..e75b983ba
--- /dev/null
+++ b/external/liborcus/Module_liborcus.mk
@@ -0,0 +1,32 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,liborcus))
+
+$(eval $(call gb_Module_add_targets,liborcus,\
+ UnpackedTarball_liborcus \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,liborcus,\
+ Library_orcus \
+ Library_orcus-parser \
+))
+
+else # !MSC
+
+$(eval $(call gb_Module_add_targets,liborcus,\
+ ExternalPackage_liborcus \
+ ExternalProject_liborcus \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liborcus/README b/external/liborcus/README
new file mode 100644
index 000000000..54e882663
--- /dev/null
+++ b/external/liborcus/README
@@ -0,0 +1,2 @@
+[https://gitlab.com/orcus/orcus]
+"Collection of parsers and import filters for spreadsheet documents."
diff --git a/external/liborcus/UnpackedTarball_liborcus.mk b/external/liborcus/UnpackedTarball_liborcus.mk
new file mode 100644
index 000000000..27668819a
--- /dev/null
+++ b/external/liborcus/UnpackedTarball_liborcus.mk
@@ -0,0 +1,52 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,liborcus))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,liborcus,$(ORCUS_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,liborcus,1))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,liborcus))
+
+# forcepoint-83.patch.1 merged as
+# https://gitlab.com/orcus/orcus/-/commit/9f6400b8192e39fefd475a96222713e9e9c60038
+# forcepoint-84.patch.1 merged as
+# https://gitlab.com/orcus/orcus/-/commit/223defe95d6f20f1bc5fd22fecc80a79a9519028
+# forcepoint-87.patch.1 merged as
+# https://gitlab.com/orcus/orcus/-/commit/a718524ca424fb8a7e7931345a118342d1d4a507
+# forcepoint-88.patch.1 merged as
+# https://gitlab.com/orcus/orcus/-/commit/0a99ca6d50af51f1b0a151fdcac5e12ec9b01bf8
+# forcepoint-95.patch.1 submitted as
+# https://gitlab.com/orcus/orcus/-/merge_requests/124
+
+$(eval $(call gb_UnpackedTarball_add_patches,liborcus,\
+ external/liborcus/rpath.patch.0 \
+ external/liborcus/gcc9.patch.0 \
+ external/liborcus/libtool.patch.0 \
+ external/liborcus/fix-pch.patch.0 \
+ external/liborcus/liborcus_newline.patch.1 \
+ external/liborcus/std-get-busted.patch.1 \
+ external/liborcus/forcepoint-83.patch.1 \
+ external/liborcus/forcepoint-84.patch.1 \
+ external/liborcus/forcepoint-87.patch.1 \
+ external/liborcus/forcepoint-88.patch.1 \
+ external/liborcus/forcepoint-95.patch.1 \
+ external/liborcus/include.patch.0 \
+ external/liborcus/overrun.patch.0 \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,liborcus,\
+ external/liborcus/windows-constants-hack.patch \
+ external/liborcus/win_path_utf16.patch \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/liborcus/fix-pch.patch.0 b/external/liborcus/fix-pch.patch.0
new file mode 100644
index 000000000..42a9d52d9
--- /dev/null
+++ b/external/liborcus/fix-pch.patch.0
@@ -0,0 +1,11 @@
+--- src/liborcus/gnumeric_cell_context.cpp.sav 2018-05-27 18:18:56.000000000 +0200
++++ src/liborcus/gnumeric_cell_context.cpp 2019-10-13 10:43:24.587258400 +0200
+@@ -248,7 +248,7 @@
+ range.last.column = col + mp_cell_data->array_cols - 1;
+ range.last.row = row + mp_cell_data->array_rows - 1;
+
+- iface::import_array_formula* af = mp_sheet->get_array_formula();
++ spreadsheet::iface::import_array_formula* af = mp_sheet->get_array_formula();
+ if (af)
+ {
+ af->set_range(range);
diff --git a/external/liborcus/forcepoint-83.patch.1 b/external/liborcus/forcepoint-83.patch.1
new file mode 100644
index 000000000..644c0dcff
--- /dev/null
+++ b/external/liborcus/forcepoint-83.patch.1
@@ -0,0 +1,38 @@
+From 4d58816e995a562f26f3cc5006ae9ddd46b1bbed Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
+Date: Wed, 23 Mar 2022 16:44:00 +0000
+Subject: [PATCH] forcepoint#83 Invalid read of size 1
+
+==343916== Invalid read of size 1
+==343916== at 0x11A7B2F0: orcus::parser_base::cur_char() const (parser_base.hpp:79)
+==343916== by 0x11B7B112: orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper, orcus::sax_parser_default_config>::element_open(long) (sax_parser.hpp:258)
+==343916== by 0x11B7A2C7: orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper, orcus::sax_parser_default_config>::element() (sax_parser.hpp:246)
+==343916== by 0x11B7A197: orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper, orcus::sax_parser_default_config>::body() (sax_parser.hpp:214)
+==343916== by 0x11B79FD9: orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper, orcus::sax_parser_default_config>::parse() (sax_parser.hpp:182)
+==343916== by 0x11B79F8B: orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::parse() (sax_ns_parser.hpp:277)
+==343916== by 0x11B79768: orcus::sax_token_parser<orcus::xml_stream_handler>::parse() (sax_token_parser.hpp:215)
+==343916== by 0x11B79406: orcus::xml_stream_parser::parse() (xml_stream_parser.cpp:68)
+==343916== by 0x11BE3805: orcus::orcus_xlsx::detect(unsigned char const*, unsigned long) (orcus_xlsx.cpp:188)
+==343916== by 0x11AB2482: orcus::detect(unsigned char const*, unsigned long) (format_detection.cpp:60)
+==343916== by 0x30E60945: (anonymous namespace)::OrcusFormatDetect::detect(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>&) (filterdetect.cxx:83)
+==343916== by 0x30E60ABE: non-virtual thunk to (anonymous namespace)::OrcusFormatDetect::detect(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>&) (filterdetect.cxx:0)
+---
+ include/orcus/sax_parser.hpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/orcus/sax_parser.hpp b/include/orcus/sax_parser.hpp
+index 15e8d917..2e707568 100644
+--- a/include/orcus/sax_parser.hpp
++++ b/include/orcus/sax_parser.hpp
+@@ -255,7 +255,7 @@ void sax_parser<_Handler,_Config>::element_open(std::ptrdiff_t begin_pos)
+ while (true)
+ {
+ skip_space_and_control();
+- char c = cur_char();
++ char c = cur_char_checked();
+ if (c == '/')
+ {
+ // Self-closing element: <element/>
+--
+2.35.1
+
diff --git a/external/liborcus/forcepoint-84.patch.1 b/external/liborcus/forcepoint-84.patch.1
new file mode 100644
index 000000000..bbe05340b
--- /dev/null
+++ b/external/liborcus/forcepoint-84.patch.1
@@ -0,0 +1,38 @@
+From ec469f774bb91302c4df21eff1314dfd508d37c8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
+Date: Wed, 23 Mar 2022 20:04:31 +0000
+Subject: [PATCH] forcepoint#84 Invalid read of size 1
+
+==356879== Invalid read of size 1
+==356879== at 0x11EC50B0: orcus::parser_base::cur_char() const (parser_base.hpp:79)
+==356879== by 0x11EDD736: orcus::sax::parser_base::value(std::basic_string_view<char, std::char_traits<char> >&, bool) (sax_parser_base.cpp:303)
+==356879== by 0x11B7C3D5: orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper, orcus::sax_parser_default_config>::attribute() (sax_parser.hpp:563)
+==356879== by 0x11B7B35E: orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper, orcus::sax_parser_default_config>::element_open(long) (sax_parser.hpp:292)
+==356879== by 0x11B7A2F7: orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper, orcus::sax_parser_default_config>::element() (sax_parser.hpp:246)
+==356879== by 0x11B7A1C7: orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper, orcus::sax_parser_default_config>::body() (sax_parser.hpp:214)
+==356879== by 0x11B7A009: orcus::sax_parser<orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::handler_wrapper, orcus::sax_parser_default_config>::parse() (sax_parser.hpp:182)
+==356879== by 0x11B79FBB: orcus::sax_ns_parser<orcus::sax_token_parser<orcus::xml_stream_handler>::handler_wrapper>::parse() (sax_ns_parser.hpp:277)
+==356879== by 0x11B79798: orcus::sax_token_parser<orcus::xml_stream_handler>::parse() (sax_token_parser.hpp:215)
+==356879== by 0x11B79436: orcus::xml_stream_parser::parse() (xml_stream_parser.cpp:68)
+==356879== by 0x11BE3855: orcus::orcus_xlsx::detect(unsigned char const*, unsigned long) (orcus_xlsx.cpp:188)
+==356879== by 0x11AB2492: orcus::detect(unsigned char const*, unsigned long) (format_detection.cpp:60)
+---
+ src/parser/sax_parser_base.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/parser/sax_parser_base.cpp b/src/parser/sax_parser_base.cpp
+index 46acb81d..1cee821e 100644
+--- a/src/parser/sax_parser_base.cpp
++++ b/src/parser/sax_parser_base.cpp
+@@ -300,7 +300,7 @@ void parser_base::value_with_encoded_char(cell_buffer& buf, std::string_view& st
+
+ bool parser_base::value(std::string_view& str, bool decode)
+ {
+- char c = cur_char();
++ char c = cur_char_checked();
+ if (c != '"' && c != '\'')
+ throw malformed_xml_error("value must be quoted", offset());
+
+--
+2.35.1
+
diff --git a/external/liborcus/forcepoint-87.patch.1 b/external/liborcus/forcepoint-87.patch.1
new file mode 100644
index 000000000..c1a58dde5
--- /dev/null
+++ b/external/liborcus/forcepoint-87.patch.1
@@ -0,0 +1,27 @@
+From e4f3741197a3af6d434850d388483b523138a214 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
+Date: Thu, 24 Mar 2022 21:31:14 +0000
+Subject: [PATCH] forcepoint#87 Assertion `mp_char <= mp_end' failed
+
+soffice.bin: ../../include/orcus/parser_base.hpp:65: bool orcus::parser_base::has_char() const: Assertion `mp_char <= mp_end' failed.
+---
+ src/parser/sax_parser_base.cpp | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/parser/sax_parser_base.cpp b/src/parser/sax_parser_base.cpp
+index 46acb81d..cb7a9c04 100644
+--- a/src/parser/sax_parser_base.cpp
++++ b/src/parser/sax_parser_base.cpp
+@@ -295,7 +295,8 @@ void parser_base::value_with_encoded_char(cell_buffer& buf, std::string_view& st
+
+ // Skip the closing quote.
+ assert(!has_char() || cur_char() == quote_char);
+- next();
++ if (has_char())
++ next();
+ }
+
+ bool parser_base::value(std::string_view& str, bool decode)
+--
+2.35.1
+
diff --git a/external/liborcus/forcepoint-88.patch.1 b/external/liborcus/forcepoint-88.patch.1
new file mode 100644
index 000000000..19d96f4d8
--- /dev/null
+++ b/external/liborcus/forcepoint-88.patch.1
@@ -0,0 +1,42 @@
+From 8c9537fe46b85acde0a7a183cee9066919c6b619 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
+Date: Fri, 25 Mar 2022 10:10:17 +0000
+Subject: [PATCH] forcepoint#88 assigned temp std::string return to string_view
+
+it's out of scope when used
+
+=ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffcaf91b111 at pc 0x000000486ec4 bp 0x7ffcaf91aed0 sp 0x7ffcaf91a680
+READ of size 2 at 0x7ffcaf91b111 thread T0
+ #0 0x486ec3 in __interceptor_memcpy.part.0 (instdir/program/soffice.bin+0x486ec3)
+ #1 0x7fa6c4471b77 in std::basic_streambuf<char, std::char_traits<char> >::xsputn(char const*, long) (/lib64/libstdc++.so.6+0x143b77)
+ #2 0x7fa6c4463ae3 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (/lib64/libstdc++.so.6+0x135ae3)
+ #3 0x7fa6b4027a26 in std::basic_ostream<char, std::char_traits<char> >& std::operator<<<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >) /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/string_view:669:14
+ #4 0x7fa6b426792b in orcus::xml_element_printer::print_namespace(std::ostream&, char const*) const workdir/UnpackedTarball/liborcus/src/liborcus/xml_util.cpp:35:12
+ #5 0x7fa6b4267c68 in orcus::xml_element_printer::print_element(std::ostream&, char const*, unsigned long) const workdir/UnpackedTarball/liborcus/src/liborcus/xml_util.cpp:46:5
+ #6 0x7fa6b41c1956 in orcus::xml_context_base::print_element(std::ostream&, std::pair<char const*, unsigned long> const&) const workdir/UnpackedTarball/liborcus/src/liborcus/xml_context_base.cpp:280:20
+---
+ src/liborcus/xml_util.cpp | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/liborcus/xml_util.cpp b/src/liborcus/xml_util.cpp
+index 906d321d..ff270d4a 100644
+--- a/src/liborcus/xml_util.cpp
++++ b/src/liborcus/xml_util.cpp
+@@ -29,10 +29,10 @@ void xml_element_printer::print_namespace(std::ostream& os, xmlns_id_t ns) const
+ if (mp_ns_cxt)
+ {
+ std::string_view alias = mp_ns_cxt->get_alias(ns);
+- if (alias.empty())
+- alias = mp_ns_cxt->get_short_name(ns);
+-
+- os << alias;
++ if (!alias.empty())
++ os << alias;
++ else
++ os << mp_ns_cxt->get_short_name(ns);
+ }
+ else
+ os << ns;
+--
+2.35.1
+
diff --git a/external/liborcus/forcepoint-95.patch.1 b/external/liborcus/forcepoint-95.patch.1
new file mode 100644
index 000000000..93dc82229
--- /dev/null
+++ b/external/liborcus/forcepoint-95.patch.1
@@ -0,0 +1,11 @@
+--- a/include/orcus/sax_parser.hpp 2022-03-30 10:54:44.043568760 +0100
++++ b/include/orcus/sax_parser.hpp 2022-03-30 10:54:55.645037322 +0100
+@@ -547,7 +547,7 @@
+
+ skip_space_and_control();
+
+- char c = cur_char();
++ char c = cur_char_checked();
+ if (c != '=')
+ {
+ std::ostringstream os;
diff --git a/external/liborcus/gcc9.patch.0 b/external/liborcus/gcc9.patch.0
new file mode 100644
index 000000000..f89b1dddc
--- /dev/null
+++ b/external/liborcus/gcc9.patch.0
@@ -0,0 +1,28 @@
+--- include/orcus/types.hpp
++++ include/orcus/types.hpp
+@@ -7,6 +7,14 @@
+
+ #ifndef INCLUDED_ORCUS_TYPES_HPP
+ #define INCLUDED_ORCUS_TYPES_HPP
++
++#ifdef __GNUC__
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wpragmas" // for old GCC
++#pragma GCC diagnostic ignored "-Wunknown-warning-option" // for Clang
++#pragma GCC diagnostic ignored "-Wdeprecated-copy"
++#pragma GCC diagnostic ignored "-Wshadow"
++#endif
+
+ #include <cstdlib>
+ #include <vector>
+@@ -145,6 +152,10 @@
+ typedef ::std::vector<xml_token_attr_t> xml_attrs_t;
+
+ }
++
++#ifdef __GNUC__
++#pragma GCC diagnostic pop
++#endif
+
+ #endif
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/liborcus/inc/pch/precompiled_orcus-parser.cxx b/external/liborcus/inc/pch/precompiled_orcus-parser.cxx
new file mode 100644
index 000000000..b93db182c
--- /dev/null
+++ b/external/liborcus/inc/pch/precompiled_orcus-parser.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_orcus-parser.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/liborcus/inc/pch/precompiled_orcus-parser.hxx b/external/liborcus/inc/pch/precompiled_orcus-parser.hxx
new file mode 100644
index 000000000..a8047d5c9
--- /dev/null
+++ b/external/liborcus/inc/pch/precompiled_orcus-parser.hxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2020-09-21 15:21:18 using:
+ ./bin/update_pch external/liborcus orcus-parser --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/liborcus/inc/pch/precompiled_orcus-parser.hxx "make external/liborcus.build" --find-conflicts
+*/
+
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <cmath>
+#include <codecvt>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <deque>
+#include <fstream>
+#include <iostream>
+#include <limits>
+#include <locale>
+#include <memory>
+#include <sstream>
+#include <tuple>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+#include <zconf.h>
+#include <zlib.h>
+#include <boost/archive/iterators/base64_from_binary.hpp>
+#include <boost/archive/iterators/binary_from_base64.hpp>
+#include <boost/archive/iterators/transform_width.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/interprocess/file_mapping.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/pool/object_pool.hpp>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <mdds/global.hpp>
+#include <mdds/sorted_string_map.hpp>
+#include <orcus/base64.hpp>
+#include <orcus/cell_buffer.hpp>
+#include <orcus/css_parser_base.hpp>
+#include <orcus/css_types.hpp>
+#include <orcus/csv_parser_base.hpp>
+#include <orcus/detail/parser_token_buffer.hpp>
+#include <orcus/exception.hpp>
+#include <orcus/global.hpp>
+#include <orcus/json_global.hpp>
+#include <orcus/json_parser.hpp>
+#include <orcus/json_parser_base.hpp>
+#include <orcus/json_parser_thread.hpp>
+#include <orcus/parser_base.hpp>
+#include <orcus/parser_global.hpp>
+#include <orcus/sax_parser_base.hpp>
+#include <orcus/sax_token_parser.hpp>
+#include <orcus/sax_token_parser_thread.hpp>
+#include <orcus/stream.hpp>
+#include <orcus/string_pool.hpp>
+#include <orcus/tokens.hpp>
+#include <orcus/types.hpp>
+#include <orcus/xml_namespace.hpp>
+#include <orcus/xml_writer.hpp>
+#include <orcus/yaml_parser_base.hpp>
+#include <orcus/zip_archive.hpp>
+#include <orcus/zip_archive_stream.hpp>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/liborcus/inc/pch/precompiled_orcus.cxx b/external/liborcus/inc/pch/precompiled_orcus.cxx
new file mode 100644
index 000000000..03b0cdf02
--- /dev/null
+++ b/external/liborcus/inc/pch/precompiled_orcus.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_orcus.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/liborcus/inc/pch/precompiled_orcus.hxx b/external/liborcus/inc/pch/precompiled_orcus.hxx
new file mode 100644
index 000000000..9543b44eb
--- /dev/null
+++ b/external/liborcus/inc/pch/precompiled_orcus.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2020-09-21 15:21:19 using:
+ ./bin/update_pch external/liborcus orcus --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/liborcus/inc/pch/precompiled_orcus.hxx "make external/liborcus.build" --find-conflicts
+*/
+
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <cassert>
+#include <codecvt>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <deque>
+#include <fstream>
+#include <functional>
+#include <iostream>
+#include <iterator>
+#include <limits>
+#include <locale>
+#include <map>
+#include <memory>
+#include <ostream>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+#include <boost/current_function.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/iostreams/filter/gzip.hpp>
+#include <boost/iostreams/filtering_stream.hpp>
+#include <boost/optional.hpp>
+#include <boost/pool/object_pool.hpp>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <mdds/global.hpp>
+#include <mdds/sorted_string_map.hpp>
+#include <orcus/config.hpp>
+#include <orcus/css_document_tree.hpp>
+#include <orcus/css_parser.hpp>
+#include <orcus/css_selector.hpp>
+#include <orcus/csv_parser.hpp>
+#include <orcus/dom_tree.hpp>
+#include <orcus/exception.hpp>
+#include <orcus/format_detection.hpp>
+#include <orcus/global.hpp>
+#include <orcus/info.hpp>
+#include <orcus/interface.hpp>
+#include <orcus/json_document_tree.hpp>
+#include <orcus/json_global.hpp>
+#include <orcus/json_parser.hpp>
+#include <orcus/json_structure_tree.hpp>
+#include <orcus/measurement.hpp>
+#include <orcus/orcus_csv.hpp>
+#include <orcus/orcus_gnumeric.hpp>
+#include <orcus/orcus_import_ods.hpp>
+#include <orcus/orcus_import_xlsx.hpp>
+#include <orcus/orcus_json.hpp>
+#include <orcus/orcus_ods.hpp>
+#include <orcus/orcus_xls_xml.hpp>
+#include <orcus/orcus_xlsx.hpp>
+#include <orcus/orcus_xml.hpp>
+#include <orcus/parser_base.hpp>
+#include <orcus/parser_global.hpp>
+#include <orcus/sax_ns_parser.hpp>
+#include <orcus/sax_parser.hpp>
+#include <orcus/sax_parser_base.hpp>
+#include <orcus/sax_token_parser.hpp>
+#include <orcus/spreadsheet/export_interface.hpp>
+#include <orcus/spreadsheet/import_interface.hpp>
+#include <orcus/spreadsheet/import_interface_pivot.hpp>
+#include <orcus/spreadsheet/import_interface_view.hpp>
+#include <orcus/spreadsheet/styles.hpp>
+#include <orcus/spreadsheet/types.hpp>
+#include <orcus/stream.hpp>
+#include <orcus/string_pool.hpp>
+#include <orcus/threaded_sax_token_parser.hpp>
+#include <orcus/tokens.hpp>
+#include <orcus/xml_namespace.hpp>
+#include <orcus/xml_structure_tree.hpp>
+#include <orcus/xml_writer.hpp>
+#include <orcus/yaml_document_tree.hpp>
+#include <orcus/yaml_parser.hpp>
+#include <orcus/zip_archive.hpp>
+#include <orcus/zip_archive_stream.hpp>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/liborcus/include.patch.0 b/external/liborcus/include.patch.0
new file mode 100644
index 000000000..1131d04d3
--- /dev/null
+++ b/external/liborcus/include.patch.0
@@ -0,0 +1,20 @@
+--- include/orcus/base64.hpp
++++ include/orcus/base64.hpp
+@@ -9,6 +9,7 @@
+ #define __ORCUS_BASE64_HPP__
+
+ #include "env.hpp"
++#include <stdint.h>
+ #include <vector>
+ #include <string>
+
+--- include/orcus/types.hpp
++++ include/orcus/types.hpp
+@@ -16,6 +16,7 @@
+ #pragma GCC diagnostic ignored "-Wshadow"
+ #endif
+
++#include <stdint.h>
+ #include <cstdlib>
+ #include <vector>
+ #include <string>
diff --git a/external/liborcus/liborcus_newline.patch.1 b/external/liborcus/liborcus_newline.patch.1
new file mode 100644
index 000000000..5b2038d5c
--- /dev/null
+++ b/external/liborcus/liborcus_newline.patch.1
@@ -0,0 +1,17 @@
+Add newline at end of KRHangulMapping.h
+
+without this, compiling output of GCC 11 -E -fdirectives-only fails with:
+
+ooxml_tokens.inl:3524:32: error: stray '#' in program
+
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100392
+
+--- liborcus/src/liborcus/ooxml_tokens.inl.orig 2021-05-01 18:12:37.490131155 +0200
++++ liborcus/src/liborcus/ooxml_tokens.inl 2021-05-01 18:12:50.994119453 +0200
+@@ -3521,4 +3521,4 @@
+ "zoomToFit" // 3517
+ };
+
+-size_t token_name_count = 3518;
+\ No newline at end of file
++size_t token_name_count = 3518;
diff --git a/external/liborcus/libtool.patch.0 b/external/liborcus/libtool.patch.0
new file mode 100644
index 000000000..663dbd809
--- /dev/null
+++ b/external/liborcus/libtool.patch.0
@@ -0,0 +1,11 @@
+--- ltmain.sh.orig 2020-09-09 21:20:23.069433984 -0400
++++ ltmain.sh 2020-09-09 21:27:13.168073996 -0400
+@@ -7373,7 +7373,7 @@
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+- -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus)
++ -specs=*|-fsanitize=*|-fuse-ld=*|--ld-path=*|-static-*|-fcilkplus)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ func_append compile_command " $arg"
diff --git a/external/liborcus/overrun.patch.0 b/external/liborcus/overrun.patch.0
new file mode 100644
index 000000000..de2097e32
--- /dev/null
+++ b/external/liborcus/overrun.patch.0
@@ -0,0 +1,63 @@
+--- src/parser/sax_token_parser.cpp
++++ src/parser/sax_token_parser.cpp
+@@ -10,6 +10,7 @@
+
+ #include <mdds/sorted_string_map.hpp>
+ #include <cctype>
++#include <limits>
+
+ namespace orcus {
+
+@@ -329,6 +330,28 @@
+ m_elem.raw_name = elem.name;
+ }
+
++static uint8_t readUint8(char const * begin, char const * end, char const ** endptr) {
++ unsigned n = 0;
++ char const * p = begin;
++ for (; p != end; ++p) {
++ char const c = *p;
++ if (c < '0' || c > '9') {
++ break;
++ }
++ n = 10 * n + (c - '0');
++ if (n > std::numeric_limits<uint8_t>::max()) {
++ *endptr = nullptr;
++ return 0;
++ }
++ }
++ if (p == begin) {
++ *endptr = nullptr;
++ return 0;
++ }
++ *endptr = p;
++ return n;
++}
++
+ void sax_token_handler_wrapper_base::attribute(std::string_view name, std::string_view val)
+ {
+ decl_attr_type dat = decl_attr::get().find(name.data(), name.size());
+@@ -340,18 +362,18 @@
+ const char* p = val.data();
+ const char* p_end = p + val.size();
+
+- char* endptr = nullptr;
+- long v = std::strtol(p, &endptr, 10);
++ const char* endptr = nullptr;
++ uint8_t v = readUint8(p, p_end, &endptr);
+
+- if (!endptr || endptr >= p_end || *endptr != '.')
++ if (!endptr || endptr == p_end || *endptr != '.')
+ break;
+
+ m_declaration.version_major = v;
+ p = endptr + 1;
+
+- v = std::strtol(p, &endptr, 10);
++ v = readUint8(p, p_end, &endptr);
+
+- if (!endptr || endptr > p_end)
++ if (!endptr)
+ break;
+
+ m_declaration.version_minor = v;
diff --git a/external/liborcus/rpath.patch.0 b/external/liborcus/rpath.patch.0
new file mode 100644
index 000000000..e7a33e693
--- /dev/null
+++ b/external/liborcus/rpath.patch.0
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -14007,6 +14007,7 @@
+ esac
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+
+ lynxos*)
diff --git a/external/liborcus/std-get-busted.patch.1 b/external/liborcus/std-get-busted.patch.1
new file mode 100644
index 000000000..40b839f65
--- /dev/null
+++ b/external/liborcus/std-get-busted.patch.1
@@ -0,0 +1,418 @@
+From f917ed284c52ae12fb0d752c17141f355158470e Mon Sep 17 00:00:00 2001
+From: Kohei Yoshida <kohei.yoshida@gmail.com>
+Date: Tue, 2 Nov 2021 22:07:51 -0400
+Subject: [PATCH] std::get<T>(...) may be flaky with some version of clang.
+
+As workaround, use boost::variant and boost::get.
+
+c.f. https://stackoverflow.com/questions/52521388/stdvariantget-does-not-compile-with-apple-llvm-10-0
+---
+ include/orcus/config.hpp | 4 ++--
+ include/orcus/css_selector.hpp | 5 +++--
+ include/orcus/json_parser_thread.hpp | 4 ++--
+ include/orcus/sax_token_parser_thread.hpp | 5 +++--
+ include/orcus/spreadsheet/pivot.hpp | 7 ++++---
+ include/orcus/threaded_json_parser.hpp | 8 ++++----
+ include/orcus/threaded_sax_token_parser.hpp | 8 ++++----
+ src/liborcus/css_document_tree.cpp | 2 +-
+ src/liborcus/css_selector.cpp | 12 ++++++------
+ src/liborcus/orcus_csv.cpp | 4 ++--
+ src/orcus_csv_main.cpp | 2 +-
+ src/orcus_test_csv.cpp | 8 ++++----
+ src/orcus_test_xlsx.cpp | 4 ++--
+ src/parser/json_parser_thread.cpp | 8 ++++----
+ src/python/sheet_rows.cpp | 3 +++
+ 15 files changed, 45 insertions(+), 39 deletions(-)
+
+diff --git a/include/orcus/config.hpp b/include/orcus/config.hpp
+index 17743e6a..fe9a7d81 100644
+--- a/include/orcus/config.hpp
++++ b/include/orcus/config.hpp
+@@ -12,7 +12,7 @@
+ #include "orcus/types.hpp"
+
+ #include <string>
+-#include <variant>
++#include <boost/variant.hpp>
+
+ namespace orcus {
+
+@@ -37,7 +37,7 @@ struct ORCUS_DLLPUBLIC config
+ };
+
+ // TODO: add config for other formats as needed.
+- using data_type = std::variant<csv_config>;
++ using data_type = boost::variant<csv_config>;
+
+ /**
+ * Enable or disable runtime debug output to stdout or stderr.
+diff --git a/include/orcus/css_selector.hpp b/include/orcus/css_selector.hpp
+index 1e41d544..dafeddf5 100644
+--- a/include/orcus/css_selector.hpp
++++ b/include/orcus/css_selector.hpp
+@@ -12,11 +12,12 @@
+ #include "css_types.hpp"
+
+ #include <ostream>
+-#include <variant>
+ #include <vector>
+ #include <unordered_set>
+ #include <unordered_map>
+
++#include <boost/variant.hpp>
++
+ namespace orcus {
+
+ struct ORCUS_DLLPUBLIC css_simple_selector_t
+@@ -73,7 +74,7 @@ struct ORCUS_DLLPUBLIC css_selector_t
+ */
+ struct ORCUS_DLLPUBLIC css_property_value_t
+ {
+- using value_type = std::variant<std::string_view, css::rgba_color_t, css::hsla_color_t>;
++ using value_type = boost::variant<std::string_view, css::rgba_color_t, css::hsla_color_t>;
+
+ css::property_value_t type;
+ value_type value;
+diff --git a/include/orcus/json_parser_thread.hpp b/include/orcus/json_parser_thread.hpp
+index 8328ef11..565008da 100644
+--- a/include/orcus/json_parser_thread.hpp
++++ b/include/orcus/json_parser_thread.hpp
+@@ -14,7 +14,7 @@
+ #include <memory>
+ #include <vector>
+ #include <ostream>
+-#include <variant>
++#include <boost/variant.hpp>
+
+ namespace orcus {
+
+@@ -47,7 +47,7 @@ enum class parse_token_t
+
+ struct ORCUS_PSR_DLLPUBLIC parse_token
+ {
+- using value_type = std::variant<std::string_view, parse_error_value_t, double>;
++ using value_type = boost::variant<std::string_view, parse_error_value_t, double>;
+
+ parse_token_t type;
+ value_type value;
+diff --git a/include/orcus/sax_token_parser_thread.hpp b/include/orcus/sax_token_parser_thread.hpp
+index b3645735..e0842013 100644
+--- a/include/orcus/sax_token_parser_thread.hpp
++++ b/include/orcus/sax_token_parser_thread.hpp
+@@ -12,10 +12,11 @@
+ #include "types.hpp"
+
+ #include <memory>
+-#include <variant>
+ #include <vector>
+ #include <ostream>
+
++#include <boost/variant.hpp>
++
+ namespace orcus {
+
+ class tokens;
+@@ -36,7 +37,7 @@ enum class parse_token_t
+
+ struct ORCUS_PSR_DLLPUBLIC parse_token
+ {
+- using value_type = std::variant<std::string_view, parse_error_value_t, const xml_token_element_t*>;
++ using value_type = boost::variant<std::string_view, parse_error_value_t, const xml_token_element_t*>;
+
+ parse_token_t type;
+ value_type value;
+diff --git a/include/orcus/spreadsheet/pivot.hpp b/include/orcus/spreadsheet/pivot.hpp
+index dee25596..fa091160 100644
+--- a/include/orcus/spreadsheet/pivot.hpp
++++ b/include/orcus/spreadsheet/pivot.hpp
+@@ -15,9 +15,10 @@
+ #include <memory>
+ #include <vector>
+ #include <limits>
+-#include <variant>
+ #include <optional>
+
++#include <boost/variant.hpp>
++
+ namespace ixion {
+
+ struct abs_range_t;
+@@ -36,7 +37,7 @@ using pivot_cache_indices_t = std::vector<size_t>;
+
+ struct ORCUS_SPM_DLLPUBLIC pivot_cache_record_value_t
+ {
+- using value_type = std::variant<bool, double, std::size_t, std::string_view, date_time_t>;
++ using value_type = boost::variant<bool, double, std::size_t, std::string_view, date_time_t>;
+
+ enum class record_type
+ {
+@@ -66,7 +67,7 @@ using pivot_cache_record_t = std::vector<pivot_cache_record_value_t>;
+
+ struct ORCUS_SPM_DLLPUBLIC pivot_cache_item_t
+ {
+- using value_type = std::variant<bool, double, std::string_view, date_time_t, error_value_t>;
++ using value_type = boost::variant<bool, double, std::string_view, date_time_t, error_value_t>;
+
+ enum class item_type
+ {
+diff --git a/include/orcus/threaded_json_parser.hpp b/include/orcus/threaded_json_parser.hpp
+index 51cdaced..3bf6e591 100644
+--- a/include/orcus/threaded_json_parser.hpp
++++ b/include/orcus/threaded_json_parser.hpp
+@@ -151,23 +151,23 @@ void threaded_json_parser<_Handler>::process_tokens(json::parse_tokens_t& tokens
+ m_handler.null();
+ break;
+ case json::parse_token_t::number:
+- m_handler.number(std::get<double>(t.value));
++ m_handler.number(boost::get<double>(t.value));
+ break;
+ case json::parse_token_t::object_key:
+ {
+- auto s = std::get<std::string_view>(t.value);
++ auto s = boost::get<std::string_view>(t.value);
+ m_handler.object_key(s.data(), s.size(), false);
+ break;
+ }
+ case json::parse_token_t::string:
+ {
+- auto s = std::get<std::string_view>(t.value);
++ auto s = boost::get<std::string_view>(t.value);
+ m_handler.string(s.data(), s.size(), false);
+ break;
+ }
+ case json::parse_token_t::parse_error:
+ {
+- auto v = std::get<parse_error_value_t>(t.value);
++ auto v = boost::get<parse_error_value_t>(t.value);
+ throw json::parse_error(std::string{v.str}, v.offset);
+ }
+ case json::parse_token_t::unknown:
+diff --git a/include/orcus/threaded_sax_token_parser.hpp b/include/orcus/threaded_sax_token_parser.hpp
+index 59ea967a..1b389be2 100644
+--- a/include/orcus/threaded_sax_token_parser.hpp
++++ b/include/orcus/threaded_sax_token_parser.hpp
+@@ -131,25 +131,25 @@ void threaded_sax_token_parser<_Handler>::process_tokens(const sax::parse_tokens
+ {
+ case sax::parse_token_t::start_element:
+ {
+- const auto* elem = std::get<const xml_token_element_t*>(t.value);
++ const auto* elem = boost::get<const xml_token_element_t*>(t.value);
+ m_handler.start_element(*elem);
+ break;
+ }
+ case sax::parse_token_t::end_element:
+ {
+- const auto* elem = std::get<const xml_token_element_t*>(t.value);
++ const auto* elem = boost::get<const xml_token_element_t*>(t.value);
+ m_handler.end_element(*elem);
+ break;
+ }
+ case sax::parse_token_t::characters:
+ {
+- auto s = std::get<std::string_view>(t.value);
++ auto s = boost::get<std::string_view>(t.value);
+ m_handler.characters(s, false);
+ break;
+ }
+ case sax::parse_token_t::parse_error:
+ {
+- auto v = std::get<parse_error_value_t>(t.value);
++ auto v = boost::get<parse_error_value_t>(t.value);
+ throw sax::malformed_xml_error(std::string{v.str}, v.offset);
+ }
+ default:
+diff --git a/src/liborcus/css_document_tree.cpp b/src/liborcus/css_document_tree.cpp
+index 46bf7e91..4b44edff 100644
+--- a/src/liborcus/css_document_tree.cpp
++++ b/src/liborcus/css_document_tree.cpp
+@@ -317,7 +317,7 @@ public:
+ {
+ // String value needs interning.
+ css_property_value_t interned = v;
+- auto s = std::get<std::string_view>(v.value);
++ auto s = boost::get<std::string_view>(v.value);
+ interned.value = m_sp.intern(s).first;
+ m_dest.push_back(interned);
+ break;
+diff --git a/src/liborcus/css_selector.cpp b/src/liborcus/css_selector.cpp
+index b7b63f37..de522062 100644
+--- a/src/liborcus/css_selector.cpp
++++ b/src/liborcus/css_selector.cpp
+@@ -155,7 +155,7 @@ std::ostream& operator<< (std::ostream& os, const css_property_value_t& v)
+ {
+ case css::property_value_t::hsl:
+ {
+- auto c = std::get<css::hsla_color_t>(v.value);
++ auto c = boost::get<css::hsla_color_t>(v.value);
+ os << "hsl("
+ << (int)c.hue << sep
+ << (int)c.saturation << sep
+@@ -165,7 +165,7 @@ std::ostream& operator<< (std::ostream& os, const css_property_value_t& v)
+ }
+ case css::property_value_t::hsla:
+ {
+- auto c = std::get<css::hsla_color_t>(v.value);
++ auto c = boost::get<css::hsla_color_t>(v.value);
+ os << "hsla("
+ << (int)c.hue << sep
+ << (int)c.saturation << sep
+@@ -176,7 +176,7 @@ std::ostream& operator<< (std::ostream& os, const css_property_value_t& v)
+ }
+ case css::property_value_t::rgb:
+ {
+- auto c = std::get<css::rgba_color_t>(v.value);
++ auto c = boost::get<css::rgba_color_t>(v.value);
+ os << "rgb("
+ << (int)c.red << sep
+ << (int)c.green << sep
+@@ -186,7 +186,7 @@ std::ostream& operator<< (std::ostream& os, const css_property_value_t& v)
+ }
+ case css::property_value_t::rgba:
+ {
+- auto c = std::get<css::rgba_color_t>(v.value);
++ auto c = boost::get<css::rgba_color_t>(v.value);
+ os << "rgba("
+ << (int)c.red << sep
+ << (int)c.green << sep
+@@ -196,10 +196,10 @@ std::ostream& operator<< (std::ostream& os, const css_property_value_t& v)
+ break;
+ }
+ case css::property_value_t::string:
+- os << std::get<std::string_view>(v.value);
++ os << boost::get<std::string_view>(v.value);
+ break;
+ case css::property_value_t::url:
+- os << "url(" << std::get<std::string_view>(v.value) << ")";
++ os << "url(" << boost::get<std::string_view>(v.value) << ")";
+ break;
+ case css::property_value_t::none:
+ default:
+diff --git a/src/liborcus/orcus_csv.cpp b/src/liborcus/orcus_csv.cpp
+index 5c71bcf5..637308ab 100644
+--- a/src/liborcus/orcus_csv.cpp
++++ b/src/liborcus/orcus_csv.cpp
+@@ -63,7 +63,7 @@ public:
+ // 0.
+ if (m_row >= mp_sheet->get_sheet_size().rows)
+ {
+- auto csv = std::get<config::csv_config>(m_app_config.data);
++ auto csv = boost::get<config::csv_config>(m_app_config.data);
+
+ if (!csv.split_to_multiple_sheets)
+ throw max_row_size_reached();
+@@ -93,7 +93,7 @@ public:
+
+ void cell(const char* p, size_t n, bool transient)
+ {
+- auto csv = std::get<config::csv_config>(m_app_config.data);
++ auto csv = boost::get<config::csv_config>(m_app_config.data);
+
+ if (m_sheet == 0 && size_t(m_row) < csv.header_row_size)
+ {
+diff --git a/src/orcus_csv_main.cpp b/src/orcus_csv_main.cpp
+index 4f6d7173..446f2684 100644
+--- a/src/orcus_csv_main.cpp
++++ b/src/orcus_csv_main.cpp
+@@ -45,7 +45,7 @@ public:
+
+ virtual void map_to_config(config& opt, const po::variables_map& vm) override
+ {
+- auto csv = std::get<config::csv_config>(opt.data);
++ auto csv = boost::get<config::csv_config>(opt.data);
+
+ if (vm.count("row-header"))
+ csv.header_row_size = vm["row-header"].as<size_t>();
+diff --git a/src/orcus_test_csv.cpp b/src/orcus_test_csv.cpp
+index 310ace9d..0b9ba994 100644
+--- a/src/orcus_test_csv.cpp
++++ b/src/orcus_test_csv.cpp
+@@ -95,8 +95,8 @@ void test_csv_import_split_sheet()
+ std::cout << "checking " << path << "..." << std::endl;
+
+ config conf(format_t::csv);
+- std::get<config::csv_config>(conf.data).header_row_size = 0;
+- std::get<config::csv_config>(conf.data).split_to_multiple_sheets = true;
++ boost::get<config::csv_config>(conf.data).header_row_size = 0;
++ boost::get<config::csv_config>(conf.data).split_to_multiple_sheets = true;
+
+ // Set the row size to 11 to make sure the split occurs.
+ spreadsheet::range_size_t ss{11, 4};
+@@ -126,7 +126,7 @@ void test_csv_import_split_sheet()
+ path = dir;
+ path.append("input.csv");
+ doc.clear();
+- std::get<config::csv_config>(conf.data).header_row_size = 1;
++ boost::get<config::csv_config>(conf.data).header_row_size = 1;
+ {
+ spreadsheet::import_factory factory(doc);
+ orcus_csv app(&factory);
+@@ -149,7 +149,7 @@ void test_csv_import_split_sheet()
+
+ // Re-import it again, but this time disable the splitting. The data should
+ // get trucated on the first sheet.
+- std::get<config::csv_config>(conf.data).split_to_multiple_sheets = false;
++ boost::get<config::csv_config>(conf.data).split_to_multiple_sheets = false;
+
+ path = dir;
+ path.append("input.csv");
+diff --git a/src/orcus_test_xlsx.cpp b/src/orcus_test_xlsx.cpp
+index 807c61e4..632fb1e7 100644
+--- a/src/orcus_test_xlsx.cpp
++++ b/src/orcus_test_xlsx.cpp
+@@ -1154,8 +1154,8 @@ void test_xlsx_pivot_group_by_numbers()
+ for (const pivot_cache_item_t& item : fld->items)
+ {
+ assert(item.type == pivot_cache_item_t::item_type::numeric);
+- assert(*fld->min_value <= std::get<double>(item.value));
+- assert(std::get<double>(item.value) <= *fld->max_value);
++ assert(*fld->min_value <= boost::get<double>(item.value));
++ assert(boost::get<double>(item.value) <= *fld->max_value);
+ }
+
+ // This field is also gruop field with 7 numeric intervals of width 2.
+diff --git a/src/parser/json_parser_thread.cpp b/src/parser/json_parser_thread.cpp
+index 36bbe6e6..65fb6255 100644
+--- a/src/parser/json_parser_thread.cpp
++++ b/src/parser/json_parser_thread.cpp
+@@ -237,19 +237,19 @@ std::ostream& operator<< (std::ostream& os, const parse_tokens_t& tokens)
+ os << "- null" << endl;
+ break;
+ case parse_token_t::number:
+- os << "- number (v=" << std::get<double>(t.value) << ")" << endl;
++ os << "- number (v=" << boost::get<double>(t.value) << ")" << endl;
+ break;
+ case parse_token_t::object_key:
+- os << "- object_key (v=" << std::get<std::string_view>(t.value) << ")" << endl;
++ os << "- object_key (v=" << boost::get<std::string_view>(t.value) << ")" << endl;
+ break;
+ case parse_token_t::parse_error:
+ {
+- auto v = std::get<parse_error_value_t>(t.value);
++ auto v = boost::get<parse_error_value_t>(t.value);
+ os << "- parse_error (v=" << v.str << ", offset=" << v.offset << ")" << endl;
+ break;
+ }
+ case parse_token_t::string:
+- os << "- string (" << std::get<std::string_view>(t.value) << ")" << endl;
++ os << "- string (" << boost::get<std::string_view>(t.value) << ")" << endl;
+ break;
+ case parse_token_t::unknown:
+ os << "- unknown" << endl;
+diff --git a/src/python/sheet_rows.cpp b/src/python/sheet_rows.cpp
+index be495894..0d21ba71 100644
+--- a/src/python/sheet_rows.cpp
++++ b/src/python/sheet_rows.cpp
+@@ -135,7 +135,10 @@ PyObject* sheet_rows_iternext(PyObject* self)
+ break;
+ }
+ case ixion::celltype_t::unknown:
++ {
++ PyErr_SetString(PyExc_RuntimeError, "Unknown cell type.");
+ break;
++ }
+ }
+
+ if (!obj)
+--
+2.25.1
+
diff --git a/external/liborcus/win_path_utf16.patch b/external/liborcus/win_path_utf16.patch
new file mode 100644
index 000000000..0a6781e72
--- /dev/null
+++ b/external/liborcus/win_path_utf16.patch
@@ -0,0 +1,33 @@
+diff --git a/src/parser/stream.cpp b/src/parser/stream.cpp
+index 00395f59ff25..8f385fb8965a 100644
+--- a/src/parser/stream.cpp
++++ b/src/parser/stream.cpp
+@@ -147,6 +147,14 @@ std::tuple<std::string_view, size_t, size_t> find_line_with_offset(std::string_v
+ return std::make_tuple(line, line_num, offset_on_line);
+ }
+
++#ifdef _WIN32
++std::wstring to_wstring(std::string_view s)
++{
++ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conversion;
++ return conversion.from_bytes(s.data(), s.data() + s.size());
++}
++#endif
++
+ } // anonymous namespace
+
+ struct file_content::impl
+@@ -162,8 +170,13 @@ struct file_content::impl
+ impl() : content_size(0), content(nullptr) {}
+
+ impl(std::string_view filepath) :
++#ifdef _WIN32
++ content_size(fs::file_size(to_wstring(filepath))),
++ mapped_file(to_wstring(filepath).c_str(), bip::read_only),
++#else
+ content_size(fs::file_size(std::string{filepath}.c_str())),
+ mapped_file(std::string{filepath}.c_str(), bip::read_only),
++#endif
+ mapped_region(mapped_file, bip::read_only, 0, content_size),
+ content(nullptr)
+ {
diff --git a/external/liborcus/windows-constants-hack.patch b/external/liborcus/windows-constants-hack.patch
new file mode 100644
index 000000000..e86c74a72
--- /dev/null
+++ b/external/liborcus/windows-constants-hack.patch
@@ -0,0 +1,15 @@
+diff --git a/src/liborcus/info.cpp b/src/liborcus/info.cpp
+index ae571f5..539ce18 100644
+--- a/src/liborcus/info.cpp
++++ b/src/liborcus/info.cpp
+@@ -7,7 +7,9 @@
+
+ #include "orcus/info.hpp"
+
+-#include "constants.inl"
++#define ORCUS_MAJOR_VERSION 0
++#define ORCUS_MINOR_VERSION 17
++#define ORCUS_MICRO_VERSION 2
+
+ namespace orcus {
+
diff --git a/external/libpagemaker/ExternalProject_libpagemaker.mk b/external/libpagemaker/ExternalProject_libpagemaker.mk
new file mode 100644
index 000000000..d663ffaf9
--- /dev/null
+++ b/external/libpagemaker/ExternalProject_libpagemaker.mk
@@ -0,0 +1,45 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libpagemaker))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libpagemaker,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libpagemaker,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libpagemaker,\
+ boost_headers \
+ revenge \
+))
+
+$(call gb_ExternalProject_get_state_target,libpagemaker,build) :
+ $(call gb_Trace_StartRange,libpagemaker,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ --disable-tools \
+ --disable-debug \
+ --disable-werror \
+ --disable-weffc \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libpagemaker)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libpagemaker)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libpagemaker,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libpagemaker/Makefile b/external/libpagemaker/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libpagemaker/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libpagemaker/Module_libpagemaker.mk b/external/libpagemaker/Module_libpagemaker.mk
new file mode 100644
index 000000000..4888775fa
--- /dev/null
+++ b/external/libpagemaker/Module_libpagemaker.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libpagemaker))
+
+$(eval $(call gb_Module_add_targets,libpagemaker,\
+ ExternalProject_libpagemaker \
+ UnpackedTarball_libpagemaker \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libpagemaker/README b/external/libpagemaker/README
new file mode 100644
index 000000000..309aa82fe
--- /dev/null
+++ b/external/libpagemaker/README
@@ -0,0 +1,3 @@
+Library parsing Adobe PageMaker documents.
+
+[https://wiki.documentfoundation.org/DLP/Libraries/libpagemaker]
diff --git a/external/libpagemaker/UnpackedTarball_libpagemaker.mk b/external/libpagemaker/UnpackedTarball_libpagemaker.mk
new file mode 100644
index 000000000..752d5c0eb
--- /dev/null
+++ b/external/libpagemaker/UnpackedTarball_libpagemaker.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libpagemaker))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libpagemaker,$(PAGEMAKER_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libpagemaker))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libpng/Makefile b/external/libpng/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libpng/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libpng/Module_libpng.mk b/external/libpng/Module_libpng.mk
new file mode 100644
index 000000000..f8f834d0e
--- /dev/null
+++ b/external/libpng/Module_libpng.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libpng))
+
+$(eval $(call gb_Module_add_targets,libpng,\
+ StaticLibrary_libpng \
+ UnpackedTarball_libpng \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libpng/README b/external/libpng/README
new file mode 100644
index 000000000..8b9c89611
--- /dev/null
+++ b/external/libpng/README
@@ -0,0 +1 @@
+libpng is the official PNG reference library, from [http://www.libpng.org/]
diff --git a/external/libpng/StaticLibrary_libpng.mk b/external/libpng/StaticLibrary_libpng.mk
new file mode 100644
index 000000000..6f07750c5
--- /dev/null
+++ b/external/libpng/StaticLibrary_libpng.mk
@@ -0,0 +1,72 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,libpng))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,libpng))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,libpng,libpng))
+
+$(eval $(call gb_StaticLibrary_use_externals,libpng,\
+ zlib \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,libpng,\
+ UnpackedTarball/libpng/png \
+ UnpackedTarball/libpng/pngerror \
+ UnpackedTarball/libpng/pngget \
+ UnpackedTarball/libpng/pngmem \
+ UnpackedTarball/libpng/pngpread \
+ UnpackedTarball/libpng/pngread \
+ UnpackedTarball/libpng/pngrio \
+ UnpackedTarball/libpng/pngrtran \
+ UnpackedTarball/libpng/pngrutil \
+ UnpackedTarball/libpng/pngset \
+ UnpackedTarball/libpng/pngtrans \
+ UnpackedTarball/libpng/pngwio \
+ UnpackedTarball/libpng/pngwrite \
+ UnpackedTarball/libpng/pngwtran \
+ UnpackedTarball/libpng/pngwutil \
+ $(if $(filter ARM AARCH64,$(CPUNAME)),\
+ UnpackedTarball/libpng/arm/arm_init \
+ UnpackedTarball/libpng/arm/filter_neon_intrinsics \
+ UnpackedTarball/libpng/arm/palette_neon_intrinsics \
+ ) \
+ $(if $(filter POWERPC POWERPC64,$(CPUNAME)), \
+ UnpackedTarball/libpng/powerpc/powerpc_init \
+ UnpackedTarball/libpng/powerpc/filter_vsx_intrinsics \
+ ) \
+ $(if $(filter INTEL X86_64,$(CPUNAME)), \
+ UnpackedTarball/libpng/intel/intel_init \
+ UnpackedTarball/libpng/intel/filter_sse2_intrinsics \
+ ) \
+))
+
+$(eval $(call gb_StaticLibrary_add_defs,libpng,\
+ $(if $(filter ARM AARCH64,$(CPUNAME)), -DPNG_ARM_NEON) \
+ $(if $(filter POWERPC POWERPC64,$(CPUNAME)), -DPNG_POWERPC_VSX ) \
+ $(if $(filter INTEL X86_64,$(CPUNAME)), -DPNG_INTEL_SSE_OPT) \
+))
+
+# At least on Linux, with --enable-lto, when building both this external/libpng and external/skia,
+# and building with GCC but building skia with Clang (which should be the sole combination that
+# matches "LO_CLANG_CC is non-empty"), build this as a fat archive (including both the intermediate GCC
+# object code for LTO and machine object code). Besides targets like Library_vcl (which benefit
+# from the intermediate GCC object code for LTO), also Library_skia (built with the Clang toolchain
+# lld, which does not understand intermediate GCC object code) includes this, so would otherwise
+# fail to link (but now does not benefit from LTO for this included StaticLibrary_libpng):
+ifeq ($(OS)-$(ENABLE_LTO),LINUX-TRUE)
+ifneq ($(filter SKIA,$(BUILD_TYPE)),)
+ifneq ($(LO_CLANG_CC),)
+$(eval $(call gb_StaticLibrary_add_cflags,libpng,-ffat-lto-objects))
+endif
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libpng/UnpackedTarball_libpng.mk b/external/libpng/UnpackedTarball_libpng.mk
new file mode 100644
index 000000000..dca4e4b5c
--- /dev/null
+++ b/external/libpng/UnpackedTarball_libpng.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libpng))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libpng,$(LIBPNG_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_add_files,libpng,.,\
+ external/libpng/configs/pnglibconf.h \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libpng/configs/pnglibconf.h b/external/libpng/configs/pnglibconf.h
new file mode 100644
index 000000000..ff5d156a6
--- /dev/null
+++ b/external/libpng/configs/pnglibconf.h
@@ -0,0 +1,214 @@
+/* libpng 1.6.19 STANDARD API DEFINITION */
+
+/* pnglibconf.h - library build configuration */
+
+/* Libpng version 1.6.19 - November 12, 2015 */
+
+/* Copyright (c) 1998-2015 Glenn Randers-Pehrson */
+
+/* This code is released under the libpng license. */
+/* For conditions of distribution and use, see the disclaimer */
+/* and license in png.h */
+
+/* pnglibconf.h */
+/* Machine generated file: DO NOT EDIT */
+/* Derived from: scripts/pnglibconf.dfa */
+#ifndef PNGLCONF_H
+#define PNGLCONF_H
+/* options */
+#define PNG_16BIT_SUPPORTED
+#define PNG_ALIGNED_MEMORY_SUPPORTED
+/*#undef PNG_ARM_NEON_API_SUPPORTED*/
+/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
+#define PNG_BENIGN_ERRORS_SUPPORTED
+#define PNG_BENIGN_READ_ERRORS_SUPPORTED
+/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
+#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_COLORSPACE_SUPPORTED
+#define PNG_CONSOLE_IO_SUPPORTED
+#define PNG_CONVERT_tIME_SUPPORTED
+#define PNG_EASY_ACCESS_SUPPORTED
+/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
+#define PNG_ERROR_TEXT_SUPPORTED
+#define PNG_FIXED_POINT_SUPPORTED
+#define PNG_FLOATING_ARITHMETIC_SUPPORTED
+#define PNG_FLOATING_POINT_SUPPORTED
+#define PNG_FORMAT_AFIRST_SUPPORTED
+#define PNG_FORMAT_BGR_SUPPORTED
+#define PNG_GAMMA_SUPPORTED
+#define PNG_GET_PALETTE_MAX_SUPPORTED
+#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#define PNG_INCH_CONVERSIONS_SUPPORTED
+#define PNG_INFO_IMAGE_SUPPORTED
+#define PNG_IO_STATE_SUPPORTED
+#define PNG_MNG_FEATURES_SUPPORTED
+#define PNG_POINTER_INDEXING_SUPPORTED
+#define PNG_PROGRESSIVE_READ_SUPPORTED
+#define PNG_READ_16BIT_SUPPORTED
+#define PNG_READ_ALPHA_MODE_SUPPORTED
+#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_READ_BACKGROUND_SUPPORTED
+#define PNG_READ_BGR_SUPPORTED
+#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
+#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
+#define PNG_READ_EXPAND_16_SUPPORTED
+#define PNG_READ_EXPAND_SUPPORTED
+#define PNG_READ_FILLER_SUPPORTED
+#define PNG_READ_GAMMA_SUPPORTED
+#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
+#define PNG_READ_GRAY_TO_RGB_SUPPORTED
+#define PNG_READ_INTERLACING_SUPPORTED
+#define PNG_READ_INT_FUNCTIONS_SUPPORTED
+#define PNG_READ_INVERT_ALPHA_SUPPORTED
+#define PNG_READ_INVERT_SUPPORTED
+#define PNG_READ_OPT_PLTE_SUPPORTED
+#define PNG_READ_PACKSWAP_SUPPORTED
+#define PNG_READ_PACK_SUPPORTED
+#define PNG_READ_QUANTIZE_SUPPORTED
+#define PNG_READ_RGB_TO_GRAY_SUPPORTED
+#define PNG_READ_SCALE_16_TO_8_SUPPORTED
+#define PNG_READ_SHIFT_SUPPORTED
+#define PNG_READ_STRIP_16_TO_8_SUPPORTED
+#define PNG_READ_STRIP_ALPHA_SUPPORTED
+#define PNG_READ_SUPPORTED
+#define PNG_READ_SWAP_ALPHA_SUPPORTED
+#define PNG_READ_SWAP_SUPPORTED
+#define PNG_READ_TEXT_SUPPORTED
+#define PNG_READ_TRANSFORMS_SUPPORTED
+#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_READ_USER_CHUNKS_SUPPORTED
+#define PNG_READ_USER_TRANSFORM_SUPPORTED
+#define PNG_READ_bKGD_SUPPORTED
+#define PNG_READ_cHRM_SUPPORTED
+#define PNG_READ_gAMA_SUPPORTED
+#define PNG_READ_hIST_SUPPORTED
+#define PNG_READ_iCCP_SUPPORTED
+#define PNG_READ_iTXt_SUPPORTED
+#define PNG_READ_oFFs_SUPPORTED
+#define PNG_READ_pCAL_SUPPORTED
+#define PNG_READ_pHYs_SUPPORTED
+#define PNG_READ_sBIT_SUPPORTED
+#define PNG_READ_sCAL_SUPPORTED
+#define PNG_READ_sPLT_SUPPORTED
+#define PNG_READ_sRGB_SUPPORTED
+#define PNG_READ_tEXt_SUPPORTED
+#define PNG_READ_tIME_SUPPORTED
+#define PNG_READ_tRNS_SUPPORTED
+#define PNG_READ_zTXt_SUPPORTED
+#define PNG_SAVE_INT_32_SUPPORTED
+#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_SEQUENTIAL_READ_SUPPORTED
+#define PNG_SETJMP_SUPPORTED
+#define PNG_SET_OPTION_SUPPORTED
+#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_SET_USER_LIMITS_SUPPORTED
+#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_READ_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_SUPPORTED
+#define PNG_STDIO_SUPPORTED
+#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_TEXT_SUPPORTED
+#define PNG_TIME_RFC1123_SUPPORTED
+#define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_USER_CHUNKS_SUPPORTED
+#define PNG_USER_LIMITS_SUPPORTED
+#define PNG_USER_MEM_SUPPORTED
+#define PNG_USER_TRANSFORM_INFO_SUPPORTED
+#define PNG_USER_TRANSFORM_PTR_SUPPORTED
+#define PNG_WARNINGS_SUPPORTED
+#define PNG_WRITE_16BIT_SUPPORTED
+#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_WRITE_BGR_SUPPORTED
+#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+#define PNG_WRITE_FILLER_SUPPORTED
+#define PNG_WRITE_FILTER_SUPPORTED
+#define PNG_WRITE_FLUSH_SUPPORTED
+#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
+#define PNG_WRITE_INTERLACING_SUPPORTED
+#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+#define PNG_WRITE_INVERT_SUPPORTED
+#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+#define PNG_WRITE_PACKSWAP_SUPPORTED
+#define PNG_WRITE_PACK_SUPPORTED
+#define PNG_WRITE_SHIFT_SUPPORTED
+#define PNG_WRITE_SUPPORTED
+#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+#define PNG_WRITE_SWAP_SUPPORTED
+#define PNG_WRITE_TEXT_SUPPORTED
+#define PNG_WRITE_TRANSFORMS_SUPPORTED
+#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#define PNG_WRITE_bKGD_SUPPORTED
+#define PNG_WRITE_cHRM_SUPPORTED
+#define PNG_WRITE_gAMA_SUPPORTED
+#define PNG_WRITE_hIST_SUPPORTED
+#define PNG_WRITE_iCCP_SUPPORTED
+#define PNG_WRITE_iTXt_SUPPORTED
+#define PNG_WRITE_oFFs_SUPPORTED
+#define PNG_WRITE_pCAL_SUPPORTED
+#define PNG_WRITE_pHYs_SUPPORTED
+#define PNG_WRITE_sBIT_SUPPORTED
+#define PNG_WRITE_sCAL_SUPPORTED
+#define PNG_WRITE_sPLT_SUPPORTED
+#define PNG_WRITE_sRGB_SUPPORTED
+#define PNG_WRITE_tEXt_SUPPORTED
+#define PNG_WRITE_tIME_SUPPORTED
+#define PNG_WRITE_tRNS_SUPPORTED
+#define PNG_WRITE_zTXt_SUPPORTED
+#define PNG_bKGD_SUPPORTED
+#define PNG_cHRM_SUPPORTED
+#define PNG_gAMA_SUPPORTED
+#define PNG_hIST_SUPPORTED
+#define PNG_iCCP_SUPPORTED
+#define PNG_iTXt_SUPPORTED
+#define PNG_oFFs_SUPPORTED
+#define PNG_pCAL_SUPPORTED
+#define PNG_pHYs_SUPPORTED
+#define PNG_sBIT_SUPPORTED
+#define PNG_sCAL_SUPPORTED
+#define PNG_sPLT_SUPPORTED
+#define PNG_sRGB_SUPPORTED
+#define PNG_tEXt_SUPPORTED
+#define PNG_tIME_SUPPORTED
+#define PNG_tRNS_SUPPORTED
+#define PNG_zTXt_SUPPORTED
+/* end of options */
+/* settings */
+#define PNG_API_RULE 0
+#define PNG_DEFAULT_READ_MACROS 1
+#define PNG_GAMMA_THRESHOLD_FIXED 5000
+#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
+#define PNG_INFLATE_BUF_SIZE 1024
+#define PNG_LINKAGE_API extern
+#define PNG_LINKAGE_CALLBACK extern
+#define PNG_LINKAGE_DATA extern
+#define PNG_LINKAGE_FUNCTION extern
+#define PNG_MAX_GAMMA_8 11
+#define PNG_QUANTIZE_BLUE_BITS 5
+#define PNG_QUANTIZE_GREEN_BITS 5
+#define PNG_QUANTIZE_RED_BITS 5
+#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
+#define PNG_USER_CHUNK_CACHE_MAX 1000
+#define PNG_USER_CHUNK_MALLOC_MAX 8000000
+#define PNG_USER_HEIGHT_MAX 1000000
+#define PNG_USER_WIDTH_MAX 1000000
+#define PNG_ZBUF_SIZE 8192
+#define PNG_ZLIB_VERNUM 0 /* unknown */
+#define PNG_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
+#define PNG_Z_DEFAULT_STRATEGY 1
+#define PNG_sCAL_PRECISION 5
+#define PNG_sRGB_PROFILE_CHECKS 2
+/* end of settings */
+#endif /* PNGLCONF_H */
diff --git a/external/libqxp/ExternalProject_libqxp.mk b/external/libqxp/ExternalProject_libqxp.mk
new file mode 100644
index 000000000..fea48ffc4
--- /dev/null
+++ b/external/libqxp/ExternalProject_libqxp.mk
@@ -0,0 +1,48 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libqxp))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libqxp,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libqxp,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libqxp,\
+ boost_headers \
+ icu \
+ revenge \
+))
+
+$(call gb_ExternalProject_get_state_target,libqxp,build) :
+ $(call gb_Trace_StartRange,libqxp,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ --disable-tests \
+ --disable-tools \
+ --disable-debug \
+ --disable-werror \
+ --disable-weffc \
+ $(if $(gb_FULLDEPS),,--disable-dependency-tracking) \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libqxp)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libqxp)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libqxp,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libqxp/Makefile b/external/libqxp/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libqxp/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libqxp/Module_libqxp.mk b/external/libqxp/Module_libqxp.mk
new file mode 100644
index 000000000..8359683da
--- /dev/null
+++ b/external/libqxp/Module_libqxp.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libqxp))
+
+$(eval $(call gb_Module_add_targets,libqxp,\
+ ExternalProject_libqxp \
+ UnpackedTarball_libqxp \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libqxp/README b/external/libqxp/README
new file mode 100644
index 000000000..6f13b86fe
--- /dev/null
+++ b/external/libqxp/README
@@ -0,0 +1,4 @@
+libqxp is a library and a set of tools for reading and converting
+QuarkXPress file format. It supports versions 3.1-4.1 currently.
+
+[https://wiki.documentfoundation.org/DLP/Libraries/libqxp]
diff --git a/external/libqxp/UnpackedTarball_libqxp.mk b/external/libqxp/UnpackedTarball_libqxp.mk
new file mode 100644
index 000000000..9f111bcb2
--- /dev/null
+++ b/external/libqxp/UnpackedTarball_libqxp.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libqxp))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libqxp,$(QXP_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libqxp))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libqxp,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libqxp, \
+ external/libqxp/android-workaround.patch.1 \
+ external/libcdr/ax_gcc_func_attribute.m4.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libqxp/android-workaround.patch.1 b/external/libqxp/android-workaround.patch.1
new file mode 100644
index 000000000..5c7529c20
--- /dev/null
+++ b/external/libqxp/android-workaround.patch.1
@@ -0,0 +1,49 @@
+--- libqxp.orig/src/lib/QXP4Parser.cpp 2017-08-28 10:12:26.009868397 +0200
++++ libqxp/src/lib/QXP4Parser.cpp 2017-08-28 10:12:39.577681705 +0200
+@@ -16,6 +16,7 @@
+ #include "QXP4Header.h"
+ #include "QXPCollector.h"
+ #include "QXPMemoryStream.h"
++#include "android-compat.h"
+
+ namespace libqxp
+ {
+--- libqxp.orig/src/lib/QXPParser.cpp 2017-08-28 10:11:14.074858068 +0200
++++ libqxp/src/lib/QXPParser.cpp 2017-08-28 10:18:04.849203430 +0200
+@@ -14,6 +14,7 @@
+
+ #include <cmath>
+ #include <memory>
++#include "android-compat.h"
+
+ namespace libqxp
+ {
+--- libqxp.orig/src/lib/QXPTypes.cpp 2017-08-26 08:38:40.000000000 +0200
++++ libqxp/src/lib/QXPTypes.cpp 2017-08-28 10:18:37.784749714 +0200
+@@ -11,6 +11,7 @@
+
+ #include <boost/math/constants/constants.hpp>
+ #include <cmath>
++#include "android-compat.h"
+
+ namespace libqxp
+ {
+--- libqxp.orig/src/lib/android-compat.h 1970-01-01 01:00:00.000000000 +0100
++++ libqxp/src/lib/android-compat.h 2017-08-28 10:21:36.766283262 +0200
+@@ -0,0 +1,16 @@
++#if defined(__ANDROID__)
++namespace std
++{
++template<typename T>
++T round(T x)
++{
++ return ::round(x);
++}
++
++template<typename T>
++T hypot(T x, T y)
++{
++ return ::hypot(x, y);
++}
++}
++#endif
diff --git a/external/libqxp/ax_gcc_func_attribute.m4.patch b/external/libqxp/ax_gcc_func_attribute.m4.patch
new file mode 100644
index 000000000..8f7457816
--- /dev/null
+++ b/external/libqxp/ax_gcc_func_attribute.m4.patch
@@ -0,0 +1,11 @@
+--- configure
++++ configure
+@@ -18136,7 +18136,7 @@
+
+ _ACEOF
+ if ac_fn_cxx_try_link "$LINENO"; then :
+- if test -s conftest.err; then :
++ if grep -- -Wattributes conftest.err; then :
+ ax_cv_have_func_attribute_visibility=no
+ else
+ ax_cv_have_func_attribute_visibility=yes
diff --git a/external/librevenge/ExternalPackage_librevenge.mk b/external/librevenge/ExternalPackage_librevenge.mk
new file mode 100644
index 000000000..4ed404c63
--- /dev/null
+++ b/external/librevenge/ExternalPackage_librevenge.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,librevenge,librevenge))
+
+$(eval $(call gb_ExternalPackage_use_external_project,librevenge,librevenge))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,librevenge,$(LIBO_LIB_FOLDER)/librevenge-0.0.0.dylib,src/lib/.libs/librevenge-0.0.0.dylib))
+else ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,librevenge,$(LIBO_LIB_FOLDER)/librevenge-0.0.dll,src/lib/.libs/librevenge-0.0.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,librevenge,$(LIBO_LIB_FOLDER)/librevenge-0.0-lo.so.0,src/lib/.libs/librevenge-0.0-lo.so.0.0.$(REVENGE_VERSION_MICRO)))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/librevenge/ExternalProject_librevenge.mk b/external/librevenge/ExternalProject_librevenge.mk
new file mode 100644
index 000000000..4e64d5534
--- /dev/null
+++ b/external/librevenge/ExternalProject_librevenge.mk
@@ -0,0 +1,50 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,librevenge))
+
+$(eval $(call gb_ExternalProject_use_autoconf,librevenge,build))
+
+$(eval $(call gb_ExternalProject_register_targets,librevenge,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,librevenge,\
+ boost_headers \
+))
+
+$(call gb_ExternalProject_get_state_target,librevenge,build) :
+ $(call gb_Trace_StartRange,librevenge,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ $(if $(DISABLE_DYNLOADING), \
+ --disable-shared --enable-static, \
+ --enable-shared --disable-static) \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-werror \
+ --disable-weffc \
+ --disable-streams \
+ --disable-generators \
+ --without-docs \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,librevenge)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/lib/.libs/librevenge-0.0.0.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,librevenge,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/librevenge/Library_revenge.mk b/external/librevenge/Library_revenge.mk
new file mode 100644
index 000000000..4250e4e57
--- /dev/null
+++ b/external/librevenge/Library_revenge.mk
@@ -0,0 +1,48 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,revenge))
+
+$(eval $(call gb_Library_use_unpacked,revenge,librevenge))
+
+$(eval $(call gb_Library_use_externals,revenge,\
+ boost_headers \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,revenge))
+
+$(eval $(call gb_Library_set_include,revenge,\
+ -I$(call gb_UnpackedTarball_get_dir,librevenge)/inc \
+ $$(INCLUDE) \
+))
+
+# -DLIBREVENGE_STREAM_BUILD is present so that linker does not complain
+# about unresolved external symbol RVNGStream::~RVNGStream
+$(eval $(call gb_Library_add_defs,revenge,\
+ -DBOOST_ALL_NO_LIB \
+ -DDLL_EXPORT \
+ -DLIBREVENGE_BUILD \
+ -DLIBREVENGE_STREAM_BUILD \
+ -DNDEBUG \
+))
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,revenge,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,revenge,\
+ UnpackedTarball/librevenge/src/lib/RVNGBinaryData \
+ UnpackedTarball/librevenge/src/lib/RVNGMemoryStream \
+ UnpackedTarball/librevenge/src/lib/RVNGProperty \
+ UnpackedTarball/librevenge/src/lib/RVNGPropertyList \
+ UnpackedTarball/librevenge/src/lib/RVNGPropertyListVector \
+ UnpackedTarball/librevenge/src/lib/RVNGString \
+ UnpackedTarball/librevenge/src/lib/RVNGStringVector \
+ UnpackedTarball/librevenge/src/lib/RVNGSVGDrawingGenerator \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/librevenge/Makefile b/external/librevenge/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/librevenge/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/librevenge/Module_librevenge.mk b/external/librevenge/Module_librevenge.mk
new file mode 100644
index 000000000..cd11805f0
--- /dev/null
+++ b/external/librevenge/Module_librevenge.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,librevenge))
+
+$(eval $(call gb_Module_add_targets,librevenge,\
+ UnpackedTarball_librevenge \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,librevenge,\
+ Library_revenge \
+))
+
+else
+
+$(eval $(call gb_Module_add_targets,librevenge,\
+ ExternalPackage_librevenge \
+ ExternalProject_librevenge \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/librevenge/README b/external/librevenge/README
new file mode 100644
index 000000000..23007ff99
--- /dev/null
+++ b/external/librevenge/README
@@ -0,0 +1,3 @@
+From [http://sourceforge.net/p/libwpd/wiki/librevenge/]. A base library
+for writing document import filters. It has interfaces for text documents,
+vector graphics, spreadsheets and presentations.
diff --git a/external/librevenge/UnpackedTarball_librevenge.mk b/external/librevenge/UnpackedTarball_librevenge.mk
new file mode 100644
index 000000000..74f28751c
--- /dev/null
+++ b/external/librevenge/UnpackedTarball_librevenge.mk
@@ -0,0 +1,30 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,librevenge))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,librevenge,$(REVENGE_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,librevenge))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,librevenge,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,librevenge, \
+ external/librevenge/rpath.patch \
+))
+
+ifneq ($(OS),MACOSX)
+ifneq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,librevenge, \
+ external/librevenge/librevenge-bundled-soname.patch.0 \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/librevenge/librevenge-bundled-soname.patch.0 b/external/librevenge/librevenge-bundled-soname.patch.0
new file mode 100644
index 000000000..d98630f0c
--- /dev/null
+++ b/external/librevenge/librevenge-bundled-soname.patch.0
@@ -0,0 +1,11 @@
+--- src/lib/Makefile.in.orig 2015-08-07 11:57:42.256742305 +0200
++++ src/lib/Makefile.in 2015-08-07 11:58:11.818741799 +0200
+@@ -470,7 +470,7 @@
+ $(am__append_2)
+ librevenge_@RVNG_MAJOR_VERSION@_@RVNG_MINOR_VERSION@_la_LIBADD = @LIBREVENGE_WIN32_RESOURCE@
+ librevenge_@RVNG_MAJOR_VERSION@_@RVNG_MINOR_VERSION@_la_DEPENDENCIES = @LIBREVENGE_WIN32_RESOURCE@
+-librevenge_@RVNG_MAJOR_VERSION@_@RVNG_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic $(no_undefined)
++librevenge_@RVNG_MAJOR_VERSION@_@RVNG_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic $(no_undefined) -release lo
+ librevenge_@RVNG_MAJOR_VERSION@_@RVNG_MINOR_VERSION@_la_SOURCES = \
+ RVNGBinaryData.cpp \
+ RVNGMemoryStream.cpp \
diff --git a/external/librevenge/rpath.patch b/external/librevenge/rpath.patch
new file mode 100644
index 000000000..c7d210080
--- /dev/null
+++ b/external/librevenge/rpath.patch
@@ -0,0 +1,11 @@
+--- configure
++++ configure
+@@ -14983,6 +14983,8 @@
+ esac
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
++runpath_var=
+ ;;
+
+ lynxos*)
diff --git a/external/libstaroffice/ExternalPackage_libstaroffice.mk b/external/libstaroffice/ExternalPackage_libstaroffice.mk
new file mode 100644
index 000000000..939fbbc2c
--- /dev/null
+++ b/external/libstaroffice/ExternalPackage_libstaroffice.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libstaroffice,libstaroffice))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libstaroffice,libstaroffice))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,libstaroffice,$(LIBO_LIB_FOLDER)/libstaroffice-0.0.0.dylib,src/lib/.libs/libstaroffice-0.0.0.dylib))
+else ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,libstaroffice,$(LIBO_LIB_FOLDER)/libstaroffice-0.0.dll,src/lib/.libs/libstaroffice-0.0.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,libstaroffice,$(LIBO_LIB_FOLDER)/libstaroffice-0.0-lo.so.0,src/lib/.libs/libstaroffice-0.0-lo.so.0.0.$(STAROFFICE_VERSION_MICRO)))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libstaroffice/ExternalProject_libstaroffice.mk b/external/libstaroffice/ExternalProject_libstaroffice.mk
new file mode 100644
index 000000000..a81428e71
--- /dev/null
+++ b/external/libstaroffice/ExternalProject_libstaroffice.mk
@@ -0,0 +1,54 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libstaroffice))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libstaroffice,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libstaroffice,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libstaroffice,\
+ revenge \
+))
+
+$(call gb_ExternalProject_get_state_target,libstaroffice,build) :
+ $(call gb_Trace_StartRange,libstaroffice,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ --with-sharedptr=c++11 \
+ --without-docs \
+ --disable-tools \
+ --disable-zip \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ --disable-werror \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libstaroffice)" \
+ $(if $(filter LINUX,$(OS)),$(if $(SYSTEM_REVENGE),, \
+ 'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN')) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/lib/.libs/libstaroffice-0.0.0.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,libstaroffice,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libstaroffice/Library_staroffice.mk b/external/libstaroffice/Library_staroffice.mk
new file mode 100644
index 000000000..66b35501d
--- /dev/null
+++ b/external/libstaroffice/Library_staroffice.mk
@@ -0,0 +1,114 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,staroffice))
+
+$(eval $(call gb_Library_use_unpacked,staroffice,libstaroffice))
+
+$(eval $(call gb_Library_use_externals,staroffice,\
+ revenge \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,staroffice))
+
+$(eval $(call gb_Library_set_precompiled_header,staroffice,external/libstaroffice/inc/pch/precompiled_staroffice))
+
+$(eval $(call gb_Library_set_include,staroffice,\
+ -I$(call gb_UnpackedTarball_get_dir,libstaroffice)/inc \
+ -I$(call gb_UnpackedTarball_get_dir,libstaroffice)/src/lib \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,staroffice,\
+ -DBUILD_STOFF \
+ -D_WINDLL \
+ -DNDEBUG \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,staroffice,\
+ UnpackedTarball/libstaroffice/src/lib/SDAParser \
+ UnpackedTarball/libstaroffice/src/lib/SDCParser \
+ UnpackedTarball/libstaroffice/src/lib/SDGParser \
+ UnpackedTarball/libstaroffice/src/lib/SDWParser \
+ UnpackedTarball/libstaroffice/src/lib/SDXParser \
+ UnpackedTarball/libstaroffice/src/lib/STOFFCell \
+ UnpackedTarball/libstaroffice/src/lib/STOFFCellStyle \
+ UnpackedTarball/libstaroffice/src/lib/STOFFChart \
+ UnpackedTarball/libstaroffice/src/lib/STOFFDebug \
+ UnpackedTarball/libstaroffice/src/lib/STOFFDocument \
+ UnpackedTarball/libstaroffice/src/lib/STOFFEntry \
+ UnpackedTarball/libstaroffice/src/lib/STOFFFont \
+ UnpackedTarball/libstaroffice/src/lib/STOFFFrameStyle \
+ UnpackedTarball/libstaroffice/src/lib/STOFFGraphicDecoder \
+ UnpackedTarball/libstaroffice/src/lib/STOFFGraphicEncoder \
+ UnpackedTarball/libstaroffice/src/lib/STOFFGraphicListener \
+ UnpackedTarball/libstaroffice/src/lib/STOFFGraphicShape \
+ UnpackedTarball/libstaroffice/src/lib/STOFFGraphicStyle \
+ UnpackedTarball/libstaroffice/src/lib/STOFFHeader \
+ UnpackedTarball/libstaroffice/src/lib/STOFFInputStream \
+ UnpackedTarball/libstaroffice/src/lib/STOFFList \
+ UnpackedTarball/libstaroffice/src/lib/STOFFListener \
+ UnpackedTarball/libstaroffice/src/lib/STOFFOLEParser \
+ UnpackedTarball/libstaroffice/src/lib/STOFFPageSpan \
+ UnpackedTarball/libstaroffice/src/lib/STOFFParagraph \
+ UnpackedTarball/libstaroffice/src/lib/STOFFParser \
+ UnpackedTarball/libstaroffice/src/lib/STOFFPosition \
+ UnpackedTarball/libstaroffice/src/lib/STOFFPropertyHandler \
+ UnpackedTarball/libstaroffice/src/lib/STOFFSection \
+ UnpackedTarball/libstaroffice/src/lib/STOFFSpreadsheetDecoder \
+ UnpackedTarball/libstaroffice/src/lib/STOFFSpreadsheetEncoder \
+ UnpackedTarball/libstaroffice/src/lib/STOFFSpreadsheetListener \
+ UnpackedTarball/libstaroffice/src/lib/STOFFStarMathToMMLConverter \
+ UnpackedTarball/libstaroffice/src/lib/STOFFStringStream \
+ UnpackedTarball/libstaroffice/src/lib/STOFFSubDocument \
+ UnpackedTarball/libstaroffice/src/lib/STOFFTable \
+ UnpackedTarball/libstaroffice/src/lib/STOFFTextListener \
+ UnpackedTarball/libstaroffice/src/lib/SWFieldManager \
+ UnpackedTarball/libstaroffice/src/lib/StarAttribute \
+ UnpackedTarball/libstaroffice/src/lib/StarBitmap \
+ UnpackedTarball/libstaroffice/src/lib/StarCellAttribute \
+ UnpackedTarball/libstaroffice/src/lib/StarCellFormula \
+ UnpackedTarball/libstaroffice/src/lib/StarCharAttribute \
+ UnpackedTarball/libstaroffice/src/lib/StarEncoding \
+ UnpackedTarball/libstaroffice/src/lib/StarEncodingChinese \
+ UnpackedTarball/libstaroffice/src/lib/StarEncodingJapanese \
+ UnpackedTarball/libstaroffice/src/lib/StarEncodingKorean \
+ UnpackedTarball/libstaroffice/src/lib/StarEncodingOtherKorean \
+ UnpackedTarball/libstaroffice/src/lib/StarEncodingTradChinese \
+ UnpackedTarball/libstaroffice/src/lib/StarEncryption \
+ UnpackedTarball/libstaroffice/src/lib/StarFileManager \
+ UnpackedTarball/libstaroffice/src/lib/StarFormatManager \
+ UnpackedTarball/libstaroffice/src/lib/StarFrameAttribute \
+ UnpackedTarball/libstaroffice/src/lib/StarGraphicAttribute \
+ UnpackedTarball/libstaroffice/src/lib/StarGraphicStruct \
+ UnpackedTarball/libstaroffice/src/lib/StarItem \
+ UnpackedTarball/libstaroffice/src/lib/StarItemPool \
+ UnpackedTarball/libstaroffice/src/lib/StarLanguage \
+ UnpackedTarball/libstaroffice/src/lib/StarLayout \
+ UnpackedTarball/libstaroffice/src/lib/StarObject \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectChart \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectDraw \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectMath \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectModel \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectNumericRuler \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectPageStyle \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectSmallGraphic \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectSmallText \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectSpreadsheet \
+ UnpackedTarball/libstaroffice/src/lib/StarObjectText \
+ UnpackedTarball/libstaroffice/src/lib/StarPageAttribute \
+ UnpackedTarball/libstaroffice/src/lib/StarParagraphAttribute \
+ UnpackedTarball/libstaroffice/src/lib/StarState \
+ UnpackedTarball/libstaroffice/src/lib/StarTable \
+ UnpackedTarball/libstaroffice/src/lib/StarWriterStruct \
+ UnpackedTarball/libstaroffice/src/lib/StarZone \
+ UnpackedTarball/libstaroffice/src/lib/libstaroffice_internal \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libstaroffice/Makefile b/external/libstaroffice/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libstaroffice/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libstaroffice/Module_libstaroffice.mk b/external/libstaroffice/Module_libstaroffice.mk
new file mode 100644
index 000000000..b96bde2b1
--- /dev/null
+++ b/external/libstaroffice/Module_libstaroffice.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libstaroffice))
+
+$(eval $(call gb_Module_add_targets,libstaroffice,\
+ UnpackedTarball_libstaroffice \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,libstaroffice,\
+ Library_staroffice \
+))
+
+else
+
+$(eval $(call gb_Module_add_targets,libstaroffice,\
+ ExternalPackage_libstaroffice \
+ ExternalProject_libstaroffice \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libstaroffice/README b/external/libstaroffice/README
new file mode 100644
index 000000000..957fb4926
--- /dev/null
+++ b/external/libstaroffice/README
@@ -0,0 +1,3 @@
+Library parsing different document file formats of StarOffice.
+
+https://github.com/fosnola/libstaroffice
diff --git a/external/libstaroffice/UnpackedTarball_libstaroffice.mk b/external/libstaroffice/UnpackedTarball_libstaroffice.mk
new file mode 100644
index 000000000..b7d8f4ee7
--- /dev/null
+++ b/external/libstaroffice/UnpackedTarball_libstaroffice.mk
@@ -0,0 +1,32 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libstaroffice))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libstaroffice,$(STAROFFICE_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libstaroffice,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libstaroffice))
+
+ifneq ($(OS),MACOSX)
+ifneq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,libstaroffice, \
+ external/libstaroffice/libstaroffice-bundled-soname.patch.0 \
+))
+endif
+endif
+
+ifeq ($(SYSTEM_REVENGE),)
+$(eval $(call gb_UnpackedTarball_add_patches,libstaroffice, \
+ external/libstaroffice/rpath.patch \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libstaroffice/inc/pch/precompiled_staroffice.cxx b/external/libstaroffice/inc/pch/precompiled_staroffice.cxx
new file mode 100644
index 000000000..5e5bfdb72
--- /dev/null
+++ b/external/libstaroffice/inc/pch/precompiled_staroffice.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_staroffice.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libstaroffice/inc/pch/precompiled_staroffice.hxx b/external/libstaroffice/inc/pch/precompiled_staroffice.hxx
new file mode 100644
index 000000000..1ad24c005
--- /dev/null
+++ b/external/libstaroffice/inc/pch/precompiled_staroffice.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2019-10-13 10:27:57 using:
+ ./bin/update_pch external/libstaroffice staroffice --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/libstaroffice/inc/pch/precompiled_staroffice.hxx "make external/libstaroffice.build" --find-conflicts
+*/
+
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <cctype>
+#include <cmath>
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctype.h>
+#include <functional>
+#include <iomanip>
+#include <iostream>
+#include <limits>
+#include <locale.h>
+#include <map>
+#include <math.h>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <stack>
+#include <string.h>
+#include <string>
+#include <time.h>
+#include <utility>
+#include <vector>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <librevenge-stream/librevenge-stream.h>
+#include <librevenge/librevenge.h>
+#include <libstaroffice/libstaroffice.hxx>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libstaroffice/libstaroffice-bundled-soname.patch.0 b/external/libstaroffice/libstaroffice-bundled-soname.patch.0
new file mode 100644
index 000000000..00b064d10
--- /dev/null
+++ b/external/libstaroffice/libstaroffice-bundled-soname.patch.0
@@ -0,0 +1,11 @@
+--- src/lib/Makefile.in.orig 2015-08-07 14:04:47.646611627 +0200
++++ src/lib/Makefile.in 2015-08-07 14:25:49.888589996 +0200
+@@ -418,7 +418,7 @@
+ AM_CXXFLAGS = -I$(top_srcdir)/inc $(REVENGE_CFLAGS) $(DEBUG_CXXFLAGS) $(ZLIB_CFLAGS) -DBUILD_STAROFFICE=1
+ libstaroffice_@STAROFFICE_MAJOR_VERSION@_@STAROFFICE_MINOR_VERSION@_la_LIBADD = $(REVENGE_LIBS) $(ZLIB_LIBS) @LIBSTAROFFICE_WIN32_RESOURCE@
+ libstaroffice_@STAROFFICE_MAJOR_VERSION@_@STAROFFICE_MINOR_VERSION@_la_DEPENDENCIES = @LIBSTAROFFICE_WIN32_RESOURCE@
+-libstaroffice_@STAROFFICE_MAJOR_VERSION@_@STAROFFICE_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined
++libstaroffice_@STAROFFICE_MAJOR_VERSION@_@STAROFFICE_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined -release lo
+ libstaroffice_@STAROFFICE_MAJOR_VERSION@_@STAROFFICE_MINOR_VERSION@_la_SOURCES = \
+ SDAParser.cxx \
+ SDAParser.hxx \
diff --git a/external/libstaroffice/rpath.patch b/external/libstaroffice/rpath.patch
new file mode 100644
index 000000000..a73d8ae22
--- /dev/null
+++ b/external/libstaroffice/rpath.patch
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -15353,6 +15353,7 @@
+ esac
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+
+ lynxos*)
diff --git a/external/libtiff/ExternalProject_libtiff.mk b/external/libtiff/ExternalProject_libtiff.mk
new file mode 100644
index 000000000..e318126dc
--- /dev/null
+++ b/external/libtiff/ExternalProject_libtiff.mk
@@ -0,0 +1,72 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libtiff))
+
+$(eval $(call gb_ExternalProject_register_targets,libtiff,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libtiff,\
+ libjpeg \
+ libwebp \
+ zlib \
+))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libtiff,build))
+
+# using ac_cv_lib_z_inflateEnd=yes to skip test for our
+# static windows lib where the name is zlib not z
+# using ac_cv_lib_jpeg_jpeg_read_scanlines to skip test
+# for our static windows lib where the name is libjpeg-turbo.lib
+# not libjpeg.lib
+# we're building this statically anyway so the lib isn't
+# used during the link done here
+
+$(call gb_ExternalProject_get_state_target,libtiff,build) :
+ $(call gb_Trace_StartRange,libtiff,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --enable-static \
+ --enable-jpeg \
+ --enable-zlib \
+ --enable-webp \
+ --disable-shared \
+ --disable-cxx \
+ --disable-libdeflate \
+ --disable-jbig \
+ --disable-lerc \
+ --disable-lzma \
+ --disable-mdi \
+ --disable-win32-io \
+ --disable-zstd \
+ --with-pic \
+ --without-x \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CFLAGS="$(CFLAGS) $(call gb_ExternalProject_get_build_flags,libtiff) $(gb_EMSCRIPTEN_CFLAGS)" \
+ $(if $(SYSTEM_ZLIB),,--with-zlib-include-dir="$(call gb_UnpackedTarball_get_dir,zlib)") \
+ $(if $(SYSTEM_ZLIB),,--with-zlib-lib-dir="$(gb_StaticLibrary_WORKDIR)") \
+ $(if $(SYSTEM_LIBJPEG),,--with-jpeg-include-dir="$(call gb_UnpackedTarball_get_dir,libjpeg-turbo)") \
+ $(if $(SYSTEM_LIBJPEG),,--with-jpeg-lib-dir="$(gb_StaticLibrary_WORKDIR)") \
+ $(if $(SYSTEM_LIBWEBP),,--with-webp-include-dir="$(call gb_UnpackedTarball_get_dir,libwebp/src)") \
+ $(if $(SYSTEM_LIBWEBP),,$(if $(filter WNT,$(OS_FOR_BUILD)),\
+ --with-webp-lib-dir="$(call gb_UnpackedTarball_get_dir,libwebp)/output/lib/libwebp$(if $(MSVC_USE_DEBUG_RUNTIME),_debug)$(gb_StaticLibrary_PLAINEXT)", \
+ --with-webp-lib-dir="$(call gb_UnpackedTarball_get_dir,libwebp)/src/.libs")) \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS) $(gb_EMSCRIPTEN_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libtiff) $(gb_EMSCRIPTEN_LDFLAGS)" \
+ ac_cv_lib_z_inflateEnd=yes \
+ ac_cv_lib_jpeg_jpeg_read_scanlines=yes \
+ ac_cv_lib_webp_WebPDecode=yes \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && cd libtiff && $(MAKE) libtiff.la \
+ )
+ $(call gb_Trace_EndRange,libtiff,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libtiff/Makefile b/external/libtiff/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libtiff/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libtiff/Module_libtiff.mk b/external/libtiff/Module_libtiff.mk
new file mode 100644
index 000000000..adf8114e6
--- /dev/null
+++ b/external/libtiff/Module_libtiff.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libtiff))
+
+$(eval $(call gb_Module_add_targets,libtiff,\
+ ExternalProject_libtiff \
+ UnpackedTarball_libtiff \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libtiff/README b/external/libtiff/README
new file mode 100644
index 000000000..a650ea584
--- /dev/null
+++ b/external/libtiff/README
@@ -0,0 +1,3 @@
+libtiff is a library to encode and decode images in TIFF format, from [http://download.osgeo.org/libtiff/]
+
+For the moment we use it only for decoding part.
diff --git a/external/libtiff/UnpackedTarball_libtiff.mk b/external/libtiff/UnpackedTarball_libtiff.mk
new file mode 100644
index 000000000..ce5a3a53d
--- /dev/null
+++ b/external/libtiff/UnpackedTarball_libtiff.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libtiff))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libtiff,$(LIBTIFF_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libtiff,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libtiff,\
+ external/libtiff/libtiff.linknolibs.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libtiff/libtiff.linknolibs.patch b/external/libtiff/libtiff.linknolibs.patch
new file mode 100644
index 000000000..0017ca9ca
--- /dev/null
+++ b/external/libtiff/libtiff.linknolibs.patch
@@ -0,0 +1,11 @@
+--- libtiff/Makefile.in 2022-05-21 15:32:48.069999327 +0100
++++ libtiff/Makefile.in 2022-05-21 15:32:59.051499293 +0100
+@@ -372,7 +372,7 @@
+ LDFLAGS = @LDFLAGS@
+ LIBDIR = @LIBDIR@
+ LIBOBJS = @LIBOBJS@
+-LIBS = @LIBS@
++#LIBS = @LIBS@
+ LIBTIFF_ALPHA_VERSION = @LIBTIFF_ALPHA_VERSION@
+ LIBTIFF_DOCDIR = @LIBTIFF_DOCDIR@
+ LIBTIFF_MAJOR_VERSION = @LIBTIFF_MAJOR_VERSION@
diff --git a/external/libtommath/ExternalProject_libtommath.mk b/external/libtommath/ExternalProject_libtommath.mk
new file mode 100644
index 000000000..2b4fb9fbd
--- /dev/null
+++ b/external/libtommath/ExternalProject_libtommath.mk
@@ -0,0 +1,38 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libtommath))
+
+$(eval $(call gb_ExternalProject_register_targets,libtommath,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_nmake,libtommath,build))
+
+ifeq ($(COM),MSC)
+$(call gb_ExternalProject_get_state_target,libtommath,build):
+ $(call gb_Trace_StartRange,libtommath,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ nmake -nologo -f makefile.msvc \
+ )
+ $(call gb_Trace_EndRange,libtommath,EXTERNAL)
+else
+$(call gb_ExternalProject_get_state_target,libtommath,build) :
+ $(call gb_Trace_StartRange,libtommath,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ unset MAKEFLAGS \
+ && export CFLAGS=" \
+ -fPIC \
+ " \
+ && $(MAKE) $(if $(verbose),V=1) NO_ADDTL_WARNINGS=1 \
+ )
+ $(call gb_Trace_EndRange,libtommath,EXTERNAL)
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libtommath/Makefile b/external/libtommath/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libtommath/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libtommath/Module_libtommath.mk b/external/libtommath/Module_libtommath.mk
new file mode 100644
index 000000000..def67f839
--- /dev/null
+++ b/external/libtommath/Module_libtommath.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libtommath))
+
+$(eval $(call gb_Module_add_targets,libtommath,\
+ ExternalProject_libtommath \
+ UnpackedTarball_libtommath \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libtommath/README b/external/libtommath/README
new file mode 100644
index 000000000..0da3128c5
--- /dev/null
+++ b/external/libtommath/README
@@ -0,0 +1,6 @@
+LibTomMath is a free open source portable number theoretic multiple-precision
+integer library written entirely in C.
+
+Used by embedded firebird (external/firebird).
+
+http://www.libtom.org/LibTomMath/
diff --git a/external/libtommath/UnpackedTarball_libtommath.mk b/external/libtommath/UnpackedTarball_libtommath.mk
new file mode 100644
index 000000000..bb0b9e352
--- /dev/null
+++ b/external/libtommath/UnpackedTarball_libtommath.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libtommath))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libtommath,$(LIBTOMMATH_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libtommath,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libtommath,\
+ external/libtommath/libtommath-msvc.patch \
+ external/libtommath/clang-cl.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libtommath/clang-cl.patch b/external/libtommath/clang-cl.patch
new file mode 100644
index 000000000..1cc92d380
--- /dev/null
+++ b/external/libtommath/clang-cl.patch
@@ -0,0 +1,16 @@
+--- tommath.h
++++ tommath.h
+@@ -15,6 +15,13 @@
+ #ifndef BN_H_
+ #define BN_H_
+
++// Work around clang-cl issue when mp_word is a typedef for unsigned __int128, see
++// <https://bugs.llvm.org/show_bug.cgi?id=25305> "Clang-cl generates a call to an undefined symbol
++// _udivti3":
++#if defined _WIN32 && defined __clang__
++#define MP_8BIT
++#endif
++
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdint.h>
diff --git a/external/libtommath/libtommath-msvc.patch b/external/libtommath/libtommath-msvc.patch
new file mode 100644
index 000000000..07884871a
--- /dev/null
+++ b/external/libtommath/libtommath-msvc.patch
@@ -0,0 +1,12 @@
+--- makefile.msvc 2016-02-05 23:25:32.000000000 +0100
++++ makefile.msvc 2016-07-21 11:34:20.618390100 +0200
+@@ -38,3 +38,9 @@
+
+ library: $(OBJECTS)
+ lib /out:tommath.lib $(OBJECTS)
++
++.cc.obj:
++ $(CC) /nologo $(CFLAGS) /c $<
++
++.c.obj:
++ $(CC) /nologo $(CFLAGS) /c $<
diff --git a/external/libvisio/ExternalProject_libvisio.mk b/external/libvisio/ExternalProject_libvisio.mk
new file mode 100644
index 000000000..01fe27290
--- /dev/null
+++ b/external/libvisio/ExternalProject_libvisio.mk
@@ -0,0 +1,48 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libvisio))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libvisio,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libvisio,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libvisio,\
+ boost_headers \
+ icu \
+ libxml2 \
+ revenge \
+))
+
+$(call gb_ExternalProject_get_state_target,libvisio,build) :
+ $(call gb_Trace_StartRange,libvisio,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ --disable-tests \
+ --disable-tools \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-werror \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(gb_FULLDEPS),,--disable-dependency-tracking) \
+ CXXFLAGS="$(CXXFLAGS) $(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libvisio)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libvisio)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libvisio,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libvisio/Makefile b/external/libvisio/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libvisio/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libvisio/Module_libvisio.mk b/external/libvisio/Module_libvisio.mk
new file mode 100644
index 000000000..00b05d25d
--- /dev/null
+++ b/external/libvisio/Module_libvisio.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libvisio))
+
+$(eval $(call gb_Module_add_targets,libvisio,\
+ ExternalProject_libvisio \
+ UnpackedTarball_libvisio \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libvisio/README b/external/libvisio/README
new file mode 100644
index 000000000..d3ddc6c9b
--- /dev/null
+++ b/external/libvisio/README
@@ -0,0 +1,3 @@
+Libvisio is library providing ability to interpret and import visio diagrams into various applications.
+
+[https://wiki.documentfoundation.org/DLP/Libraries/libvisio]
diff --git a/external/libvisio/UnpackedTarball_libvisio.mk b/external/libvisio/UnpackedTarball_libvisio.mk
new file mode 100644
index 000000000..e19878740
--- /dev/null
+++ b/external/libvisio/UnpackedTarball_libvisio.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libvisio))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libvisio,$(VISIO_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libvisio,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libvisio))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libvisio, \
+ external/libvisio/ubsan.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libvisio/ubsan.patch b/external/libvisio/ubsan.patch
new file mode 100644
index 000000000..c9ffbd98f
--- /dev/null
+++ b/external/libvisio/ubsan.patch
@@ -0,0 +1,11 @@
+--- src/lib/VSDContentCollector.cpp
++++ src/lib/VSDContentCollector.cpp
+@@ -3220,7 +3220,7 @@
+ }
+ if (U_SUCCESS(status) && conv)
+ {
+- const auto *src = (const char *)&characters[0];
++ const auto *src = (const char *)characters.data();
+ const char *srcLimit = (const char *)src + characters.size();
+ while (src < srcLimit)
+ {
diff --git a/external/libwebp/ExternalProject_libwebp.mk b/external/libwebp/ExternalProject_libwebp.mk
new file mode 100644
index 000000000..0146bd72a
--- /dev/null
+++ b/external/libwebp/ExternalProject_libwebp.mk
@@ -0,0 +1,58 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libwebp))
+
+$(eval $(call gb_ExternalProject_register_targets,libwebp,\
+ build \
+))
+
+ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalProject_use_nmake,libwebp,build))
+
+# Explicitly passing in ARCH (for the known architectures, at least) avoids
+# workdir/UnpackedTarball/libwebp/Makefile.vc not being able to detect it when CC is clang-cl:
+$(call gb_ExternalProject_get_state_target,libwebp,build):
+ $(call gb_Trace_StartRange,libwebp,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ nmake -nologo -f Makefile.vc CFG=$(if $(MSVC_USE_DEBUG_RUNTIME),debug,release)-static RTLIBCFG=dynamic OBJDIR=output \
+ $(if $(filter INTEL,$(CPUNAME)),ARCH=x86, \
+ $(if $(filter X86_64,$(CPUNAME)),ARCH=x64, \
+ $(if $(filter AARCH64,$(CPUNAME)),ARCH=ARM))) \
+ )
+ $(call gb_Trace_EndRange,libwebp,EXTERNAL)
+else
+$(eval $(call gb_ExternalProject_use_autoconf,libwebp,build))
+
+$(call gb_ExternalProject_get_state_target,libwebp,build) :
+ $(call gb_Trace_StartRange,libwebp,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --enable-static \
+ --with-pic \
+ --disable-shared \
+ --disable-gl \
+ --disable-sdl \
+ --disable-png \
+ --disable-jpeg \
+ --disable-tiff \
+ --disable-gif \
+ --disable-wic \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CFLAGS="$(CFLAGS) $(call gb_ExternalProject_get_build_flags,libwebp)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libwebp)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libwebp,EXTERNAL)
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwebp/Makefile b/external/libwebp/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libwebp/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwebp/Makefile.vc.patch b/external/libwebp/Makefile.vc.patch
new file mode 100644
index 000000000..f13c12410
--- /dev/null
+++ b/external/libwebp/Makefile.vc.patch
@@ -0,0 +1,148 @@
+--- Makefile.vc.sav 2021-07-30 00:55:37.000000000 +0200
++++ Makefile.vc 2022-01-25 17:35:30.206117700 +0100
+@@ -7,11 +7,11 @@
+ LIBWEBPDEMUX_BASENAME = libwebpdemux
+
+ !IFNDEF ARCH
+-!IF ! [ cl 2>&1 | find "x86" > NUL ]
++!IF ! [ $(CC) 2>&1 | grep -q "x86" > NUL ]
+ ARCH = x86
+-!ELSE IF ! [ cl 2>&1 | find "x64" > NUL ]
++!ELSE IF ! [ $(CC) 2>&1 | grep -q "x64" > NUL ]
+ ARCH = x64
+-!ELSE IF ! [ cl 2>&1 | find "ARM" > NUL ]
++!ELSE IF ! [ $(CC) 2>&1 | grep -q "ARM" > NUL ]
+ ARCH = ARM
+ !ELSE
+ !ERROR Unable to auto-detect toolchain architecture! \
+@@ -27,8 +27,8 @@
+ ## Nothing more to do below this line!
+
+ NOLOGO = /nologo
+-CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
+-CCDEBUG = cl.exe $(NOLOGO) /Od /Zi /D_DEBUG /RTC1
++CCNODBG = $(CC) $(NOLOGO) /O2 /DNDEBUG
++CCDEBUG = $(CC) $(NOLOGO) /Od /Zi /D_DEBUG /RTC1
+ CFLAGS = /I. /Isrc $(NOLOGO) /W3 /EHsc /c
+ CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
+ LDFLAGS = /LARGEADDRESSAWARE /MANIFEST:EMBED /NXCOMPAT /DYNAMICBASE
+@@ -67,7 +67,7 @@
+ RTLIB = /MD
+ RTLIBD = /MDd
+ !ENDIF
+-DIRBASE = $(OUTDIR)\$(CFG)\$(ARCH)
++DIRBASE = $(OUTDIR)
+ DIROBJ = $(DIRBASE)\obj
+ DIRLIB = $(DIRBASE)\lib
+ DIRINC = $(DIRBASE)\include
+@@ -86,10 +86,10 @@
+
+ # Target configuration
+ !IF "$(CFG)" == "release-static"
+-CC = $(CCNODBG)
++CC_ = $(CCNODBG)
+ STATICLIBBUILD = TRUE
+ !ELSE IF "$(CFG)" == "debug-static"
+-CC = $(CCDEBUG)
++CC_ = $(CCDEBUG)
+ RTLIB = $(RTLIBD)
+ STATICLIBBUILD = TRUE
+ LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug
+@@ -97,11 +97,11 @@
+ LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug
+ LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug
+ !ELSE IF "$(CFG)" == "release-dynamic"
+-CC = $(CCNODBG)
++CC_ = $(CCNODBG)
+ RC = $(RCNODBG)
+ DLLBUILD = TRUE
+ !ELSE IF "$(CFG)" == "debug-dynamic"
+-CC = $(CCDEBUG)
++CC_ = $(CCDEBUG)
+ RC = $(RCDEBUG)
+ RTLIB = $(RTLIBD)
+ DLLBUILD = TRUE
+@@ -112,7 +112,7 @@
+ !ENDIF
+
+ !IF "$(STATICLIBBUILD)" == "TRUE"
+-CC = $(CC) $(RTLIB)
++CC_ = $(CC_) $(RTLIB)
+ CFGSET = TRUE
+ LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME).lib
+ LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME).lib
+@@ -120,7 +120,7 @@
+ LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME).lib
+ !ELSE IF "$(DLLBUILD)" == "TRUE"
+ DLLINC = webp_dll.h
+-CC = $(CC) /I$(DIROBJ) /FI$(DLLINC) $(RTLIB) /DWEBP_DLL
++CC_ = $(CC_) /I$(DIROBJ) /FI$(DLLINC) $(RTLIB) /DWEBP_DLL
+ LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME)_dll.lib
+ LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME)_dll.lib
+ LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME)_dll.lib
+@@ -421,7 +421,7 @@
+ $(DIROBJ)\$(DLLINC)
+
+ {$(DIROBJ)}.c{$(DIROBJ)}.obj:
+- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$@ $<
++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$@ $<
+
+ {src}.rc{$(DIROBJ)}.res:
+ $(RC) /fo$@ $<
+@@ -469,41 +469,41 @@
+ # File-specific flag builds. Note batch rules take precedence over wildcards,
+ # so for now name each file individually.
+ $(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c
+- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
+ /Fo$(DIROBJ)\examples\ examples\$(@B).c
+ $(DIROBJ)\examples\anim_dump.obj: examples\anim_dump.c
+- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
+ /Fo$(DIROBJ)\examples\ examples\$(@B).c
+ $(DIROBJ)\examples\anim_util.obj: examples\anim_util.c
+- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
+ /Fo$(DIROBJ)\examples\ examples\$(@B).c
+ $(DIROBJ)\examples\gif2webp.obj: examples\gif2webp.c
+- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
+ /Fo$(DIROBJ)\examples\ examples\$(@B).c
+ $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c
+- $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
++ $(CC_) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
+ /Fo$(DIROBJ)\examples\ examples\$(@B).c
+ # Batch rules
+ {examples}.c{$(DIROBJ)\examples}.obj::
+- $(CC) $(CFLAGS) /Fd$(DIROBJ)\examples\ /Fo$(DIROBJ)\examples\ $<
++ $(CC_) $(CFLAGS) /Fd$(DIROBJ)\examples\ /Fo$(DIROBJ)\examples\ $<
+ {extras}.c{$(DIROBJ)\extras}.obj::
+- $(CC) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $<
++ $(CC_) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $<
+ {imageio}.c{$(DIROBJ)\imageio}.obj::
+- $(CC) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $<
++ $(CC_) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $<
+ {sharpyuv}.c{$(DIROBJ)\sharpyuv}.obj::
+- $(CC) $(CFLAGS) /Fd$(DIROBJ)\sharpyuv\ /Fo$(DIROBJ)\sharpyuv\ $<
++ $(CC_) $(CFLAGS) /Fd$(DIROBJ)\sharpyuv\ /Fo$(DIROBJ)\sharpyuv\ $<
+ {src\dec}.c{$(DIROBJ)\dec}.obj::
+- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $<
++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $<
+ {src\demux}.c{$(DIROBJ)\demux}.obj::
+- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\demux\ $<
++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\demux\ $<
+ {src\dsp}.c{$(DIROBJ)\dsp}.obj::
+- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dsp\ $<
++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dsp\ $<
+ {src\enc}.c{$(DIROBJ)\enc}.obj::
+- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\enc\ $<
++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\enc\ $<
+ {src\mux}.c{$(DIROBJ)\mux}.obj::
+- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\mux\ $<
++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\mux\ $<
+ {src\utils}.c{$(DIROBJ)\utils}.obj::
+- $(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $<
++ $(CC_) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $<
+
+ LNKLIBS = ole32.lib windowscodecs.lib shlwapi.lib
+ !IF "$(UNICODE)" == "1"
diff --git a/external/libwebp/Module_libwebp.mk b/external/libwebp/Module_libwebp.mk
new file mode 100644
index 000000000..b89056ac3
--- /dev/null
+++ b/external/libwebp/Module_libwebp.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libwebp))
+
+$(eval $(call gb_Module_add_targets,libwebp,\
+ ExternalProject_libwebp \
+ UnpackedTarball_libwebp \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwebp/README b/external/libwebp/README
new file mode 100644
index 000000000..1308c278b
--- /dev/null
+++ b/external/libwebp/README
@@ -0,0 +1 @@
+libwebp is a library to encode and decode images in WebP format, from [https://developers.google.com/speed/webp/]
diff --git a/external/libwebp/UnpackedTarball_libwebp.mk b/external/libwebp/UnpackedTarball_libwebp.mk
new file mode 100644
index 000000000..67f797157
--- /dev/null
+++ b/external/libwebp/UnpackedTarball_libwebp.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libwebp))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libwebp,$(LIBWEBP_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libwebp,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libwebp,\
+ external/libwebp/Makefile.vc.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpd/ExternalPackage_libwpd.mk b/external/libwpd/ExternalPackage_libwpd.mk
new file mode 100644
index 000000000..cc1ebb4da
--- /dev/null
+++ b/external/libwpd/ExternalPackage_libwpd.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libwpd,libwpd))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libwpd,libwpd))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,libwpd,$(LIBO_LIB_FOLDER)/libwpd-0.10.10.dylib,src/lib/.libs/libwpd-0.10.10.dylib))
+else ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,libwpd,$(LIBO_LIB_FOLDER)/libwpd-0.10.dll,src/lib/.libs/libwpd-0.10.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,libwpd,$(LIBO_LIB_FOLDER)/libwpd-0.10-lo.so.10,src/lib/.libs/libwpd-0.10-lo.so.10.0.$(WPD_VERSION_MICRO)))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpd/ExternalProject_libwpd.mk b/external/libwpd/ExternalProject_libwpd.mk
new file mode 100644
index 000000000..3317aecd7
--- /dev/null
+++ b/external/libwpd/ExternalProject_libwpd.mk
@@ -0,0 +1,53 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libwpd))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libwpd,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libwpd,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libwpd,\
+ boost_headers \
+ revenge \
+))
+
+$(call gb_ExternalProject_get_state_target,libwpd,build) :
+ $(call gb_Trace_StartRange,libwpd,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ $(if $(DISABLE_DYNLOADING), \
+ --disable-shared --enable-static, \
+ --enable-shared --disable-static) \
+ --without-docs \
+ --disable-tools \
+ --disable-debug \
+ --disable-werror \
+ $(if $(filter MACOSX,$(OS)), \
+ --prefix=/@.__________________________________________________OOO) \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libwpd)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ $(if $(filter LINUX,$(OS)),$(if $(SYSTEM_REVENGE),, \
+ 'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN')) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/lib/.libs/libwpd-0.10.10.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,libwpd,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpd/Library_wpd.mk b/external/libwpd/Library_wpd.mk
new file mode 100644
index 000000000..6b14f424d
--- /dev/null
+++ b/external/libwpd/Library_wpd.mk
@@ -0,0 +1,211 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,wpd))
+
+$(eval $(call gb_Library_use_unpacked,wpd,libwpd))
+
+$(eval $(call gb_Library_use_externals,wpd,\
+ boost_headers \
+ revenge \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,wpd))
+
+$(eval $(call gb_Library_set_include,wpd,\
+ -I$(call gb_UnpackedTarball_get_dir,libwpd)/inc \
+ -I$(call gb_UnpackedTarball_get_dir,libwpd)/src/lib \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_set_precompiled_header,wpd,external/libwpd/inc/pch/precompiled_wpd))
+
+$(eval $(call gb_Library_add_defs,wpd,\
+ -DBOOST_ALL_NO_LIB \
+ -DDLL_EXPORT \
+ -DLIBWPD_BUILD \
+ -DNDEBUG \
+))
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,wpd,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,wpd,\
+ UnpackedTarball/libwpd/src/lib/WP1BottomMarginGroup \
+ UnpackedTarball/libwpd/src/lib/WP1CenterTextGroup \
+ UnpackedTarball/libwpd/src/lib/WP1ContentListener \
+ UnpackedTarball/libwpd/src/lib/WP1ExtendedCharacterGroup \
+ UnpackedTarball/libwpd/src/lib/WP1FileStructure \
+ UnpackedTarball/libwpd/src/lib/WP1FixedLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP1FlushRightGroup \
+ UnpackedTarball/libwpd/src/lib/WP1FontIdGroup \
+ UnpackedTarball/libwpd/src/lib/WP1FootnoteEndnoteGroup \
+ UnpackedTarball/libwpd/src/lib/WP1HeaderFooterGroup \
+ UnpackedTarball/libwpd/src/lib/WP1Heuristics \
+ UnpackedTarball/libwpd/src/lib/WP1JustificationGroup \
+ UnpackedTarball/libwpd/src/lib/WP1LeftIndentGroup \
+ UnpackedTarball/libwpd/src/lib/WP1LeftRightIndentGroup \
+ UnpackedTarball/libwpd/src/lib/WP1Listener \
+ UnpackedTarball/libwpd/src/lib/WP1MarginReleaseGroup \
+ UnpackedTarball/libwpd/src/lib/WP1MarginResetGroup \
+ UnpackedTarball/libwpd/src/lib/WP1Parser \
+ UnpackedTarball/libwpd/src/lib/WP1Part \
+ UnpackedTarball/libwpd/src/lib/WP1PictureGroup \
+ UnpackedTarball/libwpd/src/lib/WP1PointSizeGroup \
+ UnpackedTarball/libwpd/src/lib/WP1SetTabsGroup \
+ UnpackedTarball/libwpd/src/lib/WP1SpacingResetGroup \
+ UnpackedTarball/libwpd/src/lib/WP1StylesListener \
+ UnpackedTarball/libwpd/src/lib/WP1SubDocument \
+ UnpackedTarball/libwpd/src/lib/WP1SuppressPageCharacteristicsGroup \
+ UnpackedTarball/libwpd/src/lib/WP1TopMarginGroup \
+ UnpackedTarball/libwpd/src/lib/WP1UnsupportedFixedLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP1UnsupportedVariableLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP1VariableLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP3AttributeGroup \
+ UnpackedTarball/libwpd/src/lib/WP3ContentListener \
+ UnpackedTarball/libwpd/src/lib/WP3DefinitionGroup \
+ UnpackedTarball/libwpd/src/lib/WP3DisplayGroup \
+ UnpackedTarball/libwpd/src/lib/WP3DoubleByteScriptCharacterGroup \
+ UnpackedTarball/libwpd/src/lib/WP3EndOfLinePageGroup \
+ UnpackedTarball/libwpd/src/lib/WP3ExtendedCharacterGroup \
+ UnpackedTarball/libwpd/src/lib/WP3FileStructure \
+ UnpackedTarball/libwpd/src/lib/WP3FixedLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP3FontGroup \
+ UnpackedTarball/libwpd/src/lib/WP3FootnoteEndnoteGroup \
+ UnpackedTarball/libwpd/src/lib/WP3Header \
+ UnpackedTarball/libwpd/src/lib/WP3HeaderFooterGroup \
+ UnpackedTarball/libwpd/src/lib/WP3IndentGroup \
+ UnpackedTarball/libwpd/src/lib/WP3Listener \
+ UnpackedTarball/libwpd/src/lib/WP3MiscellaneousGroup \
+ UnpackedTarball/libwpd/src/lib/WP3PageFormatGroup \
+ UnpackedTarball/libwpd/src/lib/WP3Parser \
+ UnpackedTarball/libwpd/src/lib/WP3Part \
+ UnpackedTarball/libwpd/src/lib/WP3Resource \
+ UnpackedTarball/libwpd/src/lib/WP3ResourceFork \
+ UnpackedTarball/libwpd/src/lib/WP3SingleByteFunction \
+ UnpackedTarball/libwpd/src/lib/WP3StylesListener \
+ UnpackedTarball/libwpd/src/lib/WP3SubDocument \
+ UnpackedTarball/libwpd/src/lib/WP3TabGroup \
+ UnpackedTarball/libwpd/src/lib/WP3TablesGroup \
+ UnpackedTarball/libwpd/src/lib/WP3UndoGroup \
+ UnpackedTarball/libwpd/src/lib/WP3UnsupportedFixedLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP3UnsupportedVariableLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP3VariableLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP3WindowGroup \
+ UnpackedTarball/libwpd/src/lib/WP42ContentListener \
+ UnpackedTarball/libwpd/src/lib/WP42DefineColumnsGroup \
+ UnpackedTarball/libwpd/src/lib/WP42ExtendedCharacterGroup \
+ UnpackedTarball/libwpd/src/lib/WP42FileStructure \
+ UnpackedTarball/libwpd/src/lib/WP42HeaderFooterGroup \
+ UnpackedTarball/libwpd/src/lib/WP42Heuristics \
+ UnpackedTarball/libwpd/src/lib/WP42Listener \
+ UnpackedTarball/libwpd/src/lib/WP42MarginResetGroup \
+ UnpackedTarball/libwpd/src/lib/WP42MultiByteFunctionGroup \
+ UnpackedTarball/libwpd/src/lib/WP42Parser \
+ UnpackedTarball/libwpd/src/lib/WP42Part \
+ UnpackedTarball/libwpd/src/lib/WP42StylesListener \
+ UnpackedTarball/libwpd/src/lib/WP42SubDocument \
+ UnpackedTarball/libwpd/src/lib/WP42SuppressPageCharacteristicsGroup \
+ UnpackedTarball/libwpd/src/lib/WP42UnsupportedMultiByteFunctionGroup \
+ UnpackedTarball/libwpd/src/lib/WP5AttributeGroup \
+ UnpackedTarball/libwpd/src/lib/WP5BoxGroup \
+ UnpackedTarball/libwpd/src/lib/WP5ContentListener \
+ UnpackedTarball/libwpd/src/lib/WP5DefinitionGroup \
+ UnpackedTarball/libwpd/src/lib/WP5ExtendedCharacterGroup \
+ UnpackedTarball/libwpd/src/lib/WP5FileStructure \
+ UnpackedTarball/libwpd/src/lib/WP5FixedLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP5FontGroup \
+ UnpackedTarball/libwpd/src/lib/WP5FontNameStringPoolPacket \
+ UnpackedTarball/libwpd/src/lib/WP5FootnoteEndnoteGroup \
+ UnpackedTarball/libwpd/src/lib/WP5GeneralPacketData \
+ UnpackedTarball/libwpd/src/lib/WP5GeneralPacketIndex \
+ UnpackedTarball/libwpd/src/lib/WP5GraphicsInformationPacket \
+ UnpackedTarball/libwpd/src/lib/WP5Header \
+ UnpackedTarball/libwpd/src/lib/WP5HeaderFooterGroup \
+ UnpackedTarball/libwpd/src/lib/WP5IndentGroup \
+ UnpackedTarball/libwpd/src/lib/WP5ListFontsUsedPacket \
+ UnpackedTarball/libwpd/src/lib/WP5Listener \
+ UnpackedTarball/libwpd/src/lib/WP5PageFormatGroup \
+ UnpackedTarball/libwpd/src/lib/WP5Parser \
+ UnpackedTarball/libwpd/src/lib/WP5Part \
+ UnpackedTarball/libwpd/src/lib/WP5PrefixData \
+ UnpackedTarball/libwpd/src/lib/WP5SingleByteFunction \
+ UnpackedTarball/libwpd/src/lib/WP5SpecialHeaderIndex \
+ UnpackedTarball/libwpd/src/lib/WP5StylesListener \
+ UnpackedTarball/libwpd/src/lib/WP5SubDocument \
+ UnpackedTarball/libwpd/src/lib/WP5TabGroup \
+ UnpackedTarball/libwpd/src/lib/WP5TableEOLGroup \
+ UnpackedTarball/libwpd/src/lib/WP5TableEOPGroup \
+ UnpackedTarball/libwpd/src/lib/WP5UnsupportedFixedLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP5UnsupportedVariableLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP5VariableLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP60Header \
+ UnpackedTarball/libwpd/src/lib/WP61Header \
+ UnpackedTarball/libwpd/src/lib/WP6AttributeGroup \
+ UnpackedTarball/libwpd/src/lib/WP6BoxGroup \
+ UnpackedTarball/libwpd/src/lib/WP6CharacterGroup \
+ UnpackedTarball/libwpd/src/lib/WP6ColumnGroup \
+ UnpackedTarball/libwpd/src/lib/WP6CommentAnnotationPacket \
+ UnpackedTarball/libwpd/src/lib/WP6ContentListener \
+ UnpackedTarball/libwpd/src/lib/WP6DefaultInitialFontPacket \
+ UnpackedTarball/libwpd/src/lib/WP6DisplayNumberReferenceGroup \
+ UnpackedTarball/libwpd/src/lib/WP6EOLGroup \
+ UnpackedTarball/libwpd/src/lib/WP6ExtendedCharacterGroup \
+ UnpackedTarball/libwpd/src/lib/WP6ExtendedDocumentSummaryPacket \
+ UnpackedTarball/libwpd/src/lib/WP6FileStructure \
+ UnpackedTarball/libwpd/src/lib/WP6FillStylePacket \
+ UnpackedTarball/libwpd/src/lib/WP6FixedLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP6FontDescriptorPacket \
+ UnpackedTarball/libwpd/src/lib/WP6FootnoteEndnoteGroup \
+ UnpackedTarball/libwpd/src/lib/WP6GeneralTextPacket \
+ UnpackedTarball/libwpd/src/lib/WP6GraphicsBoxStylePacket \
+ UnpackedTarball/libwpd/src/lib/WP6GraphicsCachedFileDataPacket \
+ UnpackedTarball/libwpd/src/lib/WP6GraphicsFilenamePacket \
+ UnpackedTarball/libwpd/src/lib/WP6Header \
+ UnpackedTarball/libwpd/src/lib/WP6HeaderFooterGroup \
+ UnpackedTarball/libwpd/src/lib/WP6HighlightGroup \
+ UnpackedTarball/libwpd/src/lib/WP6HyperlinkPacket \
+ UnpackedTarball/libwpd/src/lib/WP6Listener \
+ UnpackedTarball/libwpd/src/lib/WP6NumberingMethodGroup \
+ UnpackedTarball/libwpd/src/lib/WP6OutlineStylePacket \
+ UnpackedTarball/libwpd/src/lib/WP6PageGroup \
+ UnpackedTarball/libwpd/src/lib/WP6ParagraphGroup \
+ UnpackedTarball/libwpd/src/lib/WP6Parser \
+ UnpackedTarball/libwpd/src/lib/WP6Part \
+ UnpackedTarball/libwpd/src/lib/WP6PrefixData \
+ UnpackedTarball/libwpd/src/lib/WP6PrefixDataPacket \
+ UnpackedTarball/libwpd/src/lib/WP6PrefixIndice \
+ UnpackedTarball/libwpd/src/lib/WP6SetNumberGroup \
+ UnpackedTarball/libwpd/src/lib/WP6SingleByteFunction \
+ UnpackedTarball/libwpd/src/lib/WP6StyleGroup \
+ UnpackedTarball/libwpd/src/lib/WP6StylesListener \
+ UnpackedTarball/libwpd/src/lib/WP6SubDocument \
+ UnpackedTarball/libwpd/src/lib/WP6TabGroup \
+ UnpackedTarball/libwpd/src/lib/WP6TableStylePacket \
+ UnpackedTarball/libwpd/src/lib/WP6UndoGroup \
+ UnpackedTarball/libwpd/src/lib/WP6UnsupportedFixedLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP6UnsupportedVariableLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WP6VariableLengthGroup \
+ UnpackedTarball/libwpd/src/lib/WPDocument \
+ UnpackedTarball/libwpd/src/lib/WPXContentListener \
+ UnpackedTarball/libwpd/src/lib/WPXEncryption \
+ UnpackedTarball/libwpd/src/lib/WPXHeader \
+ UnpackedTarball/libwpd/src/lib/WPXHeaderFooter \
+ UnpackedTarball/libwpd/src/lib/WPXListener \
+ UnpackedTarball/libwpd/src/lib/WPXMemoryStream \
+ UnpackedTarball/libwpd/src/lib/WPXPageSpan \
+ UnpackedTarball/libwpd/src/lib/WPXParser \
+ UnpackedTarball/libwpd/src/lib/WPXStylesListener \
+ UnpackedTarball/libwpd/src/lib/WPXSubDocument \
+ UnpackedTarball/libwpd/src/lib/WPXTable \
+ UnpackedTarball/libwpd/src/lib/WPXTableList \
+ UnpackedTarball/libwpd/src/lib/libwpd_internal \
+ UnpackedTarball/libwpd/src/lib/libwpd_math \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpd/Makefile b/external/libwpd/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libwpd/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpd/Module_libwpd.mk b/external/libwpd/Module_libwpd.mk
new file mode 100644
index 000000000..db916a582
--- /dev/null
+++ b/external/libwpd/Module_libwpd.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libwpd))
+
+$(eval $(call gb_Module_add_targets,libwpd,\
+ UnpackedTarball_libwpd \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,libwpd,\
+ Library_wpd \
+))
+
+else
+
+$(eval $(call gb_Module_add_targets,libwpd,\
+ ExternalPackage_libwpd \
+ ExternalProject_libwpd \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpd/README b/external/libwpd/README
new file mode 100644
index 000000000..2cc9c8a18
--- /dev/null
+++ b/external/libwpd/README
@@ -0,0 +1 @@
+From [http://libwpd.sourceforge.net/]. Not modified. WordPerfect filter - SAX api - emits callbacks when things happen.
diff --git a/external/libwpd/UnpackedTarball_libwpd.mk b/external/libwpd/UnpackedTarball_libwpd.mk
new file mode 100644
index 000000000..eefa9331c
--- /dev/null
+++ b/external/libwpd/UnpackedTarball_libwpd.mk
@@ -0,0 +1,34 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libwpd))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libwpd,$(WPD_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libwpd,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libwpd))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libwpd,\
+ external/libwpd/libwpd-vs2013.patch.1 \
+ $(if $(SYSTEM_REVENGE),,external/libwpd/rpath.patch) \
+ external/libwpd/include.patch \
+))
+
+ifneq ($(OS),MACOSX)
+ifneq ($(OS),WNT)
+ifneq ($(OS),iOS)
+$(eval $(call gb_UnpackedTarball_add_patches,libwpd,\
+ external/libwpd/libwpd-bundled-soname.patch.0 \
+))
+endif
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpd/inc/pch/precompiled_wpd.cxx b/external/libwpd/inc/pch/precompiled_wpd.cxx
new file mode 100644
index 000000000..32c492c12
--- /dev/null
+++ b/external/libwpd/inc/pch/precompiled_wpd.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_wpd.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libwpd/inc/pch/precompiled_wpd.hxx b/external/libwpd/inc/pch/precompiled_wpd.hxx
new file mode 100644
index 000000000..8c62c61ec
--- /dev/null
+++ b/external/libwpd/inc/pch/precompiled_wpd.hxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2019-10-13 09:48:15 using:
+ ./bin/update_pch external/libwpd wpd --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/libwpd/inc/pch/precompiled_wpd.hxx "make external/libwpd.build" --find-conflicts
+*/
+
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <assert.h>
+#include <cstdarg>
+#include <cstdio>
+#include <ctype.h>
+#include <libwpd_internal.h>
+#include <libwpd_math.h>
+#include <limits>
+#include <locale.h>
+#include <math.h>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <string.h>
+#include <string>
+#include <time.h>
+#include <vector>
+#include <boost/spirit/include/qi.hpp>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <librevenge-stream/librevenge-stream.h>
+#include <librevenge/librevenge.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libwpd/include.patch b/external/libwpd/include.patch
new file mode 100644
index 000000000..57f52b4b0
--- /dev/null
+++ b/external/libwpd/include.patch
@@ -0,0 +1,10 @@
+--- src/lib/WPXTable.h
++++ src/lib/WPXTable.h
+@@ -36,6 +36,7 @@
+ #ifndef _WPXTABLE_H
+ #define _WPXTABLE_H
+
++#include <stddef.h>
+ #include <vector>
+
+ struct WPXTableCell
diff --git a/external/libwpd/libwpd-bundled-soname.patch.0 b/external/libwpd/libwpd-bundled-soname.patch.0
new file mode 100644
index 000000000..ad7cc3fb4
--- /dev/null
+++ b/external/libwpd/libwpd-bundled-soname.patch.0
@@ -0,0 +1,11 @@
+--- src/lib/Makefile.in.orig 2015-08-06 21:41:41.073622494 +0200
++++ src/lib/Makefile.in 2015-08-06 21:42:09.377622009 +0200
+@@ -429,7 +429,7 @@
+ -DLIBWPD_BUILD=1 $(am__append_1)
+ libwpd_@WPD_MAJOR_VERSION@_@WPD_MINOR_VERSION@_la_LIBADD = $(REVENGE_LIBS) @LIBWPD_WIN32_RESOURCE@
+ libwpd_@WPD_MAJOR_VERSION@_@WPD_MINOR_VERSION@_la_DEPENDENCIES = @LIBWPD_WIN32_RESOURCE@
+-libwpd_@WPD_MAJOR_VERSION@_@WPD_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic $(no_undefined)
++libwpd_@WPD_MAJOR_VERSION@_@WPD_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic $(no_undefined) -release lo
+ libwpd_@WPD_MAJOR_VERSION@_@WPD_MINOR_VERSION@_la_SOURCES = \
+ libwpd_internal.cpp \
+ libwpd_math.cpp \
diff --git a/external/libwpd/libwpd-vs2013.patch.1 b/external/libwpd/libwpd-vs2013.patch.1
new file mode 100644
index 000000000..224af4732
--- /dev/null
+++ b/external/libwpd/libwpd-vs2013.patch.1
@@ -0,0 +1,25 @@
+--- libwpd/src/lib/libwpd_math.h
++++ libwpd/src/lib/libwpd_math.h
+@@ -31,9 +31,9 @@
+
+ #include <math.h>
+
+-#if defined(_WIN32) && !defined(__MINGW32__)
++#if defined(_MSC_VER) && _MSC_VER < 1800
+ double rint(double x);
+-#endif /* _WIN32 */
++#endif /* _MSC_VER < 1800 */
+
+ #endif /* LIBWPD_MATH_H */
+ /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */
+--- libwpd/src/lib/libwpd_math.cpp
++++ libwpd/src/lib/libwpd_math.cpp
+@@ -26,7 +26,7 @@
+
+ #include "libwpd_math.h"
+
+-#if defined(_WIN32) && !defined(__MINGW32__)
++#if defined(_MSC_VER) && _MSC_VER < 1800
+
+ double rint(double x)
+ {
diff --git a/external/libwpd/rpath.patch b/external/libwpd/rpath.patch
new file mode 100644
index 000000000..fb3deaa81
--- /dev/null
+++ b/external/libwpd/rpath.patch
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -13850,6 +13850,7 @@
+ esac
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+
+ lynxos*)
diff --git a/external/libwpg/ExternalPackage_libwpg.mk b/external/libwpg/ExternalPackage_libwpg.mk
new file mode 100644
index 000000000..c3eb05c7a
--- /dev/null
+++ b/external/libwpg/ExternalPackage_libwpg.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libwpg,libwpg))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libwpg,libwpg))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,libwpg,$(LIBO_LIB_FOLDER)/libwpg-0.3.3.dylib,src/lib/.libs/libwpg-0.3.3.dylib))
+else ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,libwpg,$(LIBO_LIB_FOLDER)/libwpg-0.3.dll,src/lib/.libs/libwpg-0.3.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,libwpg,$(LIBO_LIB_FOLDER)/libwpg-0.3-lo.so.3,src/lib/.libs/libwpg-0.3-lo.so.3.0.$(WPG_VERSION_MICRO)))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpg/ExternalProject_libwpg.mk b/external/libwpg/ExternalProject_libwpg.mk
new file mode 100644
index 000000000..6a0d2c898
--- /dev/null
+++ b/external/libwpg/ExternalProject_libwpg.mk
@@ -0,0 +1,51 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libwpg))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libwpg,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libwpg,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libwpg,\
+ revenge \
+ wpd \
+))
+
+$(call gb_ExternalProject_get_state_target,libwpg,build) :
+ $(call gb_Trace_StartRange,libwpg,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ $(if $(DISABLE_DYNLOADING), \
+ --disable-shared --enable-static, \
+ --enable-shared --disable-static) \
+ --without-docs \
+ --disable-tools \
+ --disable-debug \
+ --disable-werror \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libwpg)" \
+ $(if $(filter LINUX,$(OS)), \
+ 'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
+ -Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN') \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/lib/.libs/libwpg-0.3.3.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,libwpg,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpg/Library_wpg.mk b/external/libwpg/Library_wpg.mk
new file mode 100644
index 000000000..09dc34915
--- /dev/null
+++ b/external/libwpg/Library_wpg.mk
@@ -0,0 +1,48 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,wpg))
+
+$(eval $(call gb_Library_use_unpacked,wpg,libwpg))
+
+$(eval $(call gb_Library_use_externals,wpg,\
+ revenge \
+ wpd \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,wpg))
+
+$(eval $(call gb_Library_set_include,wpg,\
+ -I$(call gb_UnpackedTarball_get_dir,libwpg)/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,wpg,\
+ -DBOOST_ALL_NO_LIB \
+ -DDLL_EXPORT \
+ -DLIBWPG_BUILD \
+ -DNDEBUG \
+))
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,wpg,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,wpg,\
+ UnpackedTarball/libwpg/src/lib/WPG1Parser \
+ UnpackedTarball/libwpg/src/lib/WPG2Parser \
+ UnpackedTarball/libwpg/src/lib/WPGBitmap \
+ UnpackedTarball/libwpg/src/lib/WPGColor \
+ UnpackedTarball/libwpg/src/lib/WPGDashArray \
+ UnpackedTarball/libwpg/src/lib/WPGHeader \
+ UnpackedTarball/libwpg/src/lib/WPGTextDataHandler \
+ UnpackedTarball/libwpg/src/lib/WPGXParser \
+ UnpackedTarball/libwpg/src/lib/WPGraphics \
+ UnpackedTarball/libwpg/src/lib/libwpg_utils \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpg/Makefile b/external/libwpg/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libwpg/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpg/Module_libwpg.mk b/external/libwpg/Module_libwpg.mk
new file mode 100644
index 000000000..668ae8404
--- /dev/null
+++ b/external/libwpg/Module_libwpg.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libwpg))
+
+$(eval $(call gb_Module_add_targets,libwpg,\
+ UnpackedTarball_libwpg \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,libwpg,\
+ Library_wpg \
+))
+
+else
+
+$(eval $(call gb_Module_add_targets,libwpg,\
+ ExternalPackage_libwpg \
+ ExternalProject_libwpg \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpg/README b/external/libwpg/README
new file mode 100644
index 000000000..19a154dd4
--- /dev/null
+++ b/external/libwpg/README
@@ -0,0 +1 @@
+From [http://libwpg.sourceforge.net/]. WordPerfect graphics filter.
diff --git a/external/libwpg/UnpackedTarball_libwpg.mk b/external/libwpg/UnpackedTarball_libwpg.mk
new file mode 100644
index 000000000..9ca55c669
--- /dev/null
+++ b/external/libwpg/UnpackedTarball_libwpg.mk
@@ -0,0 +1,32 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libwpg))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libwpg,$(WPG_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libwpg,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libwpg))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libwpg, \
+ external/libwpg/rpath.patch \
+))
+
+ifneq ($(OS),MACOSX)
+ifneq ($(OS),WNT)
+ifneq ($(OS),iOS)
+$(eval $(call gb_UnpackedTarball_add_patches,libwpg, \
+ external/libwpg/libwpg-bundled-soname.patch.0 \
+))
+endif
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwpg/libwpg-bundled-soname.patch.0 b/external/libwpg/libwpg-bundled-soname.patch.0
new file mode 100644
index 000000000..e0bfc5980
--- /dev/null
+++ b/external/libwpg/libwpg-bundled-soname.patch.0
@@ -0,0 +1,11 @@
+--- src/lib/Makefile.in.orig 2015-08-06 21:30:41.615633795 +0200
++++ src/lib/Makefile.in 2015-08-06 21:31:03.764633415 +0200
+@@ -357,7 +357,7 @@
+ $(DEBUG_CXXFLAGS) -DLIBWPG_BUILD=1 $(am__append_1)
+ libwpg_@WPG_MAJOR_VERSION@_@WPG_MINOR_VERSION@_la_LIBADD = $(WPD_LIBS) $(REVENGE_LIBS) @LIBWPG_WIN32_RESOURCE@
+ libwpg_@WPG_MAJOR_VERSION@_@WPG_MINOR_VERSION@_la_DEPENDENCIES = @LIBWPG_WIN32_RESOURCE@
+-libwpg_@WPG_MAJOR_VERSION@_@WPG_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined
++libwpg_@WPG_MAJOR_VERSION@_@WPG_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined -release lo
+ libwpg_@WPG_MAJOR_VERSION@_@WPG_MINOR_VERSION@_la_SOURCES = \
+ WPG1Parser.cpp \
+ WPG1Parser.h \
diff --git a/external/libwpg/rpath.patch b/external/libwpg/rpath.patch
new file mode 100644
index 000000000..5a8f56105
--- /dev/null
+++ b/external/libwpg/rpath.patch
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -13858,6 +13858,7 @@
+ esac
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+
+ lynxos*)
diff --git a/external/libwps/ExternalPackage_libwps.mk b/external/libwps/ExternalPackage_libwps.mk
new file mode 100644
index 000000000..daa17c117
--- /dev/null
+++ b/external/libwps/ExternalPackage_libwps.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libwps,libwps))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libwps,libwps))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,libwps,$(LIBO_LIB_FOLDER)/libwps-0.4.4.dylib,src/lib/.libs/libwps-0.4.4.dylib))
+else ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,libwps,$(LIBO_LIB_FOLDER)/libwps-0.4.dll,src/lib/.libs/libwps-0.4.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,libwps,$(LIBO_LIB_FOLDER)/libwps-0.4-lo.so.4,src/lib/.libs/libwps-0.4-lo.so.4.0.$(WPS_VERSION_MICRO)))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwps/ExternalProject_libwps.mk b/external/libwps/ExternalProject_libwps.mk
new file mode 100644
index 000000000..5ff5997f6
--- /dev/null
+++ b/external/libwps/ExternalProject_libwps.mk
@@ -0,0 +1,63 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libwps))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libwps,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libwps,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libwps,\
+ revenge \
+))
+
+libwps_CPPFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG)
+
+libwps_CXXFLAGS=$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libwps)
+
+libwps_LDFLAGS=$(call gb_ExternalProject_get_link_flags,libwps)
+ifeq ($(OS),LINUX)
+ifeq ($(SYSTEM_REVENGE),)
+libwps_LDFLAGS+=-Wl,-z,origin -Wl,-rpath,\$$$$ORIGIN
+endif
+endif
+
+$(call gb_ExternalProject_get_state_target,libwps,build) :
+ $(call gb_Trace_StartRange,libwps,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ --with-sharedptr=c++11 \
+ --without-docs \
+ --disable-tools \
+ $(if $(ENABLE_DEBUG),--enable-debug,--disable-debug) \
+ --disable-werror \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ $(if $(libwps_CXXFLAGS),CXXFLAGS='$(libwps_CXXFLAGS)') \
+ $(if $(libwps_CPPFLAGS),CPPFLAGS='$(libwps_CPPFLAGS)') \
+ $(if $(libwps_LDFLAGS),LDFLAGS='$(libwps_LDFLAGS)') \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/lib/.libs/libwps-0.4.4.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,libwps,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwps/Library_wps.mk b/external/libwps/Library_wps.mk
new file mode 100644
index 000000000..8986ae6e6
--- /dev/null
+++ b/external/libwps/Library_wps.mk
@@ -0,0 +1,102 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,wps))
+
+$(eval $(call gb_Library_use_unpacked,wps,libwps))
+
+$(eval $(call gb_Library_use_externals,wps,\
+ revenge \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,wps))
+
+$(eval $(call gb_Library_set_include,wps,\
+ -I$(call gb_UnpackedTarball_get_dir,libwps)/inc \
+ -I$(call gb_UnpackedTarball_get_dir,libwps)/src/lib \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_set_precompiled_header,wps,external/libwps/inc/pch/precompiled_wps))
+
+$(eval $(call gb_Library_add_defs,wps,\
+ -DBUILD_WPS\
+ -DDLL_EXPORT \
+ -DNDEBUG \
+))
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,wps,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,wps,\
+ UnpackedTarball/libwps/src/lib/DosWord \
+ UnpackedTarball/libwps/src/lib/Lotus \
+ UnpackedTarball/libwps/src/lib/LotusChart \
+ UnpackedTarball/libwps/src/lib/LotusGraph \
+ UnpackedTarball/libwps/src/lib/LotusSpreadsheet \
+ UnpackedTarball/libwps/src/lib/LotusStyleManager \
+ UnpackedTarball/libwps/src/lib/MSWrite \
+ UnpackedTarball/libwps/src/lib/Multiplan \
+ UnpackedTarball/libwps/src/lib/PocketWord \
+ UnpackedTarball/libwps/src/lib/Quattro \
+ UnpackedTarball/libwps/src/lib/Quattro9 \
+ UnpackedTarball/libwps/src/lib/Quattro9Graph \
+ UnpackedTarball/libwps/src/lib/Quattro9Spreadsheet \
+ UnpackedTarball/libwps/src/lib/QuattroDos \
+ UnpackedTarball/libwps/src/lib/QuattroDosChart \
+ UnpackedTarball/libwps/src/lib/QuattroDosSpreadsheet \
+ UnpackedTarball/libwps/src/lib/QuattroFormula \
+ UnpackedTarball/libwps/src/lib/QuattroGraph \
+ UnpackedTarball/libwps/src/lib/QuattroSpreadsheet \
+ UnpackedTarball/libwps/src/lib/WKS4 \
+ UnpackedTarball/libwps/src/lib/WKS4Chart \
+ UnpackedTarball/libwps/src/lib/WKS4Format \
+ UnpackedTarball/libwps/src/lib/WKS4Spreadsheet \
+ UnpackedTarball/libwps/src/lib/WKSChart \
+ UnpackedTarball/libwps/src/lib/WKSContentListener \
+ UnpackedTarball/libwps/src/lib/WKSParser \
+ UnpackedTarball/libwps/src/lib/WKSSubDocument \
+ UnpackedTarball/libwps/src/lib/WPS4 \
+ UnpackedTarball/libwps/src/lib/WPS4Graph \
+ UnpackedTarball/libwps/src/lib/WPS4Text \
+ UnpackedTarball/libwps/src/lib/WPS8 \
+ UnpackedTarball/libwps/src/lib/WPS8Graph \
+ UnpackedTarball/libwps/src/lib/WPS8Struct \
+ UnpackedTarball/libwps/src/lib/WPS8Table \
+ UnpackedTarball/libwps/src/lib/WPS8Text \
+ UnpackedTarball/libwps/src/lib/WPS8TextStyle \
+ UnpackedTarball/libwps/src/lib/WPSCell \
+ UnpackedTarball/libwps/src/lib/WPSContentListener \
+ UnpackedTarball/libwps/src/lib/WPSDebug \
+ UnpackedTarball/libwps/src/lib/WPSDocument \
+ UnpackedTarball/libwps/src/lib/WPSEntry \
+ UnpackedTarball/libwps/src/lib/WPSFont \
+ UnpackedTarball/libwps/src/lib/WPSGraphicShape \
+ UnpackedTarball/libwps/src/lib/WPSGraphicStyle \
+ UnpackedTarball/libwps/src/lib/WPSHeader \
+ UnpackedTarball/libwps/src/lib/WPSList \
+ UnpackedTarball/libwps/src/lib/WPSListener \
+ UnpackedTarball/libwps/src/lib/WPSOLE1Parser \
+ UnpackedTarball/libwps/src/lib/WPSOLEObject \
+ UnpackedTarball/libwps/src/lib/WPSOLEParser \
+ UnpackedTarball/libwps/src/lib/WPSOLEStream \
+ UnpackedTarball/libwps/src/lib/WPSPageSpan \
+ UnpackedTarball/libwps/src/lib/WPSParagraph \
+ UnpackedTarball/libwps/src/lib/WPSParser \
+ UnpackedTarball/libwps/src/lib/WPSStream \
+ UnpackedTarball/libwps/src/lib/WPSStringStream \
+ UnpackedTarball/libwps/src/lib/WPSSubDocument \
+ UnpackedTarball/libwps/src/lib/WPSTable \
+ UnpackedTarball/libwps/src/lib/WPSTextParser \
+ UnpackedTarball/libwps/src/lib/WPSTextSubDocument \
+ UnpackedTarball/libwps/src/lib/XYWrite \
+ UnpackedTarball/libwps/src/lib/libwps_internal \
+ UnpackedTarball/libwps/src/lib/libwps_tools_win \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwps/Makefile b/external/libwps/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libwps/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwps/Module_libwps.mk b/external/libwps/Module_libwps.mk
new file mode 100644
index 000000000..2b52c4acb
--- /dev/null
+++ b/external/libwps/Module_libwps.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libwps))
+
+$(eval $(call gb_Module_add_targets,libwps,\
+ UnpackedTarball_libwps \
+))
+
+ifeq ($(COM),MSC)
+
+$(eval $(call gb_Module_add_targets,libwps,\
+ Library_wps \
+))
+
+else
+
+$(eval $(call gb_Module_add_targets,libwps,\
+ ExternalPackage_libwps \
+ ExternalProject_libwps \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwps/README b/external/libwps/README
new file mode 100644
index 000000000..3ce52187d
--- /dev/null
+++ b/external/libwps/README
@@ -0,0 +1 @@
+Microsoft Works file word processor format import library from [http://libwps.sourceforge.net/].
diff --git a/external/libwps/UnpackedTarball_libwps.mk b/external/libwps/UnpackedTarball_libwps.mk
new file mode 100644
index 000000000..f53a8fffc
--- /dev/null
+++ b/external/libwps/UnpackedTarball_libwps.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libwps))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libwps,$(WPS_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,libwps,1))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libwps))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libwps,\
+ $(if $(SYSTEM_REVENGE),,external/libwps/rpath.patch.0) \
+ external/libwps/libtool.patch.0 \
+))
+
+ifneq ($(OS),MACOSX)
+ifneq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,libwps,\
+ external/libwps/libwps-bundled-soname.patch.0 \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libwps/inc/pch/precompiled_wps.cxx b/external/libwps/inc/pch/precompiled_wps.cxx
new file mode 100644
index 000000000..9cbc329ad
--- /dev/null
+++ b/external/libwps/inc/pch/precompiled_wps.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_wps.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libwps/inc/pch/precompiled_wps.hxx b/external/libwps/inc/pch/precompiled_wps.hxx
new file mode 100644
index 000000000..77d92f761
--- /dev/null
+++ b/external/libwps/inc/pch/precompiled_wps.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2019-10-13 10:00:18 using:
+ ./bin/update_pch external/libwps wps --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/libwps/inc/pch/precompiled_wps.hxx "make external/libwps.build" --find-conflicts
+*/
+
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <cmath>
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctype.h>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <libwps_internal.h>
+#include <libwps_tools_win.h>
+#include <limits>
+#include <list>
+#include <locale>
+#include <map>
+#include <regex>
+#include <set>
+#include <sstream>
+#include <stack>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+#include <time.h>
+#include <utility>
+#include <vector>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <librevenge-stream/librevenge-stream.h>
+#include <librevenge/librevenge.h>
+#include <libwps/libwps.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/libwps/libtool.patch.0 b/external/libwps/libtool.patch.0
new file mode 100644
index 000000000..cc4b08ba2
--- /dev/null
+++ b/external/libwps/libtool.patch.0
@@ -0,0 +1,12 @@
+--- ltmain.sh.sav 2018-08-02 14:21:34.000000000 +0200
++++ ltmain.sh 2019-05-05 22:04:15.433588776 +0200
+@@ -7277,7 +7277,8 @@ func_mode_link ()
+ # -stdlib=* select c++ std lib with clang
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+- -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
++ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
++ -fuse-ld=*|--ld-path=*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ func_append compile_command " $arg"
diff --git a/external/libwps/libwps-bundled-soname.patch.0 b/external/libwps/libwps-bundled-soname.patch.0
new file mode 100644
index 000000000..013ba7a88
--- /dev/null
+++ b/external/libwps/libwps-bundled-soname.patch.0
@@ -0,0 +1,11 @@
+--- src/lib/Makefile.in.orig 2015-08-06 11:41:55.081239194 +0200
++++ src/lib/Makefile.in 2015-08-06 11:42:16.903238820 +0200
+@@ -369,7 +369,7 @@
+ AM_CXXFLAGS = -I$(top_srcdir)/inc $(REVENGE_CFLAGS) $(DEBUG_CXXFLAGS) -DBUILD_WPS=1
+ libwps_@WPS_MAJOR_VERSION@_@WPS_MINOR_VERSION@_la_LIBADD = $(REVENGE_LIBS) @LIBWPS_WIN32_RESOURCE@
+ libwps_@WPS_MAJOR_VERSION@_@WPS_MINOR_VERSION@_la_DEPENDENCIES = @LIBWPS_WIN32_RESOURCE@
+-libwps_@WPS_MAJOR_VERSION@_@WPS_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined
++libwps_@WPS_MAJOR_VERSION@_@WPS_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined -release lo
+ libwps_@WPS_MAJOR_VERSION@_@WPS_MINOR_VERSION@_la_SOURCES = \
+ libwps_internal.cpp \
+ libwps_tools_win.h \
diff --git a/external/libwps/rpath.patch.0 b/external/libwps/rpath.patch.0
new file mode 100644
index 000000000..600cc3d34
--- /dev/null
+++ b/external/libwps/rpath.patch.0
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -14306,6 +14306,7 @@
+ esac
+ ;;
+ esac
++hardcode_libdir_flag_spec_CXX=
+ ;;
+
+ lynxos*)
diff --git a/external/libxml2/ExternalPackage_libxml2.mk b/external/libxml2/ExternalPackage_libxml2.mk
new file mode 100644
index 000000000..6338fb20b
--- /dev/null
+++ b/external/libxml2/ExternalPackage_libxml2.mk
@@ -0,0 +1,28 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libxml2,libxml2))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libxml2,libxml2))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2.2.dylib,.libs/libxml2.2.dylib))
+else ifeq ($(OS),WNT)
+ifeq ($(COM),GCC)
+$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2.dll,.libs/libxml2.dll))
+else # COM=MSC
+$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2.dll,win32/bin.msvc/libxml2.dll))
+endif
+else # OS!=WNT
+$(eval $(call gb_ExternalPackage_add_file,libxml2,$(LIBO_URE_LIB_FOLDER)/libxml2.so.2,.libs/libxml2.so.2.10.$(LIBXML_VERSION_MICRO)))
+endif
+endif # DISABLE_DYNLOADING
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxml2/ExternalProject_libxml2.mk b/external/libxml2/ExternalProject_libxml2.mk
new file mode 100644
index 000000000..7bb2b5895
--- /dev/null
+++ b/external/libxml2/ExternalProject_libxml2.mk
@@ -0,0 +1,53 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libxml2))
+
+$(eval $(call gb_ExternalProject_register_targets,libxml2,\
+ build \
+))
+
+ifeq ($(OS),EMSCRIPTEN)
+$(call gb_ExternalProject_use_external_project,libxml2,icu)
+endif
+
+ifeq ($(OS),WNT)
+$(call gb_ExternalProject_use_external_project,libxml2,icu)
+
+$(eval $(call gb_ExternalProject_use_nmake,libxml2,build))
+
+$(call gb_ExternalProject_get_state_target,libxml2,build):
+ $(call gb_Trace_StartRange,libxml2,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ cscript /e:javascript configure.js \
+ iconv=no icu=yes sax1=yes $(if $(MSVC_USE_DEBUG_RUNTIME),run_debug=yes cruntime=/MDd) \
+ $(if $(filter TRUE,$(ENABLE_DBGUTIL)),debug=yes) \
+ && nmake \
+ ,win32)
+ $(call gb_Trace_EndRange,libxml2,EXTERNAL)
+else # OS!=WNT
+$(call gb_ExternalProject_get_state_target,libxml2,build):
+ $(call gb_Trace_StartRange,libxml2,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure --disable-ipv6 --without-python --without-zlib --with-sax1 \
+ --without-lzma \
+ $(if $(debug),--with-run-debug) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________URELIB) \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libxml2) $(if $(SYSBASE),-L$(SYSBASE)/usr/lib)" \
+ CFLAGS="$(CFLAGS) \
+ $(if $(SYSBASE),-I$(SYSBASE)/usr/include) \
+ $(call gb_ExternalProject_get_build_flags,libxml2)" \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),--disable-shared,--disable-static) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libxml2,EXTERNAL)
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxml2/Makefile b/external/libxml2/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libxml2/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxml2/Module_libxml2.mk b/external/libxml2/Module_libxml2.mk
new file mode 100644
index 000000000..31a90fadd
--- /dev/null
+++ b/external/libxml2/Module_libxml2.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libxml2))
+
+$(eval $(call gb_Module_add_targets,libxml2,\
+ ExternalPackage_libxml2 \
+ ExternalProject_libxml2 \
+ UnpackedTarball_libxml2 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxml2/README b/external/libxml2/README
new file mode 100644
index 000000000..12d96977c
--- /dev/null
+++ b/external/libxml2/README
@@ -0,0 +1 @@
+Gnome xml parser library written in C, from [http://xmlsoft.org/]
diff --git a/external/libxml2/UnpackedTarball_libxml2.mk b/external/libxml2/UnpackedTarball_libxml2.mk
new file mode 100644
index 000000000..8c81c3d26
--- /dev/null
+++ b/external/libxml2/UnpackedTarball_libxml2.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libxml2))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libxml2,$(LIBXML_TARBALL),,libxml2))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libxml2))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libxml2,\
+ external/libxml2/libxml2-global-symbols.patch \
+ external/libxml2/libxml2-vc10.patch \
+ $(if $(filter ANDROID,$(OS)),external/libxml2/libxml2-android.patch) \
+ $(if $(gb_Module_CURRENTMODULE_SYMBOLS_ENABLED), \
+ external/libxml2/libxml2-icu-sym.patch.0, \
+ external/libxml2/libxml2-icu.patch.0) \
+))
+
+$(eval $(call gb_UnpackedTarball_add_file,libxml2,xml2-config.in,external/libxml2/xml2-config.in))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxml2/libxml2-android.patch b/external/libxml2/libxml2-android.patch
new file mode 100644
index 000000000..acf9b17e0
--- /dev/null
+++ b/external/libxml2/libxml2-android.patch
@@ -0,0 +1,11 @@
+--- misc/libxml2-2.7.6/Makefile.in
++++ misc/build/libxml2-2.7.6/Makefile.in
+@@ -1635,7 +1635,7 @@
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+ check: check-recursive
+-all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(SCRIPTS) $(DATA) \
++all-am: Makefile $(LTLIBRARIES) \
+ config.h
+ install-binPROGRAMS: install-libLTLIBRARIES
+
diff --git a/external/libxml2/libxml2-global-symbols.patch b/external/libxml2/libxml2-global-symbols.patch
new file mode 100644
index 000000000..cfec9c530
--- /dev/null
+++ b/external/libxml2/libxml2-global-symbols.patch
@@ -0,0 +1,59 @@
+--- misc/libxml2-2.7.6/libxml2.syms Tue Oct 6 18:31:35 2009
++++ misc/build/libxml2-2.7.6/libxml2.syms Wed Jul 7 15:43:17 2010
+@@ -2184,10 +2184,10 @@
+ } LIBXML2_2.6.27;
+
+ LIBXML2_2.6.29 {
+- global:
++# global:
+
+ # threads
+- xmlDllMain;
++#WIN32 only! xmlDllMain;
+ } LIBXML2_2.6.28;
+
+ LIBXML2_2.6.32 {
+@@ -2231,3 +2231,43 @@
+ xmlPopOutputCallbacks;
+ } LIBXML2_2.9.8;
+
++# HACK: export global variable accessor functions (globals.h)
++LIBXML2_GLOBAL_VARIABLES {
++ global:
++# __xmlMalloc;
++# __xmlMallocAtomic;
++# __xmlRealloc;
++# __xmlFree;
++# __xmlMemStrdup;
++ __docbDefaultSAXHandler;
++ __htmlDefaultSAXHandler;
++ __xmlLastError;
++ __oldXMLWDcompatibility;
++ __xmlBufferAllocScheme;
++ __xmlDefaultBufferSize;
++ __xmlDefaultSAXHandler;
++ __xmlDefaultSAXLocator;
++ __xmlDoValidityCheckingDefaultValue;
++ __xmlGenericError;
++ __xmlStructuredError;
++ __xmlGenericErrorContext;
++ __xmlStructuredErrorContext;
++ __xmlGetWarningsDefaultValue;
++ __xmlIndentTreeOutput;
++ __xmlTreeIndentString;
++ __xmlKeepBlanksDefaultValue;
++ __xmlLineNumbersDefaultValue;
++ __xmlLoadExtDtdDefaultValue;
++ __xmlParserDebugEntities;
++ __xmlParserVersion;
++ __xmlPedanticParserDefaultValue;
++ __xmlSaveNoEmptyTags;
++ __xmlSubstituteEntitiesDefaultValue;
++ __xmlRegisterNodeDefaultValue;
++ __xmlDeregisterNodeDefaultValue;
++ __xmlParserInputBufferCreateFilenameValue;
++ __xmlOutputBufferCreateFilenameValue;
++# Solaris ld needs explicit auto-reduction (or, alternatively, "-B local")
++ local:
++ *;
++} LIBXML2_2.7.4;
diff --git a/external/libxml2/libxml2-icu-sym.patch.0 b/external/libxml2/libxml2-icu-sym.patch.0
new file mode 100644
index 000000000..aac9d09ef
--- /dev/null
+++ b/external/libxml2/libxml2-icu-sym.patch.0
@@ -0,0 +1,37 @@
+Find bundled ICU in workdir and use debug .libs when needed
+
+diff -up win32/Makefile.msvc.dt win32/Makefile.msvc
+--- win32/Makefile.msvc.dt 2014-07-18 19:00:23.372103963 +0200
++++ win32/Makefile.msvc 2014-07-18 19:01:39.347982929 +0200
+@@ -46,6 +46,7 @@ CPPFLAGS = $(CPPFLAGS) /D "_REENTRANT"
+ CC = cl.exe
+ CFLAGS = /nologo /D "_WINDOWS" /D "_MBCS" /D "NOLIBTOOL" /W3 /wd4244 /wd4267 $(CRUNTIME)
+ CFLAGS = $(CFLAGS) /I$(XML_SRCDIR) /I$(XML_SRCDIR)\include /I$(INCPREFIX)
++CFLAGS = $(CFLAGS) /I$(WORKDIR)/UnpackedTarball/icu/source/i18n /I$(WORKDIR)/UnpackedTarball/icu/source/common
+ !if "$(WITH_THREADS)" != "no"
+ CFLAGS = $(CFLAGS) /D "_REENTRANT"
+ !endif
+@@ -62,7 +63,9 @@
+ # The linker and its options.
+ LD = link.exe
+ LDFLAGS = /nologo /VERSION:$(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION)
++LDFLAGS = $(LDFLAGS) /LIBPATH:$(WORKDIR)/UnpackedTarball/icu/source/lib
+ LDFLAGS = $(LDFLAGS) /LIBPATH:$(BINDIR) /LIBPATH:$(LIBPREFIX)
++LDFLAGS = $(LDFLAGS) /DEBUG /OPT:REF
+ LIBS =
+ !if "$(WITH_FTP)" == "1" || "$(WITH_HTTP)" == "1"
+ LIBS = $(LIBS) wsock32.lib ws2_32.lib
+@@ -74,9 +77,13 @@
+ !if "$(STATIC)" == "1"
+ LIBS = $(LIBS) advapi32.lib sicuuc.lib sicuin.lib sicudt.lib
+ !else
++!if "$(WITH_RUN_DEBUG)" == "1"
++LIBS = $(LIBS) icuind.lib icuucd.lib icudtd.lib
++!else
+ LIBS = $(LIBS) icuuc.lib icuin.lib icudt.lib
+ !endif
+ !endif
++!endif
+ !if "$(WITH_ZLIB)" == "1"
+ # could be named differently zdll or zlib
+ # LIBS = $(LIBS) zdll.lib
diff --git a/external/libxml2/libxml2-icu.patch.0 b/external/libxml2/libxml2-icu.patch.0
new file mode 100644
index 000000000..b390b03d8
--- /dev/null
+++ b/external/libxml2/libxml2-icu.patch.0
@@ -0,0 +1,33 @@
+Find bundled ICU in workdir and use debug .libs when needed
+
+diff -up win32/Makefile.msvc.dt win32/Makefile.msvc
+--- win32/Makefile.msvc.dt 2014-07-18 19:00:23.372103963 +0200
++++ win32/Makefile.msvc 2014-07-18 19:01:39.347982929 +0200
+@@ -45,6 +45,7 @@ CPPFLAGS = $(CPPFLAGS) /D "_REENTRANT"
+ CC = cl.exe
+ CFLAGS = /nologo /D "_WINDOWS" /D "_MBCS" /D "NOLIBTOOL" /W3 /wd4244 /wd4267 $(CRUNTIME)
+ CFLAGS = $(CFLAGS) /I$(XML_SRCDIR) /I$(XML_SRCDIR)\include /I$(INCPREFIX)
++CFLAGS = $(CFLAGS) /I$(WORKDIR)/UnpackedTarball/icu/source/i18n /I$(WORKDIR)/UnpackedTarball/icu/source/common
+ !if "$(WITH_THREADS)" != "no"
+ CFLAGS = $(CFLAGS) /D "_REENTRANT"
+ !endif
+@@ -67,6 +68,7 @@ CFLAGS = $(CFLAGS) $(SOLARINC)
+ # The linker and its options.
+ LD = link.exe
+ LDFLAGS = /nologo /VERSION:$(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION)
++LDFLAGS = $(LDFLAGS) /LIBPATH:$(WORKDIR)/UnpackedTarball/icu/source/lib
+ LDFLAGS = $(LDFLAGS) /LIBPATH:$(BINDIR) /LIBPATH:$(LIBPREFIX)
+ LIBS =
+ !if "$(WITH_FTP)" == "1" || "$(WITH_HTTP)" == "1"
+@@ -78,7 +78,11 @@ LIBS = $(LIBS) wsock32.lib ws2_32.lib
+ !if "$(STATIC)" == "1"
+ LIBS = $(LIBS) advapi32.lib sicuuc.lib sicuin.lib sicudt.lib
+ !else
++!if "$(WITH_RUN_DEBUG)" == "1"
++LIBS = $(LIBS) icuind.lib icuucd.lib icudtd.lib
++!else
+ LIBS = $(LIBS) icuuc.lib icuin.lib icudt.lib
++!endif
+ !endif
+ !endif
+ !if "$(WITH_ZLIB)" == "1"
diff --git a/external/libxml2/libxml2-vc10.patch b/external/libxml2/libxml2-vc10.patch
new file mode 100644
index 000000000..15bc4d973
--- /dev/null
+++ b/external/libxml2/libxml2-vc10.patch
@@ -0,0 +1,12 @@
+Add SOLARINC, and disable SSE2 default for MSVC2012
+
+--- build/libxml2-2.7.6/win32/Makefile.msvc.old 2010-09-20 20:22:41.500000000 +0200
++++ build/libxml2-2.7.6/win32/Makefile.msvc 2010-09-20 20:23:00.250000000 +0200
+@@ -59,6 +59,7 @@
+ CFLAGS = $(CFLAGS) /D "HAVE_PTHREAD_H"
+ !endif
+ CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE
++CFLAGS = $(CFLAGS) $(SOLARINC)
+
+ # The linker and its options.
+ LD = link.exe
diff --git a/external/libxml2/xml2-config.in b/external/libxml2/xml2-config.in
new file mode 100644
index 000000000..164508e47
--- /dev/null
+++ b/external/libxml2/xml2-config.in
@@ -0,0 +1,28 @@
+#! /bin/sh
+
+while test $# -gt 0; do
+ case "$1" in
+ -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ case "$1" in
+ --version)
+ echo @VERSION@
+ exit 0
+ ;;
+ --cflags)
+ cflags="$LIBXML_CFLAGS"
+ ;;
+ --libs)
+ libs="$LIBXML_LIBS"
+ ;;
+ esac
+ shift
+done
+
+if test -n "$cflags$libs"; then
+ echo $cflags $libs
+fi
+
+exit 0
diff --git a/external/libxslt/ExternalPackage_libxslt.mk b/external/libxslt/ExternalPackage_libxslt.mk
new file mode 100644
index 000000000..c22a2e1b5
--- /dev/null
+++ b/external/libxslt/ExternalPackage_libxslt.mk
@@ -0,0 +1,32 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,libxslt,libxslt))
+
+$(eval $(call gb_ExternalPackage_use_external_project,libxslt,libxslt))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,libxslt,$(LIBO_LIB_FOLDER)/libxslt.1.dylib,libxslt/.libs/libxslt.1.dylib))
+$(eval $(call gb_ExternalPackage_add_file,libxslt,$(LIBO_LIB_FOLDER)/libexslt.0.dylib,libexslt/.libs/libexslt.0.dylib))
+else ifeq ($(OS),WNT)
+ifeq ($(COM),GCC)
+$(eval $(call gb_ExternalPackage_add_file,libxslt,$(LIBO_LIB_FOLDER)/libxslt.dll,libxslt/.libs/libxslt.dll))
+$(eval $(call gb_ExternalPackage_add_file,libxslt,$(LIBO_LIB_FOLDER)/libexslt.dll,libexslt/.libs/libexslt.dll))
+else # COM=MSC
+$(eval $(call gb_ExternalPackage_add_file,libxslt,$(LIBO_LIB_FOLDER)/libxslt.dll,win32/bin.msvc/libxslt.dll))
+$(eval $(call gb_ExternalPackage_add_file,libxslt,$(LIBO_LIB_FOLDER)/libexslt.dll,win32/bin.msvc/libexslt.dll))
+endif
+else # OS!=WNT
+$(eval $(call gb_ExternalPackage_add_file,libxslt,$(LIBO_LIB_FOLDER)/libxslt.so.1,libxslt/.libs/libxslt.so.1.1.$(LIBXSLT_VERSION_MICRO)))
+$(eval $(call gb_ExternalPackage_add_file,libxslt,$(LIBO_LIB_FOLDER)/libexslt.so.0,libexslt/.libs/libexslt.so.0.8.20))
+endif
+endif # DISABLE_DYNLOADING
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxslt/ExternalProject_libxslt.mk b/external/libxslt/ExternalProject_libxslt.mk
new file mode 100644
index 000000000..842f60db2
--- /dev/null
+++ b/external/libxslt/ExternalProject_libxslt.mk
@@ -0,0 +1,55 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libxslt))
+
+$(eval $(call gb_ExternalProject_use_external,libxslt,libxml2))
+
+$(eval $(call gb_ExternalProject_register_targets,libxslt,\
+ build \
+))
+ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalProject_use_nmake,libxslt,build))
+
+$(call gb_ExternalProject_get_state_target,libxslt,build):
+ $(call gb_Trace_StartRange,libxslt,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ cscript /e:javascript configure.js \
+ $(if $(MSVC_USE_DEBUG_RUNTIME),cruntime=/MDd) \
+ $(if $(filter TRUE,$(ENABLE_DBGUTIL)),debug=yes) \
+ vcmanifest=yes \
+ lib=$(call gb_UnpackedTarball_get_dir,libxml2)/win32/bin.msvc \
+ && nmake \
+ ,win32)
+ $(call gb_Trace_EndRange,libxslt,EXTERNAL)
+else # OS!=WNT
+$(call gb_ExternalProject_get_state_target,libxslt,build):
+ $(call gb_Trace_StartRange,libxslt,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure --without-crypto --without-python \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ LDFLAGS="$(if $(filter LINUX FREEBSD,$(OS)),-Wl$(COMMA)-z$(COMMA)origin -Wl$(COMMA)-rpath$(COMMA)\\"\$$\$$ORIGIN" -Wl$(COMMA)-noinhibit-exec) \
+ $(if $(SYSBASE),$(if $(filter SOLARIS LINUX,$(OS)),-L$(SYSBASE)/lib -L$(SYSBASE)/usr/lib -lpthread -ldl))" \
+ $(if $(SYSBASE),CPPFLAGS="-I$(SYSBASE)/usr/include") \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)), \
+ $(if $(filter iOS,$(OS)),LIBS="-liconv") \
+ --disable-shared,--disable-static) \
+ $(if $(SYSTEM_LIBXML),,--with-libxml-src=$(call gb_UnpackedTarball_get_dir,libxml2)) \
+ && chmod 777 xslt-config \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),\
+ && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/libxslt/.libs/libxslt.1.dylib \
+ ) \
+ )
+ $(call gb_Trace_EndRange,libxslt,EXTERNAL)
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxslt/Makefile b/external/libxslt/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libxslt/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxslt/Module_libxslt.mk b/external/libxslt/Module_libxslt.mk
new file mode 100644
index 000000000..970433892
--- /dev/null
+++ b/external/libxslt/Module_libxslt.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libxslt))
+
+$(eval $(call gb_Module_add_targets,libxslt,\
+ ExternalPackage_libxslt \
+ ExternalProject_libxslt \
+ UnpackedTarball_libxslt \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxslt/README b/external/libxslt/README
new file mode 100644
index 000000000..dd69a9d73
--- /dev/null
+++ b/external/libxslt/README
@@ -0,0 +1 @@
+Gnome xslt library written in C, from [http://xmlsoft.org/xslt/]
diff --git a/external/libxslt/UnpackedTarball_libxslt.mk b/external/libxslt/UnpackedTarball_libxslt.mk
new file mode 100644
index 000000000..7d39cb1e3
--- /dev/null
+++ b/external/libxslt/UnpackedTarball_libxslt.mk
@@ -0,0 +1,26 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libxslt))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libxslt,$(LIBXSLT_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libxslt))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libxslt,\
+ external/libxslt/libxslt-config.patch.1 \
+ external/libxslt/libxslt-internal-symbols.patch.1 \
+ $(if $(gb_Module_CURRENTMODULE_SYMBOLS_ENABLED),\
+ external/libxslt/libxslt-msvc-sym.patch.2, \
+ external/libxslt/libxslt-msvc.patch.2) \
+ external/libxslt/libxslt-1.1.26-memdump.patch \
+ external/libxslt/rpath.patch.0 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libxslt/libxslt-1.1.26-memdump.patch b/external/libxslt/libxslt-1.1.26-memdump.patch
new file mode 100644
index 000000000..28724f749
--- /dev/null
+++ b/external/libxslt/libxslt-1.1.26-memdump.patch
@@ -0,0 +1,10 @@
+--- misc/libxslt-1.1.26/xsltproc/xsltproc.c 2009-08-23 14:53:33.000000000 +0200
++++ misc/build/libxslt-1.1.26/xsltproc/xsltproc.c 2013-01-18 14:16:12.202767222 +0100
+@@ -877,7 +877,6 @@
+ xsltFreeSecurityPrefs(sec);
+ xsltCleanupGlobals();
+ xmlCleanupParser();
+- xmlMemoryDump();
+ return(errorno);
+ }
+
diff --git a/external/libxslt/libxslt-config.patch.1 b/external/libxslt/libxslt-config.patch.1
new file mode 100644
index 000000000..e4ce5d9e2
--- /dev/null
+++ b/external/libxslt/libxslt-config.patch.1
@@ -0,0 +1,35 @@
+Hack the xslt-config to return paths into WORKDIR.
+
+--- a/xslt-config.in Wed Jan 17 14:18:26 2007
++++ b/xslt-config.in Wed Jun 25 13:06:05 2008
+@@ -1,10 +1,16 @@
+ #! /bin/sh
+
+-prefix=@prefix@
+-exec_prefix=@exec_prefix@
++#prefix=@prefix@
++#exec_prefix=@exec_prefix@
++#exec_prefix_set=no
++#includedir=@includedir@
++#libdir=@libdir@
++
++prefix=${WORKDIR}/UnpackedTarball/libxslt
++exec_prefix=${WORKDIR}/UnpackedTarball/libxslt
+ exec_prefix_set=no
+-includedir=@includedir@
+-libdir=@libdir@
++includedir=${WORKDIR}/UnpackedTarball/libxslt
++libdir=${WORKDIR}/UnpackedTarball/libxslt
+
+ usage()
+ {
+@@ -92,7 +98,8 @@
+ libs="@XSLT_LIBDIR@ $libs"
+ fi
+
+- libs="$libs @EXTRA_LIBS@"
++ #libs="$libs @EXTRA_LIBS@"
++ libs="-L${libdir}/libxslt/.libs -L${libdir}/libexslt/.libs -lxslt -lm"
+ ;;
+
+ *)
diff --git a/external/libxslt/libxslt-internal-symbols.patch.1 b/external/libxslt/libxslt-internal-symbols.patch.1
new file mode 100644
index 000000000..84a15154d
--- /dev/null
+++ b/external/libxslt/libxslt-internal-symbols.patch.1
@@ -0,0 +1,13 @@
+--- xslt/libxslt/libxslt.syms.orig 2017-09-05 16:25:50.504966267 +0200
++++ xslt/libxslt/libxslt.syms 2017-09-05 16:41:00.256895709 +0200
+@@ -497,5 +497,10 @@
+
+ # pattern
+ xsltCompMatchClearCache;
++
++# Solaris ld needs explicit auto-reduction (or, alternatively, "-B local")
++ local:
++ *;
++
+ } LIBXML2_1.1.30;
+
diff --git a/external/libxslt/libxslt-msvc-sym.patch.2 b/external/libxslt/libxslt-msvc-sym.patch.2
new file mode 100644
index 000000000..636c22a82
--- /dev/null
+++ b/external/libxslt/libxslt-msvc-sym.patch.2
@@ -0,0 +1,16 @@
+--- build/libxslt-1.1.26/win32/Makefile.msvc.old 2019-10-20 01:02:55.359375000 +0200
++++ build/libxslt-1.1.26/win32/Makefile.msvc 2019-10-20 01:03:05.187500000 +0200
+@@ -54,11 +54,13 @@
+ CFLAGS = /nologo /D "_WINDOWS" /D "_MBCS" /W3 /wd4244 /wd4267 $(CRUNTIME) /D "_REENTRANT"
+ CFLAGS = $(CFLAGS) /I$(BASEDIR) /I$(XSLT_SRCDIR) /I$(INCPREFIX)
+ CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE
++CFLAGS = $(CFLAGS) $(SOLARINC) -I$(WORKDIR)\UnpackedTarball\libxml2\include -I$(WORKDIR)/UnpackedTarball/icu/source/i18n -I$(WORKDIR)/UnpackedTarball/icu/source/common
+
+ # The linker and its options.
+ LD = link.exe
+ LDFLAGS = /nologo
+ LDFLAGS = $(LDFLAGS) /LIBPATH:$(BINDIR) /LIBPATH:$(LIBPREFIX)
++LDFLAGS = $(LDFLAGS) /DEBUG /OPT:REF
+ LIBS =
+
+ # The archiver and its options.
diff --git a/external/libxslt/libxslt-msvc.patch.2 b/external/libxslt/libxslt-msvc.patch.2
new file mode 100644
index 000000000..fea5f9dc6
--- /dev/null
+++ b/external/libxslt/libxslt-msvc.patch.2
@@ -0,0 +1,10 @@
+--- build/libxslt-1.1.26/win32/Makefile.msvc.old 2010-10-20 01:02:55.359375000 +0200
++++ build/libxslt-1.1.26/win32/Makefile.msvc 2010-10-20 01:03:05.187500000 +0200
+@@ -54,6 +54,7 @@
+ CFLAGS = /nologo /D "_WINDOWS" /D "_MBCS" /W3 /wd4244 /wd4267 $(CRUNTIME) /D "_REENTRANT"
+ CFLAGS = $(CFLAGS) /I$(BASEDIR) /I$(XSLT_SRCDIR) /I$(INCPREFIX)
+ CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE
++CFLAGS = $(CFLAGS) $(SOLARINC) -I$(WORKDIR)\UnpackedTarball\libxml2\include -I$(WORKDIR)/UnpackedTarball/icu/source/i18n -I$(WORKDIR)/UnpackedTarball/icu/source/common
+
+ # The linker and its options.
+ LD = link.exe
diff --git a/external/libxslt/rpath.patch.0 b/external/libxslt/rpath.patch.0
new file mode 100644
index 000000000..798bccec7
--- /dev/null
+++ b/external/libxslt/rpath.patch.0
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -10196,6 +10196,7 @@
+ else
+ ld_shlibs=no
+ fi
++hardcode_libdir_flag_spec=
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
diff --git a/external/libzmf/ExternalProject_libzmf.mk b/external/libzmf/ExternalProject_libzmf.mk
new file mode 100644
index 000000000..1a338526c
--- /dev/null
+++ b/external/libzmf/ExternalProject_libzmf.mk
@@ -0,0 +1,49 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,libzmf))
+
+$(eval $(call gb_ExternalProject_use_autoconf,libzmf,build))
+
+$(eval $(call gb_ExternalProject_register_targets,libzmf,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,libzmf,\
+ boost_headers \
+ icu \
+ libpng \
+ revenge \
+ zlib \
+))
+
+$(call gb_ExternalProject_get_state_target,libzmf,build) :
+ $(call gb_Trace_StartRange,libzmf,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PKG_CONFIG="" \
+ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic \
+ --enable-static \
+ --disable-shared \
+ --without-docs \
+ --disable-tests \
+ --disable-tools \
+ --disable-debug \
+ --disable-werror \
+ --disable-weffc \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CXXFLAGS="$(gb_CXXFLAGS) $(call gb_ExternalProject_get_build_flags,libzmf)" \
+ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libzmf)" \
+ $(gb_CONFIGURE_PLATFORMS) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,libzmf,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libzmf/Makefile b/external/libzmf/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/libzmf/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libzmf/Module_libzmf.mk b/external/libzmf/Module_libzmf.mk
new file mode 100644
index 000000000..c024e697c
--- /dev/null
+++ b/external/libzmf/Module_libzmf.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,libzmf))
+
+$(eval $(call gb_Module_add_targets,libzmf,\
+ ExternalProject_libzmf \
+ UnpackedTarball_libzmf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libzmf/README b/external/libzmf/README
new file mode 100644
index 000000000..ceb21ba87
--- /dev/null
+++ b/external/libzmf/README
@@ -0,0 +1,4 @@
+libzmf is a library and a set of tools for reading and converting
+Zoner Draw and Zebra file formats.
+
+[https://wiki.documentfoundation.org/DLP/Libraries/libzmf]
diff --git a/external/libzmf/UnpackedTarball_libzmf.mk b/external/libzmf/UnpackedTarball_libzmf.mk
new file mode 100644
index 000000000..d37e16fcb
--- /dev/null
+++ b/external/libzmf/UnpackedTarball_libzmf.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,libzmf))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,libzmf,$(ZMF_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,libzmf))
+
+$(eval $(call gb_UnpackedTarball_add_patches,libzmf, \
+ external/libzmf/android-workaround.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/libzmf/android-workaround.patch.1 b/external/libzmf/android-workaround.patch.1
new file mode 100644
index 000000000..a46c5e8c3
--- /dev/null
+++ b/external/libzmf/android-workaround.patch.1
@@ -0,0 +1,14 @@
+--- libzmf.orig/src/lib/ZMFTypes.cpp 2017-09-17 12:14:41.987990622 +0100
++++ libzmf/src/lib/ZMFTypes.cpp 2017-09-17 12:16:32.636850391 +0100
+@@ -38,10 +38,9 @@
+
+ double Point::distance(const Point &p2) const
+ {
+- return std::hypot(p2.x - x, p2.y - y);
++ return ::hypot(p2.x - x, p2.y - y);
+ }
+
+-
+ BoundingBox::BoundingBox(const std::vector<Point> &points_)
+ : m_points(points_)
+ , m_width(0.0)
diff --git a/external/lpsolve/ExternalPackage_lpsolve.mk b/external/lpsolve/ExternalPackage_lpsolve.mk
new file mode 100644
index 000000000..23c2c5abf
--- /dev/null
+++ b/external/lpsolve/ExternalPackage_lpsolve.mk
@@ -0,0 +1,24 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,lpsolve,lpsolve))
+
+$(eval $(call gb_ExternalPackage_use_external_project,lpsolve,lpsolve))
+
+ifneq ($(DISABLE_DYNLOADING),TRUE)
+ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,lpsolve,$(LIBO_LIB_FOLDER)/lpsolve55.dll,lpsolve55/lpsolve55.dll))
+else ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,lpsolve,$(LIBO_LIB_FOLDER)/liblpsolve55.dylib,lpsolve55/liblpsolve55.dylib))
+else # $(OS) != WNT/MACOSX
+$(eval $(call gb_ExternalPackage_add_file,lpsolve,$(LIBO_LIB_FOLDER)/liblpsolve55.so,lpsolve55/liblpsolve55.so))
+endif # $(OS)
+endif # $(DISABLE_DYNLOADING)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lpsolve/ExternalProject_lpsolve.mk b/external/lpsolve/ExternalProject_lpsolve.mk
new file mode 100644
index 000000000..7b5338b24
--- /dev/null
+++ b/external/lpsolve/ExternalProject_lpsolve.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,lpsolve))
+
+$(eval $(call gb_ExternalProject_register_targets,lpsolve,\
+ build \
+))
+
+ifeq ($(OS),WNT)
+$(call gb_ExternalProject_get_state_target,lpsolve,build):
+ $(call gb_Trace_StartRange,lpsolve,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ LIB="$(ILIB)" RUNTIME_FLAG="$(if $(MSVC_USE_DEBUG_RUNTIME),/MDd,/MD)" \
+ cmd /c cvc6.bat \
+ ,lpsolve55)
+ $(call gb_Trace_EndRange,lpsolve,EXTERNAL)
+else # $(OS)!=WNT
+$(call gb_ExternalProject_get_state_target,lpsolve,build):
+ $(call gb_Trace_StartRange,lpsolve,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ CC="$(CC) $(call gb_ExternalProject_get_build_flags,lpsolve)" \
+ $(if $(filter MACOSX,$(OS)),EXTRA_LINKFLAGS='-install_name @__________________________________________________OOO/liblpsolve55.dylib') \
+ sh -e $(if $(filter MACOSX,$(OS)),ccc.osx, \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),ccc.static, \
+ $(if $(filter AIXGCC,$(OS)$(COM)),ccc.aix.gcc, \
+ ccc))) \
+ ,lpsolve55)
+ $(call gb_Trace_EndRange,lpsolve,EXTERNAL)
+endif # $(OS)
+# vim: set noet sw=4 ts=4:
diff --git a/external/lpsolve/Makefile b/external/lpsolve/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/lpsolve/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lpsolve/Module_lpsolve.mk b/external/lpsolve/Module_lpsolve.mk
new file mode 100644
index 000000000..e0094f609
--- /dev/null
+++ b/external/lpsolve/Module_lpsolve.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,lpsolve))
+
+$(eval $(call gb_Module_add_targets,lpsolve,\
+ UnpackedTarball_lpsolve \
+ ExternalPackage_lpsolve \
+ ExternalProject_lpsolve \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lpsolve/README b/external/lpsolve/README
new file mode 100644
index 000000000..3ef9db3e1
--- /dev/null
+++ b/external/lpsolve/README
@@ -0,0 +1 @@
+A mixed Integer Linear Programming (MILP) solver from [http://lpsolve.sourceforge.net/].
diff --git a/external/lpsolve/UnpackedTarball_lpsolve.mk b/external/lpsolve/UnpackedTarball_lpsolve.mk
new file mode 100644
index 000000000..3d17c0e9b
--- /dev/null
+++ b/external/lpsolve/UnpackedTarball_lpsolve.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,lpsolve))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,lpsolve,$(LPSOLVE_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,lpsolve,3))
+
+ifeq ($(OS_FOR_BUILD),WNT)
+
+$(eval $(call gb_UnpackedTarball_set_patchflags,lpsolve,--binary))
+$(eval $(call gb_UnpackedTarball_add_patches,lpsolve,\
+ external/lpsolve/lp_solve_5.5-windows.patch \
+))
+
+else
+
+$(eval $(call gb_UnpackedTarball_add_patches,lpsolve,\
+ external/lpsolve/lp_solve-aix.patch \
+ external/lpsolve/lp_solve-fixed-warn.patch \
+ external/lpsolve/lp_solve_5.5.patch \
+ external/lpsolve/lpsolve-ubsan.patch.0 \
+))
+
+$(eval $(call gb_UnpackedTarball_add_file,lpsolve,lpsolve55/ccc.static,external/lpsolve/ccc.static))
+
+endif
+# vim: set noet sw=4 ts=4:
+
+
diff --git a/external/lpsolve/ccc.static b/external/lpsolve/ccc.static
new file mode 100644
index 000000000..6911c4b2c
--- /dev/null
+++ b/external/lpsolve/ccc.static
@@ -0,0 +1,11 @@
+src='../lp_MDO.c ../shared/commonlib.c ../shared/mmio.c ../shared/myblas.c ../ini.c ../fortify.c ../colamd/colamd.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_LUSOL/lp_LUSOL.c ../bfp/bfp_LUSOL/LUSOL/lusol.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c'
+obj=`echo $src|sed -e 's/\.c/.o/g' -e 's!\([^ ]*/\)*!!g'`
+
+opts='-O3'
+
+def=
+
+$CC -I.. -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I../shared $opts $def -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine -c $src
+
+$AR -r liblpsolve55.a $obj
+rm $obj
diff --git a/external/lpsolve/lp_solve-aix.patch b/external/lpsolve/lp_solve-aix.patch
new file mode 100644
index 000000000..6ad5877ca
--- /dev/null
+++ b/external/lpsolve/lp_solve-aix.patch
@@ -0,0 +1,39 @@
+--- /dev/null 2010-07-28 04:47:47.000000000 -0500
++++ misc/build/lp_solve_5.5/lpsolve55/ccc.aix.gcc 2010-06-29 17:44:53.000000000 -0500
+@@ -0,0 +1,25 @@
++src='../lp_MDO.c ../shared/commonlib.c ../shared/mmio.c ../shared/myblas.c ../ini.c ../fortify.c ../colamd/colamd.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_LUSOL/lp_LUSOL.c ../bfp/bfp_LUSOL/LUSOL/lusol.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c'
++c=$CC
++
++def=
++so=
++if [ "$PLATFORM" = "SCO_UNIX" ]
++then def='-dy -K PIC -DNOLONGLONG'
++ dl=-lc
++else dl=-ldl
++ so=y
++fi
++
++opts='-O3'
++
++$c -s -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd $opts $def -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
++ar rv liblpsolve55.a `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'`
++ranlib liblpsolve55.a
++
++if [ "$so" != "" ]
++then
++ $c -fpic -s -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I. $opts -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
++ $c -shared $lpsolve_LDFLAGS -o liblpsolve55.so `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'` -lc -lm -ldl
++fi
++
++rm *.o 2>/dev/null
+--- misc/lp_solve_5.5/lp_lib.h 2010-07-28 05:15:10.000000000 -0500
++++ misc/build/lp_solve_5.5/lp_lib.h 2010-07-28 05:15:55.000000000 -0500
+@@ -56,7 +56,7 @@
+ /* Define user program feature option switches */
+ /* ------------------------------------------------------------------------- */
+
+-#if !defined _WINDOWS && !defined _WIN32 && !defined WIN32
++#if !defined _WINDOWS && !defined _WIN32 && !defined WIN32 && !defined(_AIX)
+ # define _isnan(x) FALSE
+ #endif
+
diff --git a/external/lpsolve/lp_solve-fixed-warn.patch b/external/lpsolve/lp_solve-fixed-warn.patch
new file mode 100644
index 000000000..46742887a
--- /dev/null
+++ b/external/lpsolve/lp_solve-fixed-warn.patch
@@ -0,0 +1,84 @@
+--- misc/build/lp_solve_5.5/lp_report.c 2007-01-14 10:31:34.000000000 -0800
++++ misc/build/lp_solve_5.5/lp_report.c 2007-01-14 10:31:34.000000000 -0800
+@@ -160,7 +160,7 @@
+ {
+ int i, k = 0;
+
+- fprintf(output, label);
++ fputs(label, output);
+ fprintf(output, "\n");
+ for(i = first; i <= last; i++) {
+ fprintf(output, " %18g", vector[i]);
+@@ -189,7 +189,7 @@
+ if(last < 0)
+ last = lp->rows;
+
+- fprintf(output, label);
++ fputs(label, output);
+ fprintf(output, "\n");
+
+ if(first == 0) {
+@@ -254,7 +254,7 @@
+ if(last < 0)
+ last = lp->rows;
+
+- fprintf(output, label);
++ fputs(label, output);
+ fprintf(output, "\n");
+
+ for(i = first; i <= last; i++) {
+--- misc/build/lp_solve_5.5/lp_rlp.h 2007-01-14 10:31:52.000000000 -0800
++++ misc/build/lp_solve_5.5/lp_rlp.h 2007-01-14 10:31:52.000000000 -0800
+@@ -615,7 +615,7 @@
+ /* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+-#define ECHO (void) fwrite( lp_yytext, lp_yyleng, 1, lp_yyout )
++#define ECHO if(fwrite( lp_yytext, lp_yyleng, 1, lp_yyout ) != 1) YY_FATAL_ERROR( "can't write into lp_yytext" )
+ #endif
+
+ /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+--- misc/build/lp_solve_5.5/shared/commonlib.c 2007-01-14 10:33:14.000000000 -0800
++++ misc/build/lp_solve_5.5/shared/commonlib.c 2007-01-14 10:33:14.000000000 -0800
+@@ -715,7 +715,7 @@
+ {
+ int i, k = 0;
+
+- fprintf(output, label);
++ fputs(label, output);
+ fprintf(output, "\n");
+ for(i = first; i <= last; i++) {
+ fprintf(output, " %5d", myvector[i]);
+@@ -734,7 +734,7 @@
+ {
+ int i, k = 0;
+
+- fprintf(output, label);
++ fputs(label, output);
+ fprintf(output, "\n");
+ for(i = first; i <= last; i++) {
+ if(asRaw)
+@@ -756,7 +756,7 @@
+ {
+ int i, k = 0;
+
+- fprintf(output, label);
++ fputs(label, output);
+ fprintf(output, "\n");
+ for(i = first; i <= last; i++) {
+ fprintf(output, " %18g", myvector[i]);
+--- misc/build/lp_solve_5.5/shared/mmio.c 2007-01-14 10:33:14.000000000 -0800
++++ misc/build/lp_solve_5.5/shared/mmio.c 2007-01-14 10:33:14.000000000 -0800
+@@ -74,7 +74,11 @@
+
+ for (i=0; i<nz; i++)
+ {
+- fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]);
++ if(fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]) != 3)
++ {
++ fprintf(stderr, "read_unsymmetric_sparse(): could not parse values.\n");
++ return -1;
++ }
+ I[i]--; /* adjust from 1-based to 0-based */
+ J[i]--;
+ }
diff --git a/external/lpsolve/lp_solve_5.5-windows.patch b/external/lpsolve/lp_solve_5.5-windows.patch
new file mode 100644
index 000000000..16d5261c7
--- /dev/null
+++ b/external/lpsolve/lp_solve_5.5-windows.patch
@@ -0,0 +1,60 @@
+*** misc/lp_solve_5.5/lpsolve55/cgcc.bat Sun Jun 12 04:27:28 2005
+--- misc/build/lp_solve_5.5/lpsolve55/cgcc.bat Sun Dec 14 07:55:19 2008
+***************
+*** 7,14 ****
+
+ set c=gcc
+
+! rem rc lpsolve.rc
+! %c% -DINLINE=static -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -s -O3 -shared -mno-cygwin -enable-stdcall-fixup -D_USRDLL -DWIN32 -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine %src% ..\lp_solve.def -o lpsolve55.dll
+
+ %c% -DINLINE=static -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -s -O3 -shared -D_USRDLL -DWIN32 -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine %src% -o liblpsolve55.so
+
+--- 7,14 ----
+
+ set c=gcc
+
+! windres lpsolve.rc lpsolve_res.obj
+! %c% -DINLINE=static -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -s -O3 -shared -mno-cygwin -enable-stdcall-fixup -mthreads %lpsolve_LDFLAGS% -D_USRDLL -DWIN32 -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine %src% lpsolve_res.obj ..\lp_solve.def %lpsolve_LIBS% -o lpsolve55.dll
+
+ %c% -DINLINE=static -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -s -O3 -shared -D_USRDLL -DWIN32 -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine %src% -o liblpsolve55.so
+
+*** misc/lp_solve_5.5/lpsolve55/lpsolve.rc Sun Jun 4 00:15:24 2006
+--- misc/build/lp_solve_5.5/lpsolve55/lpsolve.rc Fri Nov 23 16:34:22 2007
+***************
+*** 7,13 ****
+ //
+ // Generated from the TEXTINCLUDE 2 resource.
+ //
+! #include "afxres.h"
+
+ /////////////////////////////////////////////////////////////////////////////
+ #undef APSTUDIO_READONLY_SYMBOLS
+--- 7,13 ----
+ //
+ // Generated from the TEXTINCLUDE 2 resource.
+ //
+! #include "winresrc.h"
+
+ /////////////////////////////////////////////////////////////////////////////
+ #undef APSTUDIO_READONLY_SYMBOLS
+--- misc/lp_solve_5.5/lpsolve55/cvc6.bat
++++ misc/build/lp_solve_5.5/lpsolve55/cvc6.bat
+@@ -14,15 +14,4 @@
+ set c=cl
+
+-rc lpsolve.rc
++rc %SOLARINC% lpsolve.rc
+-%c% -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd /LD /MD /O1 /Zp8 /Gz -D_WINDLL -D_USRDLL -DWIN32 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine %src% lpsolve.res ..\lp_solve.def -o lpsolve55.dll
++%c% -Zi -FS -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd %SOLARINC% /LD %RUNTIME_FLAG% /O1 /Zp8 /Gz -D_WINDLL -D_USRDLL -DWIN32 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine %src% lpsolve.res ..\lp_solve.def -Felpsolve55.dll
+-rem /link /LINK50COMPAT
+-
+-if exist a.obj del a.obj
+-%c% -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd /MT /O1 /Zp8 /Gd /c -DWIN32 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine %src%
+-lib *.obj /OUT:liblpsolve55.lib
+-
+-if exist a.obj del a.obj
+-%c% -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd /MTd /O1 /Zp8 /Gd /c -DWIN32 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine %src%
+-lib *.obj /OUT:liblpsolve55d.lib
+-
+-if exist *.obj del *.obj
diff --git a/external/lpsolve/lp_solve_5.5.patch b/external/lpsolve/lp_solve_5.5.patch
new file mode 100644
index 000000000..2b2588a9f
--- /dev/null
+++ b/external/lpsolve/lp_solve_5.5.patch
@@ -0,0 +1,95 @@
+--- misc/build/lp_solve_5.5/lpsolve55/ccc.orig Sat Jun 11 21:27:18 2005
++++ misc/build/lp_solve_5.5/lpsolve55/ccc Sun May 22 11:20:19 2011
+@@ -1,25 +1,42 @@
+ src='../lp_MDO.c ../shared/commonlib.c ../shared/mmio.c ../shared/myblas.c ../ini.c ../fortify.c ../colamd/colamd.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_LUSOL/lp_LUSOL.c ../bfp/bfp_LUSOL/LUSOL/lusol.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c'
+-c=cc
++ar=$AR
++c=$CC
++ranlib=$RANLIB
+
+ def=
+ so=
+-if [ "$PLATFORM" = "SCO_UNIX" ]
+-then def='-dy -K PIC -DNOLONGLONG'
+- dl=-lc
+-else dl=-ldl
+- so=y
++soprefix=
++libs=
++pic=
++ldflags=
++inline=
++if [ "$OS" = "WNT" -a "$COM" = "GCC" ]; then
++ so=dll
++ a=dll.a
++ inline=-DINLINE=static
++else
++ so=so
++ a=a
++ soprefix=lib
++ libs="-lm"
++ pic=-fpic
++ ldflags="-Wl,-Bsymbolic -Wl,-soname,liblpsolve55.$so"
+ fi
+
++if [ "$OS" = "LINUX" ]; then
++ libs="$libs -ldl"
++fi
++
+ opts='-O3'
+
+-$c -s -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd $opts $def -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
++$c -s $inline -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd $opts $def -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
+-ar rv liblpsolve55.a `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'`
+-ranlib liblpsolve55.a
++$ar rv liblpsolve55.$a `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'`
++$ranlib liblpsolve55.$a
+
+ if [ "$so" != "" ]
+ then
+- $c -fpic -s -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I. $opts -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
+- $c -shared -Wl,-Bsymbolic -Wl,-soname,liblpsolve55.so -o liblpsolve55.so `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'` -lc -lm -ldl
++ $c $pic -s $inline -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I. $opts -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
++ $c -shared $ldflags -o ${soprefix}lpsolve55.$so `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'` $libs
+ fi
+
+ rm *.o 2>/dev/null
+--- misc/build/lp_solve_5.5/lpsolve55/ccc.osx.orig Thu Jun 23 22:53:08 2005
++++ misc/build/lp_solve_5.5/lpsolve55/ccc.osx
+@@ -1,23 +1,30 @@
+ src='../lp_MDO.c ../shared/commonlib.c ../shared/mmio.c ../shared/myblas.c ../ini.c ../fortify.c ../colamd/colamd.c ../lp_rlp.c ../lp_crash.c ../bfp/bfp_LUSOL/lp_LUSOL.c ../bfp/bfp_LUSOL/LUSOL/lusol.c ../lp_Hash.c ../lp_lib.c ../lp_wlp.c ../lp_matrix.c ../lp_mipbb.c ../lp_MPS.c ../lp_params.c ../lp_presolve.c ../lp_price.c ../lp_pricePSE.c ../lp_report.c ../lp_scale.c ../lp_simplex.c ../lp_SOS.c ../lp_utils.c ../yacc_read.c'
+-c=cc
++c=$CC
+
++if test -n "$verbose"; then
++ set -x
++fi
++
+ def=
+ so=
++# EXTRA_LINKFLAGS is set in the ExternalProject_lpsolve.mk
++extra_linkflags=$EXTRA_LINKFLAGS
++
+ if [ "$PLATFORM" = "SCO_UNIX" ]
+ then def='-DLoadInverseLib=0 -DLoadLanguageLib=0 -D__HYPER=long'
+ else dl=-ldl
+ so=y
+ fi
+
+-opts='-idirafter /usr/include/sys -O3 -DINTEGERTIME -Wno-long-double'
++opts='-idirafter /usr/include/sys -O3 -DINTEGERTIME'
+
+-$c -s -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd $opts $def -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
++$c -s -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd $opts $def -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
+-libtool -static -o liblpsolve55.a `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'`
++$LIBTOOL -static -o liblpsolve55.a `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'`
+
+ if [ "$so" != "" ]
+ then
+- $c -fPIC -fno-common -s -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I. $opts -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
+- $c -dynamiclib liblpsolve55.a -compatibility_version 5.5.0 -current_version 5.5.0 -o liblpsolve55.dylib `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'` -lc
++ $c -fPIC -fno-common -s -c -I.. -I../shared -I../bfp -I../bfp/bfp_LUSOL -I../bfp/bfp_LUSOL/LUSOL -I../colamd -I. $opts -DYY_NEVER_INTERACTIVE -DPARSER_LP -DINVERSE_ACTIVE=INVERSE_LUSOL -DRoleIsExternalInvEngine $src
++ $c $extra_linkflags -dynamiclib liblpsolve55.a -compatibility_version 5.5.0 -current_version 5.5.0 -o liblpsolve55.dylib `echo $src|sed s/[.]c/.o/g|sed 's/[^ ]*\///g'` -lc
+ fi
+
+ rm *.o 2>/dev/null
diff --git a/external/lpsolve/lpsolve-ubsan.patch.0 b/external/lpsolve/lpsolve-ubsan.patch.0
new file mode 100644
index 000000000..7a5e308c6
--- /dev/null
+++ b/external/lpsolve/lpsolve-ubsan.patch.0
@@ -0,0 +1,22 @@
+--- lp_presolve.c
++++ lp_presolve.c
+@@ -168,7 +168,7 @@
+ if(isprimal) {
+ if(psdata->primalundo != NULL)
+ mat = psdata->primalundo->tracker;
+- solution = lp->full_solution + lp->presolve_undo->orig_rows;
++ solution = lp->full_solution == NULL ? NULL : lp->full_solution + lp->presolve_undo->orig_rows;
+ slacks = lp->full_solution;
+ }
+ else {
+--- lp_pricePSE.c
++++ lp_pricePSE.c
+@@ -145,7 +147,7 @@
+
+ /* Store the active/current pricing type */
+ if(isdual == AUTOMATIC)
+- isdual = (MYBOOL) lp->edgeVector[0];
++ isdual = lp->edgeVector[0] != 0.0;
+ else
+ lp->edgeVector[0] = isdual;
+
diff --git a/external/lxml/ExternalProject_lxml.mk b/external/lxml/ExternalProject_lxml.mk
new file mode 100644
index 000000000..a282546b1
--- /dev/null
+++ b/external/lxml/ExternalProject_lxml.mk
@@ -0,0 +1,45 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,lxml))
+
+$(eval $(call gb_ExternalProject_use_external_project,lxml,python3))
+$(eval $(call gb_ExternalProject_use_external_project,lxml,libxml2))
+$(eval $(call gb_ExternalProject_use_external_project,lxml,libxslt))
+$(eval $(call gb_ExternalProject_use_external_project,lxml,zlib))
+
+$(eval $(call gb_ExternalProject_register_targets,lxml,\
+ build \
+))
+
+lxml_PYTHON := $(call gb_ExternalExecutable_get_command,python)
+
+$(call gb_ExternalProject_get_state_target,lxml,build): \
+ $(call gb_ExternalExecutable_get_dependencies,python)
+ $(call gb_Trace_StartRange,lxml,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ export PYTHONPATH=$${PYTHONPATH:+$$PYTHONPATH:}$(call gb_UnpackedTarball_get_dir,lxml)/install && \
+ $(if $(PYTHON_FOR_BUILD), \
+ unset MACOSX_DEPLOYMENT_TARGET && , \
+ CFLAGS="$$CFLAGS -I$(call gb_UnpackedTarball_get_dir,python3)" && \
+ CFLAGS="$$CFLAGS -I$(call gb_UnpackedTarball_get_dir,python3)/Include" && \
+ LDFLAGS="$$LDFLAGS -L$(call gb_UnpackedTarball_get_dir,python3)" && \
+ _PYTHON_PROJECT_BASE=$(call gb_UnpackedTarball_get_dir,python3) && \
+ export CFLAGS LDFLAGS _PYTHON_PROJECT_BASE && ) \
+ $(lxml_PYTHON) setup.py build \
+ $(if $(SYSTEM_LIBXML),,--with-xml2-config=$(call gb_UnpackedTarball_get_dir,libxml2)/xml2-config) \
+ $(if $(SYSTEM_LIBXSLT),,--with-xslt-config=$(call gb_UnpackedTarball_get_dir,libxslt)/xslt-config) && \
+ rm -fr install && \
+ mkdir install && \
+ $(lxml_PYTHON) setup.py install \
+ --install-lib install \
+ )
+ $(call gb_Trace_EndRange,lxml,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lxml/Makefile b/external/lxml/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/lxml/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lxml/Module_lxml.mk b/external/lxml/Module_lxml.mk
new file mode 100644
index 000000000..9fe3b85ad
--- /dev/null
+++ b/external/lxml/Module_lxml.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,lxml))
+
+$(eval $(call gb_Module_add_targets,lxml,\
+ UnpackedTarball_lxml \
+ ExternalProject_lxml \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/lxml/README b/external/lxml/README
new file mode 100644
index 000000000..ad9f0952c
--- /dev/null
+++ b/external/lxml/README
@@ -0,0 +1,7 @@
+LXML XML processing python Library from [http://lxml.de/].
+
+This library is used for the .ui accessibility checker bin/gla11y
+
+The archive was downloaded from:
+[http://lxml.de/files/lxml-4.1.1.tgz]
+on 2018-02-22.
diff --git a/external/lxml/UnpackedTarball_lxml.mk b/external/lxml/UnpackedTarball_lxml.mk
new file mode 100644
index 000000000..bfb5dc2b0
--- /dev/null
+++ b/external/lxml/UnpackedTarball_lxml.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,lxml))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,lxml,$(LXML_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mariadb-connector-c/Makefile b/external/mariadb-connector-c/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/mariadb-connector-c/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mariadb-connector-c/Module_mariadb-connector-c.mk b/external/mariadb-connector-c/Module_mariadb-connector-c.mk
new file mode 100644
index 000000000..e6608a011
--- /dev/null
+++ b/external/mariadb-connector-c/Module_mariadb-connector-c.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,mariadb-connector-c))
+
+$(eval $(call gb_Module_add_targets,mariadb-connector-c,\
+ StaticLibrary_mariadb-connector-c \
+ UnpackedTarball_mariadb-connector-c \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mariadb-connector-c/README b/external/mariadb-connector-c/README
new file mode 100644
index 000000000..25209f97f
--- /dev/null
+++ b/external/mariadb-connector-c/README
@@ -0,0 +1,8 @@
+MariaDB Connector/C
+
+https://mariadb.com/kb/en/mariadb-connector-c-release-notes/
+https://downloads.mariadb.com/Connectors/c/
+
+configs/ generated like this:
+
+cmake -DWITH_CURL=OFF -DWITH_SSL=OFF -DWITH_UNIT_TESTS=OFF -DWITH_DYNCOL=OFF .../workdir/UnpackedTarball/mariadb-connector-c/
diff --git a/external/mariadb-connector-c/StaticLibrary_mariadb-connector-c.mk b/external/mariadb-connector-c/StaticLibrary_mariadb-connector-c.mk
new file mode 100644
index 000000000..3458089ce
--- /dev/null
+++ b/external/mariadb-connector-c/StaticLibrary_mariadb-connector-c.mk
@@ -0,0 +1,82 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,mariadb-connector-c))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,mariadb-connector-c))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,mariadb-connector-c,mariadb-connector-c))
+
+$(eval $(call gb_StaticLibrary_set_include,mariadb-connector-c,\
+ $$(INCLUDE) \
+ -I$(call gb_UnpackedTarball_get_dir,mariadb-connector-c)/include \
+))
+
+# This is needed for MSVC 2008: it somehow finds a dlopen somewhere
+# but the static library then contains unreferenced symbols.
+# This macro enables a re-definition to native Win32 APIs in my_global.h.
+## TODO missing enable: -D HAVE_COMPRESS
+## (but then need to add "-lz" to mysqlcppconn linking)
+$(eval $(call gb_StaticLibrary_add_cflags,mariadb-connector-c,-DHAVE_DLOPEN -D ENABLED_LOCAL_INFILE -D LIBMARIADB -D THREAD -DSQLITE_ENABLE_COLUMN_METADATA=1))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_StaticLibrary_add_cflags,mariadb-connector-c,-D_TIMESPEC_DEFINED -DHAVE_STRTOULL))
+$(eval $(call gb_StaticLibrary_set_include,mariadb-connector-c,\
+ $$(INCLUDE) \
+ -I$(call gb_UnpackedTarball_get_dir,mariadb-connector-c)/win-iconv \
+))
+else
+$(eval $(call gb_StaticLibrary_use_external,mariadb-connector-c,openssl_headers))
+$(eval $(call gb_StaticLibrary_add_cflags,mariadb-connector-c,-DHAVE_OPENSSL))
+endif
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,mariadb-connector-c,\
+ UnpackedTarball/mariadb-connector-c/libmariadb/get_password \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_alloc \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_array \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_charset \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_compress \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_context \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_default \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_dtoa \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_errmsg \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_hash \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_init \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_io \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_list \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_ll2str \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_loaddata \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_net \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_password \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_pvio \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_sha1 \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_stmt_codec \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_string \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_time \
+ UnpackedTarball/mariadb-connector-c/libmariadb/mariadb_async \
+ UnpackedTarball/mariadb-connector-c/libmariadb/mariadb_charset \
+ UnpackedTarball/mariadb-connector-c/libmariadb/mariadb_dyncol \
+ UnpackedTarball/mariadb-connector-c/libmariadb/mariadb_lib \
+ UnpackedTarball/mariadb-connector-c/libmariadb/mariadb_stmt \
+ UnpackedTarball/mariadb-connector-c/libmariadb/ma_client_plugin \
+ UnpackedTarball/mariadb-connector-c/plugins/auth/my_auth \
+ UnpackedTarball/mariadb-connector-c/plugins/auth/caching_sha2_pw \
+ UnpackedTarball/mariadb-connector-c/plugins/pvio/pvio_socket \
+ $(if $(filter $(OS),WNT), \
+ UnpackedTarball/mariadb-connector-c/libmariadb/win32_errmsg \
+ UnpackedTarball/mariadb-connector-c/libmariadb/secure/win_crypt \
+ UnpackedTarball/mariadb-connector-c/win-iconv/win_iconv \
+ UnpackedTarball/mariadb-connector-c/plugins/pvio/pvio_npipe \
+ UnpackedTarball/mariadb-connector-c/plugins/pvio/pvio_shmem \
+ , \
+ UnpackedTarball/mariadb-connector-c/libmariadb/secure/openssl_crypt \
+ ) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mariadb-connector-c/UnpackedTarball_mariadb-connector-c.mk b/external/mariadb-connector-c/UnpackedTarball_mariadb-connector-c.mk
new file mode 100644
index 000000000..241e12db6
--- /dev/null
+++ b/external/mariadb-connector-c/UnpackedTarball_mariadb-connector-c.mk
@@ -0,0 +1,57 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,mariadb-connector-c))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,mariadb-connector-c,$(MARIADB_CONNECTOR_C_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_add_file,mariadb-connector-c,include/mariadb_version.h,external/mariadb-connector-c/configs/mariadb_version.h))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_file,mariadb-connector-c,include/ma_config.h,external/mariadb-connector-c/configs/wnt_ma_config.h))
+else
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_UnpackedTarball_add_file,mariadb-connector-c,include/ma_config.h,external/mariadb-connector-c/configs/mac_my_config.h))
+else
+$(eval $(call gb_UnpackedTarball_add_file,mariadb-connector-c,include/ma_config.h,external/mariadb-connector-c/configs/linux_my_config.h))
+endif
+endif # $(OS),WNT
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,mariadb-connector-c,1))
+
+$(eval $(call gb_UnpackedTarball_add_patches,mariadb-connector-c,\
+ external/mariadb-connector-c/clang-cl.patch.0 \
+))
+
+# TODO are any "plugins" needed?
+$(eval $(call gb_UnpackedTarball_set_post_action,mariadb-connector-c, \
+ < libmariadb/ma_client_plugin.c.in sed \
+ -e 's/@EXTERNAL_PLUGINS@/ \
+ extern struct st_mysql_client_plugin pvio_socket_client_plugin\; \
+ extern struct st_mysql_client_plugin caching_sha2_password_client_plugin\; \
+ extern struct st_mysql_client_plugin mysql_native_password_client_plugin\; \
+ $(if $(filter WNT,$(OS)), \
+ extern struct st_mysql_client_plugin pvio_shmem_client_plugin\; \
+ extern struct st_mysql_client_plugin pvio_npipe_client_plugin\; \
+ ) \
+ /' \
+ -e 's/@BUILTIN_PLUGINS@/ \
+ (struct st_mysql_client_plugin *)\&pvio_socket_client_plugin$(COMMA) \
+ (struct st_mysql_client_plugin *)\&caching_sha2_password_client_plugin$(COMMA) \
+ (struct st_mysql_client_plugin *)\&mysql_native_password_client_plugin$(COMMA) \
+ $(if $(filter WNT,$(OS)), \
+ (struct st_mysql_client_plugin *)\&pvio_shmem_client_plugin$(COMMA) \
+ (struct st_mysql_client_plugin *)\&pvio_npipe_client_plugin$(COMMA) \
+ ) \
+ /' \
+ > libmariadb/ma_client_plugin.c \
+))
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mariadb-connector-c/clang-cl.patch.0 b/external/mariadb-connector-c/clang-cl.patch.0
new file mode 100644
index 000000000..4c9ef4def
--- /dev/null
+++ b/external/mariadb-connector-c/clang-cl.patch.0
@@ -0,0 +1,11 @@
+--- unittest/libmariadb/getopt.c
++++ unittest/libmariadb/getopt.c
+@@ -38,7 +38,7 @@
+ #include <config.h>
+ #endif
+
+-#if (!defined (__STDC__) || !__STDC__) && !defined(MSDOS) && !defined(OS2)
++#if (!defined (__STDC__) || !__STDC__) && !defined(MSDOS) && !defined(OS2) && !(defined _MSC_VER && defined __clang__)
+ /* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+ #ifndef const
diff --git a/external/mariadb-connector-c/configs/linux_my_config.h b/external/mariadb-connector-c/configs/linux_my_config.h
new file mode 100644
index 000000000..577a6e163
--- /dev/null
+++ b/external/mariadb-connector-c/configs/linux_my_config.h
@@ -0,0 +1,142 @@
+
+/*
+ * Include file constants (processed in LibmysqlIncludeFiles.txt 1
+ */
+/* #undef HAVE_OPENSSL_APPLINK_C */
+#define HAVE_ALLOCA_H 1
+/* #undef HAVE_BIGENDIAN */
+#define HAVE_SETLOCALE 1
+#define HAVE_NL_LANGINFO 1
+#define HAVE_DLFCN_H 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FLOAT_H 1
+#define HAVE_LIMITS_H 1
+#define HAVE_PWD_H 1
+/* #undef HAVE_SELECT_H */
+#define HAVE_STDDEF_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRING_H 1
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_SOCKET_H 1
+/* #undef HAVE_SYS_STREAM_H */
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_UN_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UCONTEXT_H 1
+
+/*
+ * function definitions - processed in LibmysqlFunctions.txt
+ */
+
+/* #undef HAVE_DLERROR */
+/* #undef HAVE_DLOPEN */
+#define HAVE_GETPWUID 1
+#define HAVE_MEMCPY 1
+#define HAVE_POLL 1
+/* #undef HAVE_STRTOK_R */
+/* #undef HAVE_STRTOL */
+/* #undef HAVE_STRTOLL */
+/* #undef HAVE_STRTOUL */
+/* #undef HAVE_STRTOULL */
+/* #undef HAVE_TELL */
+/* #undef HAVE_THR_SETCONCURRENCY */
+/* #undef HAVE_THR_YIELD */
+/* #undef HAVE_VASPRINTF */
+/* #undef HAVE_VSNPRINTF */
+#define HAVE_CUSERID 1
+
+/*
+ * types and sizes
+ */
+
+
+#define SIZEOF_CHARP 8
+#if defined(SIZEOF_CHARP)
+# define HAVE_CHARP 1
+#endif
+
+
+#define SIZEOF_INT 4
+#if defined(SIZEOF_INT)
+# define HAVE_INT 1
+#endif
+
+#define SIZEOF_LONG 8
+#if defined(SIZEOF_LONG)
+# define HAVE_LONG 1
+#endif
+
+#define SIZEOF_LONG_LONG 8
+#if defined(SIZEOF_LONG_LONG)
+# define HAVE_LONG_LONG 1
+#endif
+
+
+#define SIZEOF_SIZE_T 8
+#if defined(SIZEOF_SIZE_T)
+# define HAVE_SIZE_T 1
+#endif
+
+
+#define SIZEOF_UINT 4
+#if defined(SIZEOF_UINT)
+# define HAVE_UINT 1
+#endif
+
+#define SIZEOF_ULONG 8
+#if defined(SIZEOF_ULONG)
+# define HAVE_ULONG 1
+#endif
+
+/* #undef SIZEOF_INT8 */
+#if defined(SIZEOF_INT8)
+# define HAVE_INT8 1
+#endif
+/* #undef SIZEOF_UINT8 */
+#if defined(SIZEOF_UINT8)
+# define HAVE_UINT8 1
+#endif
+
+/* #undef SIZEOF_INT16 */
+#if defined(SIZEOF_INT16)
+# define HAVE_INT16 1
+#endif
+/* #undef SIZEOF_UINT16 */
+#if defined(SIZEOF_UINT16)
+# define HAVE_UINT16 1
+#endif
+
+/* #undef SIZEOF_INT32 */
+#if defined(SIZEOF_INT32)
+# define HAVE_INT32 1
+#endif
+/* #undef SIZEOF_UINT32 */
+#if defined(SIZEOF_UINT32)
+# define HAVE_UINT32 1
+#endif
+
+/* #undef SIZEOF_INT64 */
+#if defined(SIZEOF_INT64)
+# define HAVE_INT64 1
+#endif
+/* #undef SIZEOF_UINT64 */
+#if defined(SIZEOF_UINT64)
+# define HAVE_UINT64 1
+#endif
+
+/* #undef SIZEOF_SOCKLEN_T */
+#if defined(SIZEOF_SOCKLEN_T)
+# define HAVE_SOCKLEN_T 1
+#endif
+
+#define SOCKET_SIZE_TYPE socklen_t
+
+#define LOCAL_INFILE_MODE_OFF 0
+#define LOCAL_INFILE_MODE_ON 1
+#define LOCAL_INFILE_MODE_AUTO 2
+#define ENABLED_LOCAL_INFILE LOCAL_INFILE_MODE_AUTO
+
+#define MARIADB_DEFAULT_CHARSET "latin1"
+
diff --git a/external/mariadb-connector-c/configs/mac_my_config.h b/external/mariadb-connector-c/configs/mac_my_config.h
new file mode 100644
index 000000000..c94856115
--- /dev/null
+++ b/external/mariadb-connector-c/configs/mac_my_config.h
@@ -0,0 +1,142 @@
+
+/*
+ * Include file constants (processed in LibmysqlIncludeFiles.txt 1
+ */
+/* #undef HAVE_OPENSSL_APPLINK_C */
+#define HAVE_ALLOCA_H 1
+/* #undef HAVE_BIGENDIAN */
+#define HAVE_SETLOCALE 1
+#define HAVE_NL_LANGINFO 1
+#define HAVE_DLFCN_H 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FLOAT_H 1
+#define HAVE_LIMITS_H 1
+#define HAVE_PWD_H 1
+/* #undef HAVE_SELECT_H */
+#define HAVE_STDDEF_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRING_H 1
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_SOCKET_H 1
+/* #undef HAVE_SYS_STREAM_H */
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_UN_H 1
+#define HAVE_UNISTD_H 1
+/* #undef HAVE_UCONTEXT_H */
+
+/*
+ * function definitions - processed in LibmysqlFunctions.txt
+ */
+
+#define HAVE_DLERROR 1
+#define HAVE_DLOPEN 1
+#define HAVE_GETPWUID 1
+#define HAVE_MEMCPY 1
+#define HAVE_POLL 1
+/* #undef HAVE_STRTOK_R */
+/* #undef HAVE_STRTOL */
+/* #undef HAVE_STRTOLL */
+/* #undef HAVE_STRTOUL */
+/* #undef HAVE_STRTOULL */
+/* #undef HAVE_TELL */
+/* #undef HAVE_THR_SETCONCURRENCY */
+/* #undef HAVE_THR_YIELD */
+/* #undef HAVE_VASPRINTF */
+/* #undef HAVE_VSNPRINTF */
+/* #undef HAVE_CUSERID */
+
+/*
+ * types and sizes
+ */
+
+
+#define SIZEOF_CHARP 8
+#if defined(SIZEOF_CHARP)
+# define HAVE_CHARP 1
+#endif
+
+
+#define SIZEOF_INT 4
+#if defined(SIZEOF_INT)
+# define HAVE_INT 1
+#endif
+
+#define SIZEOF_LONG 8
+#if defined(SIZEOF_LONG)
+# define HAVE_LONG 1
+#endif
+
+#define SIZEOF_LONG_LONG 8
+#if defined(SIZEOF_LONG_LONG)
+# define HAVE_LONG_LONG 1
+#endif
+
+
+#define SIZEOF_SIZE_T 8
+#if defined(SIZEOF_SIZE_T)
+# define HAVE_SIZE_T 1
+#endif
+
+
+#define SIZEOF_UINT 4
+#if defined(SIZEOF_UINT)
+# define HAVE_UINT 1
+#endif
+
+/* #undef SIZEOF_ULONG */
+#if defined(SIZEOF_ULONG)
+# define HAVE_ULONG 1
+#endif
+
+/* #undef SIZEOF_INT8 */
+#if defined(SIZEOF_INT8)
+# define HAVE_INT8 1
+#endif
+/* #undef SIZEOF_UINT8 */
+#if defined(SIZEOF_UINT8)
+# define HAVE_UINT8 1
+#endif
+
+/* #undef SIZEOF_INT16 */
+#if defined(SIZEOF_INT16)
+# define HAVE_INT16 1
+#endif
+/* #undef SIZEOF_UINT16 */
+#if defined(SIZEOF_UINT16)
+# define HAVE_UINT16 1
+#endif
+
+/* #undef SIZEOF_INT32 */
+#if defined(SIZEOF_INT32)
+# define HAVE_INT32 1
+#endif
+/* #undef SIZEOF_UINT32 */
+#if defined(SIZEOF_UINT32)
+# define HAVE_UINT32 1
+#endif
+
+/* #undef SIZEOF_INT64 */
+#if defined(SIZEOF_INT64)
+# define HAVE_INT64 1
+#endif
+/* #undef SIZEOF_UINT64 */
+#if defined(SIZEOF_UINT64)
+# define HAVE_UINT64 1
+#endif
+
+/* #undef SIZEOF_SOCKLEN_T */
+#if defined(SIZEOF_SOCKLEN_T)
+# define HAVE_SOCKLEN_T 1
+#endif
+
+#define SOCKET_SIZE_TYPE socklen_t
+
+#define LOCAL_INFILE_MODE_OFF 0
+#define LOCAL_INFILE_MODE_ON 1
+#define LOCAL_INFILE_MODE_AUTO 2
+#define ENABLED_LOCAL_INFILE LOCAL_INFILE_MODE_AUTO
+
+#define MARIADB_DEFAULT_CHARSET "latin1"
+
diff --git a/external/mariadb-connector-c/configs/mariadb_version.h b/external/mariadb-connector-c/configs/mariadb_version.h
new file mode 100644
index 000000000..7344982a6
--- /dev/null
+++ b/external/mariadb-connector-c/configs/mariadb_version.h
@@ -0,0 +1,38 @@
+/* Copyright Abandoned 1996, 1999, 2001 MySQL AB
+ This file is public domain and comes with NO WARRANTY of any kind */
+
+/* Version numbers for protocol & mysqld */
+
+#ifndef _mariadb_version_h_
+#define _mariadb_version_h_
+
+#ifdef _CUSTOMCONFIG_
+#include <custom_conf.h>
+#else
+#define PROTOCOL_VERSION 10
+#define MARIADB_CLIENT_VERSION_STR "10.4.3"
+#define MARIADB_BASE_VERSION "mariadb-10.4"
+#define MARIADB_VERSION_ID 100403
+#define MARIADB_PORT 3306
+#define MARIADB_UNIX_ADDR "/tmp/mysql.sock"
+
+#define MYSQL_CONFIG_NAME "my"
+#define MYSQL_VERSION_ID 100403
+#define MYSQL_SERVER_VERSION "10.4.3-MariaDB"
+
+#define MARIADB_PACKAGE_VERSION "3.1.8"
+#define MARIADB_PACKAGE_VERSION_ID 30108
+#define MARIADB_SYSTEM_TYPE "Linux"
+#define MARIADB_MACHINE_TYPE "x86_64"
+#define MARIADB_PLUGINDIR "/usr/local/lib/mariadb/plugin"
+
+/* mysqld compile time options */
+#ifndef MYSQL_CHARSET
+#define MYSQL_CHARSET ""
+#endif
+#endif
+
+/* Source information */
+#define CC_SOURCE_REVISION ""
+
+#endif /* _mariadb_version_h_ */
diff --git a/external/mariadb-connector-c/configs/wnt_ma_config.h b/external/mariadb-connector-c/configs/wnt_ma_config.h
new file mode 100644
index 000000000..d06393509
--- /dev/null
+++ b/external/mariadb-connector-c/configs/wnt_ma_config.h
@@ -0,0 +1,154 @@
+
+/*
+ * Include file constants (processed in LibmysqlIncludeFiles.txt 1
+ */
+/* #undef HAVE_OPENSSL_APPLINK_C */
+/* #undef HAVE_ALLOCA_H */
+/* #undef HAVE_BIGENDIAN */
+#define HAVE_SETLOCALE 1
+/* #undef HAVE_NL_LANGINFO */
+/* #undef HAVE_DLFCN_H */
+#define HAVE_FCNTL_H 1
+#define HAVE_FLOAT_H 1
+#define HAVE_LIMITS_H 1
+/* #undef HAVE_PWD_H */
+/* #undef HAVE_SELECT_H */
+#define HAVE_STDDEF_H 1
+/* #undef HAVE_STDINT_H */
+#define HAVE_STDLIB_H 1
+#define HAVE_STRING_H 1
+/* #undef HAVE_SYS_IOCTL_H */
+/* #undef HAVE_SYS_SELECT_H */
+/* #undef HAVE_SYS_SOCKET_H */
+/* #undef HAVE_SYS_STREAM_H */
+#define HAVE_SYS_TYPES_H 1
+/* #undef HAVE_SYS_UN_H */
+/* #undef HAVE_UNISTD_H */
+/* #undef HAVE_UCONTEXT_H */
+
+/*
+ * function definitions - processed in LibmysqlFunctions.txt
+ */
+
+/* #undef HAVE_DLERROR */
+/* #undef HAVE_DLOPEN */
+/* #undef HAVE_GETPWUID */
+#define HAVE_MEMCPY 1
+/* #undef HAVE_POLL */
+/* #undef HAVE_STRTOK_R */
+#define HAVE_STRTOL 1
+/* #undef HAVE_STRTOLL */
+#define HAVE_STRTOUL 1
+/* #undef HAVE_STRTOULL */
+#define HAVE_TELL 1
+/* #undef HAVE_THR_SETCONCURRENCY */
+/* #undef HAVE_THR_YIELD */
+/* #undef HAVE_VASPRINTF */
+#define HAVE_VSNPRINTF 1
+/* #undef HAVE_CUSERID */
+
+/*
+ * types and sizes
+ */
+
+
+#ifdef _M_X64
+#define SIZEOF_CHARP 8
+#else
+#define SIZEOF_CHARP 4
+#endif
+#if defined(SIZEOF_CHARP)
+# define HAVE_CHARP 1
+#endif
+
+
+#define SIZEOF_INT 4
+#if defined(SIZEOF_INT)
+# define HAVE_INT 1
+#endif
+
+#define SIZEOF_LONG 4
+#if defined(SIZEOF_LONG)
+# define HAVE_LONG 1
+#endif
+
+#ifdef _M_X64
+#define SIZEOF_LONG_LONG 8
+#else
+#define SIZEOF_LONG_LONG 4
+#endif
+#if defined(SIZEOF_LONG_LONG)
+# define HAVE_LONG_LONG 1
+#endif
+
+
+#ifdef _M_X64
+#define SIZEOF_SIZE_T 8
+#else
+#define SIZEOF_SIZE_T 4
+#endif
+#if defined(SIZEOF_SIZE_T)
+# define HAVE_SIZE_T 1
+#endif
+
+
+/* #undef SIZEOF_UINT */
+#if defined(SIZEOF_UINT)
+# define HAVE_UINT 1
+#endif
+
+/* #undef SIZEOF_ULONG */
+#if defined(SIZEOF_ULONG)
+# define HAVE_ULONG 1
+#endif
+
+/* #undef SIZEOF_INT8 */
+#if defined(SIZEOF_INT8)
+# define HAVE_INT8 1
+#endif
+/* #undef SIZEOF_UINT8 */
+#if defined(SIZEOF_UINT8)
+# define HAVE_UINT8 1
+#endif
+
+/* #undef SIZEOF_INT16 */
+#if defined(SIZEOF_INT16)
+# define HAVE_INT16 1
+#endif
+/* #undef SIZEOF_UINT16 */
+#if defined(SIZEOF_UINT16)
+# define HAVE_UINT16 1
+#endif
+
+/* #undef SIZEOF_INT32 */
+#if defined(SIZEOF_INT32)
+# define HAVE_INT32 1
+#endif
+/* #undef SIZEOF_UINT32 */
+#if defined(SIZEOF_UINT32)
+# define HAVE_UINT32 1
+#endif
+
+/* #undef SIZEOF_INT64 */
+#if defined(SIZEOF_INT64)
+# define HAVE_INT64 1
+#endif
+/* #undef SIZEOF_UINT64 */
+#if defined(SIZEOF_UINT64)
+# define HAVE_UINT64 1
+#endif
+
+/* #undef SIZEOF_SOCKLEN_T */
+#if defined(SIZEOF_SOCKLEN_T)
+# define HAVE_SOCKLEN_T 1
+#endif
+
+#define SOCKET_SIZE_TYPE int
+
+#define LOCAL_INFILE_MODE_OFF 0
+#define LOCAL_INFILE_MODE_ON 1
+#define LOCAL_INFILE_MODE_AUTO 2
+#define ENABLED_LOCAL_INFILE LOCAL_INFILE_MODE_AUTO
+
+#define MARIADB_DEFAULT_CHARSET "latin1"
+
diff --git a/external/mdds/Makefile b/external/mdds/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/mdds/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mdds/Module_mdds.mk b/external/mdds/Module_mdds.mk
new file mode 100644
index 000000000..47745940b
--- /dev/null
+++ b/external/mdds/Module_mdds.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,mdds))
+
+$(eval $(call gb_Module_add_targets,mdds,\
+ UnpackedTarball_mdds \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mdds/README b/external/mdds/README
new file mode 100644
index 000000000..140f07bac
--- /dev/null
+++ b/external/mdds/README
@@ -0,0 +1,4 @@
+Multi-dimensional data structure (mdds) library, available from [https://gitlab.com/mdds/mdds].
+
+mdds primarily provides data structures that are used by the calc
+core.
diff --git a/external/mdds/UnpackedTarball_mdds.mk b/external/mdds/UnpackedTarball_mdds.mk
new file mode 100644
index 000000000..271d20b0f
--- /dev/null
+++ b/external/mdds/UnpackedTarball_mdds.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,mdds))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,mdds,$(MDDS_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,mdds,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,mdds,\
+ external/mdds/use-after-free.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mdds/use-after-free.patch b/external/mdds/use-after-free.patch
new file mode 100644
index 000000000..981c94582
--- /dev/null
+++ b/external/mdds/use-after-free.patch
@@ -0,0 +1,12 @@
+--- include/mdds/flat_segment_tree_def.inl
++++ include/mdds/flat_segment_tree_def.inl
+@@ -84,8 +84,8 @@
+ // Move on to the next destination node, and have the next node point
+ // back to the previous node.
+ node_ptr old_node = dest_node;
++ dest_node->next->prev = old_node;
+ dest_node = dest_node->next;
+- dest_node->prev = old_node;
+
+ if (src_node == r.m_right_leaf.get())
+ {
diff --git a/external/mdnsresponder/Makefile b/external/mdnsresponder/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/mdnsresponder/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mdnsresponder/Module_mdnsresponder.mk b/external/mdnsresponder/Module_mdnsresponder.mk
new file mode 100644
index 000000000..b2996840b
--- /dev/null
+++ b/external/mdnsresponder/Module_mdnsresponder.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,mdnsresponder))
+
+$(eval $(call gb_Module_add_targets,mdnsresponder,\
+ UnpackedTarball_mDNSResponder \
+))
+
+$(eval $(call gb_Module_add_targets,mdnsresponder,\
+ StaticLibrary_mDNSResponder \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mdnsresponder/README b/external/mdnsresponder/README
new file mode 100644
index 000000000..d263b0521
--- /dev/null
+++ b/external/mdnsresponder/README
@@ -0,0 +1,4 @@
+Apple's ZeroConf Multicast DNS implementation
+
+https://developer.apple.com/bonjour/
+http://www.opensource.apple.com/tarballs/mDNSResponder/
diff --git a/external/mdnsresponder/StaticLibrary_mDNSResponder.mk b/external/mdnsresponder/StaticLibrary_mDNSResponder.mk
new file mode 100644
index 000000000..222776ad3
--- /dev/null
+++ b/external/mdnsresponder/StaticLibrary_mDNSResponder.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,mDNSResponder))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,mDNSResponder))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,mDNSResponder,mDNSResponder))
+
+$(eval $(call gb_StaticLibrary_set_include,mDNSResponder,\
+ -I$(call gb_UnpackedTarball_get_dir,mDNSResponder)/mDNSShared \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_StaticLibrary_add_defs,mDNSResponder,\
+ -DWIN32_LEAN_AND_MEAN \
+ -D_WINSOCK_DEPRECATED_NO_WARNINGS \
+ -DUSE_TCP_LOOPBACK \
+ -DNOT_HAVE_SA_LEN \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,mDNSResponder,\
+ UnpackedTarball/mDNSResponder/mDNSShared/DebugServices \
+ UnpackedTarball/mDNSResponder/mDNSShared/GenLinkedList \
+ UnpackedTarball/mDNSResponder/mDNSShared/dnssd_clientlib \
+ UnpackedTarball/mDNSResponder/mDNSShared/dnssd_clientstub \
+ UnpackedTarball/mDNSResponder/mDNSShared/dnssd_ipc \
+ UnpackedTarball/mDNSResponder/mDNSWindows/DLL/dllmain \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mdnsresponder/UnpackedTarball_mDNSResponder.mk b/external/mdnsresponder/UnpackedTarball_mDNSResponder.mk
new file mode 100644
index 000000000..9b436b2f0
--- /dev/null
+++ b/external/mdnsresponder/UnpackedTarball_mDNSResponder.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,mDNSResponder))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,mDNSResponder,$(MDNSRESPONDER_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/misc_extensions/ExtensionPackageSet_misc_extensions.mk b/external/misc_extensions/ExtensionPackageSet_misc_extensions.mk
new file mode 100644
index 000000000..b03254845
--- /dev/null
+++ b/external/misc_extensions/ExtensionPackageSet_misc_extensions.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExtensionPackageSet_ExtensionPackageSet,misc_extensions))
+
+ifneq ($(NUMBERTEXT_EXTENSION_PACK),)
+$(eval $(call gb_ExtensionPackageSet_add_extension,misc_extensions,numbertext,$(NUMBERTEXT_EXTENSION_PACK)))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/misc_extensions/Makefile b/external/misc_extensions/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/misc_extensions/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/misc_extensions/Module_misc_extensions.mk b/external/misc_extensions/Module_misc_extensions.mk
new file mode 100644
index 000000000..86f65c2dd
--- /dev/null
+++ b/external/misc_extensions/Module_misc_extensions.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,misc_extensions))
+
+$(eval $(call gb_Module_add_targets,misc_extensions,\
+ ExtensionPackageSet_misc_extensions \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/misc_extensions/README b/external/misc_extensions/README
new file mode 100644
index 000000000..9c6fa2e54
--- /dev/null
+++ b/external/misc_extensions/README
@@ -0,0 +1 @@
+misc_extensions contains some extensions may be downloaded and bundled as-is
diff --git a/external/more_fonts/ExternalPackage_EmojiOne_Color.mk b/external/more_fonts/ExternalPackage_EmojiOne_Color.mk
new file mode 100644
index 000000000..76cdb6684
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_EmojiOne_Color.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_emojione_color,font_emojione_color))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_emojione_color,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ EmojiOneColor-SVGinOT.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_alef.mk b/external/more_fonts/ExternalPackage_alef.mk
new file mode 100644
index 000000000..f41aca483
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_alef.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_alef,font_alef))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_alef,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ Alef-Bold.ttf \
+ Alef-Regular.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_amiri.mk b/external/more_fonts/ExternalPackage_amiri.mk
new file mode 100644
index 000000000..d938b8cf7
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_amiri.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_amiri,font_amiri))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_amiri,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ Amiri-Bold.ttf \
+ Amiri-BoldSlanted.ttf \
+ AmiriQuran.ttf \
+ Amiri-Regular.ttf \
+ Amiri-Slanted.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_caladea.mk b/external/more_fonts/ExternalPackage_caladea.mk
new file mode 100644
index 000000000..9632a9d6b
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_caladea.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_caladea,font_caladea))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_caladea,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ Caladea-Italic.ttf \
+ Caladea-Regular.ttf \
+ Caladea-BoldItalic.ttf \
+ Caladea-Bold.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_carlito.mk b/external/more_fonts/ExternalPackage_carlito.mk
new file mode 100644
index 000000000..1e09a554d
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_carlito.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_carlito,font_carlito))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_carlito,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ Carlito-BoldItalic.ttf \
+ Carlito-Regular.ttf \
+ Carlito-Italic.ttf \
+ Carlito-Bold.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_culmus.mk b/external/more_fonts/ExternalPackage_culmus.mk
new file mode 100644
index 000000000..f7a537e80
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_culmus.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_culmus,font_culmus))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_culmus,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ DavidCLM-Bold.otf \
+ DavidCLM-BoldItalic.otf \
+ DavidCLM-Medium.otf \
+ DavidCLM-MediumItalic.otf \
+ FrankRuehlCLM-Bold.ttf \
+ FrankRuehlCLM-BoldOblique.ttf \
+ FrankRuehlCLM-Medium.ttf \
+ FrankRuehlCLM-MediumOblique.ttf \
+ MiriamCLM-Bold.ttf \
+ MiriamCLM-Book.ttf \
+ MiriamMonoCLM-Bold.ttf \
+ MiriamMonoCLM-BoldOblique.ttf \
+ MiriamMonoCLM-Book.ttf \
+ MiriamMonoCLM-BookOblique.ttf \
+ NachlieliCLM-Bold.otf \
+ NachlieliCLM-BoldOblique.otf \
+ NachlieliCLM-Light.otf \
+ NachlieliCLM-LightOblique.otf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_dejavu.mk b/external/more_fonts/ExternalPackage_dejavu.mk
new file mode 100644
index 000000000..981875ce7
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_dejavu.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_dejavu,font_dejavu))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_dejavu,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ ttf/DejaVuMathTeXGyre.ttf \
+ ttf/DejaVuSans-Bold.ttf \
+ ttf/DejaVuSans-BoldOblique.ttf \
+ ttf/DejaVuSans-ExtraLight.ttf \
+ ttf/DejaVuSans-Oblique.ttf \
+ ttf/DejaVuSans.ttf \
+ ttf/DejaVuSansCondensed-Bold.ttf \
+ ttf/DejaVuSansCondensed-BoldOblique.ttf \
+ ttf/DejaVuSansCondensed-Oblique.ttf \
+ ttf/DejaVuSansCondensed.ttf \
+ ttf/DejaVuSansMono-Bold.ttf \
+ ttf/DejaVuSansMono-BoldOblique.ttf \
+ ttf/DejaVuSansMono-Oblique.ttf \
+ ttf/DejaVuSansMono.ttf \
+ ttf/DejaVuSerif-Bold.ttf \
+ ttf/DejaVuSerif-BoldItalic.ttf \
+ ttf/DejaVuSerif-Italic.ttf \
+ ttf/DejaVuSerif.ttf \
+ ttf/DejaVuSerifCondensed-Bold.ttf \
+ ttf/DejaVuSerifCondensed-BoldItalic.ttf \
+ ttf/DejaVuSerifCondensed-Italic.ttf \
+ ttf/DejaVuSerifCondensed.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_gentium.mk b/external/more_fonts/ExternalPackage_gentium.mk
new file mode 100644
index 000000000..aa846271d
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_gentium.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_gentium,font_gentium))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_gentium,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ GenBasB.ttf \
+ GenBasBI.ttf \
+ GenBasI.ttf \
+ GenBasR.ttf \
+ GenBkBasB.ttf \
+ GenBkBasBI.ttf \
+ GenBkBasI.ttf \
+ GenBkBasR.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_kacst.mk b/external/more_fonts/ExternalPackage_kacst.mk
new file mode 100644
index 000000000..909ed1111
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_kacst.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_kacst,font_kacst))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_kacst,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ KacstBook.ttf \
+ KacstOffice.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_liberation.mk b/external/more_fonts/ExternalPackage_liberation.mk
new file mode 100644
index 000000000..a57207446
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_liberation.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_liberation,font_liberation))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_liberation,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ LiberationMono-Bold.ttf \
+ LiberationMono-BoldItalic.ttf \
+ LiberationMono-Italic.ttf \
+ LiberationMono-Regular.ttf \
+ LiberationSans-Bold.ttf \
+ LiberationSans-BoldItalic.ttf \
+ LiberationSans-Italic.ttf \
+ LiberationSans-Regular.ttf \
+ LiberationSerif-Bold.ttf \
+ LiberationSerif-BoldItalic.ttf \
+ LiberationSerif-Italic.ttf \
+ LiberationSerif-Regular.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_liberation_narrow.mk b/external/more_fonts/ExternalPackage_liberation_narrow.mk
new file mode 100644
index 000000000..2fc52f3bb
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_liberation_narrow.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_liberation_narrow,font_liberation_narrow))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_liberation_narrow,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ LiberationSansNarrow-Bold.ttf \
+ LiberationSansNarrow-BoldItalic.ttf \
+ LiberationSansNarrow-Italic.ttf \
+ LiberationSansNarrow-Regular.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_libertineg.mk b/external/more_fonts/ExternalPackage_libertineg.mk
new file mode 100644
index 000000000..9c97b3ba3
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_libertineg.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_libertineg,font_libertineg))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_libertineg,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ LinBiolinum_RB_G.ttf \
+ LinBiolinum_RI_G.ttf \
+ LinBiolinum_R_G.ttf \
+ LinLibertine_DR_G.ttf \
+ LinLibertine_RBI_G.ttf \
+ LinLibertine_RB_G.ttf \
+ LinLibertine_RI_G.ttf \
+ LinLibertine_RZI_G.ttf \
+ LinLibertine_RZ_G.ttf \
+ LinLibertine_R_G.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_libre_hebrew.mk b/external/more_fonts/ExternalPackage_libre_hebrew.mk
new file mode 100644
index 000000000..ec2bd0024
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_libre_hebrew.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_libre_hebrew,font_libre_hebrew))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_libre_hebrew,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ DavidLibre-Bold.ttf \
+ DavidLibre-Regular.ttf \
+ FrankRuhlHofshi-Bold.otf \
+ FrankRuhlHofshi-Regular.otf \
+ MiriamLibre-Bold.otf \
+ MiriamLibre-Regular.otf \
+ Rubik-Bold.ttf \
+ Rubik-BoldItalic.ttf \
+ Rubik-Italic.ttf \
+ Rubik-Regular.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_noto.mk b/external/more_fonts/ExternalPackage_noto.mk
new file mode 100644
index 000000000..dd52ac956
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_noto.mk
@@ -0,0 +1,63 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_noto,font_noto))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_noto,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ NotoKufiArabic-Bold.ttf \
+ NotoKufiArabic-Regular.ttf \
+ NotoMono-Regular.ttf \
+ NotoNaskhArabic-Bold.ttf \
+ NotoNaskhArabic-Regular.ttf \
+ NotoNaskhArabicUI-Bold.ttf \
+ NotoNaskhArabicUI-Regular.ttf \
+ NotoSansArabic-Bold.ttf \
+ NotoSansArabic-Regular.ttf \
+ NotoSansArabicUI-Bold.ttf \
+ NotoSansArabicUI-Regular.ttf \
+ NotoSansArmenian-Bold.ttf \
+ NotoSansArmenian-Regular.ttf \
+ NotoSans-Bold.ttf \
+ NotoSans-BoldItalic.ttf \
+ NotoSans-Condensed.ttf \
+ NotoSans-CondensedBold.ttf \
+ NotoSans-CondensedBoldItalic.ttf \
+ NotoSans-CondensedItalic.ttf \
+ NotoSansGeorgian-Bold.ttf \
+ NotoSansGeorgian-Regular.ttf \
+ NotoSansHebrew-Bold.ttf \
+ NotoSansHebrew-Regular.ttf \
+ NotoSans-Italic.ttf \
+ NotoSansLao-Bold.ttf \
+ NotoSansLao-Regular.ttf \
+ NotoSans-Light.ttf \
+ NotoSans-LightItalic.ttf \
+ NotoSansLisu-Regular.ttf \
+ NotoSans-Regular.ttf \
+ NotoSerifArmenian-Bold.ttf \
+ NotoSerifArmenian-Regular.ttf \
+ NotoSerif-Bold.ttf \
+ NotoSerif-BoldItalic.ttf \
+ NotoSerif-Condensed.ttf \
+ NotoSerif-CondensedBold.ttf \
+ NotoSerif-CondensedBoldItalic.ttf \
+ NotoSerif-CondensedItalic.ttf \
+ NotoSerifGeorgian-Bold.ttf \
+ NotoSerifGeorgian-Regular.ttf \
+ NotoSerifHebrew-Bold.ttf \
+ NotoSerifHebrew-Regular.ttf \
+ NotoSerif-Italic.ttf \
+ NotoSerifLao-Bold.ttf \
+ NotoSerifLao-Regular.ttf \
+ NotoSerif-Light.ttf \
+ NotoSerif-LightItalic.ttf \
+ NotoSerif-Regular.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_reem.mk b/external/more_fonts/ExternalPackage_reem.mk
new file mode 100644
index 000000000..bc26cecc7
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_reem.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_reem,font_reem))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_reem,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ ttf/ReemKufi-Regular.ttf \
+ ttf/ReemKufi-Bold.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_scheherazade.mk b/external/more_fonts/ExternalPackage_scheherazade.mk
new file mode 100644
index 000000000..8bf269e89
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_scheherazade.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_scheherazade,font_scheherazade))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_scheherazade,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ Scheherazade-Bold.ttf \
+ Scheherazade-Regular.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_sourcecode.mk b/external/more_fonts/ExternalPackage_sourcecode.mk
new file mode 100644
index 000000000..5f1d7f7c5
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_sourcecode.mk
@@ -0,0 +1,29 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_sourcecode,font_sourcecode))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_sourcecode,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ SourceCodePro-BlackIt.ttf \
+ SourceCodePro-Black.ttf \
+ SourceCodePro-BoldIt.ttf \
+ SourceCodePro-Bold.ttf \
+ SourceCodePro-ExtraLightIt.ttf \
+ SourceCodePro-ExtraLight.ttf \
+ SourceCodePro-It.ttf \
+ SourceCodePro-LightIt.ttf \
+ SourceCodePro-Light.ttf \
+ SourceCodePro-MediumIt.ttf \
+ SourceCodePro-Medium.ttf \
+ SourceCodePro-Regular.ttf \
+ SourceCodePro-SemiboldIt.ttf \
+ SourceCodePro-Semibold.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_sourcesans.mk b/external/more_fonts/ExternalPackage_sourcesans.mk
new file mode 100644
index 000000000..cd7ac29e9
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_sourcesans.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_sourcesans,font_sourcesans))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_sourcesans,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ SourceSansPro-BlackIt.ttf \
+ SourceSansPro-Black.ttf \
+ SourceSansPro-BoldIt.ttf \
+ SourceSansPro-Bold.ttf \
+ SourceSansPro-ExtraLightIt.ttf \
+ SourceSansPro-ExtraLight.ttf \
+ SourceSansPro-It.ttf \
+ SourceSansPro-LightIt.ttf \
+ SourceSansPro-Light.ttf \
+ SourceSansPro-Regular.ttf \
+ SourceSansPro-SemiboldIt.ttf \
+ SourceSansPro-Semibold.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/ExternalPackage_sourceserif.mk b/external/more_fonts/ExternalPackage_sourceserif.mk
new file mode 100644
index 000000000..6a5272bba
--- /dev/null
+++ b/external/more_fonts/ExternalPackage_sourceserif.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fonts_sourceserif,font_sourceserif))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,fonts_sourceserif,$(LIBO_SHARE_FOLDER)/fonts/truetype,\
+ SourceSerifPro-BoldIt.ttf \
+ SourceSerifPro-ExtraLight.ttf \
+ SourceSerifPro-Light.ttf \
+ SourceSerifPro-Semibold.ttf \
+ SourceSerifPro-BlackIt.ttf \
+ SourceSerifPro-Bold.ttf \
+ SourceSerifPro-It.ttf \
+ SourceSerifPro-Regular.ttf \
+ SourceSerifPro-Black.ttf \
+ SourceSerifPro-ExtraLightIt.ttf \
+ SourceSerifPro-LightIt.ttf \
+ SourceSerifPro-SemiboldIt.ttf \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/Makefile b/external/more_fonts/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/more_fonts/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/Module_more_fonts.mk b/external/more_fonts/Module_more_fonts.mk
new file mode 100644
index 000000000..c6e56c5b9
--- /dev/null
+++ b/external/more_fonts/Module_more_fonts.mk
@@ -0,0 +1,53 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,more_fonts))
+
+$(eval $(call gb_Module_add_targets,more_fonts,\
+ ExternalPackage_alef \
+ ExternalPackage_amiri \
+ ExternalPackage_caladea \
+ ExternalPackage_carlito \
+ $(if $(MPL_SUBSET),,ExternalPackage_culmus) \
+ ExternalPackage_dejavu \
+ ExternalPackage_gentium \
+ $(if $(MPL_SUBSET),,ExternalPackage_kacst) \
+ ExternalPackage_liberation \
+ ExternalPackage_liberation_narrow \
+ ExternalPackage_libertineg \
+ ExternalPackage_libre_hebrew \
+ ExternalPackage_sourcecode \
+ ExternalPackage_sourcesans \
+ ExternalPackage_sourceserif \
+ ExternalPackage_noto \
+ ExternalPackage_reem \
+ ExternalPackage_scheherazade \
+ ExternalPackage_EmojiOne_Color \
+ UnpackedTarball_alef \
+ UnpackedTarball_amiri \
+ UnpackedTarball_caladea \
+ UnpackedTarball_carlito \
+ $(if $(MPL_SUBSET),,UnpackedTarball_culmus) \
+ UnpackedTarball_dejavu \
+ UnpackedTarball_gentium \
+ $(if $(MPL_SUBSET),,UnpackedTarball_kacst) \
+ UnpackedTarball_liberation \
+ UnpackedTarball_liberation_narrow \
+ UnpackedTarball_libertineg \
+ UnpackedTarball_libre_hebrew \
+ UnpackedTarball_sourcecode \
+ UnpackedTarball_sourcesans \
+ UnpackedTarball_sourceserif \
+ UnpackedTarball_noto \
+ UnpackedTarball_reem \
+ UnpackedTarball_scheherazade \
+ UnpackedTarball_EmojiOne_Color \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/README b/external/more_fonts/README
new file mode 100644
index 000000000..4a676e9f6
--- /dev/null
+++ b/external/more_fonts/README
@@ -0,0 +1 @@
+This module packages some external fonts. \ No newline at end of file
diff --git a/external/more_fonts/UnpackedTarball_EmojiOne_Color.mk b/external/more_fonts/UnpackedTarball_EmojiOne_Color.mk
new file mode 100644
index 000000000..d931c7705
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_EmojiOne_Color.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_emojione_color))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_emojione_color,$(FONT_EMOJIONE_COLOR_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_alef.mk b/external/more_fonts/UnpackedTarball_alef.mk
new file mode 100644
index 000000000..fbabe9fec
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_alef.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_alef))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_alef,$(FONT_ALEF_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_amiri.mk b/external/more_fonts/UnpackedTarball_amiri.mk
new file mode 100644
index 000000000..75d0246b6
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_amiri.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_amiri))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_amiri,$(FONT_AMIRI_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_caladea.mk b/external/more_fonts/UnpackedTarball_caladea.mk
new file mode 100644
index 000000000..7f5d65c12
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_caladea.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_caladea))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_caladea,$(FONT_CALADEA_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_carlito.mk b/external/more_fonts/UnpackedTarball_carlito.mk
new file mode 100644
index 000000000..d14f29169
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_carlito.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_carlito))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_carlito,$(FONT_CARLITO_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_culmus.mk b/external/more_fonts/UnpackedTarball_culmus.mk
new file mode 100644
index 000000000..3b776ed5c
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_culmus.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_culmus))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_culmus,$(FONT_CULMUS_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_dejavu.mk b/external/more_fonts/UnpackedTarball_dejavu.mk
new file mode 100644
index 000000000..d7742df8c
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_dejavu.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_dejavu))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_dejavu,$(FONT_DEJAVU_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_gentium.mk b/external/more_fonts/UnpackedTarball_gentium.mk
new file mode 100644
index 000000000..0827c0e23
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_gentium.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_gentium))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_gentium,$(FONT_GENTIUM_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_kacst.mk b/external/more_fonts/UnpackedTarball_kacst.mk
new file mode 100644
index 000000000..7972da8d3
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_kacst.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_kacst))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_kacst,$(FONT_KACST_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_liberation.mk b/external/more_fonts/UnpackedTarball_liberation.mk
new file mode 100644
index 000000000..8e428f55b
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_liberation.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_liberation))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_liberation,$(FONT_LIBERATION_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_liberation_narrow.mk b/external/more_fonts/UnpackedTarball_liberation_narrow.mk
new file mode 100644
index 000000000..52e6f860b
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_liberation_narrow.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_liberation_narrow))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_liberation_narrow,$(FONT_LIBERATION_NARROW_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_libertineg.mk b/external/more_fonts/UnpackedTarball_libertineg.mk
new file mode 100644
index 000000000..51610baa5
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_libertineg.mk
@@ -0,0 +1,15 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_libertineg))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_libertineg,$(FONT_LINLIBERTINEG_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
+
diff --git a/external/more_fonts/UnpackedTarball_libre_hebrew.mk b/external/more_fonts/UnpackedTarball_libre_hebrew.mk
new file mode 100644
index 000000000..1d6c56166
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_libre_hebrew.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_libre_hebrew))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_libre_hebrew,$(FONT_LIBRE_HEBREW_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_noto.mk b/external/more_fonts/UnpackedTarball_noto.mk
new file mode 100644
index 000000000..ee6f223f8
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_noto.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_noto))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_noto,$(FONT_NOTO_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_reem.mk b/external/more_fonts/UnpackedTarball_reem.mk
new file mode 100644
index 000000000..77e336539
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_reem.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_reem))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_reem,$(FONT_REEM_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_scheherazade.mk b/external/more_fonts/UnpackedTarball_scheherazade.mk
new file mode 100644
index 000000000..b5b6f368f
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_scheherazade.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_scheherazade))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_scheherazade,$(FONT_SCHEHERAZADE_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_sourcecode.mk b/external/more_fonts/UnpackedTarball_sourcecode.mk
new file mode 100644
index 000000000..7040e9b18
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_sourcecode.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_sourcecode))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_sourcecode,$(FONT_SOURCECODE_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_sourcesans.mk b/external/more_fonts/UnpackedTarball_sourcesans.mk
new file mode 100644
index 000000000..65ff32553
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_sourcesans.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_sourcesans))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_sourcesans,$(FONT_SOURCESANS_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/UnpackedTarball_sourceserif.mk b/external/more_fonts/UnpackedTarball_sourceserif.mk
new file mode 100644
index 000000000..0e8407320
--- /dev/null
+++ b/external/more_fonts/UnpackedTarball_sourceserif.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,font_sourceserif))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,font_sourceserif,$(FONT_SOURCESERIF_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/more_fonts/fc_local.snippet b/external/more_fonts/fc_local.snippet
new file mode 100644
index 000000000..cb49929b0
--- /dev/null
+++ b/external/more_fonts/fc_local.snippet
@@ -0,0 +1,29 @@
+ <!-- Alias similar/metric-compatible families from various sources: -->
+
+ <alias binding="same">
+ <family>Liberation Sans Narrow</family>
+ <default>
+ <family>Arial Narrow</family>
+ </default>
+ </alias>
+
+ <alias binding="same">
+ <family>Arial Narrow</family>
+ <accept>
+ <family>Liberation Sans Narrow</family>
+ </accept>
+ </alias>
+
+ <alias binding="same">
+ <family>Calibri</family>
+ <accept>
+ <family>Carlito</family>
+ </accept>
+ </alias>
+
+ <alias binding="same">
+ <family>Cambria</family>
+ <accept>
+ <family>Caladea</family>
+ </accept>
+ </alias>
diff --git a/external/msc-externals/Makefile b/external/msc-externals/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/msc-externals/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/msc-externals/Module_msc-externals.mk b/external/msc-externals/Module_msc-externals.mk
new file mode 100644
index 000000000..07ea3878a
--- /dev/null
+++ b/external/msc-externals/Module_msc-externals.mk
@@ -0,0 +1,29 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,msc-externals))
+
+ifneq ($(BUILD_X64),)
+
+$(eval $(call gb_Module_add_targets,msc-externals,\
+ Package_msvc_dlls \
+))
+
+endif
+
+# Install the universal crts (tdf#108580)
+ifneq ($(UCRT_REDISTDIR),)
+
+$(eval $(call gb_Module_add_targets,msc-externals,\
+ Package_ucrt \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/msc-externals/Package_msvc_dlls.mk b/external/msc-externals/Package_msvc_dlls.mk
new file mode 100644
index 000000000..d82dd06c3
--- /dev/null
+++ b/external/msc-externals/Package_msvc_dlls.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Package_Package,msvc_dlls,$(MSVC_DLL_PATH)))
+
+$(eval $(call gb_Package_add_files,msvc_dlls,program/shlxthdl,\
+ $(MSVC_DLLS) \
+))
+
+# vim:set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/external/msc-externals/Package_ucrt.mk b/external/msc-externals/Package_ucrt.mk
new file mode 100644
index 000000000..52e6f0cba
--- /dev/null
+++ b/external/msc-externals/Package_ucrt.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Package_Package,ucrt,$(UCRT_REDISTDIR)))
+
+$(eval $(call gb_Package_add_files,ucrt,$(LIBO_ETC_FOLDER),\
+ Windows6.1-KB2999226-x64.msu \
+ Windows6.1-KB2999226-x86.msu \
+ Windows8.1-KB2999226-x64.msu \
+ Windows8.1-KB2999226-x86.msu \
+ Windows8-RT-KB2999226-x64.msu \
+ Windows8-RT-KB2999226-x86.msu \
+))
+
+# vim:set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/external/msc-externals/README b/external/msc-externals/README
new file mode 100644
index 000000000..9ffb415c3
--- /dev/null
+++ b/external/msc-externals/README
@@ -0,0 +1 @@
+module msc-externals copies the bundled MSVC runtime DLLs into instdir
diff --git a/external/mythes/ExternalProject_mythes.mk b/external/mythes/ExternalProject_mythes.mk
new file mode 100644
index 000000000..b0e0a6bbd
--- /dev/null
+++ b/external/mythes/ExternalProject_mythes.mk
@@ -0,0 +1,32 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,mythes))
+
+ifneq ($(ENABLE_WASM_STRIP_HUNSPELL),TRUE)
+$(eval $(call gb_ExternalProject_use_external,mythes,hunspell))
+endif
+
+$(eval $(call gb_ExternalProject_register_targets,mythes,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,mythes,build):
+ $(call gb_Trace_StartRange,mythes,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ CXXFLAGS=" $(CXXFLAGS) $(call gb_ExternalProject_get_build_flags,mythes)" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,mythes)" \
+ LIBS="$(gb_STDLIBS) $(LIBS)" $(gb_RUN_CONFIGURE) ./configure --disable-shared --with-pic \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),gio_can_sniff=no) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,mythes,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mythes/Makefile b/external/mythes/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/mythes/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mythes/Module_mythes.mk b/external/mythes/Module_mythes.mk
new file mode 100644
index 000000000..56d95fc91
--- /dev/null
+++ b/external/mythes/Module_mythes.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,mythes))
+
+$(eval $(call gb_Module_add_targets,mythes,\
+ UnpackedTarball_mythes \
+))
+ifeq ($(COM),MSC)
+$(eval $(call gb_Module_add_targets,mythes,\
+ StaticLibrary_mythes \
+))
+else
+$(eval $(call gb_Module_add_targets,mythes,\
+ ExternalProject_mythes \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mythes/README b/external/mythes/README
new file mode 100644
index 000000000..8a1792ee0
--- /dev/null
+++ b/external/mythes/README
@@ -0,0 +1 @@
+Library for handling thesaurus files from [http://hunspell.sourceforge.net].
diff --git a/external/mythes/StaticLibrary_mythes.mk b/external/mythes/StaticLibrary_mythes.mk
new file mode 100644
index 000000000..74a9e07c4
--- /dev/null
+++ b/external/mythes/StaticLibrary_mythes.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,mythes))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,mythes,mythes))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,mythes))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,mythes,\
+ UnpackedTarball/mythes/mythes \
+))
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mythes/UnpackedTarball_mythes.mk b/external/mythes/UnpackedTarball_mythes.mk
new file mode 100644
index 000000000..cba16fd56
--- /dev/null
+++ b/external/mythes/UnpackedTarball_mythes.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,mythes))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,mythes,$(MYTHES_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,mythes))
+
+$(eval $(call gb_UnpackedTarball_add_patches,mythes,\
+ external/mythes/mythes-1.2.0-vanilla-th-gen-idx.patch \
+ external/mythes/mythes-fdo48017-wfopen.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mythes/mythes-1.2.0-vanilla-th-gen-idx.patch b/external/mythes/mythes-1.2.0-vanilla-th-gen-idx.patch
new file mode 100644
index 000000000..3752e2912
--- /dev/null
+++ b/external/mythes/mythes-1.2.0-vanilla-th-gen-idx.patch
@@ -0,0 +1,90 @@
+--- misc/mythes-1.2.3.orig/th_gen_idx.pl
++++ misc/build/mythes-1.2.3/th_gen_idx.pl
+@@ -1,11 +1,25 @@
+-#!/usr/bin/perl
+-
+-# perl program to take a thesaurus structured text data file
+-# and create the proper sorted index file (.idx)
++:
++eval 'exec perl -wS $0 ${1+"$@"}'
++ if 0;
++#
++# This file is part of the LibreOffice project.
++#
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++#
++# This file incorporates work covered by the following license notice:
++#
++# Licensed to the Apache Software Foundation (ASF) under one or more
++# contributor license agreements. See the NOTICE file distributed
++# with this work for additional information regarding copyright
++# ownership. The ASF licenses this file to you under the Apache
++# License, Version 2.0 (the "License"); you may not use this file
++# except in compliance with the License. You may obtain a copy of
++# the License at http://www.apache.org/licenses/LICENSE-2.0 .
++#
+ #
+-# typically invoked as follows:
+-# cat th_en_US_new.dat | ./th_gen_idx.pl > th_en_US_new.idx
+ #
+
+ sub by_entry {
+ my ($aent, $aoff) = split('\|',$a);
+@@ -13,6 +34,27 @@ sub by_entry {
+ $aent cmp $bent;
+ }
+
++#FIXME: someone may want "infile" or even parameter parsing
++sub get_outfile {
++ my $next_is_file = 0;
++ foreach ( @ARGV ) {
++ if ( $next_is_file ) {
++ return $_
++ }
++ if ( $_ eq "-o" ) {
++ $next_is_file = 1;
++ }
++ }
++ return "";
++}
++
++sub usage {
++ print "usage:\n";
++ print "$0 -o outfile < input\n";
++
++ exit 99;
++}
++
+ # main routine
+ my $ne = 0; # number of entries in index
+ my @tindex=(); # the index itself
+@@ -24,6 +66,10 @@ my $nm=0; # number of meaning fo
+ my $meaning=""; # current meaning and synonyms
+ my $p; # misc uses
+ my $encoding; # encoding used by text file
++my $outfile = "";
++
++$outfile = get_outfile();
++usage() if ( $outfile eq "" );
+
+ # top line of thesaurus provides encoding
+ $encoding=<STDIN>;
+@@ -51,9 +97,13 @@ while ($rec=<STDIN>){
+ # now we have all of the information
+ # so sort it and then output the encoding, count and index data
+ @tindex = sort by_entry @tindex;
+-print STDOUT "$encoding\n";
+-print STDOUT "$ne\n";
++
++print "$outfile\n";
++open OUTFILE, ">$outfile" or die "ERROR: Can't open $outfile for writing!";
++print OUTFILE "$encoding\n";
++print OUTFILE "$ne\n";
+ foreach $one (@tindex) {
+- print STDOUT "$one\n";
++ print OUTFILE "$one\n";
+ }
++close OUTFILE;
+
diff --git a/external/mythes/mythes-fdo48017-wfopen.patch b/external/mythes/mythes-fdo48017-wfopen.patch
new file mode 100644
index 000000000..82d69ad66
--- /dev/null
+++ b/external/mythes/mythes-fdo48017-wfopen.patch
@@ -0,0 +1,77 @@
+diff -u mythes/mythes.cxx build/mythes/mythes.cxx
+--- mythes/mythes.cxx 2014-05-22 00:27:38.508588487 +0200
++++ build/mythes/mythes.cxx 2014-05-22 10:07:06.107547417 +0200
+@@ -8,6 +8,11 @@
+
+ #include "mythes.hxx"
+
++#ifdef _WIN32
++#include <windows.h>
++#include <wchar.h>
++#endif
++
+ MyThes::MyThes(const char* idxpath, const char * datpath)
+ {
+ nw = 0;
+@@ -35,7 +40,7 @@
+ {
+
+ // open the index file
+- FILE * pifile = fopen(idxpath,"r");
++ FILE * pifile = myfopen(idxpath,"r");
+ if (!pifile) {
+ return 0;
+ }
+@@ -90,7 +95,7 @@
+ fclose(pifile);
+
+ /* next open the data file */
+- pdfile = fopen(datpath,"r");
++ pdfile = myfopen(datpath,"r");
+ if (!pdfile) {
+ return 0;
+ }
+@@ -373,3 +378,22 @@
+ return -1;
+ }
+
++FILE * MyThes::myfopen(const char * path, const char * mode) {
++#ifdef _WIN32
++#define WIN32_LONG_PATH_PREFIX "\\\\?\\"
++ if (strncmp(path, WIN32_LONG_PATH_PREFIX, 4) == 0) {
++ int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
++ wchar_t *buff = (wchar_t *) malloc(len * sizeof(wchar_t));
++ wchar_t *buff2 = (wchar_t *) malloc(len * sizeof(wchar_t));
++ FILE * f = NULL;
++ MultiByteToWideChar(CP_UTF8, 0, path, -1, buff, len);
++ if (_wfullpath( buff2, buff, len ) != NULL) {
++ f = _wfopen(buff2, (strcmp(mode, "r") == 0) ? L"r" : L"rb");
++ }
++ free(buff);
++ free(buff2);
++ return f;
++ }
++#endif
++ return fopen(path, mode);
++}
+diff -u mythes/mythes.hxx build/mythes/mythes.hxx
+--- mythes/mythes.hxx 2010-03-04 12:56:23.000000000 +0100
++++ build/mythes/mythes.hxx 2014-05-22 10:11:14.363543731 +0200
+@@ -30,6 +30,7 @@
+ MyThes & operator = (const MyThes &);
+
+ public:
++ // use UTF-8 encoded paths in WIN32 environment
+ MyThes(const char* idxpath, const char* datpath);
+ ~MyThes();
+
+@@ -66,6 +67,9 @@
+ // return index of char in string
+ int mystr_indexOfChar(const char * d, int c);
+
++ // fopen or _wfopen
++ FILE * myfopen(const char * path, const char * mode);
++
+ };
+
+ #endif
diff --git a/external/nss/ExternalPackage_nss.mk b/external/nss/ExternalPackage_nss.mk
new file mode 100644
index 000000000..2b15fc3eb
--- /dev/null
+++ b/external/nss/ExternalPackage_nss.mk
@@ -0,0 +1,67 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,nss,nss))
+
+$(eval $(call gb_ExternalPackage_use_external_project,nss,nss))
+
+ifeq ($(OS),iOS)
+# nothing...
+else ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_files,nss,$(LIBO_LIB_FOLDER),\
+ dist/out/lib/libfreebl3.dylib \
+ dist/out/lib/libnspr4.dylib \
+ dist/out/lib/libnss3.dylib \
+ dist/out/lib/libnssckbi.dylib \
+ dist/out/lib/libnssdbm3.dylib \
+ dist/out/lib/libnssutil3.dylib \
+ dist/out/lib/libplc4.dylib \
+ dist/out/lib/libplds4.dylib \
+ dist/out/lib/libsmime3.dylib \
+ dist/out/lib/libsoftokn3.dylib \
+ dist/out/lib/libssl3.dylib \
+))
+else ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_files,nss,$(LIBO_LIB_FOLDER),\
+ dist/out/lib/freebl3.dll \
+ dist/out/lib/nspr4.dll \
+ dist/out/lib/nss3.dll \
+ dist/out/lib/nssckbi.dll \
+ dist/out/lib/nssdbm3.dll \
+ dist/out/lib/nssutil3.dll \
+ dist/out/lib/plc4.dll \
+ dist/out/lib/plds4.dll \
+ dist/out/lib/smime3.dll \
+ dist/out/lib/softokn3.dll \
+ dist/out/lib/sqlite3.dll \
+ dist/out/lib/ssl3.dll \
+))
+else # OS!=WNT/MACOSX
+$(eval $(call gb_ExternalPackage_add_files,nss,$(LIBO_LIB_FOLDER),\
+ dist/out/lib/libfreebl3.so \
+ dist/out/lib/libnspr4.so \
+ dist/out/lib/libnss3.so \
+ dist/out/lib/libnssckbi.so \
+ dist/out/lib/libnssdbm3.so \
+ dist/out/lib/libnssutil3.so \
+ dist/out/lib/libplc4.so \
+ dist/out/lib/libplds4.so \
+ dist/out/lib/libsmime3.so \
+ dist/out/lib/libsoftokn3.so \
+ dist/out/lib/libssl3.so \
+ dist/out/lib/libsqlite3.so \
+))
+endif
+ifeq ($(OS),LINUX)
+$(eval $(call gb_ExternalPackage_add_files,nss,$(LIBO_LIB_FOLDER),\
+ dist/out/lib/libfreeblpriv3.so \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/nss/ExternalProject_nss.mk b/external/nss/ExternalProject_nss.mk
new file mode 100644
index 000000000..ee3c7839f
--- /dev/null
+++ b/external/nss/ExternalProject_nss.mk
@@ -0,0 +1,103 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,nss))
+
+# nss build calls configure for nspr itself - if for some reason the configure step should be split out,
+# make sure to create config.status (aka run configure) in dir specified with OBJDIR_NAME (nspr/out)
+$(eval $(call gb_ExternalProject_register_targets,nss,\
+ build \
+))
+
+$(eval $(call gb_ExternalProject_use_externals,nss,\
+ zlib \
+))
+
+ifeq ($(OS),WNT)
+$(call gb_ExternalProject_get_state_target,nss,build): \
+ $(call gb_ExternalExecutable_get_dependencies,python) \
+ $(SRCDIR)/external/nss/nsinstall.py
+ $(call gb_Trace_StartRange,nss,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(if $(MSVC_USE_DEBUG_RUNTIME),USE_DEBUG_RTL=1,BUILD_OPT=1) \
+ $(if $(gb_Module_CURRENTMODULE_SYMBOLS_ENABLED), \
+ MOZ_DEBUG_SYMBOLS=1 \
+ MOZ_DEBUG_FLAGS=" " \
+ OPT_CODE_SIZE=0) \
+ OS_TARGET=WIN95 \
+ USE_SYSTEM_ZLIB=1 \
+ $(if $(filter X86_64,$(CPUNAME)),USE_64=1) \
+ $(if $(filter AARCH64,$(CPUNAME)),USE_64=1 CPU_ARCH=aarch64) \
+ LIB="$(ILIB)" \
+ XCFLAGS="$(SOLARINC) $(ZLIB_CFLAGS)" \
+ NSPR_CONFIGURE_OPTS="$(gb_CONFIGURE_PLATFORMS)" \
+ $(if $(CROSS_COMPILING),\
+ CROSS_COMPILE=1 \
+ $(if $(filter AARCH64,$(CPUNAME)),CPU_ARCH=aarch64)) \
+ $(MAKE) nss_build_all RC="rc.exe $(SOLARINC)" \
+ NSINSTALL='$(call gb_ExternalExecutable_get_command,python) $(SRCDIR)/external/nss/nsinstall.py' \
+ NSS_DISABLE_GTESTS=1 \
+ CCC="$(CXX)" \
+ ,nss)
+ $(call gb_Trace_EndRange,nss,EXTERNAL)
+
+else # OS!=WNT
+# make sure to specify NSPR_CONFIGURE_OPTS as env (before make command), so nss can append it's own defaults
+# OTOH specify e.g. CC and NSINSTALL as arguments (after make command), so they will overrule nss makefile values
+$(call gb_ExternalProject_get_state_target,nss,build): \
+ $(call gb_ExternalExecutable_get_dependencies,python) \
+ $(SRCDIR)/external/nss/nsinstall.py
+ $(call gb_Trace_StartRange,nss,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(if $(filter ANDROID FREEBSD LINUX MACOSX,$(OS)),$(if $(filter X86_64,$(CPUNAME)),USE_64=1)) \
+ $(if $(filter AARCH64,$(CPUNAME)),USE_64=1 CPU_ARCH=aarch64) \
+ $(if $(filter POWERPC64,$(CPUNAME)),USE_64=1 CPU_ARCH=ppc64le) \
+ $(if $(filter MACOSX,$(OS)),\
+ MACOS_SDK_DIR=$(MACOSX_SDK_PATH) \
+ NSS_USE_SYSTEM_SQLITE=1) \
+ $(if $(filter LINUX,$(OS)),$(if $(ENABLE_DBGUTIL),,BUILD_OPT=1)) \
+ $(if $(filter SOLARIS,$(OS)),NS_USE_GCC=1) \
+ $(if $(filter ARM,$(CPUNAME)),NSS_DISABLE_ARM32_NEON=1) \
+ NSPR_CONFIGURE_OPTS="$(gb_CONFIGURE_PLATFORMS)" \
+ $(if $(CROSS_COMPILING),CROSS_COMPILE=1) \
+ $(if $(filter MACOSX-X86_64-arm64,$(OS)-$(CPUNAME)-$(shell uname -m)), \
+ CPU_ARCH=x86_64) \
+ NSDISTMODE=copy \
+ $(MAKE) \
+ AR="$(AR)" \
+ RANLIB="$(RANLIB)" \
+ NMEDIT="$(NM)edit" \
+ COMMA=$(COMMA) \
+ CC="$(CC)$(if $(filter iOS,$(OS)), -DNSS_STATIC_SOFTOKEN=1 -DNSS_STATIC_FREEBL=1 -DNSS_STATIC_PKCS11=1)$(if $(filter ANDROID,$(OS)), -D_PR_NO_LARGE_FILES=1 -DSQLITE_DISABLE_LFS=1)" CCC="$(CXX)" \
+ $(if $(CROSS_COMPILING),NSINSTALL="$(if $(filter MACOSX,$(OS_FOR_BUILD)),xcrun python3,$(call gb_ExternalExecutable_get_command,python)) $(SRCDIR)/external/nss/nsinstall.py") \
+ $(if $(filter ANDROID,$(OS)),OS_TARGET=Android OS_TARGET_RELEASE=16 ARCHFLAG="" DEFAULT_COMPILER=clang ANDROID_NDK=$(ANDROID_NDK_DIR) ANDROID_TOOLCHAIN_VERSION=$(ANDROID_GCC_TOOLCHAIN_VERSION) ANDROID_PREFIX=$(HOST_PLATFORM) ANDROID_SYSROOT=$(ANDROID_NDK_DIR)/sysroot ANDROID_TOOLCHAIN=$(ANDROID_BINUTILS_PREBUILT_ROOT)) \
+ NSS_DISABLE_GTESTS=1 \
+ nss_build_all \
+ && rm -f $(call gb_UnpackedTarball_get_dir,nss)/dist/out/lib/*.a \
+ $(if $(filter MACOSX,$(OS)),\
+ && chmod u+w $(call gb_UnpackedTarball_get_dir,nss)/dist/out/lib/*.dylib \
+ && $(PERL) \
+ $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libfreebl3.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libnspr4.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libnss3.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libnssckbi.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libnssdbm3.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libnssutil3.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libplc4.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libplds4.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libsmime3.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libsoftokn3.dylib \
+ $(EXTERNAL_WORKDIR)/dist/out/lib/libssl3.dylib) \
+ ,nss)
+ $(call gb_Trace_EndRange,nss,EXTERNAL)
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/nss/Makefile b/external/nss/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/nss/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/nss/Module_nss.mk b/external/nss/Module_nss.mk
new file mode 100644
index 000000000..eae9e9524
--- /dev/null
+++ b/external/nss/Module_nss.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,nss))
+
+$(eval $(call gb_Module_add_targets,nss,\
+ UnpackedTarball_nss \
+ ExternalPackage_nss \
+ ExternalProject_nss \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/nss/README b/external/nss/README
new file mode 100644
index 000000000..6997cea6c
--- /dev/null
+++ b/external/nss/README
@@ -0,0 +1,37 @@
+Contains the Network Security Services (NSS) libraries from Mozilla
+
+== Fips 140 and signed libraries ==
+
+Fips 140 mode is not supported. That is, the *.chk files containing the
+checksums for the cryptographic module are not delivered into instdir and will
+not be part of the OOo installation sets.
+
+Signing has been turned off because
+- we change the rpath (install names) after signing which breaks the signatures
+(Mac)
+- sqlite conflicts with the system sqlite when signing which breaks the build
+
+See also
+[https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_Tech_Notes/nss_tech_note6]
+
+== libsqlite3 ==
+
+With all supported macOS SDK we use
+NSS_USE_SYSTEM_SQLITE=1
+to build using the system sqlite.
+
+== system NSS on Linux ==
+
+Note that different Linux distributions use different SONAMEs for the
+NSS libraries, so it is not possible to use --with-system-nss and build
+a portable generic LO installation set, despite NSS upstream apparently
+maintaining ABI compatibility.
+
+Debian Squeeze:
+0x000000000000000e (SONAME) Library soname: [libnss3.so.1d]
+Fedora 20:
+0x000000000000000e (SONAME) Library soname: [libnss3.so]
+
+For the record, the LSB specified SONAME is libnss3.so
+http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/libnss3.html
+
diff --git a/external/nss/UnpackedTarball_nss.mk b/external/nss/UnpackedTarball_nss.mk
new file mode 100644
index 000000000..ab64f95de
--- /dev/null
+++ b/external/nss/UnpackedTarball_nss.mk
@@ -0,0 +1,49 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,nss))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,nss,$(NSS_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,nss,nspr/build/autoconf))
+
+$(eval $(call gb_UnpackedTarball_add_patches,nss,\
+ external/nss/nss.patch \
+ external/nss/nss.aix.patch \
+ external/nss/nss_macosx.patch \
+ external/nss/nss-win32-make.patch.1 \
+ external/nss/ubsan.patch.0 \
+ external/nss/clang-cl.patch.0 \
+ external/nss/nss.vs2015.patch \
+ external/nss/nss.vs2015.pdb.patch \
+ external/nss/nss.bzmozilla1238154.patch \
+ external/nss/nss-bz1646594.patch.1 \
+ external/nss/macos-dlopen.patch.0 \
+ external/nss/nss-restore-manual-pre-dependencies.patch.1 \
+ $(if $(filter iOS,$(OS)), \
+ external/nss/nss-ios.patch) \
+ $(if $(filter ANDROID,$(OS)), \
+ external/nss/nss-android.patch.1) \
+ $(if $(filter MSC-INTEL,$(COM)-$(CPUNAME)), \
+ external/nss/nss.cygwin64.in32bit.patch) \
+ $(if $(filter WNT,$(OS)), \
+ external/nss/nss.windows.patch \
+ external/nss/nss.nowerror.patch \
+ external/nss/nss.utf8bom.patch.1) \
+))
+
+ifeq ($(COM_IS_CLANG),TRUE)
+ifneq ($(filter -fsanitize=%,$(CC)),)
+$(eval $(call gb_UnpackedTarball_add_patches,nss,\
+ external/nss/asan.patch.1 \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/nss/asan.patch.1 b/external/nss/asan.patch.1
new file mode 100644
index 000000000..ccabd446e
--- /dev/null
+++ b/external/nss/asan.patch.1
@@ -0,0 +1,12 @@
+diff -ur nss.org/nss/coreconf/Linux.mk nss/nss/coreconf/Linux.mk
+--- nss.org/nss/coreconf/Linux.mk 2014-05-06 04:36:01.817838877 +0200
++++ nss/nss/coreconf/Linux.mk 2014-05-06 04:37:25.387835456 +0200
+@@ -157,7 +157,7 @@
+ # we don't use -z defs there.
+ # Also, -z defs conflicts with Address Sanitizer, which emits relocations
+ # against the libsanitizer runtime built into the main executable.
+-ZDEFS_FLAG = -Wl,-z,defs
++ZDEFS_FLAG =
+ DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell $(LD) -v)),,$(ZDEFS_FLAG)) $(if $(filter-out $(OS),ANDROID),-Wl$(COMMA)-z$(COMMA)origin '-Wl$(COMMA)-rpath$(COMMA)$$ORIGIN')
+ LDFLAGS += $(ARCHFLAG) -z noexecstack
+
diff --git a/external/nss/clang-cl.patch.0 b/external/nss/clang-cl.patch.0
new file mode 100644
index 000000000..e20aab3b9
--- /dev/null
+++ b/external/nss/clang-cl.patch.0
@@ -0,0 +1,122 @@
+# "#pragma deprecated" and "#pragma intrinsic" not (yet?) handled in the "if
+# (LangOpts.MicrosoftExt)" block in Preprocessor::RegisterBuiltinPragmas in
+# Clang's lib/Lex/Pragma.cpp:
+--- nspr/pr/include/pratom.h
++++ nspr/pr/include/pratom.h
+@@ -83,7 +83,7 @@
+
+ #include <intrin.h>
+
+-#ifdef _MSC_VER
++#if defined _WIN32 && !defined __clang__
+ #pragma intrinsic(_InterlockedIncrement)
+ #pragma intrinsic(_InterlockedDecrement)
+ #pragma intrinsic(_InterlockedExchange)
+--- nspr/pr/include/prbit.h
++++ nspr/pr/include/prbit.h
+@@ -15,7 +15,7 @@
+ */
+ #if defined(_WIN32) && (_MSC_VER >= 1300) && \
+ (defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM) || \
+- defined(_M_ARM64))
++ defined(_M_ARM64)) && !defined __clang__
+ # include <intrin.h>
+ # pragma intrinsic(_BitScanForward,_BitScanReverse)
+ __forceinline static int __prBitScanForward32(unsigned int val)
+@@ -33,7 +33,7 @@
+ # define pr_bitscan_ctz32(val) __prBitScanForward32(val)
+ # define pr_bitscan_clz32(val) __prBitScanReverse32(val)
+ # define PR_HAVE_BUILTIN_BITSCAN32
+-#elif ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && \
++#elif defined __GNUC__ && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && \
+ (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
+ defined(__aarch64__))
+ # define pr_bitscan_ctz32(val) __builtin_ctz(val)
+@@ -138,7 +138,7 @@
+ */
+
+ #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \
+- defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64))
++ defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64)) && !defined __clang__
+ #include <stdlib.h>
+ #pragma intrinsic(_rotl, _rotr)
+ #define PR_ROTATE_LEFT32(a, bits) _rotl(a, bits)
+--- nss/lib/certdb/certdb.h
++++ nss/lib/certdb/certdb.h
+@@ -21,7 +21,7 @@
+ /* On Windows, Mac, and Linux (and other gcc platforms), we can give compile
+ * time deprecation warnings when applications use the old CERTDB_VALID_PEER
+ * define */
+-#if __GNUC__ > 3
++#if defined __GNUC__ && __GNUC__ > 3
+ #if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
+ typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated));
+ #else
+@@ -30,7 +30,7 @@
+ #endif
+ #define CERTDB_VALID_PEER ((__CERTDB_VALID_PEER)CERTDB_TERMINAL_RECORD)
+ #else
+-#ifdef _WIN32
++#if defined _WIN32 && !defined __clang__
+ #pragma deprecated(CERTDB_VALID_PEER)
+ #endif
+ #define CERTDB_VALID_PEER CERTDB_TERMINAL_RECORD
+--- nss/lib/freebl/blapit.h
++++ nss/lib/freebl/blapit.h
+@@ -53,7 +53,7 @@
+ * Mark the old defines as deprecated. This will warn code that expected
+ * DSA1 only that they need to change if the are to support DSA2.
+ */
+-#if defined(__GNUC__) && (__GNUC__ > 3)
++#if defined(__GNUC__) && (__GNUC__ > 3) || defined __clang__
+ /* make GCC warn when we use these #defines */
+ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
+ #define DSA_SUBPRIME_LEN ((__BLAPI_DEPRECATED)DSA1_SUBPRIME_LEN)
+--- nss/lib/util/pkcs11n.h
++++ nss/lib/util/pkcs11n.h
+@@ -563,7 +563,7 @@
+ /* keep the old value for compatibility reasons*/
+ #define CKT_NSS_MUST_VERIFY ((__CKT_NSS_MUST_VERIFY)(CKT_NSS + 4))
+ #else
+-#ifdef _WIN32
++#if defined _WIN32 && !defined __clang__
+ /* This magic gets the windows compiler to give us a deprecation
+ * warning */
+ #pragma deprecated(CKT_NSS_UNTRUSTED, CKT_NSS_MUST_VERIFY, CKT_NSS_VALID)
+
+# While MSVC uses
+# #pragma warning(disable : 4103)
+# in the inner pkcs11p.h, clang-cl wants
+# #pragma clang diagnostic ignored "-Wpragma-pack"
+# in the outer pkcs11t.h:
+--- nss/lib/util/pkcs11t.h
++++ nss/lib/util/pkcs11t.h
+@@ -78,7 +78,14 @@
+ #define CK_INVALID_HANDLE 0
+
+ /* pack */
++#if defined __clang__ && defined _MSC_VER
++#pragma clang diagnostic push
++#pragma clang diagnostic ignored "-Wpragma-pack"
++#endif
+ #include "pkcs11p.h"
++#if defined __clang__ && defined _MSC_VER
++#pragma clang diagnostic pop
++#endif
+
+ typedef struct CK_VERSION {
+ CK_BYTE major; /* integer portion of version number */
+@@ -2586,6 +2593,13 @@
+ #include "pkcs11n.h"
+
+ /* undo packing */
++#if defined __clang__ && defined _MSC_VER
++#pragma clang diagnostic push
++#pragma clang diagnostic ignored "-Wpragma-pack"
++#endif
+ #include "pkcs11u.h"
++#if defined __clang__ && defined _MSC_VER
++#pragma clang diagnostic pop
++#endif
+
+ #endif
diff --git a/external/nss/macos-dlopen.patch.0 b/external/nss/macos-dlopen.patch.0
new file mode 100644
index 000000000..e8abc8f59
--- /dev/null
+++ b/external/nss/macos-dlopen.patch.0
@@ -0,0 +1,25 @@
+--- nspr/pr/src/linking/prlink.c
++++ nspr/pr/src/linking/prlink.c
+@@ -555,7 +555,7 @@
+ * The reason is that DARWIN's dlopen ignores the provided path
+ * and checks for the plain filename in DYLD_LIBRARY_PATH,
+ * which could load an unexpected version of a library. */
+- if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) {
++ if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL || strncmp(name, "@loader_path/", 13) == 0) {
+ /* no slash, allow to load from any location */
+ okToLoad = PR_TRUE;
+ } else {
+--- nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
++++ nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
+@@ -224,7 +224,11 @@
+ static PRStatus PR_CALLBACK pkix_getDecodeFunction(void)
+ {
+ pkix_decodeFunc.smimeLib =
++#if defined DARWIN
++ PR_LoadLibrary("@loader_path/" SHLIB_PREFIX"smime3."SHLIB_SUFFIX);
++#else
+ PR_LoadLibrary(SHLIB_PREFIX"smime3."SHLIB_SUFFIX);
++#endif
+ if (pkix_decodeFunc.smimeLib == NULL) {
+ return PR_FAILURE;
+ }
diff --git a/external/nss/nsinstall.py b/external/nss/nsinstall.py
new file mode 100644
index 000000000..d90a85e6c
--- /dev/null
+++ b/external/nss/nsinstall.py
@@ -0,0 +1,169 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Axel Hecht <axel@pike.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# This is a partial python port of nsinstall.
+# It's intended to be used when there's no natively compile nsinstall
+# available, and doesn't intend to be fully equivalent.
+# Its major use is for l10n repackaging on systems that don't have
+# a full build environment set up.
+# The basic limitation is, it doesn't even try to link and ignores
+# all related options.
+
+from optparse import OptionParser
+import os
+import os.path
+import sys
+import shutil
+
+def nsinstall(argv):
+ usage = "usage: %prog [options] arg1 [arg2 ...] target-directory"
+ p = OptionParser(usage=usage)
+
+ p.add_option('-D', action="store_true",
+ help="Create a single directory only")
+ p.add_option('-t', action="store_true",
+ help="Preserve time stamp")
+ p.add_option('-m', action="store",
+ help="Set mode", metavar="mode")
+ p.add_option('-d', action="store_true",
+ help="Create directories in target")
+ p.add_option('-R', action="store_true",
+ help="Use relative symbolic links (ignored)")
+ p.add_option('-l', action="store_true",
+ help="Create link (ignored)")
+ p.add_option('-L', action="store", metavar="linkprefix",
+ help="Link prefix (ignored)")
+
+ # The remaining arguments are not used in our tree, thus they're not
+ # implented.
+ def BadArg(option, opt, value, parser):
+ parser.error('option not supported: %s' % opt)
+
+ p.add_option('-C', action="callback", metavar="CWD",
+ callback=BadArg,
+ help="NOT SUPPORTED")
+ p.add_option('-o', action="callback", callback=BadArg,
+ help="Set owner (NOT SUPPORTED)", metavar="owner")
+ p.add_option('-g', action="callback", callback=BadArg,
+ help="Set group (NOT SUPPORTED)", metavar="group")
+
+ (options, args) = p.parse_args(argv)
+
+ if options.m:
+ # mode is specified
+ try:
+ options.m = int(options.m, 8)
+ # I have no idea why nss insists on using this mode for installed headers.
+ # It causes problems with updating the files during a rebuild.
+ if options.m == 0o444:
+ options.m = 0o644
+ except:
+ sys.stderr.write('nsinstall: ' + options.m + ' is not a valid mode\n')
+ return 1
+
+ # just create one directory?
+ if options.D:
+ if len(args) != 1:
+ return 1
+ try:
+ if options.m:
+ os.makedirs(args[0], options.m)
+ else:
+ os.makedirs(args[0])
+ except FileExistsError:
+ if not os.path.isdir(args[0]):
+ sys.stderr.write('nsinstall: ' + args[0] + ' is not a directory\n')
+ sys.exit(1)
+ if options.m:
+ os.chmod(args[0], options.m)
+ return 0
+
+ # nsinstall arg1 [...] directory
+ if len(args) < 2:
+ p.error('not enough arguments')
+
+ def copy_all_entries(entries, target):
+ for e in entries:
+ dest = os.path.join(target,
+ os.path.basename(os.path.normpath(e)))
+ handleTarget(e, dest)
+ if options.m:
+ os.chmod(dest, options.m)
+
+ # set up handler
+ if options.d:
+ # we're supposed to create directories
+ def handleTarget(srcpath, targetpath):
+ # target directory was already created, just use mkdir
+ os.mkdir(targetpath)
+ else:
+ # we're supposed to copy files
+ def handleTarget(srcpath, targetpath):
+ if os.path.isdir(srcpath):
+ if not os.path.exists(targetpath):
+ os.mkdir(targetpath)
+ entries = [os.path.join(srcpath, e) for e in os.listdir(srcpath)]
+ copy_all_entries(entries, targetpath)
+ # options.t is not relevant for directories
+ if options.m:
+ os.chmod(targetpath, options.m)
+ elif options.t:
+ if os.path.exists(targetpath):
+ os.remove(targetpath)
+ shutil.copy2(srcpath, targetpath)
+ else:
+ if os.path.exists(targetpath):
+ os.chmod(targetpath, 0o755)
+ os.remove(targetpath)
+ shutil.copy(srcpath, targetpath)
+
+ # the last argument is the target directory
+ target = args.pop()
+ # ensure target directory
+ if not os.path.isdir(target):
+ try:
+ os.makedirs(target)
+ except FileExistsError:
+ if not os.path.isdir(target):
+ sys.stderr.write('nsinstall: ' + target + ' is not a directoy!\n')
+ return 1
+
+ copy_all_entries(args, target)
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(nsinstall(sys.argv[1:]))
diff --git a/external/nss/nss-android.patch.1 b/external/nss/nss-android.patch.1
new file mode 100644
index 000000000..707fcf99a
--- /dev/null
+++ b/external/nss/nss-android.patch.1
@@ -0,0 +1,93 @@
+diff -ur nss.org/nspr/build/autoconf/config.sub nss/nspr/build/autoconf/config.sub
+--- nss.org/nspr/build/autoconf/config.sub 2017-09-07 15:29:45.031246453 +0200
++++ nss/nspr/build/autoconf/config.sub 2017-09-07 15:32:13.087235423 +0200
+@@ -110,6 +110,11 @@
+ exit 1;;
+ esac
+
++if test $1 = "arm-unknown-linux-androideabi"; then echo $1; exit; fi
++if test $1 = "aarch64-unknown-linux-android"; then echo $1; exit; fi
++if test $1 = "i686-pc-linux-android"; then echo $1; exit; fi
++if test $1 = "x86_64-pc-linux-android"; then echo $1; exit; fi
++
+ # Split fields of configuration type
+ # shellcheck disable=SC2162
+ IFS="-" read field1 field2 field3 field4 <<EOF
+diff -ur nss.org/nspr/configure nss/nspr/configure
+--- nss.org/nspr/configure 2017-09-07 15:29:45.018246359 +0200
++++ nss/nspr/configure 2017-09-07 15:31:47.604075663 +0200
+@@ -2728,18 +2728,15 @@
+ esac
+
+ AS="$android_toolchain"/bin/"$android_tool_prefix"-as
+- CC="$android_toolchain"/bin/"$android_tool_prefix"-gcc
+- CXX="$android_toolchain"/bin/"$android_tool_prefix"-g++
+- CPP="$android_toolchain"/bin/"$android_tool_prefix"-cpp
++ CC="$CC"
++ CXX="$CXX"
++ CPP="$CC" -E
+ LD="$android_toolchain"/bin/"$android_tool_prefix"-ld
+ AR="$android_toolchain"/bin/"$android_tool_prefix"-ar
+ RANLIB="$android_toolchain"/bin/"$android_tool_prefix"-ranlib
+ STRIP="$android_toolchain"/bin/"$android_tool_prefix"-strip
+
+ CPPFLAGS="-I$android_platform/usr/include $CPPFLAGS"
+- CFLAGS="-mandroid -I$android_platform/usr/include -fno-short-enums -fno-exceptions $CFLAGS"
+- CXXFLAGS="-mandroid -I$android_platform/usr/include -fpic -fno-short-enums -fno-exceptions $CXXFLAGS"
+- LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform $LDFLAGS"
+
+ $as_echo "#define ANDROID 1" >>confdefs.h
+
+diff -ur nss.org/nss/Makefile nss/nss/Makefile
+--- nss.org/nss/Makefile 2017-09-07 15:29:44.933245745 +0200
++++ nss/nss/Makefile 2017-09-07 15:32:04.347181076 +0200
+@@ -65,7 +65,7 @@
+
+ ifeq ($(OS_TARGET),Android)
+ NSPR_CONFIGURE_OPTS += --with-android-ndk=$(ANDROID_NDK) \
+- --target=$(ANDROID_PREFIX) \
++ --with-arch=toolchain-default \
+ --with-android-version=$(OS_TARGET_RELEASE) \
+ --with-android-toolchain=$(ANDROID_TOOLCHAIN) \
+ --with-android-platform=$(ANDROID_SYSROOT)
+--- nss/nss/Makefile.orig 2019-11-26 14:52:15.934561202 +0100
++++ nss/nss/Makefile 2019-11-26 14:52:20.538559612 +0100
+@@ -140,7 +140,6 @@
+
+ build_nspr: $(NSPR_CONFIG_STATUS)
+ $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
+- $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)/pr/tests
+
+ install_nspr: build_nspr
+ $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) install
+--- nss/nss/lib/ckfw/builtins/manifest.mn.orig 2019-11-26 15:18:22.185985193 +0100
++++ nss/nss/lib/ckfw/builtins/manifest.mn 2019-11-26 15:18:29.281982387 +0100
+@@ -5,7 +5,7 @@
+
+ CORE_DEPTH = ../../..
+
+-DIRS = testlib
++DIRS =
+
+ MODULE = nss
+
+diff -ur nss/nss/coreconf/arch.mk nss/nss/coreconf/arch.mk
+--- nss/nss/coreconf/arch.mk 2019-11-01 10:29:44.933245745 +0100
++++ nss/nss/coreconf/arch.mk 2019-11-01 10:32:04.347181076 +0100
+@@ -213,7 +213,15 @@
+ #
+ # this should be configurable from the user
+ #
+- OS_TEST := arm
++ ifneq (,$(filter x86 x86_64,$(ANDROID_APP_ABI)))
++ OS_TEST := $(ANDROID_APP_ABI)
++ else
++ ifeq ($(USE_64),1)
++ OS_TEST := aarch64
++ else
++ OS_TEST := arm
++ endif
++ endif
+ OS_ARCH = Android
+ ifndef OS_TARGET_RELEASE
+ OS_TARGET_RELEASE := 8
diff --git a/external/nss/nss-bz1646594.patch.1 b/external/nss/nss-bz1646594.patch.1
new file mode 100644
index 000000000..cffb9f5fe
--- /dev/null
+++ b/external/nss/nss-bz1646594.patch.1
@@ -0,0 +1,15 @@
+regression from https://bugzilla.mozilla.org/show_bug.cgi?id=1646594
+
+--- nss/nss/coreconf/arch.mk.orig2 2020-08-18 14:33:21.295252404 +0200
++++ nss/nss/coreconf/arch.mk 2020-08-18 14:33:46.360320806 +0200
+@@ -94,8 +94,10 @@
+ OS_RELEASE := $(word 1,$(OS_RELEASE)).$(word 2,$(OS_RELEASE))
+ endif
+ KERNEL = Linux
++ifneq ($(OS_TARGET),Android)
+ include $(CORE_DEPTH)/coreconf/Linux.mk
+ endif
++endif
+
+ # Since all uses of OS_ARCH that follow affect only userland, we can
+ # merge other Glibc systems with Linux here.
diff --git a/external/nss/nss-ios.patch b/external/nss/nss-ios.patch
new file mode 100644
index 000000000..58239f718
--- /dev/null
+++ b/external/nss/nss-ios.patch
@@ -0,0 +1,300 @@
+--- a/a/nss/Makefile
++++ a/a/nss/Makefile
+@@ -91,13 +91,11 @@
+ ifdef NS_USE_GCC
+ NSPR_CONFIGURE_ENV = CC=gcc CXX=g++
+ endif
+-# Make sure to remove -arch arguments. NSPR can't handle that.
+-remove_arch = $(filter-out __REMOVEME%,$(subst $(NULL) -arch , __REMOVEME,$(1)))
+ ifdef CC
+-NSPR_CONFIGURE_ENV = CC="$(call remove_arch,$(CC))"
++NSPR_CONFIGURE_ENV = CC="$(CC)"
+ endif
+ ifdef CCC
+-NSPR_CONFIGURE_ENV += CXX="$(call remove_arch,$(CCC))"
++NSPR_CONFIGURE_ENV += CXX="$(CCC)"
+ endif
+
+ #
+@@ -140,7 +138,6 @@
+
+ build_nspr: $(NSPR_CONFIG_STATUS)
+ $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
+- $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)/pr/tests
+
+ install_nspr: build_nspr
+ $(MAKE) -C $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) install
+--- a/a/nss/lib/ckfw/builtins/manifest.mn
++++ a/a/nss/lib/ckfw/builtins/manifest.mn
+@@ -5,7 +5,7 @@
+
+ CORE_DEPTH = ../../..
+
+-DIRS = testlib
++DIRS =
+
+ MODULE = nss
+
+--- a/a/nss/lib/nss/nssinit.c
++++ a/a/nss/lib/nss/nssinit.c
+@@ -275,6 +275,7 @@
+ const char *secmodprefix,
+ char **retoldpath, char **retnewpath)
+ {
++#ifndef NSS_STATIC_PKCS11
+ char *path, *oldpath = NULL, *lastsep;
+ int len, path_len, secmod_len, dll_len;
+
+@@ -309,6 +310,10 @@
+ }
+ *retoldpath = oldpath;
+ *retnewpath = path;
++#else
++ *retoldpath = NULL;
++ *retnewpath = PORT_Strdup("NSSCKBI");
++#endif
+ return;
+ }
+
+--- a/a/nss/lib/pk11wrap/pk11load.c
++++ a/a/nss/lib/pk11wrap/pk11load.c
+@@ -390,6 +390,8 @@
+ /*
+ * load a new module into our address space and initialize it.
+ */
++extern CK_RV NSSCKBI_C_GetFunctionList();
++
+ SECStatus
+ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
+ {
+@@ -468,6 +470,7 @@
+ /* load the library. If this succeeds, then we have to remember to
+ * unload the library if anything goes wrong from here on out...
+ */
++#ifndef NSS_STATIC_PKCS11 // With NSS_STATIC_PKCS11, the only module wodule we load here is nssckbi
+ #if defined(_WIN32)
+ if (nssUTF8_Length(mod->dllName, NULL)) {
+ wchar_t *dllNameWide = _NSSUTIL_UTF8ToWide(mod->dllName);
+@@ -507,6 +510,11 @@
+ mod->moduleDBFunc = (void *)
+ PR_FindSymbol(library, "NSS_ReturnModuleSpecData");
+ }
++#else
++ if (strcmp(mod->dllName, "NSSCKBI") == 0)
++ fentry = NSSCKBI_C_GetFunctionList;
++#endif
++
+ if (mod->moduleDBFunc == NULL)
+ mod->isModuleDB = PR_FALSE;
+ if ((ientry == NULL) && (fentry == NULL)) {
+@@ -643,10 +651,12 @@
+ }
+ fail:
+ mod->functionList = NULL;
++#ifndef NSS_STATIC_PKCS11
+ disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
+ if (library && !disableUnload) {
+ PR_UnloadLibrary(library);
+ }
++#endif
+ return SECFailure;
+ }
+
+--- a/a/nss/lib/ckfw/nssck.api
++++ a/a/nss/lib/ckfw/nssck.api
+@@ -1842,7 +1842,11 @@
+
+ /* This one is always present */
+ CK_RV CK_ENTRY
++#ifndef NSS_STATIC_PKCS11
+ C_GetFunctionList
++#else
++NSSCKBI_C_GetFunctionList
++#endif
+ (
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList
+ )
+--- a/a/nss/lib/freebl/loader.c
++++ a/a/nss/lib/freebl/loader.c
+@@ -35,6 +35,7 @@
+ static PRStatus
+ freebl_LoadDSO(void)
+ {
++#ifndef NSS_STATIC_FREEBL
+ PRLibrary *handle;
+ const char *name = getLibName();
+
+@@ -47,32 +48,42 @@
+ if (handle) {
+ PRFuncPtr address = PR_FindFunctionSymbol(handle, "FREEBL_GetVector");
+ if (address) {
+- FREEBLGetVectorFn *getVector = (FREEBLGetVectorFn *)address;
++#else
++ FREEBLGetVectorFn *getVector = FREEBL_GetVector;
++#endif
+ const FREEBLVector *dsoVector = getVector();
+ if (dsoVector) {
+ unsigned short dsoVersion = dsoVector->version;
+ unsigned short myVersion = FREEBL_VERSION;
+ if (MSB(dsoVersion) == MSB(myVersion) &&
+ LSB(dsoVersion) >= LSB(myVersion) &&
+ dsoVector->length >= sizeof(FREEBLVector)) {
+ vector = dsoVector;
++#ifndef NSS_STATIC_FREEBL
+ libraryName = name;
+ blLib = handle;
++#else
++ libraryName = "self";
++#endif
+ return PR_SUCCESS;
+ }
+ }
++ else
++ return PR_FAILURE;
++#ifndef NSS_STATIC_FREEBL
+ }
+ #ifdef DEBUG
+ if (blLib) {
+ PRStatus status = PR_UnloadLibrary(blLib);
+ PORT_Assert(PR_SUCCESS == status);
+ }
+ #else
+ if (blLib)
+ PR_UnloadLibrary(blLib);
+ #endif
+ }
+ return PR_FAILURE;
++#endif
+ }
+
+ static const PRCallOnceType pristineCallOnce;
+@@ -860,6 +871,7 @@
+ void
+ BL_Unload(void)
+ {
++#ifndef NSS_STATIC_FREEBL
+ /* This function is not thread-safe, but doesn't need to be, because it is
+ * only called from functions that are also defined as not thread-safe,
+ * namely C_Finalize in softoken, and the SSL bypass shutdown callback called
+@@ -872,6 +884,7 @@
+ PR_UnloadLibrary(blLib);
+ #endif
+ }
++#endif
+ blLib = NULL;
+ loadFreeBLOnce = pristineCallOnce;
+ }
+--- a/a/nspr/build/autoconf/config.sub 2017-09-07 15:29:45.031246453 +0200
++++ a/a/nspr/build/autoconf/config.sub 2017-09-07 15:32:13.087235423 +0200
+@@ -110,6 +110,9 @@
+ exit 1;;
+ esac
+
++if test $1 = "arm64-apple-darwin"; then echo $1; exit; fi
++if test $1 = "aarch64-apple-darwin"; then echo $1; exit; fi
++
+ # Split fields of configuration type
+ # shellcheck disable=SC2162
+ IFS="-" read field1 field2 field3 field4 <<EOF
+--- a/a/nspr/config/autoconf.mk.in
++++ a/a/nspr/config/autoconf.mk.in
+@@ -69,7 +69,7 @@
+ MSC_VER = @MSC_VER@
+ AR = @AR@
+ AR_FLAGS = @AR_FLAGS@
+-LD = @LD@
++LD = echo
+ RANLIB = @RANLIB@
+ PERL = @PERL@
+ RC = @RC@
+--- a/a/nspr/configure
++++ a/a/nspr/configure
+@@ -2507,7 +2507,7 @@
+ OBJDIR='$(OBJDIR_NAME)'
+ OBJDIR_NAME=.
+ OBJDIR_SUFFIX=OBJ
+-NSINSTALL='$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall'
++NSINSTALL=${NSINSTALL?'$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall'}
+ NOSUCHFILE=/no-such-file
+ LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)'
+ LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)'
+@@ -5571,7 +5571,7 @@
+ LIB_SUFFIX=a
+ DLL_SUFFIX=so
+ ASM_SUFFIX=s
+-MKSHLIB='$(LD) $(DSO_LDOPTS) -o $@'
++MKSHLIB='touch $@; echo'
+ PR_MD_ASFILES=
+ PR_MD_CSRCS=
+ PR_MD_ARCH_DIR=unix
+@@ -6485,7 +6485,7 @@
+ DSO_CFLAGS=-fPIC
+ DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @__________________________________________________OOO/$@ -headerpad_max_install_names'
+ _OPTIMIZE_FLAGS=-O2
+- MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
++ MKSHLIB=touch $@
+ STRIP="$STRIP -x -S"
+ DLL_SUFFIX=dylib
+ USE_PTHREADS=1
+--- a/a/nss/coreconf/ruleset.mk
++++ a/a/nss/coreconf/ruleset.mk
+@@ -45,7 +45,7 @@
+ endif
+
+ ifeq ($(MKPROG),)
+- MKPROG = $(CC)
++ MKPROG = touch $@; echo
+ endif
+
+ #
+--- a/a/nss/coreconf/Darwin.mk
++++ a/a/nss/coreconf/Darwin.mk
+@@ -116,7 +116,7 @@
+ DSO_LDOPTS += --coverage
+ endif
+
+-MKSHLIB = $(CC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS)
++MKSHLIB = touch $@; echo
+ DLL_SUFFIX = dylib
+ ifdef MAPFILE
+ MKSHLIB += -exported_symbols_list $(MAPFILE)
+--- a/a/nss/coreconf/UNIX.mk
++++ a/a/nss/coreconf/UNIX.mk
+@@ -19,10 +19,14 @@
+
+ ifdef BUILD_TREE
+ NSINSTALL_DIR = $(BUILD_TREE)/nss
++ifndef NSINSTALL
+ NSINSTALL = $(BUILD_TREE)/nss/nsinstall
++endif
+ else
+ NSINSTALL_DIR = $(CORE_DEPTH)/coreconf/nsinstall
++ifndef NSINSTALL
+ NSINSTALL = $(NSINSTALL_DIR)/$(OBJDIR_NAME)/nsinstall
++endif
+ endif
+
+ ####################################################################
+--- a/a/nspr/pr/include/md/_darwin.h
++++ a/a/nspr/pr/include/md/_darwin.h
+@@ -26,6 +26,8 @@
+ #define _PR_SI_ARCHITECTURE "ppc"
+ #elif defined(__arm__)
+ #define _PR_SI_ARCHITECTURE "arm"
++#elif defined(__arm64__)
++#define _PR_SI_ARCHITECTURE "arm64"
+ #elif defined(__aarch64__)
+ #define _PR_SI_ARCHITECTURE "aarch64"
+ #else
+--- a/a/nss/cmd/shlibsign/sign.sh
++++ a/a/nss/cmd/shlibsign/sign.sh
+@@ -2,6 +2,9 @@
+ # This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++# Pointless to sign anything for iOS as we don't build any real shared libraries
++exit 0
+
+ # arguments:
+ # 1: full path to DIST/OBJDIR (parent dir of "lib")
diff --git a/external/nss/nss-restore-manual-pre-dependencies.patch.1 b/external/nss/nss-restore-manual-pre-dependencies.patch.1
new file mode 100644
index 000000000..ea034f0dc
--- /dev/null
+++ b/external/nss/nss-restore-manual-pre-dependencies.patch.1
@@ -0,0 +1,83 @@
+Revert of upstream:
+
+changeset: 15608:744881490c78
+user: Jan-Marek Glogowski <glogow@fbihome.de>
+date: Wed May 13 19:00:40 2020 +0000
+summary: Bug 1637083 Replace pre-dependency with shell hack r=rrelyea
+
+--- b/nss/coreconf/rules.mk Wed May 13 19:00:40 2020 +0000
++++ a/nss/coreconf/rules.mk Tue May 12 21:33:43 2020 +0000
+@@ -31,21 +31,10 @@
+ USE_NT_C_SYNTAX=1
+ endif
+
+-# For whatever reason, "." can't be handled using make conditionals.
+-# Based on automake's SUBDIRS "." handling.
+ ifdef DIRS
+ ifndef IGNORE_DIRS
+-ifneq (,$(filter .,$(DIRS)))
+-TARGETS = $(NULL)
+-ALL_TRASH = $(NULL)
+-endif
+-
+ $(DIRS):
++ $(IGNORE_ERROR)@$(MAKE) -C $@ $(MAKECMDGOALS)
+- $(IGNORE_ERROR)@if [ "$@" != "." ]; then \
+- $(MAKE) -C $@ $(MAKECMDGOALS) ; \
+- else \
+- IGNORE_DIRS=1 $(MAKE) -C $@ $(MAKECMDGOALS) ; \
+- fi
+ @$(CLICK_STOPWATCH)
+ endif
+ endif
+@@ -84,9 +73,7 @@
+ check: $(DIRS)
+
+ clean clobber: $(DIRS)
+-ifneq (,$(ALL_TRASH))
+ rm -rf $(ALL_TRASH)
+-endif
+
+ realclean clobber_all: $(DIRS)
+ rm -rf $(wildcard *.OBJ) dist $(ALL_TRASH)
+--- b/nss/lib/ckfw/builtins/manifest.mn Wed May 13 19:00:40 2020 +0000
++++ a/nss/lib/ckfw/builtins/manifest.mn Tue May 12 21:33:43 2020 +0000
+@@ -5,9 +5,7 @@
+
+ CORE_DEPTH = ../../..
+
++DIRS = testlib
+-DIRS = . testlib
+-
+-testlib: .
+
+ MODULE = nss
+
+--- b/nss/lib/ckfw/manifest.mn Wed May 13 19:00:40 2020 +0000
++++ a/nss/lib/ckfw/manifest.mn Tue May 12 21:33:43 2020 +0000
+@@ -5,9 +5,7 @@
+
+ CORE_DEPTH = ../..
+
++DIRS = builtins
+-DIRS = . builtins
+-
+-builtins: .
+
+ PRIVATE_EXPORTS = \
+ ck.h \
+--- b/nss/manifest.mn Wed May 13 19:00:40 2020 +0000
++++ a/nss/manifest.mn Tue May 12 21:33:43 2020 +0000
+@@ -24,6 +24,12 @@
+ # no real way to encode these in any sensible way
+ $(MAKE) -C coreconf/nsinstall program
+ $(MAKE) export
++ # pre-build child dir -> parent dir dependencies
++ # ckfw/builtins -> ckfw
++ IGNORE_DIRS=1 $(MAKE) -C lib/ckfw libs
++ # ckfw/builtins/testlib -> ckfw/builtins + base
++ $(MAKE) -C lib/base libs
++ IGNORE_DIRS=1 $(MAKE) -C lib/ckfw/builtins libs
+
+ lib: coreconf
+ cmd: lib
diff --git a/external/nss/nss-win32-make.patch.1 b/external/nss/nss-win32-make.patch.1
new file mode 100644
index 000000000..6a3201a08
--- /dev/null
+++ b/external/nss/nss-win32-make.patch.1
@@ -0,0 +1,20 @@
+--- nss/nss/coreconf/rules.mk.orig2 2014-06-03 15:30:01.667200000 +0200
++++ nss/nss/coreconf/rules.mk 2014-06-03 15:30:14.537200000 +0200
+@@ -174,7 +174,7 @@
+ $(LIBRARY): $(OBJS) | $$(@D)/d
+ rm -f $@
+ ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET)))
+- $(AR) $(subst /,\\,$(OBJS))
++ $(AR) $(OBJS)
+ else
+ $(AR) cr $@ $(OBJS)
+ endif
+@@ -214,7 +214,7 @@
+ ifdef NS_USE_GCC
+ $(LINK_DLL) $(OBJS) $(SUB_SHLOBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS) $(RES)
+ else
+- $(LINK_DLL) -MAP $(DLLBASE) $(subst /,\\,$(OBJS) $(SUB_SHLOBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS) $(RES))
++ $(LINK_DLL) -MAP $(DLLBASE) $(OBJS) $(SUB_SHLOBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS) $(RES)
+ ifdef MT
+ if test -f $@.manifest; then \
+ $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;2; \
diff --git a/external/nss/nss.aix.patch b/external/nss/nss.aix.patch
new file mode 100644
index 000000000..10572f947
--- /dev/null
+++ b/external/nss/nss.aix.patch
@@ -0,0 +1,140 @@
+diff -ru a/nspr/configure b/nspr/configure
+--- a/a/nspr/configure 2014-09-29 16:47:42.984012225 +0100
++++ b/b/nspr/configure 2014-09-29 16:50:33.907375937 +0100
+@@ -6325,7 +6325,6 @@
+ AIX_LINK_OPTS='-brtl -bnso -berok'
+ ;;
+ esac
+- CFLAGS="$CFLAGS -qro -qroconst"
+ AIX_WRAP='$(DIST)/lib/aixwrap.o'
+ AIX_TMP='./_aix_tmp.o'
+ if test -n "$USE_64"; then
+diff -ru a/nspr/configure.in b/nspr/configure.in
+--- a/a/nspr/configure.in 2014-09-29 16:46:35.257394860 +0100
++++ b/b/nspr/configure.in 2014-09-29 16:50:33.908375942 +0100
+@@ -1180,7 +1180,8 @@
+ AC_DEFINE(XP_UNIX)
+ AC_DEFINE(AIX)
+ AC_DEFINE(SYSV)
+- DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib'
++ DSO_LDOPTS='-Wl,-brtl -Wl,-bnortllib -Wl,-blibpath:/usr/lib:/lib'
++ MKSHLIB='$(CCC) -shared $(DSO_LDOPTS) -o $@'
+ AC_CHECK_HEADER(sys/atomic_op.h, AC_DEFINE(AIX_HAVE_ATOMIC_OP_H))
+ case "${target_os}" in
+ aix3.2*)
+@@ -1220,10 +1221,9 @@
+ AC_DEFINE(HAVE_SOCKLEN_T)
+ AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+ USE_IPV6=1
+- AIX_LINK_OPTS='-brtl -bnso -berok'
++ AIX_LINK_OPTS='-Wl,-brtl -Wl,-bnso -Wl,-berok'
+ ;;
+ esac
+- CFLAGS="$CFLAGS -qro -qroconst"
+ AIX_WRAP='$(DIST)/lib/aixwrap.o'
+ AIX_TMP='./_aix_tmp.o'
+ if test -n "$USE_64"; then
+diff -ru a/nspr/pr/src/Makefile.in b/nspr/pr/src/Makefile.in
+--- a/a/nspr/pr/src/Makefile.in 2014-09-29 16:46:35.281395079 +0100
++++ b/b/nspr/pr/src/Makefile.in 2014-09-29 16:50:33.909375948 +0100
+@@ -74,7 +74,6 @@
+ endif # SunOS
+
+ ifeq ($(OS_ARCH),AIX)
+-DSO_LDOPTS += -binitfini::_PR_Fini
+ OS_LIBS = -lodm -lcfg
+ ifeq ($(CLASSIC_NSPR),1)
+ ifeq ($(OS_RELEASE),4.1)
+diff -ru a/nss/cmd/platlibs.mk b/nss/cmd/platlibs.mk
+--- a/a/nss/cmd/platlibs.mk 2014-09-29 16:47:42.987012253 +0100
++++ b/b/nss/cmd/platlibs.mk 2014-09-29 16:50:33.910375955 +0100
+@@ -171,7 +171,7 @@
+ $(NULL)
+
+ ifeq ($(OS_ARCH), AIX)
+-EXTRA_SHARED_LIBS += -brtl
++EXTRA_SHARED_LIBS += -Wl,-brtl
+ endif
+
+ # $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
+@@ -217,7 +217,7 @@
+ $(NULL)
+
+ ifeq ($(OS_ARCH), AIX)
+-EXTRA_SHARED_LIBS += -brtl
++EXTRA_SHARED_LIBS += -Wl,-brtl
+ endif
+
+ # $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
+diff -ru a/nss/cmd/shlibsign/Makefile b/nss/cmd/shlibsign/Makefile
+--- a/a/nss/cmd/shlibsign/Makefile 2014-09-29 16:46:35.139393785 +0100
++++ b/b/nss/cmd/shlibsign/Makefile 2014-09-29 16:50:33.910375955 +0100
+@@ -43,6 +43,9 @@
+
+ endif
+
++ifeq ($(OS), AIX)
++EXTRA_SHARED_LIBS += -lpthreads
++endif
+
+ # sign any and all shared libraries that contain the word freebl
+ ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1)
+diff -ru a/nss/cmd/shlibsign/mangle/Makefile b/nss/cmd/shlibsign/mangle/Makefile
+--- a/a/nss/cmd/shlibsign/mangle/Makefile 2014-09-29 16:46:35.139393785 +0100
++++ b/b/nss/cmd/shlibsign/mangle/Makefile 2014-09-29 16:50:33.910375955 +0100
+@@ -43,7 +43,9 @@
+
+ endif
+
+-
++ifeq ($(OS), AIX)
++EXTRA_SHARED_LIBS += -lpthreads
++endif
+
+ #######################################################################
+ # (5) Execute "global" rules. (OPTIONAL) #
+diff -ru a/nss/coreconf/AIX.mk b/nss/coreconf/AIX.mk
+--- a/a/nss/coreconf/AIX.mk 2014-09-29 16:46:35.040392883 +0100
++++ b/b/nss/coreconf/AIX.mk 2014-09-29 16:50:33.909375948 +0100
+@@ -30,35 +30,30 @@
+
+ DEFAULT_COMPILER = xlc_r
+
+-CC = xlc_r
+-CCC = xlC_r
++CCC = $(CXX)
+
+ CPU_ARCH = rs6000
+
+ RANLIB = ranlib
+
+ OS_CFLAGS = -DAIX -DSYSV
+-OS_LIBS += -blibpath:/usr/lib:/lib -lc -lm
++OS_LIBS += -Wl,-blibpath:/usr/lib:/lib -lc -lm
+
+-DSO_LDOPTS = -brtl -bnortllib -bM:SRE -bnoentry
+-MKSHLIB = $(LD) $(DSO_LDOPTS) -blibpath:/usr/lib:/lib -lc -lm
++DSO_LDOPTS = -Wl,-brtl -Wl,-bnortllib
++MKSHLIB = $(CC) --shared $(DSO_LDOPTS) -Wl,-blibpath:/usr/lib:/lib -lc -lm
+
+ AIX_WRAP = $(DIST)/lib/aixwrap.o
+ AIX_TMP = $(OBJDIR)/_aix_tmp.o
+
+ ifdef MAPFILE
+-DSO_LDOPTS += -bexport:$(MAPFILE)
++DSO_LDOPTS += -Wl,-bexport:$(MAPFILE)
+ else
+-DSO_LDOPTS += -bexpall
++DSO_LDOPTS += -Wl,-bexpall
+ endif
+
+ PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \
+ sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' > $@
+
+-ifdef BUILD_OPT
+- OPTIMIZER += -qmaxmem=-1
+-endif
+-
+ ifeq ($(USE_64), 1)
+ OS_CFLAGS += -DAIX_64BIT
+ OBJECT_MODE=64
diff --git a/external/nss/nss.bzmozilla1238154.patch b/external/nss/nss.bzmozilla1238154.patch
new file mode 100644
index 000000000..425f38257
--- /dev/null
+++ b/external/nss/nss.bzmozilla1238154.patch
@@ -0,0 +1,12 @@
+diff -ru a/nspr/configure b/nspr/configure
+--- a/a/nspr/configure 2019-01-26 12:23:06.589389910 +0100
++++ b/b/nspr/configure 2019-01-26 12:26:56.566222293 +0100
+@@ -6883,7 +6883,7 @@
+
+ # Determine compiler version
+
+- _MSVC_VER_FILTER='s|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p'
++ _MSVC_VER_FILTER='s|.*[^!-~]\([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p'
+
+ CC_VERSION=`${CC} -v 2>&1 | sed -ne "$_MSVC_VER_FILTER"`
+ if test -z "$CC_VERSION"; then
diff --git a/external/nss/nss.cygwin64.in32bit.patch b/external/nss/nss.cygwin64.in32bit.patch
new file mode 100644
index 000000000..bce0f1d09
--- /dev/null
+++ b/external/nss/nss.cygwin64.in32bit.patch
@@ -0,0 +1,14 @@
+This fixes architecture mismatch, when building
+on Cygwin 64bit and in 32bit mode
+diff -ru nss.orig/nss/Makefile nss/nss/Makefile
+--- a/nss.orig/nss/Makefile 2016-02-26 01:00:52.146713100 +0100
++++ b/nss/nss/Makefile 2016-02-26 01:02:05.303560100 +0100
+@@ -63,6 +63,8 @@
+ # Translate coreconf build options to NSPR configure options.
+ #
+
++NSPR_CONFIGURE_OPTS += --host=i686-pc-cygwin
++
+ ifeq ($(OS_TARGET),Android)
+ NSPR_CONFIGURE_OPTS += --with-android-ndk=$(ANDROID_NDK) \
+ --target=$(ANDROID_PREFIX) \
diff --git a/external/nss/nss.nowerror.patch b/external/nss/nss.nowerror.patch
new file mode 100644
index 000000000..bdf7a33a8
--- /dev/null
+++ b/external/nss/nss.nowerror.patch
@@ -0,0 +1,12 @@
+diff -ur nss.org/nss/coreconf/WIN32.mk nss/nss/coreconf/WIN32.mk
+--- a/nss.org/nss/coreconf/WIN32.mk 2016-04-13 11:33:09.322294523 +0200
++++ b/nss/nss/coreconf/WIN32.mk 2016-04-13 11:33:27.744323969 +0200
+@@ -121,7 +121,7 @@
+ -D_CRT_NONSTDC_NO_WARNINGS
+ OS_DLLFLAGS += -nologo -DLL -SUBSYSTEM:WINDOWS
+ ifndef NSS_ENABLE_WERROR
+- NSS_ENABLE_WERROR = 1
++ NSS_ENABLE_WERROR = 0
+ endif
+ ifeq ($(NSS_ENABLE_WERROR),1)
+ WARNING_CFLAGS += -WX
diff --git a/external/nss/nss.patch b/external/nss/nss.patch
new file mode 100644
index 000000000..cc9eeed1b
--- /dev/null
+++ b/external/nss/nss.patch
@@ -0,0 +1,155 @@
+--- a/a/nspr/configure 2017-08-29 23:44:13.686045013 +0530
++++ b/b/nspr/configure 2017-08-29 23:46:53.774768655 +0530
+@@ -6794,7 +6794,7 @@
+ PR_MD_CSRCS=linux.c
+ MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+ DSO_CFLAGS=-fPIC
+- DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
++ DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@) $(if $(filter-out $(OS),ANDROID),-Wl$(COMMA)-z$(COMMA)origin -Wl$(COMMA)-rpath$(COMMA)\$$ORIGIN)'
+ _OPTIMIZE_FLAGS=-O2
+ _DEBUG_FLAGS="-g -fno-inline" # most people on linux use gcc/gdb, and that
+ # combo is not yet good at debugging inlined
+--- a/nss.orig/nspr/pr/src/misc/prnetdb.c 2017-08-29 23:44:13.690045031 +0530
++++ b/nss/nspr/pr/src/misc/prnetdb.c 2017-08-29 23:47:03.810814019 +0530
+@@ -441,7 +441,7 @@
+ char *buf = *bufp;
+ PRIntn buflen = *buflenp;
+
+- if (align && ((long)buf & (align - 1))) {
++ if (align && ((ptrdiff_t)buf & (align - 1))) {
+ PRIntn skip = align - ((ptrdiff_t)buf & (align - 1));
+ if (buflen < skip) {
+ return 0;
+--- a/a/nss/cmd/platlibs.mk 2017-08-29 23:44:13.554044416 +0530
++++ b/b/nss/cmd/platlibs.mk 2017-08-29 23:46:09.638569150 +0530
+@@ -10,17 +10,22 @@
+
+ ifeq ($(OS_ARCH), SunOS)
+ ifeq ($(USE_64), 1)
+-EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1/64:/usr/lib/mps/64'
++#In OOo we would probable put the executables next to libs
++EXTRA_SHARED_LIBS += -R '$$ORIGIN'
+ else
+-EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1:/usr/lib/mps'
++EXTRA_SHARED_LIBS += -R '$$ORIGIN'
+ endif
+ endif
+
++ifeq ($(OS_ARCH), FreeBSD)
++EXTRA_SHARED_LIBS += -Wl,-z,origin -Wl,-rpath,'$$ORIGIN'
++endif
++
+ ifeq ($(OS_ARCH), Linux)
+ ifeq ($(USE_64), 1)
+-EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib64:/opt/sun/private/lib64:$$ORIGIN/../lib'
++EXTRA_SHARED_LIBS += -Wl,-z,origin -Wl,-rpath,'$$ORIGIN'
+ else
+-EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib:/opt/sun/private/lib'
++EXTRA_SHARED_LIBS += -Wl,-z,origin -Wl,-rpath,'$$ORIGIN'
+ endif
+ endif
+
+--- a/nss.org/nss/coreconf/arch.mk 2017-08-29 23:44:13.646044832 +0530
++++ b/nss/nss/coreconf/arch.mk 2017-08-29 23:45:51.494487134 +0530
+@@ -284,11 +284,17 @@
+ OBJDIR_NAME_COMPILER = $(COMPILER_TAG)
+ endif
+ OBJDIR_NAME_BASE = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(OBJDIR_NAME_COMPILER)$(LIBC_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG)
+-OBJDIR_NAME = $(OBJDIR_NAME_BASE).OBJ
++# OBJDIR_NAME is used to build the directory containing the built objects, for
++# example mozilla/dist/Linux2.6_x86_glibc_PTH_DBG.OBJ
++# We need to deliver the contents of that folder into instdir. To make that
++# easier in the makefile we rename this directory to "out".
++#OBJDIR_NAME = $(OBJDIR_NAME_BASE).OBJ
++OBJDIR_NAME = out
+
+
+ ifeq (,$(filter-out WIN%,$(OS_TARGET)))
+-ifndef BUILD_OPT
++ifdef THIS_HAS_BEEN_DISABLED_TO_GET_out
++
+ #
+ # Define USE_DEBUG_RTL if you want to use the debug runtime library
+ # (RTL) in the debug build
+--- a/nss.org/nss/coreconf/FreeBSD.mk 2017-08-29 23:44:13.642044814 +0530
++++ b/nss/nss/coreconf/FreeBSD.mk 2017-08-29 23:45:20.850348615 +0530
+@@ -25,6 +25,7 @@
+
+ DSO_CFLAGS = -fPIC
+ DSO_LDOPTS = -shared -Wl,-soname -Wl,$(notdir $@)
++DSO_LDOPTS += -Wl,-z,origin '-Wl,-rpath,$$ORIGIN'
+
+ #
+ # The default implementation strategy for FreeBSD is pthreads.
+--- a/nss.org/nss/coreconf/Linux.mk 2017-08-29 23:44:13.642044814 +0530
++++ b/nss/nss/coreconf/Linux.mk 2017-08-29 23:47:26.318915759 +0530
+@@ -158,7 +158,7 @@
+ # Also, -z defs conflicts with Address Sanitizer, which emits relocations
+ # against the libsanitizer runtime built into the main executable.
+ ZDEFS_FLAG = -Wl,-z,defs
+-DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell $(LD) -v)),,$(ZDEFS_FLAG))
++DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell $(LD) -v)),,$(ZDEFS_FLAG)) $(if $(filter-out $(OS),ANDROID),-Wl$(COMMA)-z$(COMMA)origin '-Wl$(COMMA)-rpath$(COMMA)$$ORIGIN')
+ LDFLAGS += $(ARCHFLAG) -z noexecstack
+
+ # On Maemo, we need to use the -rpath-link flag for even the standard system
+@@ -188,8 +188,13 @@
+ endif
+ endif
+
++ifneq ($(SYSTEM_ZLIB),)
++# Currently (3.12.4) only the tools modutil and signtool are linked with libz
++# If USE_SYSTEM_ZLIB is not set then the tools link statically libzlib.a which
++# is also built in nss.
+ USE_SYSTEM_ZLIB = 1
+ ZLIB_LIBS = -lz
++endif
+
+ # The -rpath '$$ORIGIN' linker option instructs this library to search for its
+ # dependencies in the same directory where it resides.
+--- a/nss.org/nss/coreconf/rules.mk 2017-08-29 23:44:13.646044832 +0530
++++ b/nss/nss/coreconf/rules.mk 2017-08-29 23:47:37.442966042 +0530
+@@ -176,7 +176,7 @@
+ ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET)))
+ $(AR) $(subst /,\\,$(OBJS))
+ else
+- $(AR) $(OBJS)
++ $(AR) cr $@ $(OBJS)
+ endif
+ $(RANLIB) $@
+
+--- a/nss.org/nss/coreconf/SunOS5.mk 2017-08-29 23:44:13.646044832 +0530
++++ b/nss/nss/coreconf/SunOS5.mk 2017-08-29 23:45:00.902258445 +0530
+@@ -46,8 +46,11 @@
+ # OPTIMIZER += -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer
+ endif
+ else
+- CC = cc
+- CCC = CC
++ # CC is taken from environment automatically.
++ # CC = cc
++ # Use CXX from environment.
++ # CCC = CC
++ CCC = $(CXX)
+ ASFLAGS += -Wa,-P
+ OS_CFLAGS += $(NOMD_OS_CFLAGS) $(ARCHFLAG)
+ ifndef BUILD_OPT
+--- a/nss.org/nss/coreconf/Werror.mk 2017-08-29 23:44:13.646044832 +0530
++++ b/nss/nss/coreconf/Werror.mk 2017-08-29 23:44:23.994091608 +0530
+@@ -96,7 +96,8 @@
+ endif #ndef NSS_ENABLE_WERROR
+
+ ifeq ($(NSS_ENABLE_WERROR),1)
+- WARNING_CFLAGS += -Werror
++ # We do not treat warnings as errors.
++ # WARNING_CFLAGS += -Werror
+ else
+ # Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
+ # Use this to disable use of that #pragma and the warnings it suppresses.
+--- a/nss.org/nss/Makefile 2017-08-29 23:44:13.402043729 +0530
++++ b/nss/nss/Makefile 2017-08-29 23:44:39.774162939 +0530
+@@ -1,3 +1,5 @@
++export AR
++export RANLIB
+ #! gmake
+ #
+ # This Source Code Form is subject to the terms of the Mozilla Public
diff --git a/external/nss/nss.utf8bom.patch.1 b/external/nss/nss.utf8bom.patch.1
new file mode 100644
index 000000000..f474adf6f
--- /dev/null
+++ b/external/nss/nss.utf8bom.patch.1
@@ -0,0 +1,21 @@
+diff -ur nss.org/nss/lib/ckfw/builtins/certdata.perl nss/nss/lib/ckfw/builtins/certdata.perl
+--- nss.org/nss/lib/ckfw/builtins/certdata.perl 2016-03-31 18:26:07.890190900 +0800
++++ nss/nss/lib/ckfw/builtins/certdata.perl 2016-03-31 19:16:16.727269600 +0800
+@@ -122,6 +122,9 @@
+ sub doprint {
+ my $i;
+
++print chr(0xEF);
++print chr(0xBB);
++print chr(0xBF);
+ print <<EOD
+ /* THIS IS A GENERATED FILE */
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+@@ -131,6 +134,7 @@
+ #ifndef BUILTINS_H
+ #include "builtins.h"
+ #endif /* BUILTINS_H */
++#pragma execution_character_set("utf-8")
+
+ EOD
+ ;
diff --git a/external/nss/nss.vs2015.patch b/external/nss/nss.vs2015.patch
new file mode 100644
index 000000000..73cff7c83
--- /dev/null
+++ b/external/nss/nss.vs2015.patch
@@ -0,0 +1,12 @@
+diff -ru nss.org/nss/coreconf/WIN32.mk nss/nss/coreconf/WIN32.mk
+--- a/nss.org/nss/coreconf/WIN32.mk 2016-02-12 15:36:18.000000000 +0100
++++ b/nss/nss/coreconf/WIN32.mk 2016-02-26 00:42:43.170809600 +0100
+@@ -192,7 +192,7 @@
+ # Disable C4244: conversion from 'type1' to 'type2', possible loss of data
+ # Disable C4018: 'expression' : signed/unsigned mismatch
+ # Disable C4312: 'type cast': conversion from 'type1' to 'type2' of greater size
+- OS_CFLAGS += -w44267 -w44244 -w44018 -w44312
++ OS_CFLAGS += -w44267 -w44244 -w44018 -w44312 -wd4996 -wd4554
+ ifeq ($(_MSC_VER_GE_12),1)
+ OS_CFLAGS += -FS
+ endif
diff --git a/external/nss/nss.vs2015.pdb.patch b/external/nss/nss.vs2015.pdb.patch
new file mode 100644
index 000000000..3b498f976
--- /dev/null
+++ b/external/nss/nss.vs2015.pdb.patch
@@ -0,0 +1,22 @@
+diff -ru nss.orig/nss/coreconf/WIN32.mk nss/nss/coreconf/WIN32.mk
+--- a/nss.orig/nss/coreconf/WIN32.mk 2016-03-04 08:30:16.306639400 +0100
++++ b/nss/nss/coreconf/WIN32.mk 2016-03-04 08:31:17.987233200 +0100
+@@ -163,15 +163,15 @@
+ DLLFLAGS += -OUT:$@
+ ifdef MOZ_DEBUG_SYMBOLS
+ ifdef MOZ_DEBUG_FLAGS
+- OPTIMIZER += $(MOZ_DEBUG_FLAGS) -Fd$(OBJDIR)/
++ OPTIMIZER += $(MOZ_DEBUG_FLAGS) -Fd./
+ else
+- OPTIMIZER += -Zi -Fd$(OBJDIR)/
++ OPTIMIZER += -Zi -Fd./
+ endif
+ DLLFLAGS += -DEBUG -OPT:REF
+ LDFLAGS += -DEBUG -OPT:REF
+ endif
+ else
+- OPTIMIZER += -Zi -Fd$(OBJDIR)/ -Od
++ OPTIMIZER += -Zi -Fd./ -Od
+ NULLSTRING :=
+ DEFINES += -DDEBUG -UNDEBUG
+ DLLFLAGS += -DEBUG -OUT:$@
diff --git a/external/nss/nss.windows.patch b/external/nss/nss.windows.patch
new file mode 100644
index 000000000..27a440458
--- /dev/null
+++ b/external/nss/nss.windows.patch
@@ -0,0 +1,33 @@
+--- a/a/nspr/config/rules.mk 2008-12-03 00:24:39.000000000 +0100
++++ b/b/nspr/config/rules.mk 2009-11-27 13:36:22.662753328 +0100
+@@ -423,7 +423,7 @@
+
+ ifdef NEED_ABSOLUTE_PATH
+ # The quotes allow absolute paths to contain spaces.
+-pr_abspath = "$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(CURDIR)/$(1)))"
++pr_abspath = "$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(shell cygpath -m $(1))),$(1),$(shell cygpath -m $(CURDIR)/$(1))))"
+ endif
+
+ $(OBJDIR)/%.$(OBJ_SUFFIX): %.cpp
+--- a/a/nss/coreconf/rules.mk 2008-12-03 00:24:39.000000000 +0100
++++ b/b/nss/coreconf/rules.mk 2009-11-27 13:36:22.662753328 +0100
+@@ -280,7 +280,7 @@
+ endif
+
+ # The quotes allow absolute paths to contain spaces.
+-core_abspath = '$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1)))'
++core_abspath = '$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(shell cygpath -m $(1))),$(1),$(shell cygpath -m $(PWD)/$(1))))'
+
+ $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.c | $$(@D)/d
+ ifdef USE_NT_C_SYNTAX
+--- a/a/nspr/pr/include/md/_win95.h
++++ b/b/nspr/pr/include/md/_win95.h
+@@ -317,7 +317,7 @@
+ #define _MD_ATOMIC_ADD(ptr,val) (InterlockedExchangeAdd((PLONG)ptr, (LONG)val) + val)
+ #define _MD_ATOMIC_DECREMENT(x) InterlockedDecrement((PLONG)x)
+ #endif /* x86 */
+-#define _MD_ATOMIC_SET(x,y) InterlockedExchange((PLONG)x, (LONG)y)
++#define _MD_ATOMIC_SET(x,y) _InterlockedExchange((PLONG)x, (LONG)y)
+
+ #define _MD_INIT_IO _PR_MD_INIT_IO
+
diff --git a/external/nss/nss_macosx.patch b/external/nss/nss_macosx.patch
new file mode 100644
index 000000000..456bd62d5
--- /dev/null
+++ b/external/nss/nss_macosx.patch
@@ -0,0 +1,90 @@
+diff -ru a/nspr/configure b/nspr/configure
+--- a/a/nspr/configure 2014-09-29 16:50:33.907375937 +0100
++++ b/b/nspr/configure 2014-09-29 16:51:59.213931947 +0100
+@@ -6448,6 +6448,9 @@
+ AS='$(CC) -x assembler-with-cpp'
+ CFLAGS="$CFLAGS -Wall -fno-common"
+ case "${target_cpu}" in
++ aarch64)
++ CPU_ARCH=arm64
++ ;;
+ arm*)
+ CPU_ARCH=arm
+ ;;
+@@ -6483,7 +6486,7 @@
+
+
+ DSO_CFLAGS=-fPIC
+- DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names'
++ DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @__________________________________________________OOO/$@ -headerpad_max_install_names'
+ _OPTIMIZE_FLAGS=-O2
+ MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+ STRIP="$STRIP -x -S"
+diff -ru a/nss/coreconf/Darwin.mk b/nss/coreconf/Darwin.mk
+--- a/a/nss/coreconf/Darwin.mk 2014-09-29 16:50:22.992304799 +0100
++++ b/b/nss/coreconf/Darwin.mk 2014-09-29 16:51:59.214931953 +0100
+@@ -20,13 +20,17 @@
+
+ ifeq (,$(filter-out i%86,$(CPU_ARCH)))
+ ifdef USE_64
++ifeq (,$(findstring -arch ,$(CC)))
+ CC += -arch x86_64
+ CCC += -arch x86_64
++endif
+ override CPU_ARCH = x86_64
+ else
+ OS_REL_CFLAGS = -Di386
++ifeq (,$(findstring -arch ,$(CC)))
+ CC += -arch i386
+ CCC += -arch i386
++endif
+ override CPU_ARCH = x86
+ endif
+ else
+@@ -33,19 +37,20 @@
+ ifeq (arm,$(CPU_ARCH))
+ # Nothing set for arm currently.
+ else
+-OS_REL_CFLAGS = -Dppc
+-CC += -arch ppc
+-CCC += -arch ppc
+ endif
+ endif
+
+ ifneq (,$(MACOS_SDK_DIR))
++ CLANG_VERSION_FULL := $(shell $(CC) -v 2>&1 | grep "clang version" | sed -e "s/^.*clang version[ ]*//" | awk '{ print $$1 }')
+ GCC_VERSION_FULL := $(shell $(CC) -dumpversion)
+ GCC_VERSION_MAJOR := $(shell echo $(GCC_VERSION_FULL) | awk -F. '{ print $$1 }')
+ GCC_VERSION_MINOR := $(shell echo $(GCC_VERSION_FULL) | awk -F. '{ print $$2 }')
+ GCC_VERSION = $(GCC_VERSION_MAJOR).$(GCC_VERSION_MINOR)
++ ifneq (,$(CLANG_VERSION_FULL))
++ DARWIN_SDK_CFLAGS = -isysroot $(MACOS_SDK_DIR)
++ DARWIN_SDK_SHLIBFLAGS = -isysroot $(MACOS_SDK_DIR)
+
+- ifeq (,$(filter-out 2 3,$(GCC_VERSION_MAJOR)))
++ else ifeq (,$(filter-out 2 3,$(GCC_VERSION_MAJOR)))
+ # GCC <= 3
+ DARWIN_SDK_FRAMEWORKS = -F$(MACOS_SDK_DIR)/System/Library/Frameworks
+ ifneq (,$(shell find $(MACOS_SDK_DIR)/Library/Frameworks -maxdepth 0))
+@@ -108,7 +113,7 @@
+ # May override this with different compatibility and current version numbers.
+ DARWIN_DYLIB_VERSIONS = -compatibility_version 1 -current_version 1
+ # May override this with -bundle to create a loadable module.
+-DSO_LDOPTS = -dynamiclib $(DARWIN_DYLIB_VERSIONS) -install_name @executable_path/$(notdir $@) -headerpad_max_install_names
++DSO_LDOPTS = -dynamiclib $(DARWIN_DYLIB_VERSIONS) -install_name @__________________________________________________OOO/$(notdir $@) -headerpad_max_install_names
+
+ ifdef USE_GCOV
+ OS_CFLAGS += --coverage
+diff -ru a/nss/Makefile b/nss/Makefile
+--- a/a/nss/Makefile 2014-09-29 16:50:22.990304789 +0100
++++ b/b/nss/Makefile 2014-09-29 16:51:59.207931908 +0100
+@@ -82,6 +82,9 @@
+ ifeq ($(OS_TARGET),WIN95)
+ NSPR_CONFIGURE_OPTS += --enable-win32-target=WIN95
+ endif
++ifdef MACOS_SDK_DIR
++NSPR_CONFIGURE_OPTS += --with-macos-sdk=$(MACOS_SDK_DIR)
++endif
+ ifdef USE_DEBUG_RTL
+ NSPR_CONFIGURE_OPTS += --enable-debug-rtl
+ endif
diff --git a/external/nss/ubsan.patch.0 b/external/nss/ubsan.patch.0
new file mode 100644
index 000000000..5f97d3e9d
--- /dev/null
+++ b/external/nss/ubsan.patch.0
@@ -0,0 +1,38 @@
+--- nss/lib/base/item.c
++++ nss/lib/base/item.c
+@@ -182,5 +182,5 @@
+ return PR_FALSE;
+ }
+
+- return nsslibc_memequal(one->data, two->data, one->size, statusOpt);
++ return one->size == 0 || nsslibc_memequal(one->data, two->data, one->size, statusOpt);
+ }
+--- nss/lib/softoken/legacydb/pk11db.c
++++ nss/lib/softoken/legacydb/pk11db.c
+@@ -65,7 +65,7 @@
+ unsigned char isModuleDBOnly;
+ unsigned char isCritical;
+ unsigned char reserved[4];
+- unsigned char names[6]; /* enough space for the length fields */
++ unsigned char names[1]; /* +5: enough space for the length fields */
+ };
+
+ struct lgdbSlotDataStr {
+@@ -148,7 +148,7 @@
+ goto loser;
+ }
+
+- dataLen = sizeof(lgdbData) + len + len2 + len3 + sizeof(unsigned short) +
++ dataLen = sizeof(lgdbData)+5 + len + len2 + len3 + sizeof(unsigned short) +
+ count * sizeof(lgdbSlotData);
+
+ data->data = (unsigned char *)PORT_ZAlloc(dataLen);
+@@ -329,7 +329,7 @@
+ }
+ if ((encoded->major == LGDB_DB_EXT1_VERSION_MAJOR) &&
+ (encoded->minor >= LGDB_DB_EXT1_VERSION_MINOR)) {
+- CHECK_SIZE(sizeof(lgdbData));
++ CHECK_SIZE(sizeof(lgdbData)+5);
+ trustOrder = LGDB_GETLONG(encoded->trustOrder);
+ cipherOrder = LGDB_GETLONG(encoded->cipherOrder);
+ isModuleDB = (encoded->isModuleDB != 0) ? PR_TRUE : PR_FALSE;
diff --git a/external/openldap/ExternalProject_openldap.mk b/external/openldap/ExternalProject_openldap.mk
new file mode 100644
index 000000000..5f85fb323
--- /dev/null
+++ b/external/openldap/ExternalProject_openldap.mk
@@ -0,0 +1,65 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,openldap))
+
+$(eval $(call gb_ExternalProject_use_externals,openldap,nss3))
+
+$(eval $(call gb_ExternalProject_register_targets,openldap,\
+ build \
+))
+
+openldap_CFLAGS =
+ifeq ($(OS),LINUX) # i.e., assuming glibc
+# glibc needs at least _XOPEN_SOURCE=500 to declare pthread_getconcurrency and
+# pthread_setconcurrency in <pthread.h> (and once that is defined, it also needs either
+# _DEFUALT_SOURCE (glibc >= 2.19) or the deprecated _BSD_SOURCE (glibc <= 2.18) to be defined
+# explicitly, so that e.g. u_char is declared in <sys/types.h>):
+openldap_CFLAGS = -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -D_BSD_SOURCE
+endif
+
+openldap_LDFLAGS = $(call gb_ExternalProject_get_link_flags,openldap)
+ifeq ($(SYSTEM_NSS),)
+openldap_LDFLAGS += -L$(call gb_UnpackedTarball_get_dir,nss)/dist/out/lib \
+ $(if $(filter AIX,$(OS)),-Wl$(COMMA)-brtl)
+endif
+# Help openldap's configure determine that it needs -lpthread even if libasan.so
+# contains a pthread_create override:
+ifneq ($(filter -fsanitize=address,$(CC)),)
+openldap_LDFLAGS += -pthread
+endif
+
+$(call gb_ExternalProject_get_state_target,openldap,build) :
+ $(call gb_Trace_StartRange,openldap,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure \
+ --disable-slapd \
+ --with-pic \
+ --with-tls=moznss \
+ --without-cyrus-sasl \
+ --disable-shared \
+ --enable-static \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING), \
+ --with-yielding_select=yes \
+ ac_cv_func_memcmp_working=yes \
+ ) \
+ $(if $(SYSTEM_NSS), \
+ CPPFLAGS="$(CPPFLAGS) $(NSS_CFLAGS)" CFLAGS="$(CFLAGS) $(openldap_CFLAGS) $(NSS_CFLAGS) $(call gb_ExternalProject_get_build_flags,openldap)" LDFLAGS="$(LDFLAGS) $(NSS_LIBS)" \
+ , \
+ CPPFLAGS="$(CPPFLAGS) -I$(call gb_UnpackedTarball_get_dir,nss)/dist/public/nss -I$(call gb_UnpackedTarball_get_dir,nss)/dist/out/include" \
+ CFLAGS="$(CFLAGS) $(openldap_CFLAGS) $(call gb_ExternalProject_get_build_flags,openldap) -I$(call gb_UnpackedTarball_get_dir,nss)/dist/public/nss -I$(call gb_UnpackedTarball_get_dir,nss)/dist/out/include" \
+ ) \
+ $(if $(openldap_LDFLAGS),LDFLAGS="$(LDFLAGS) $(openldap_LDFLAGS)") \
+ && MAKEFLAGS= && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,openldap,EXTERNAL)
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/openldap/Makefile b/external/openldap/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/openldap/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/openldap/Module_openldap.mk b/external/openldap/Module_openldap.mk
new file mode 100644
index 000000000..c6a22bc4e
--- /dev/null
+++ b/external/openldap/Module_openldap.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,openldap))
+
+$(eval $(call gb_Module_add_targets,openldap,\
+ ExternalProject_openldap \
+ UnpackedTarball_openldap \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/openldap/README b/external/openldap/README
new file mode 100644
index 000000000..0c1828c12
--- /dev/null
+++ b/external/openldap/README
@@ -0,0 +1,3 @@
+OpenLDAP provides an LDAP client library
+
+http://www.openldap.org/
diff --git a/external/openldap/UnpackedTarball_openldap.mk b/external/openldap/UnpackedTarball_openldap.mk
new file mode 100644
index 000000000..999a1edda
--- /dev/null
+++ b/external/openldap/UnpackedTarball_openldap.mk
@@ -0,0 +1,26 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,openldap))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,openldap,$(OPENLDAP_TARBALL),,openldap))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,openldap,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,openldap,\
+ build \
+ contrib/ldapc++ \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,openldap,\
+ external/openldap/openldap-2.4.44.patch.1 \
+ external/openldap/configure-c99.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/openldap/configure-c99.patch b/external/openldap/configure-c99.patch
new file mode 100644
index 000000000..f1c3da6c4
--- /dev/null
+++ b/external/openldap/configure-c99.patch
@@ -0,0 +1,11 @@
+--- configure
++++ configure
+@@ -14691,7 +14691,7 @@
+ #include <sys/types.h>
+ #include <regex.h>
+ static char *pattern, *string;
+-main()
++int main()
+ {
+ int rc;
+ regex_t re;
diff --git a/external/openldap/openldap-2.4.44.patch.1 b/external/openldap/openldap-2.4.44.patch.1
new file mode 100644
index 000000000..317ef9a62
--- /dev/null
+++ b/external/openldap/openldap-2.4.44.patch.1
@@ -0,0 +1,85 @@
+-*- Mode: diff -*-
+--- openldap.org/configure
++++ openldap/configure
+@@ -15735,7 +15735,7 @@
+ $as_echo_n "(cached) " >&6
+ else
+ ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lnss3 $LIBS"
++LIBS="-lnss3 -lssl3 -lsmime3 -lnss3 -lnssutil3 -lplds4 -lplc4 -lnspr4 $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+--- openldap.org/configure.in
++++ openldap/configure.in
+@@ -1239,7 +1239,8 @@
+ AC_CHECK_HEADERS([nssutil.h])
+ if test "$ac_cv_header_nssutil_h" = yes ; then
+ AC_CHECK_LIB([nss3], [NSS_Initialize],
+- [ have_moznss=yes ], [ have_moznss=no ])
++ [ have_moznss=yes ], [ have_moznss=no ],
++ [ -lssl3 -lsmime3 -lnss3 -lnssutil3 -lplds4 -lplc4 -lnspr4 ])
+ fi
+
+ if test "$have_moznss" = yes ; then
+--- openldap.org/libraries/libldap/tls_m.c
++++ openldap/libraries/libldap/tls_m.c
+@@ -49,17 +49,17 @@
+ #include <termios.h> /* for echo on/off */
+ #endif
+
+-#include <nspr/nspr.h>
+-#include <nspr/private/pprio.h>
+-#include <nss/nss.h>
+-#include <nss/ssl.h>
+-#include <nss/sslerr.h>
+-#include <nss/sslproto.h>
+-#include <nss/pk11pub.h>
+-#include <nss/secerr.h>
+-#include <nss/keyhi.h>
+-#include <nss/secmod.h>
+-#include <nss/cert.h>
++#include <nspr.h>
++#include <private/pprio.h>
++#include <nss.h>
++#include <ssl.h>
++#include <sslerr.h>
++#include <sslproto.h>
++#include <pk11pub.h>
++#include <secerr.h>
++#include <keyhi.h>
++#include <secmod.h>
++#include <cert.h>
+
+ #undef NSS_VERSION_INT
+ #define NSS_VERSION_INT ((NSS_VMAJOR << 24) | (NSS_VMINOR << 16) | \
+--- openldap.org/libraries/libldap/tls2.c
++++ openldap.org/libraries/libldap/tls2.c
+@@ -80,6 +80,8 @@
+ { BER_BVNULL, BER_BVNULL }
+ };
+
++int ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in );
++
+ #ifdef HAVE_TLS
+
+ void
+--- openldap.org/Makefile.in
++++ openldap/Makefile.in
+@@ -13,7 +13,7 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+
+-SUBDIRS= include libraries clients servers tests doc
++SUBDIRS= include libraries
+ CLEANDIRS=
+ INSTALLDIRS=
+
+@@ -32,7 +32,3 @@
+ $(RM) config.status libtool stamp-h stamp-h.in
+
+ distclean: veryclean FORCE
+-
+-check: test
+-test: FORCE
+- cd tests; $(MAKE) test
diff --git a/external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1 b/external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1
new file mode 100644
index 000000000..f87f8f588
--- /dev/null
+++ b/external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1
@@ -0,0 +1,222 @@
+From 879f7080d7e141f415c79eaa3a8ac4a3dad0348b Mon Sep 17 00:00:00 2001
+From: Pauli <pauli@openssl.org>
+Date: Wed, 8 Mar 2023 15:28:20 +1100
+Subject: [PATCH] x509: excessive resource use verifying policy constraints
+
+A security vulnerability has been identified in all supported versions
+of OpenSSL related to the verification of X.509 certificate chains
+that include policy constraints. Attackers may be able to exploit this
+vulnerability by creating a malicious certificate chain that triggers
+exponential use of computational resources, leading to a denial-of-service
+(DoS) attack on affected systems.
+
+Fixes CVE-2023-0464
+
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
+(Merged from https://github.com/openssl/openssl/pull/20569)
+---
+ crypto/x509v3/pcy_local.h | 8 +++++++-
+ crypto/x509v3/pcy_node.c | 12 +++++++++---
+ crypto/x509v3/pcy_tree.c | 37 +++++++++++++++++++++++++++----------
+ 3 files changed, 43 insertions(+), 14 deletions(-)
+
+diff --git a/crypto/x509v3/pcy_local.h b/crypto/x509v3/pcy_local.h
+index 5daf78de45..344aa06765 100644
+--- a/crypto/x509v3/pcy_local.h
++++ b/crypto/x509v3/pcy_local.h
+@@ -111,6 +111,11 @@ struct X509_POLICY_LEVEL_st {
+ };
+
+ struct X509_POLICY_TREE_st {
++ /* The number of nodes in the tree */
++ size_t node_count;
++ /* The maximum number of nodes in the tree */
++ size_t node_maximum;
++
+ /* This is the tree 'level' data */
+ X509_POLICY_LEVEL *levels;
+ int nlevel;
+@@ -159,7 +164,8 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
+ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
+ X509_POLICY_DATA *data,
+ X509_POLICY_NODE *parent,
+- X509_POLICY_TREE *tree);
++ X509_POLICY_TREE *tree,
++ int extra_data);
+ void policy_node_free(X509_POLICY_NODE *node);
+ int policy_node_match(const X509_POLICY_LEVEL *lvl,
+ const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
+diff --git a/crypto/x509v3/pcy_node.c b/crypto/x509v3/pcy_node.c
+index e2d7b15322..d574fb9d66 100644
+--- a/crypto/x509v3/pcy_node.c
++++ b/crypto/x509v3/pcy_node.c
+@@ -59,10 +59,15 @@ X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
+ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
+ X509_POLICY_DATA *data,
+ X509_POLICY_NODE *parent,
+- X509_POLICY_TREE *tree)
++ X509_POLICY_TREE *tree,
++ int extra_data)
+ {
+ X509_POLICY_NODE *node;
+
++ /* Verify that the tree isn't too large. This mitigates CVE-2023-0464 */
++ if (tree->node_maximum > 0 && tree->node_count >= tree->node_maximum)
++ return NULL;
++
+ node = OPENSSL_zalloc(sizeof(*node));
+ if (node == NULL) {
+ X509V3err(X509V3_F_LEVEL_ADD_NODE, ERR_R_MALLOC_FAILURE);
+@@ -70,7 +75,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
+ }
+ node->data = data;
+ node->parent = parent;
+- if (level) {
++ if (level != NULL) {
+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+ if (level->anyPolicy)
+ goto node_error;
+@@ -90,7 +95,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
+ }
+ }
+
+- if (tree) {
++ if (extra_data) {
+ if (tree->extra_data == NULL)
+ tree->extra_data = sk_X509_POLICY_DATA_new_null();
+ if (tree->extra_data == NULL){
+@@ -103,6 +108,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
+ }
+ }
+
++ tree->node_count++;
+ if (parent)
+ parent->nchild++;
+
+diff --git a/crypto/x509v3/pcy_tree.c b/crypto/x509v3/pcy_tree.c
+index 6e8322cbc5..6c7fd35405 100644
+--- a/crypto/x509v3/pcy_tree.c
++++ b/crypto/x509v3/pcy_tree.c
+@@ -13,6 +13,18 @@
+
+ #include "pcy_local.h"
+
++/*
++ * If the maximum number of nodes in the policy tree isn't defined, set it to
++ * a generous default of 1000 nodes.
++ *
++ * Defining this to be zero means unlimited policy tree growth which opens the
++ * door on CVE-2023-0464.
++ */
++
++#ifndef OPENSSL_POLICY_TREE_NODES_MAX
++# define OPENSSL_POLICY_TREE_NODES_MAX 1000
++#endif
++
+ /*
+ * Enable this to print out the complete policy tree at various point during
+ * evaluation.
+@@ -168,6 +180,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
+ return X509_PCY_TREE_INTERNAL;
+ }
+
++ /* Limit the growth of the tree to mitigate CVE-2023-0464 */
++ tree->node_maximum = OPENSSL_POLICY_TREE_NODES_MAX;
++
+ /*
+ * http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3.
+ *
+@@ -184,7 +199,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
+ level = tree->levels;
+ if ((data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0)) == NULL)
+ goto bad_tree;
+- if (level_add_node(level, data, NULL, tree) == NULL) {
++ if (level_add_node(level, data, NULL, tree, 1) == NULL) {
+ policy_data_free(data);
+ goto bad_tree;
+ }
+@@ -243,7 +258,8 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
+ * Return value: 1 on success, 0 otherwise
+ */
+ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
+- X509_POLICY_DATA *data)
++ X509_POLICY_DATA *data,
++ X509_POLICY_TREE *tree)
+ {
+ X509_POLICY_LEVEL *last = curr - 1;
+ int i, matched = 0;
+@@ -253,13 +269,13 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
+ X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i);
+
+ if (policy_node_match(last, node, data->valid_policy)) {
+- if (level_add_node(curr, data, node, NULL) == NULL)
++ if (level_add_node(curr, data, node, tree, 0) == NULL)
+ return 0;
+ matched = 1;
+ }
+ }
+ if (!matched && last->anyPolicy) {
+- if (level_add_node(curr, data, last->anyPolicy, NULL) == NULL)
++ if (level_add_node(curr, data, last->anyPolicy, tree, 0) == NULL)
+ return 0;
+ }
+ return 1;
+@@ -272,7 +288,8 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
+ * Return value: 1 on success, 0 otherwise.
+ */
+ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
+- const X509_POLICY_CACHE *cache)
++ const X509_POLICY_CACHE *cache,
++ X509_POLICY_TREE *tree)
+ {
+ int i;
+
+@@ -280,7 +297,7 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
+ X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i);
+
+ /* Look for matching nodes in previous level */
+- if (!tree_link_matching_nodes(curr, data))
++ if (!tree_link_matching_nodes(curr, data, tree))
+ return 0;
+ }
+ return 1;
+@@ -311,7 +328,7 @@ static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
+ /* Curr may not have anyPolicy */
+ data->qualifier_set = cache->anyPolicy->qualifier_set;
+ data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+- if (level_add_node(curr, data, node, tree) == NULL) {
++ if (level_add_node(curr, data, node, tree, 1) == NULL) {
+ policy_data_free(data);
+ return 0;
+ }
+@@ -373,7 +390,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
+ }
+ /* Finally add link to anyPolicy */
+ if (last->anyPolicy &&
+- level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL) == NULL)
++ level_add_node(curr, cache->anyPolicy, last->anyPolicy, tree, 0) == NULL)
+ return 0;
+ return 1;
+ }
+@@ -555,7 +572,7 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree,
+ extra->qualifier_set = anyPolicy->data->qualifier_set;
+ extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
+ | POLICY_DATA_FLAG_EXTRA_NODE;
+- node = level_add_node(NULL, extra, anyPolicy->parent, tree);
++ node = level_add_node(NULL, extra, anyPolicy->parent, tree, 1);
+ }
+ if (!tree->user_policies) {
+ tree->user_policies = sk_X509_POLICY_NODE_new_null();
+@@ -582,7 +599,7 @@ static int tree_evaluate(X509_POLICY_TREE *tree)
+
+ for (i = 1; i < tree->nlevel; i++, curr++) {
+ cache = policy_cache_set(curr->cert);
+- if (!tree_link_nodes(curr, cache))
++ if (!tree_link_nodes(curr, cache, tree))
+ return X509_PCY_TREE_INTERNAL;
+
+ if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
+--
+2.34.1
+
diff --git a/external/openssl/ExternalPackage_openssl.mk b/external/openssl/ExternalPackage_openssl.mk
new file mode 100644
index 000000000..d0c0dbaab
--- /dev/null
+++ b/external/openssl/ExternalPackage_openssl.mk
@@ -0,0 +1,29 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,openssl,openssl))
+
+$(eval $(call gb_ExternalPackage_use_external_project,openssl,openssl))
+
+ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalPackage_add_files,openssl,$(LIBO_LIB_FOLDER),\
+ libcrypto-1_1.dll \
+ libssl-1_1.dll \
+))
+ifneq ($(DISABLE_PYTHON),TRUE)
+ifneq ($(SYSTEM_PYTHON),TRUE)
+$(eval $(call gb_ExternalPackage_add_files,openssl,$(LIBO_LIB_FOLDER)/python-core-$(PYTHON_VERSION)/lib, \
+ libcrypto-1_1.dll \
+ libssl-1_1.dll \
+))
+endif
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/openssl/ExternalProject_openssl.mk b/external/openssl/ExternalProject_openssl.mk
new file mode 100644
index 000000000..e44ccf5f3
--- /dev/null
+++ b/external/openssl/ExternalProject_openssl.mk
@@ -0,0 +1,97 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,openssl))
+
+$(eval $(call gb_ExternalProject_register_targets,openssl,\
+ build \
+))
+
+# For multi-line conditionals, align the $(if and the corresponding ),
+# putting the latter on a line of its own. Also put the "else" comma
+# on a line of its own. Hopefully should make the logic more clear.
+
+OPENSSL_PLATFORM := \
+ $(if $(filter LINUX FREEBSD ANDROID,$(OS)),\
+ $(if $(filter INTEL,$(CPUNAME)),\
+ $(if $(filter GNU/kFreeBSD,$(shell uname)),debian-kfreebsd-i386,linux-elf)\
+ ,\
+ $(if $(filter X86_64,$(CPUNAME)),\
+ $(if $(filter GNU/kFreeBSD,$(shell uname)),\
+ debian-kfreebsd-amd64\
+ ,\
+ $(if $(filter TRUE, $(ENABLE_DBGUTIL)), debug-linux-generic64, linux-generic64) no-asm\
+ )\
+ ,\
+ $(if $(filter TRUE, $(ENABLE_DBGUTIL)), debug-linux-generic32, linux-generic32)\
+ )\
+ )\
+ ,\
+ $(if $(filter SOLARIS,$(OS)),\
+ $(if $(filter INTEL,$(CPUNAME)),solaris-x86-cc,\
+ $(if $(filter X86_64,$(CPUNAME)),solaris64-x86_64-cc,solaris-sparcv9-cc)\
+ )\
+ ,\
+ $(if $(filter iOS,$(OS)),\
+ ios-aarch64\
+ ,\
+ $(if $(filter WNT,$(OS)),\
+ $(if $(filter INTEL,$(CPUNAME)),VC-WIN32)\
+ $(if $(filter X86_64,$(CPUNAME)),VC-WIN64A)\
+ $(if $(filter AARCH64,$(CPUNAME)),VC-WIN64-ARM)\
+ ,\
+ $(if $(filter MACOSX,$(OS)),\
+ $(if $(filter X86_64,$(CPUNAME)),darwin64-x86_64-cc)\
+ $(if $(filter AARCH64,$(CPUNAME)),darwin64-arm64-cc)\
+ ,\
+ $(if $(filter EMSCRIPTEN,$(OS)),no-engine no-dso no-dgram no-srtp no-err no-ocsp no-psk no-ts no-asm) \
+ )\
+ )\
+ )\
+ )\
+ )
+
+ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalProject_use_nmake,openssl,build))
+
+$(call gb_ExternalProject_get_state_target,openssl,build):
+ $(call gb_Trace_StartRange,openssl,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ CONFIGURE_INSIST=1 $(PERL) Configure $(OPENSSL_PLATFORM) no-tests no-multilib \
+ && export PERL="$(shell cygpath -w $(PERL))" \
+ && nmake -f makefile \
+ $(if $(call gb_Module__symbols_enabled,openssl),DEBUG_FLAGS_VALUE="$(gb_DEBUGINFO_FLAGS)") \
+ )
+ $(call gb_Trace_EndRange,openssl,EXTERNAL)
+
+else
+$(call gb_ExternalProject_get_state_target,openssl,build):
+ $(call gb_Trace_StartRange,openssl,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ unset MAKEFLAGS && \
+ $(if $(filter LINUX MACOSX FREEBSD ANDROID SOLARIS iOS,$(OS)), \
+ ./Configure, \
+ $(if $(filter WNT,$(OS)), \
+ $(PERL) Configure, \
+ ./config)) \
+ $(OPENSSL_PLATFORM) no-dso no-shared no-tests no-multilib threads \
+ $(if $(filter-out ANDROID iOS WNT,$(OS)), \
+ $(if $(SYSBASE),-I$(SYSBASE)/usr/include -L$(SYSBASE)/usr/lib)) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ && $(MAKE) build_libs \
+ CC="$(CC) -fPIC \
+ $(if $(filter TRUE, $(ENABLE_DBGUTIL)), -DPURIFY,) \
+ $(if $(filter-out WNT MACOSX,$(OS)),-fvisibility=hidden)" \
+ && ln -s . lib \
+ )
+ $(call gb_Trace_EndRange,openssl,EXTERNAL)
+# symlink lib dir for python3
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/openssl/Makefile b/external/openssl/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/openssl/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/openssl/Module_openssl.mk b/external/openssl/Module_openssl.mk
new file mode 100644
index 000000000..7a03fe536
--- /dev/null
+++ b/external/openssl/Module_openssl.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,openssl))
+
+$(eval $(call gb_Module_add_targets,openssl,\
+ UnpackedTarball_openssl \
+ ExternalPackage_openssl \
+ ExternalProject_openssl \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/openssl/README b/external/openssl/README
new file mode 100644
index 000000000..399bdd56f
--- /dev/null
+++ b/external/openssl/README
@@ -0,0 +1,7 @@
+Open Source toolkit implementing SSL and TLS.
+
+From [http://www.openssl.org/].
+
+SSL = Secure Sockets Layer (SSL v2/v3) protocol.
+TLS = Transport Layer Security (TLS v1) protocol.
+
diff --git a/external/openssl/UnpackedTarball_openssl.mk b/external/openssl/UnpackedTarball_openssl.mk
new file mode 100644
index 000000000..650ca154d
--- /dev/null
+++ b/external/openssl/UnpackedTarball_openssl.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,openssl))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,openssl,$(OPENSSL_TARBALL),,openssl))
+
+$(eval $(call gb_UnpackedTarball_add_patches,openssl,\
+ external/openssl/0001-x509-excessive-resource-use-verifying-policy-constra.patch.1 \
+ external/openssl/openssl-no-multilib.patch.0 \
+ external/openssl/configurable-z-option.patch.0 \
+ external/openssl/openssl-no-_umul128-on-aarch64.patch.1 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/openssl/configurable-z-option.patch.0 b/external/openssl/configurable-z-option.patch.0
new file mode 100644
index 000000000..99d46f754
--- /dev/null
+++ b/external/openssl/configurable-z-option.patch.0
@@ -0,0 +1,34 @@
+--- Configurations/10-main.conf.sav 2021-08-24 13:38:47.000000000 +0000
++++ Configurations/10-main.conf 2021-11-02 22:20:44.377653700 +0000
+@@ -13,7 +13,7 @@
+ } elsif ($disabled{asm}) {
+ # assembler is still used to compile uplink shim
+ $vc_win64a_info = { AS => "ml64",
+- ASFLAGS => "/nologo /Zi",
++ ASFLAGS => "/nologo $$(DEBUG_FLAGS_VALUE)",
+ asflags => "/c /Cp /Cx",
+ asoutflag => "/Fo" };
+ } else {
+@@ -41,7 +41,7 @@
+ } elsif ($disabled{asm}) {
+ # not actually used, uplink shim is inlined into C code
+ $vc_win32_info = { AS => "ml",
+- ASFLAGS => "/nologo /Zi",
++ ASFLAGS => "/nologo $$(DEBUG_FLAGS_VALUE)",
+ asflags => "/Cp /coff /c /Cx",
+ asoutflag => "/Fo",
+ perlasm_scheme => "win32" };
+@@ -1252,10 +1252,10 @@
+ "UNICODE", "_UNICODE",
+ "_CRT_SECURE_NO_DEPRECATE",
+ "_WINSOCK_DEPRECATED_NO_WARNINGS"),
+- lib_cflags => add("/Zi /Fdossl_static.pdb"),
++ lib_cflags => add("\$(DEBUG_FLAGS_VALUE)"),
+ lib_defines => add("L_ENDIAN"),
+- dso_cflags => "/Zi /Fddso.pdb",
+- bin_cflags => "/Zi /Fdapp.pdb",
++ dso_cflags => "\$(DEBUG_FLAGS_VALUE)",
++ bin_cflags => "\$(DEBUG_FLAGS_VALUE)",
+ shared_ldflag => "/dll",
+ shared_target => "win-shared", # meaningless except it gives Configure a hint
+ thread_scheme => "winthreads",
diff --git a/external/openssl/openssl-no-_umul128-on-aarch64.patch.1 b/external/openssl/openssl-no-_umul128-on-aarch64.patch.1
new file mode 100644
index 000000000..c7ca53bc5
--- /dev/null
+++ b/external/openssl/openssl-no-_umul128-on-aarch64.patch.1
@@ -0,0 +1,58 @@
+From 98f9a401c3964c7ff0e6ca048685e28a2a6401d4 Mon Sep 17 00:00:00 2001
+From: Hubert Kario <hkario@redhat.com>
+Date: Wed, 8 Feb 2023 14:13:24 +0100
+Subject: [PATCH] rsa: add msvc intrinsic for non x64 platforms
+
+_umul128() is x86_64 (x64) only, while __umulh() works everywhere, but
+doesn't generate optimal code on x64
+
+Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
+Reviewed-by: Paul Dale <pauli@openssl.org>
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/20244)
+
+(cherry picked from commit 075652f224479dad2e64b92e791b296177af8705)
+---
+ crypto/bn/rsa_sup_mul.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/bn/rsa_sup_mul.c b/crypto/bn/rsa_sup_mul.c
+index 0e0d02e1946e..3b57161b4589 100644
+--- a/crypto/bn/rsa_sup_mul.c
++++ b/crypto/bn/rsa_sup_mul.c
+@@ -110,12 +110,34 @@ static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
+ *lo = (limb_t)t;
+ }
+ #elif (BN_BYTES == 8) && (defined _MSC_VER)
+-/* https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-170 */
++# if defined(_M_X64)
++/*
++ * on x86_64 (x64) we can use the _umul128 intrinsic to get one `mul`
++ * instruction to get both high and low 64 bits of the multiplication.
++ * https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-140
++ */
++#include <intrin.h>
+ #pragma intrinsic(_umul128)
+ static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
+ {
+ *lo = _umul128(a, b, hi);
+ }
++# elif defined(_M_ARM64) || defined (_M_IA64)
++/*
++ * We can't use the __umulh() on x86_64 as then msvc generates two `mul`
++ * instructions; so use this more portable intrinsic on platforms that
++ * don't support _umul128 (like aarch64 (ARM64) or ia64)
++ * https://learn.microsoft.com/en-us/cpp/intrinsics/umulh?view=msvc-140
++ */
++#include <intrin.h>
++static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
++{
++ *lo = a * b;
++ *hi = __umulh(a, b);
++}
++# else
++# error Only x64, ARM64 and IA64 supported.
++# endif /* defined(_M_X64) */
+ #else
+ /*
+ * if the compiler doesn't have either a 128bit data type nor a "return
diff --git a/external/openssl/openssl-no-multilib.patch.0 b/external/openssl/openssl-no-multilib.patch.0
new file mode 100644
index 000000000..3d0083ed4
--- /dev/null
+++ b/external/openssl/openssl-no-multilib.patch.0
@@ -0,0 +1,38 @@
+--- Configure.orig 2020-04-21 14:22:39.000000000 +0200
++++ Configure 2020-07-07 17:25:19.256297500 +0200
+@@ -24,7 +24,7 @@
+ my $orig_death_handler = $SIG{__DIE__};
+ $SIG{__DIE__} = \&death_handler;
+
+-my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
++my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [no-multilib] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
+
+ # Options:
+ #
+@@ -59,6 +59,7 @@
+ # If disabled, it also disables shared and dynamic-engine.
+ # no-asm do not use assembler
+ # no-egd do not compile support for the entropy-gathering daemon APIs
++# no-multilib exclude multilib identifier from library name
+ # [no-]zlib [don't] compile support for zlib compression.
+ # zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
+ # library and will be loaded in run-time by the OpenSSL library.
+@@ -393,6 +394,7 @@
+ "mdc2",
+ "msan",
+ "multiblock",
++ "multilib",
+ "nextprotoneg",
+ "pinshared",
+ "ocb",
+@@ -1770,6 +1772,10 @@
+ if (-f catfile($srcdir, "test", $_, "build.info"));
+ }
+
++ if ($disabled{"multilib"}) {
++ $target{"multilib"} = "";
++ }
++
+ $config{build_infos} = [ ];
+
+ my %ordinals = ();
diff --git a/external/pdfium/AndroidNDK19.patch.1 b/external/pdfium/AndroidNDK19.patch.1
new file mode 100644
index 000000000..f0d926f55
--- /dev/null
+++ b/external/pdfium/AndroidNDK19.patch.1
@@ -0,0 +1,16 @@
+diff -Naur pdfium.org/third_party/base/allocator/partition_allocator/page_allocator_internals_posix.h pdfium/third_party/base/allocator/partition_allocator/page_allocator_internals_posix.h
+--- pdfium.org/third_party/base/allocator/partition_allocator/page_allocator_internals_posix.h 2021-05-05 23:01:25.705057178 +0200
++++ pdfium/third_party/base/allocator/partition_allocator/page_allocator_internals_posix.h 2021-05-05 23:06:52.194081762 +0200
+@@ -15,6 +15,12 @@
+ #endif
+ #if BUILDFLAG(IS_ANDROID)
+ #include <sys/prctl.h>
++#ifndef PR_SET_VMA
++#define PR_SET_VMA 0x53564d41
++#endif
++#ifndef PR_SET_VMA_ANON_NAME
++#define PR_SET_VMA_ANON_NAME 0
++#endif
+ #endif
+ #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+ #include <sys/resource.h>
diff --git a/external/pdfium/Library_pdfium.mk b/external/pdfium/Library_pdfium.mk
new file mode 100644
index 000000000..57f676934
--- /dev/null
+++ b/external/pdfium/Library_pdfium.mk
@@ -0,0 +1,733 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,pdfium))
+
+$(eval $(call gb_Library_use_unpacked,pdfium,pdfium))
+
+$(eval $(call gb_Library_set_warnings_disabled,pdfium))
+
+$(eval $(call gb_Library_set_precompiled_header,pdfium,external/pdfium/inc/pch/precompiled_pdfium))
+
+$(eval $(call gb_Library_set_include,pdfium,\
+ -I$(call gb_UnpackedTarball_get_dir,pdfium) \
+ -I$(call gb_UnpackedTarball_get_dir,pdfium)/third_party \
+ -I$(call gb_UnpackedTarball_get_dir,pdfium)/third_party/agg23 \
+ $(if $(filter TRUE,$(SYSTEM_ABSEIL)),$(ABSEIL_CFLAGS),-I$(call gb_UnpackedTarball_get_dir,pdfium)/third_party/abseil-cpp) \
+ $(if $(filter TRUE,$(SYSTEM_OPENJPEG2)),$(OPENJPEG2_CFLAGS)) \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,pdfium,\
+ -DFPDF_IMPLEMENTATION \
+ -DUSE_SYSTEM_LCMS2 \
+ -DUSE_SYSTEM_LIBJPEG \
+ -DUSE_SYSTEM_ZLIB \
+ -DUSE_SYSTEM_ICUUC \
+ -DMEMORY_TOOL_REPLACES_ALLOCATOR \
+ -DUNICODE \
+ -DWIN32_LEAN_AND_MEAN \
+ -DCOMPONENT_BUILD \
+))
+ifeq ($(SYSTEM_OPENJPEG2),TRUE)
+$(eval $(call gb_Library_add_defs,pdfium,\
+ -DUSE_SYSTEM_LIBOPENJPEG2 \
+))
+endif
+
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,pdfium,cpp))
+
+# pdfium
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_annot \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_annotiteration \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_baannot \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_formfillenvironment \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_pageview \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_widget \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_dataavail \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_ext \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_flatten \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_progressive \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_searchex \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_structtree \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_sysfontinfo \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_transformpage \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_annotiterator \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_customaccess \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_filewriteadapter \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_helpers \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_annot \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_attachment \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_catalog \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_doc \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_editimg \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_editpage \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_editpath \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_edittext \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_formfill \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_save \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_text \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_view \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_pauseadapter \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_interactiveform \
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_renderpage \
+ UnpackedTarball/pdfium/fpdfsdk/fpdf_signature \
+ UnpackedTarball/pdfium/constants/annotation_common \
+ UnpackedTarball/pdfium/constants/appearance \
+ UnpackedTarball/pdfium/constants/form_fields \
+ UnpackedTarball/pdfium/constants/page_object \
+ UnpackedTarball/pdfium/constants/stream_dict_common \
+ UnpackedTarball/pdfium/constants/transparency \
+ UnpackedTarball/pdfium/constants/font_encodings \
+))
+
+# fdrm
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fdrm/fx_crypt \
+ UnpackedTarball/pdfium/core/fdrm/fx_crypt_aes \
+ UnpackedTarball/pdfium/core/fdrm/fx_crypt_sha \
+))
+
+# formfiller
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_checkbox \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_combobox \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_formfield \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_interactiveformfiller \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_listbox \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_pushbutton \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_radiobutton \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_textfield \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_button \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_textobject \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_fieldaction \
+ UnpackedTarball/pdfium/fpdfsdk/formfiller/cffl_perwindowdata \
+))
+
+# fpdfapi
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/Adobe-CNS1-UCS2_5 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/B5pc-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/B5pc-V_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/CNS-EUC-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/CNS-EUC-V_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/ETen-B5-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/ETen-B5-V_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/ETenms-B5-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/ETenms-B5-V_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/HKscs-B5-H_5 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/HKscs-B5-V_5 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/UniCNS-UCS2-H_3 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/UniCNS-UCS2-V_3 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/UniCNS-UTF16-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/CNS1/cmaps_cns1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/Adobe-GB1-UCS2_5 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GB-EUC-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GB-EUC-V_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBK-EUC-H_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBK-EUC-V_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBK2K-H_5 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBK2K-V_5 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBKp-EUC-H_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBKp-EUC-V_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBpc-EUC-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/GBpc-EUC-V_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/UniGB-UCS2-H_4 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/UniGB-UCS2-V_4 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/GB1/cmaps_gb1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/83pv-RKSJ-H_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/90ms-RKSJ-H_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/90ms-RKSJ-V_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/90msp-RKSJ-H_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/90msp-RKSJ-V_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/90pv-RKSJ-H_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/Add-RKSJ-H_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/Add-RKSJ-V_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/Adobe-Japan1-UCS2_4 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/EUC-H_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/EUC-V_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/Ext-RKSJ-H_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/Ext-RKSJ-V_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/H_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/UniJIS-UCS2-HW-H_4 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/UniJIS-UCS2-HW-V_4 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/UniJIS-UCS2-H_4 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/UniJIS-UCS2-V_4 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/V_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Japan1/cmaps_japan1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/Adobe-Korea1-UCS2_2 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSC-EUC-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSC-EUC-V_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSCms-UHC-HW-H_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSCms-UHC-HW-V_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSCms-UHC-H_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSCms-UHC-V_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/KSCpc-EUC-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/UniKS-UCS2-H_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/UniKS-UCS2-V_1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/UniKS-UTF16-H_0 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/Korea1/cmaps_korea1 \
+ UnpackedTarball/pdfium/core/fpdfapi/cmaps/fpdf_cmaps \
+ UnpackedTarball/pdfium/core/fpdfapi/edit/cpdf_pagecontentgenerator \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_cidfont \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_font \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_fontencoding \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_simplefont \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_truetypefont \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_type1font \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_type3char \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_type3font \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_allstates \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_clippath \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_color \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_colorspace \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_colorstate \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_contentmarks \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_contentmarkitem \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_contentparser \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_docpagedata \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_form \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_formobject \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_generalstate \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_graphicstates \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_image \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_imageobject \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_meshstream \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_page \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_pagemodule \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_pageobject \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_pageobjectholder \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_path \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_pathobject \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_pattern \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_shadingobject \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_shadingpattern \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_streamcontentparser \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_streamparser \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_textobject \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_textstate \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_tilingpattern \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cfdf_document \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_array \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_boolean \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_crypto_handler \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_data_avail \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_dictionary \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_document \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_hint_tables \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_indirect_object_holder \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_linearized_header \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_name \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_null \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_number \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_object \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_parser \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_reference \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_security_handler \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_simple_parser \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_stream \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_stream_acc \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_string \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_syntax_parser \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/fpdf_parser_decode \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/fpdf_parser_utility \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_object_walker \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_read_validator \
+ UnpackedTarball/pdfium/core/fpdfapi/render/charposlist \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_devicebuffer \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_docrenderdata \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_imagecacheentry \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_imageloader \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_imagerenderer \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_pagerendercache \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_progressiverenderer \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_rendercontext \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_renderoptions \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_renderstatus \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_scaledrenderbuffer \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_textrenderer \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_type3cache \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_type3glyphmap \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_rendershading \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_rendertiling \
+ UnpackedTarball/pdfium/core/fpdfapi/edit/cpdf_creator \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_encryptor \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_flateencoder \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cfx_cttgsubtable \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cfx_stockfontarray \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_cid2unicodemap \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_cmap \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_cmapparser \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_fontglobals \
+ UnpackedTarball/pdfium/core/fpdfapi/font/cpdf_tounicodemap \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_devicecs \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_expintfunc \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_function \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_iccprofile \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_patterncs \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_psengine \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_psfunc \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_sampledfunc \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_stitchfunc \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_object_avail \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_page_object_avail \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_cross_ref_avail \
+ UnpackedTarball/pdfium/core/fpdfapi/edit/cpdf_pagecontentmanager \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_transparency \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_dib \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_object_stream \
+ UnpackedTarball/pdfium/core/fpdfapi/parser/cpdf_cross_ref_table \
+ UnpackedTarball/pdfium/core/fpdfapi/edit/cpdf_stringarchivestream \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_occontext \
+ UnpackedTarball/pdfium/core/fpdfapi/edit/cpdf_contentstream_write_utils \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_annotcontext \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_pagerendercontext \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_transferfuncdib \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_transferfunc \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_basedcs \
+ UnpackedTarball/pdfium/core/fpdfapi/page/cpdf_indexedcs \
+))
+
+# fpdfdoc
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_aaction \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_action \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_annot \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_annotlist \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_apsettings \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_bookmark \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_bookmarktree \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_defaultappearance \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_dest \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_filespec \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_formcontrol \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_formfield \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_iconfit \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_interactiveform \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_link \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_linklist \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_metadata \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_nametree \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_numbertree \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_pagelabel \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_viewerpreferences \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpvt_fontmap \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpvt_wordinfo \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_structelement \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_structtree \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_color_utils \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_icon \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_bafontmap \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpdf_generateap \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpvt_section \
+ UnpackedTarball/pdfium/core/fpdfdoc/cpvt_variabletext \
+))
+
+# fpdftext
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fpdftext/cpdf_linkextract \
+ UnpackedTarball/pdfium/core/fpdftext/cpdf_textpage \
+ UnpackedTarball/pdfium/core/fpdftext/cpdf_textpagefind \
+ UnpackedTarball/pdfium/core/fpdftext/unicodenormalizationdata \
+))
+
+# fxcodec
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fxcodec/fx_codec \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_ArithDecoder \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_ArithIntDecoder \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_BitStream \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_Context \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_GrdProc \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_GrrdProc \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_HtrdProc \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_HuffmanDecoder \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_HuffmanTable \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_Image \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_PatternDict \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_PddProc \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_SddProc \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_Segment \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_SymbolDict \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_TrdProc \
+ UnpackedTarball/pdfium/core/fxcodec/gif/cfx_gif \
+ UnpackedTarball/pdfium/core/fxcodec/gif/lzw_decompressor \
+ UnpackedTarball/pdfium/core/fxcodec/cfx_codec_memory \
+ UnpackedTarball/pdfium/core/fxcodec/fax/faxmodule \
+ UnpackedTarball/pdfium/core/fxcodec/scanlinedecoder \
+ UnpackedTarball/pdfium/core/fxcodec/jpeg/jpegmodule \
+ UnpackedTarball/pdfium/core/fxcodec/jpx/cjpx_decoder \
+ UnpackedTarball/pdfium/core/fxcodec/jpx/jpx_decode_utils \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/JBig2_DocumentContext \
+ UnpackedTarball/pdfium/core/fxcodec/basic/basicmodule \
+ UnpackedTarball/pdfium/core/fxcodec/flate/flatemodule \
+ UnpackedTarball/pdfium/core/fxcodec/icc/icc_transform \
+ UnpackedTarball/pdfium/core/fxcodec/jbig2/jbig2_decoder \
+ UnpackedTarball/pdfium/core/fxcodec/jpeg/jpeg_common \
+))
+
+# fxcrt
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fxcrt/cfx_memorystream \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_seekablestreamproxy \
+ UnpackedTarball/pdfium/core/fxcrt/fx_bidi \
+ UnpackedTarball/pdfium/core/fxcrt/fx_coordinates \
+ UnpackedTarball/pdfium/core/fxcrt/fx_extension \
+ UnpackedTarball/pdfium/core/fxcrt/fx_memory \
+ UnpackedTarball/pdfium/core/fxcrt/fx_stream \
+ UnpackedTarball/pdfium/core/fxcrt/fx_system \
+ UnpackedTarball/pdfium/core/fxcrt/fx_unicode \
+ UnpackedTarball/pdfium/core/fxcrt/xml/cfx_xmldocument \
+ UnpackedTarball/pdfium/core/fxcrt/xml/cfx_xmlelement \
+ UnpackedTarball/pdfium/core/fxcrt/xml/cfx_xmlparser \
+ UnpackedTarball/pdfium/core/fxcrt/xml/cfx_xmlnode \
+ UnpackedTarball/pdfium/core/fxcrt/xml/cfx_xmlinstruction \
+ UnpackedTarball/pdfium/core/fxcrt/xml/cfx_xmltext \
+ UnpackedTarball/pdfium/core/fxcrt/xml/cfx_xmlchardata \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_csscolorvalue \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_csscomputedstyle \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_csscustomproperty \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssdeclaration \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssenumvalue \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssnumbervalue \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_csspropertyholder \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssrulecollection \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssselector \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssstringvalue \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssstylerule \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssstyleselector \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssstylesheet \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_csssyntaxparser \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssvalue \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssvaluelist \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssvaluelistparser \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssinputtextbuf \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssoutputtextbuf \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_datetime \
+ UnpackedTarball/pdfium/core/fxcrt/bytestring \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_binarybuf \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_bitstream \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_utf8decoder \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_widetextbuf \
+ UnpackedTarball/pdfium/core/fxcrt/fx_random \
+ UnpackedTarball/pdfium/core/fxcrt/fx_string \
+ UnpackedTarball/pdfium/core/fxcrt/widestring \
+ UnpackedTarball/pdfium/core/fxcrt/css/cfx_cssdata \
+ UnpackedTarball/pdfium/core/fxcrt/fx_codepage \
+ UnpackedTarball/pdfium/core/fxcrt/fx_number \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_utf8encoder \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_readonlymemorystream \
+ UnpackedTarball/pdfium/core/fxcrt/observed_ptr \
+ UnpackedTarball/pdfium/core/fxcrt/string_data_template \
+))
+
+# fxge
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_bitmapcomposer \
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_bitmapstorer \
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_dibextractor \
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_dibitmap \
+ UnpackedTarball/pdfium/core/fxge/cfx_drawutils \
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_imagerenderer \
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_imagestretcher \
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_imagetransformer \
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_scanlinecompositor \
+ UnpackedTarball/pdfium/core/fxge/dib/cstretchengine \
+ UnpackedTarball/pdfium/core/fxge/dib/fx_dib \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitDingbats \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitFixed \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitFixedBold \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitFixedBoldItalic \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitFixedItalic \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSans \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSansBold \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSansBoldItalic \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSansItalic \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSansMM \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSerif \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSerifBold \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSerifBoldItalic \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSerifItalic \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSerifMM \
+ UnpackedTarball/pdfium/core/fxge/fontdata/chromefontdata/FoxitSymbol \
+ UnpackedTarball/pdfium/core/fxge/freetype/fx_freetype \
+ UnpackedTarball/pdfium/core/fxge/renderdevicedriver_iface \
+ UnpackedTarball/pdfium/core/fxge/agg/fx_agg_driver \
+ UnpackedTarball/pdfium/core/fxge/cfx_cliprgn \
+ UnpackedTarball/pdfium/core/fxge/cfx_color \
+ UnpackedTarball/pdfium/core/fxge/cfx_glyphcache \
+ UnpackedTarball/pdfium/core/fxge/cfx_folderfontinfo \
+ UnpackedTarball/pdfium/core/fxge/cfx_font \
+ UnpackedTarball/pdfium/core/fxge/cfx_fontcache \
+ UnpackedTarball/pdfium/core/fxge/cfx_fontmapper \
+ UnpackedTarball/pdfium/core/fxge/cfx_fontmgr \
+ UnpackedTarball/pdfium/core/fxge/cfx_gemodule \
+ UnpackedTarball/pdfium/core/fxge/cfx_graphstate \
+ UnpackedTarball/pdfium/core/fxge/cfx_graphstatedata \
+ UnpackedTarball/pdfium/core/fxge/cfx_path \
+ UnpackedTarball/pdfium/core/fxge/cfx_renderdevice \
+ UnpackedTarball/pdfium/core/fxge/cfx_substfont \
+ UnpackedTarball/pdfium/core/fxge/cfx_unicodeencoding \
+ UnpackedTarball/pdfium/core/fxge/cfx_glyphbitmap \
+ UnpackedTarball/pdfium/core/fxge/scoped_font_transform \
+ UnpackedTarball/pdfium/core/fxge/text_glyph_pos \
+ UnpackedTarball/pdfium/core/fxge/fx_font \
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_dibbase \
+ UnpackedTarball/pdfium/core/fxge/dib/cfx_cmyk_to_srgb \
+ UnpackedTarball/pdfium/core/fxge/text_char_pos \
+ UnpackedTarball/pdfium/core/fxge/cfx_face \
+ UnpackedTarball/pdfium/core/fxge/calculate_pitch \
+))
+
+# javascript, build with pdf_enable_v8 disabled.
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/fxjs/cjs_event_context_stub \
+ UnpackedTarball/pdfium/fxjs/cjs_runtimestub \
+ UnpackedTarball/pdfium/fxjs/ijs_runtime \
+))
+
+# pwl
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/fpdfsdk/cpdfsdk_appstream \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_button \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_caret \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_combo_box \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_edit \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_edit_impl \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_sbbutton \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_list_box \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_cbbutton \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_cblistbox \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_list_ctrl \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_scroll_bar \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_special_button \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_timer \
+ UnpackedTarball/pdfium/fpdfsdk/pwl/cpwl_wnd \
+))
+
+# third_party/fx_agg
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/third_party/agg23/agg_curves \
+ UnpackedTarball/pdfium/third_party/agg23/agg_path_storage \
+ UnpackedTarball/pdfium/third_party/agg23/agg_rasterizer_scanline_aa \
+ UnpackedTarball/pdfium/third_party/agg23/agg_vcgen_dash \
+ UnpackedTarball/pdfium/third_party/agg23/agg_vcgen_stroke \
+))
+
+ifneq ($(SYSTEM_ABSEIL),TRUE)
+# third_party/abseil-cpp
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/third_party/abseil-cpp/absl/types/bad_optional_access \
+))
+endif
+
+ifneq ($(SYSTEM_OPENJPEG2),TRUE)
+# third_party/fx_libopenjpeg
+$(eval $(call gb_Library_add_generated_cobjects,pdfium,\
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/bio \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/cio \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/dwt \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/event \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/function_list \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/image \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/invert \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/j2k \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/jp2 \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/mct \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/mqc \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/openjpeg \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/opj_clock \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/pi \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/thread \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/t1 \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/t2 \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/tcd \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/tgt \
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/sparse_array \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/third_party/libopenjpeg20/opj_malloc \
+))
+endif
+
+# pdfium_base
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/address_space_randomization \
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/page_allocator \
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/spin_lock \
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/partition_alloc \
+ UnpackedTarball/pdfium/third_party/base/debug/alias \
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/oom_callback \
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/partition_bucket \
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/partition_oom \
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/partition_page \
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/partition_root_base \
+ UnpackedTarball/pdfium/third_party/base/allocator/partition_allocator/random \
+ UnpackedTarball/pdfium/third_party/base/memory/aligned_memory \
+))
+
+# skia_shared
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/third_party/skia_shared/SkFloatToDecimal \
+))
+
+$(eval $(call gb_Library_use_externals,pdfium,\
+ libjpeg \
+ lcms2 \
+ zlib \
+ icu_headers \
+ icuuc \
+))
+
+ifneq (,$(filter LINUX ANDROID,$(OS)))
+$(eval $(call gb_Library_add_libs,pdfium,\
+ -ldl \
+ -lrt \
+))
+
+ifeq ($(SYSTEM_OPENJPEG2),TRUE)
+$(eval $(call gb_Library_add_libs,pdfium,\
+ $(OPENJPEG2_LIBS) \
+))
+endif
+
+ifeq ($(SYSTEM_ABSEIL),TRUE)
+$(eval $(call gb_Library_add_libs,pdfium,\
+ $(ABSEIL_LIBS) \
+))
+endif
+
+$(eval $(call gb_Library_use_external,pdfium,freetype))
+$(eval $(call gb_Library_add_defs,pdfium,\
+ -DDEFINE_PS_TABLES_DATA \
+))
+
+else
+$(eval $(call gb_Library_set_include,pdfium,\
+ -I$(call gb_UnpackedTarball_get_dir,pdfium)/third_party/freetype/include/ \
+ -I$(call gb_UnpackedTarball_get_dir,pdfium)/third_party/freetype/src/include/ \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,pdfium,\
+ -DFT2_BUILD_LIBRARY \
+ -DFT_CONFIG_MODULES_H='<freetype-custom-config/ftmodule.h>' \
+ -DFT_CONFIG_OPTIONS_H='<freetype-custom-config/ftoption.h>' \
+))
+
+# third_party/freetype
+$(eval $(call gb_Library_add_generated_cobjects,pdfium,\
+ UnpackedTarball/pdfium/third_party/freetype/src/src/base/ftbase \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/base/ftbitmap \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/base/ftglyph \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/base/ftinit \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/base/ftmm \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/base/ftsystem \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/cff/cff \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/cid/type1cid \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/psaux/psaux \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/pshinter/pshinter \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/psnames/psmodule \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/raster/raster \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/sfnt/sfnt \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/smooth/smooth \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/truetype/truetype \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/type1/type1 \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/base/ftdebug \
+ UnpackedTarball/pdfium/third_party/freetype/src/src/base/ftfstype \
+))
+endif
+
+ifneq ($(OS),WNT)
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fxcrt/cfx_fileaccess_posix \
+ UnpackedTarball/pdfium/core/fxcrt/fx_folder_posix \
+))
+endif
+
+ifeq ($(OS),WNT)
+# fxge
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fxge/win32/cfx_psrenderer \
+ UnpackedTarball/pdfium/core/fxge/win32/cpsoutput \
+ UnpackedTarball/pdfium/core/fxge/win32/cgdi_device_driver \
+ UnpackedTarball/pdfium/core/fxge/win32/cgdi_display_driver \
+ UnpackedTarball/pdfium/core/fxge/win32/cgdi_plus_ext \
+ UnpackedTarball/pdfium/core/fxge/win32/cgdi_printer_driver \
+ UnpackedTarball/pdfium/core/fxge/win32/cps_printer_driver \
+ UnpackedTarball/pdfium/core/fxge/win32/ctext_only_printer_driver \
+ UnpackedTarball/pdfium/core/fxge/win32/cwin32_platform \
+ UnpackedTarball/pdfium/core/fxge/win32/cfx_psfonttracker \
+ UnpackedTarball/pdfium/core/fxge/cfx_windowsrenderdevice \
+ UnpackedTarball/pdfium/core/fxcrt/cfx_fileaccess_windows \
+ UnpackedTarball/pdfium/core/fxcrt/fx_folder_windows \
+ UnpackedTarball/pdfium/third_party/base/win/win_util \
+ UnpackedTarball/pdfium/core/fpdfapi/render/cpdf_windowsrenderdevice \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,pdfium,\
+ gdi32 \
+))
+
+$(eval $(call gb_Library_add_defs,pdfium,\
+ -DWIN32 \
+))
+endif
+
+ifeq ($(OS),MACOSX)
+# fxge
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fxge/apple/fx_apple_platform \
+ UnpackedTarball/pdfium/core/fxge/apple/fx_apple_impl \
+ UnpackedTarball/pdfium/core/fxge/apple/fx_quartz_device \
+))
+
+$(eval $(call gb_Library_use_system_darwin_frameworks,pdfium,\
+ AppKit \
+ CoreFoundation \
+))
+endif
+
+ifeq ($(OS),iOS)
+# fxge
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fxge/apple/fx_apple_platform \
+ UnpackedTarball/pdfium/core/fxge/apple/fx_apple_impl \
+ UnpackedTarball/pdfium/core/fxge/apple/fx_quartz_device \
+))
+
+$(eval $(call gb_Library_use_system_darwin_frameworks,pdfium,\
+ CoreGraphics \
+ CoreFoundation \
+))
+endif
+
+ifeq ($(OS),ANDROID)
+# fxge
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fxge/android/cfpf_skiadevicemodule \
+ UnpackedTarball/pdfium/core/fxge/android/cfpf_skiafont \
+ UnpackedTarball/pdfium/core/fxge/android/cfpf_skiafontmgr \
+ UnpackedTarball/pdfium/core/fxge/android/cfx_androidfontinfo \
+ UnpackedTarball/pdfium/core/fxge/android/fx_android_impl \
+ UnpackedTarball/pdfium/core/fxge/android/cfpf_skiapathfont \
+))
+endif
+
+ifeq ($(OS),LINUX)
+# fxge
+$(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
+ UnpackedTarball/pdfium/core/fxge/linux/fx_linux_impl \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/pdfium/Makefile b/external/pdfium/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/pdfium/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/pdfium/Module_pdfium.mk b/external/pdfium/Module_pdfium.mk
new file mode 100644
index 000000000..3a52d5bd0
--- /dev/null
+++ b/external/pdfium/Module_pdfium.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,pdfium))
+
+$(eval $(call gb_Module_add_targets,pdfium,\
+ Library_pdfium \
+ UnpackedTarball_pdfium \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/pdfium/README b/external/pdfium/README
new file mode 100644
index 000000000..2be9e8f11
--- /dev/null
+++ b/external/pdfium/README
@@ -0,0 +1,17 @@
+External package containing pdfium.
+
+"Insert -> Picture -> From File..." uses this library when a PDF file is
+selected.
+
+https://pdfium.googlesource.com/pdfium/
+
+How to update the tarball:
+
+version=$(git for-each-ref|grep chromium/|tail -n 1|sed 's|.*/||')
+git checkout --track origin/chromium/$version
+gclient sync
+git archive --prefix=pdfium/ --format=tar origin/chromium/${version} > pdfium-${version}.tar
+(cd ..; tar --append --file pdfium/pdfium-${version}.tar pdfium/third_party/freetype/src/include/ pdfium/third_party/freetype/src/src/)
+(cd ..; tar --append --file pdfium/pdfium-${version}.tar pdfium/third_party/abseil-cpp/absl/)
+(cd ..; tar --append --file pdfium/pdfium-${version}.tar pdfium/build/build_config.h pdfium/build/buildflag.h)
+bzip2 pdfium-${version}.tar
diff --git a/external/pdfium/UnpackedTarball_pdfium.mk b/external/pdfium/UnpackedTarball_pdfium.mk
new file mode 100644
index 000000000..06b94e4d0
--- /dev/null
+++ b/external/pdfium/UnpackedTarball_pdfium.mk
@@ -0,0 +1,61 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+pdfium_patches :=
+pdfium_patches += ubsan.patch
+# Fixes build on our baseline.
+pdfium_patches += build.patch.1
+# Avoids Windows 8 build dependency.
+pdfium_patches += windows7.patch.1
+pdfium_patches += c++20-comparison.patch
+# Use CoreGraphics.h instead of Carbon.h
+pdfium_patches += cg-instead-of-carbon.patch.1
+# Android NDK 19 - that is known to work well - does not have 2 defines
+pdfium_patches += AndroidNDK19.patch.1
+
+# Work around <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94141> "c++20 rewritten operator==
+# recursive call mixing friend and external operators for template class" in GCC with
+# --with-latest-c++:
+pdfium_patches += gcc-c++20-comparison.patch
+
+pdfium_patches += include.patch
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,pdfium))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,pdfium,$(PDFIUM_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,pdfium,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,pdfium,\
+ $(foreach patch,$(pdfium_patches),external/pdfium/$(patch)) \
+))
+
+$(eval $(call gb_UnpackedTarball_set_post_action,pdfium,\
+ mv third_party/bigint/BigInteger.cc third_party/bigint/BigInteger.cpp && \
+ mv third_party/bigint/BigIntegerUtils.cc third_party/bigint/BigIntegerUtils.cpp && \
+ mv third_party/bigint/BigUnsigned.cc third_party/bigint/BigUnsigned.cpp && \
+ mv third_party/bigint/BigUnsignedInABase.cc third_party/bigint/BigUnsignedInABase.cpp && \
+ mv third_party/base/allocator/partition_allocator/address_space_randomization.cc third_party/base/allocator/partition_allocator/address_space_randomization.cpp && \
+ mv third_party/base/allocator/partition_allocator/page_allocator.cc third_party/base/allocator/partition_allocator/page_allocator.cpp && \
+ mv third_party/base/allocator/partition_allocator/partition_alloc.cc third_party/base/allocator/partition_allocator/partition_alloc.cpp && \
+ mv third_party/base/allocator/partition_allocator/spin_lock.cc third_party/base/allocator/partition_allocator/spin_lock.cpp && \
+ mv third_party/base/debug/alias.cc third_party/base/debug/alias.cpp && \
+ mv third_party/base/allocator/partition_allocator/oom_callback.cc third_party/base/allocator/partition_allocator/oom_callback.cpp && \
+ mv third_party/base/allocator/partition_allocator/partition_bucket.cc third_party/base/allocator/partition_allocator/partition_bucket.cpp && \
+ mv third_party/base/allocator/partition_allocator/partition_oom.cc third_party/base/allocator/partition_allocator/partition_oom.cpp && \
+ mv third_party/base/allocator/partition_allocator/partition_page.cc third_party/base/allocator/partition_allocator/partition_page.cpp && \
+ mv third_party/base/allocator/partition_allocator/partition_root_base.cc third_party/base/allocator/partition_allocator/partition_root_base.cpp && \
+ mv third_party/base/allocator/partition_allocator/random.cc third_party/base/allocator/partition_allocator/random.cpp && \
+ mv third_party/base/memory/aligned_memory.cc third_party/base/memory/aligned_memory.cpp && \
+ mv third_party/base/win/win_util.cc third_party/base/win/win_util.cpp && \
+ mv third_party/libopenjpeg20/opj_malloc.cc third_party/libopenjpeg20/opj_malloc.cpp && \
+ mv third_party/abseil-cpp/absl/types/bad_optional_access.cc third_party/abseil-cpp/absl/types/bad_optional_access.cpp \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/pdfium/build.patch.1 b/external/pdfium/build.patch.1
new file mode 100644
index 000000000..46ea17fbc
--- /dev/null
+++ b/external/pdfium/build.patch.1
@@ -0,0 +1,147 @@
+-*- Mode: diff -*-
+diff --git a/core/fpdfdoc/cpdf_metadata.cpp b/core/fpdfdoc/cpdf_metadata.cpp
+index 323de4ffc..f11a0b0ad 100644
+--- a/core/fpdfdoc/cpdf_metadata.cpp
++++ b/core/fpdfdoc/cpdf_metadata.cpp
+@@ -74,7 +74,7 @@ std::vector<UnsupportedFeature> CPDF_Metadata::CheckForSharedForm() const {
+ CFX_XMLParser parser(stream);
+ std::unique_ptr<CFX_XMLDocument> doc = parser.Parse();
+ if (!doc)
+- return {};
++ return std::vector<UnsupportedFeature>();
+
+ std::vector<UnsupportedFeature> unsupported;
+ CheckForSharedFormInternal(doc->GetRoot(), &unsupported);
+diff --git a/third_party/base/span.h b/third_party/base/span.h
+index 0fb627ba8..f71c362e2 100644
+--- a/third_party/base/span.h
++++ b/third_party/base/span.h
+@@ -214,7 +214,7 @@ class span {
+ // Conversions from spans of compatible types: this allows a span<T> to be
+ // seamlessly used as a span<const T>, but not the other way around.
+ template <typename U, typename = internal::EnableIfLegalSpanConversion<U, T>>
+- constexpr span(const span<U>& other) : span(other.data(), other.size()) {}
++ span(const span<U>& other) : span(other.data(), other.size()) {}
+ span& operator=(const span& other) noexcept = default;
+ ~span() noexcept {
+ if (!size_) {
+diff --git a/third_party/base/span.h b/third_party/base/span.h
+index 0fb627ba8..dda1fc8bc 100644
+--- a/third_party/base/span.h
++++ b/third_party/base/span.h
+@@ -204,7 +204,7 @@ class span {
+ // size()|.
+ template <typename Container,
+ typename = internal::EnableIfSpanCompatibleContainer<Container, T>>
+- constexpr span(Container& container)
++ span(Container& container)
+ : span(container.data(), container.size()) {}
+ template <
+ typename Container,
+diff --git a/core/fxcodec/jpx/cjpx_decoder.cpp b/core/fxcodec/jpx/cjpx_decoder.cpp
+index d8875786c..bc019ebe1 100644
+--- a/core/fxcodec/jpx/cjpx_decoder.cpp
++++ b/core/fxcodec/jpx/cjpx_decoder.cpp
+@@ -73,7 +73,7 @@ absl::optional<OpjImageRgbData> alloc_rgb(size_t size) {
+ if (!data.b)
+ return absl::nullopt;
+
+- return data;
++ return std::move(data);
+ }
+
+ void sycc_to_rgb(int offset,
+diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
+index 8b3a72700..ea1db23f4 100644
+--- a/core/fxge/cfx_font.cpp
++++ b/core/fxge/cfx_font.cpp
+@@ -47,25 +47,9 @@ struct OUTLINE_PARAMS {
+ // TODO(crbug.com/pdfium/1400): When FT_Done_MM_Var() is more likely to be
+ // available to all users in the future, remove FreeMMVar() and use
+ // FT_Done_MM_Var() directly.
+-//
+-// Use weak symbols to check if FT_Done_MM_Var() is available at runtime.
+-#if !BUILDFLAG(IS_WIN)
+-extern "C" __attribute__((weak)) decltype(FT_Done_MM_Var) FT_Done_MM_Var;
+-#endif
+
+ void FreeMMVar(FXFT_FaceRec* rec, FXFT_MM_VarPtr variation_desc) {
+-#if BUILDFLAG(IS_WIN)
+- // Assume `use_system_freetype` GN var is never set on Windows.
+- constexpr bool has_ft_done_mm_var_func = true;
+-#else
+- static const bool has_ft_done_mm_var_func = !!FT_Done_MM_Var;
+-#endif
+- if (has_ft_done_mm_var_func) {
+- FT_Done_MM_Var(CFX_GEModule::Get()->GetFontMgr()->GetFTLibrary(),
+- variation_desc);
+- } else {
+ FXFT_Free(rec, variation_desc);
+- }
+ }
+
+ FX_RECT FXRectFromFTPos(FT_Pos left, FT_Pos top, FT_Pos right, FT_Pos bottom) {
+diff --git a/third_party/base/numerics/safe_conversions_impl.h b/third_party/base/numerics/safe_conversions_impl.h
+index 4d8a7b7d9..d14c6dc06 100644
+--- a/third_party/base/numerics/safe_conversions_impl.h
++++ b/third_party/base/numerics/safe_conversions_impl.h
+@@ -88,7 +88,7 @@ constexpr typename std::make_unsigned<T>::type SafeUnsignedAbs(T value) {
+
+ // TODO(jschuh): Switch to std::is_constant_evaluated() once C++20 is supported.
+ // Alternately, the usage could be restructured for "consteval if" in C++23.
+-#define IsConstantEvaluated() (__builtin_is_constant_evaluated())
++#define IsConstantEvaluated() (false)
+
+ // TODO(jschuh): Debug builds don't reliably propagate constants, so we restrict
+ // some accelerated runtime paths to release builds until this can be forced
+--- pdfium/core/fpdfapi/font/cpdf_cidfont.cpp.orig 2022-05-20 09:25:52.066728467 +0000
++++ pdfium/core/fpdfapi/font/cpdf_cidfont.cpp 2022-05-20 09:25:56.146736531 +0000
+@@ -738,7 +738,7 @@
+ uint32_t maccode = CharCodeFromUnicodeForFreetypeEncoding(
+ FT_ENCODING_APPLE_ROMAN, name_unicode);
+ index = maccode ? FT_Get_Char_Index(face, maccode)
+- : FT_Get_Name_Index(face, name);
++ : FT_Get_Name_Index(face, const_cast<char*>(name));
+ }
+ if (index == 0 || index == 0xffff)
+ return charcode ? static_cast<int>(charcode) : -1;
+--- pdfium/core/fpdfapi/font/cpdf_type1font.cpp.orig 2022-05-20 09:26:59.090862058 +0000
++++ pdfium/core/fpdfapi/font/cpdf_type1font.cpp 2022-05-20 09:27:33.810932435 +0000
+@@ -260,7 +260,7 @@
+ static_cast<uint32_t>(charcode));
+ if (name) {
+ m_Encoding.SetUnicode(charcode, UnicodeFromAdobeName(name));
+- m_GlyphIndex[charcode] = FT_Get_Name_Index(m_Font.GetFaceRec(), name);
++ m_GlyphIndex[charcode] = FT_Get_Name_Index(m_Font.GetFaceRec(), const_cast<char*>(name));
+ } else {
+ m_GlyphIndex[charcode] = FT_Get_Char_Index(
+ m_Font.GetFaceRec(), static_cast<uint32_t>(charcode));
+@@ -291,7 +291,7 @@
+ continue;
+
+ m_Encoding.SetUnicode(charcode, UnicodeFromAdobeName(name));
+- m_GlyphIndex[charcode] = FT_Get_Name_Index(m_Font.GetFaceRec(), name);
++ m_GlyphIndex[charcode] = FT_Get_Name_Index(m_Font.GetFaceRec(), const_cast<char*>(name));
+ if (m_GlyphIndex[charcode] != 0)
+ continue;
+
+--- pdfium/core/fpdfapi/font/cpdf_truetypefont.cpp.orig 2022-05-20 09:26:12.066767996 +0000
++++ pdfium/core/fpdfapi/font/cpdf_truetypefont.cpp 2022-05-20 09:26:46.690836923 +0000
+@@ -90,7 +90,7 @@
+ FT_ENCODING_APPLE_ROMAN,
+ m_Encoding.UnicodeFromCharCode(charcode));
+ if (!maccode) {
+- m_GlyphIndex[charcode] = FT_Get_Name_Index(face, name);
++ m_GlyphIndex[charcode] = FT_Get_Name_Index(face, const_cast<char*>(name));
+ } else {
+ m_GlyphIndex[charcode] = FT_Get_Char_Index(face, maccode);
+ }
+@@ -104,7 +104,7 @@
+ m_GlyphIndex[charcode] = FT_Get_Char_Index(face, 32);
+ continue;
+ }
+- m_GlyphIndex[charcode] = FT_Get_Name_Index(face, name);
++ m_GlyphIndex[charcode] = FT_Get_Name_Index(face, const_cast<char*>(name));
+ if (m_GlyphIndex[charcode] != 0 || !bToUnicode)
+ continue;
+
diff --git a/external/pdfium/c++20-comparison.patch b/external/pdfium/c++20-comparison.patch
new file mode 100644
index 000000000..638497f6a
--- /dev/null
+++ b/external/pdfium/c++20-comparison.patch
@@ -0,0 +1,13 @@
+--- core/fxcrt/fx_memory_wrappers.h
++++ core/fxcrt/fx_memory_wrappers.h
+@@ -70,8 +70,8 @@ struct FxPartitionAllocAllocator {
+ }
+
+ // There's no state, so they are all the same,
+- bool operator==(const FxPartitionAllocAllocator& that) { return true; }
+- bool operator!=(const FxPartitionAllocAllocator& that) { return false; }
++ bool operator==(const FxPartitionAllocAllocator& that) const { return true; }
++ bool operator!=(const FxPartitionAllocAllocator& that) const { return false; }
+ };
+
+ // Used to put backing store for std::vector<> and such
diff --git a/external/pdfium/cg-instead-of-carbon.patch.1 b/external/pdfium/cg-instead-of-carbon.patch.1
new file mode 100644
index 000000000..055eac735
--- /dev/null
+++ b/external/pdfium/cg-instead-of-carbon.patch.1
@@ -0,0 +1,23 @@
+-*- Mode: Diff -*-
+--- a/core/fxge/apple/fx_quartz_device.h
++++ b/core/fxge/apple/fx_quartz_device.h
+@@ -7,7 +7,7 @@
+ #ifndef CORE_FXGE_APPLE_FX_QUARTZ_DEVICE_H_
+ #define CORE_FXGE_APPLE_FX_QUARTZ_DEVICE_H_
+
+-#include <Carbon/Carbon.h>
++#include <CoreGraphics/CoreGraphics.h>
+ #include <stdint.h>
+
+ #include "core/fxcrt/retain_ptr.h"
+--- a/core/fpdfapi/font/cpdf_type1font.cpp
++++ b/core/fpdfapi/font/cpdf_type1font.cpp
+@@ -19,7 +19,7 @@
+ #include "core/fxge/fx_font.h"
+
+ #if BUILDFLAG(IS_APPLE)
+-#include <Carbon/Carbon.h>
++#include <CoreGraphics/CoreGraphics.h>
+ #endif // BUILDFLAG(IS_APPLE)
+
+ namespace {
diff --git a/external/pdfium/gcc-c++20-comparison.patch b/external/pdfium/gcc-c++20-comparison.patch
new file mode 100644
index 000000000..0895ea8b5
--- /dev/null
+++ b/external/pdfium/gcc-c++20-comparison.patch
@@ -0,0 +1,18 @@
+--- core/fxcrt/retain_ptr.h
++++ core/fxcrt/retain_ptr.h
+@@ -135,6 +135,7 @@
+ mutable intptr_t m_nRefCount = 0;
+ };
+
++#if __cplusplus < 202002L
+ template <typename T, typename U>
+ inline bool operator==(const U* lhs, const RetainPtr<T>& rhs) {
+ return rhs == lhs;
+@@ -144,6 +144,7 @@
+ inline bool operator!=(const U* lhs, const RetainPtr<T>& rhs) {
+ return rhs != lhs;
+ }
++#endif
+
+ } // namespace fxcrt
+
diff --git a/external/pdfium/inc/pch/precompiled_pdfium.cxx b/external/pdfium/inc/pch/precompiled_pdfium.cxx
new file mode 100644
index 000000000..063660fe2
--- /dev/null
+++ b/external/pdfium/inc/pch/precompiled_pdfium.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_pdfium.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/pdfium/inc/pch/precompiled_pdfium.hxx b/external/pdfium/inc/pch/precompiled_pdfium.hxx
new file mode 100644
index 000000000..eaa6090cf
--- /dev/null
+++ b/external/pdfium/inc/pch/precompiled_pdfium.hxx
@@ -0,0 +1,496 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2020-09-21 15:21:21 using:
+ ./bin/update_pch external/pdfium pdfium --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/pdfium/inc/pch/precompiled_pdfium.hxx "make external/pdfium.build" --find-conflicts
+*/
+
+#include <sal/config.h>
+#if PCH_LEVEL >= 1
+#include <agg_curves.h>
+#include <agg_math.h>
+#include <agg_path_storage.h>
+#include <agg_rasterizer_scanline_aa.h>
+#include <agg_shorten_path.h>
+#include <agg_vcgen_dash.h>
+#include <agg_vcgen_stroke.h>
+#include <algorithm>
+#include <array>
+#include <atomic>
+#include <cassert>
+#include <cfloat>
+#include <climits>
+#include <cmath>
+#include <ctype.h>
+#include <functional>
+#include <iterator>
+#include <limits.h>
+#include <limits>
+#include <list>
+#include <map>
+#include <math.h>
+#include <memory>
+#include <new>
+#include <numeric>
+#include <ostream>
+#include <set>
+#include <setjmp.h>
+#include <sstream>
+#include <stack>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+#include <time.h>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include <vector>
+#include <wchar.h>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <build/build_config.h>
+#include <constants/access_permissions.h>
+#include <constants/annotation_common.h>
+#include <constants/annotation_flags.h>
+#include <constants/appearance.h>
+#include <constants/ascii.h>
+#include <constants/font_encodings.h>
+#include <constants/form_fields.h>
+#include <constants/form_flags.h>
+#include <constants/page_object.h>
+#include <constants/stream_dict_common.h>
+#include <constants/transparency.h>
+#include <core/fdrm/fx_crypt.h>
+#include <core/fpdfapi/cmaps/CNS1/cmaps_cns1.h>
+#include <core/fpdfapi/cmaps/GB1/cmaps_gb1.h>
+#include <core/fpdfapi/cmaps/Japan1/cmaps_japan1.h>
+#include <core/fpdfapi/cmaps/Korea1/cmaps_korea1.h>
+#include <core/fpdfapi/cmaps/fpdf_cmaps.h>
+#include <core/fpdfapi/edit/cpdf_contentstream_write_utils.h>
+#include <core/fpdfapi/edit/cpdf_creator.h>
+#include <core/fpdfapi/edit/cpdf_pagecontentgenerator.h>
+#include <core/fpdfapi/edit/cpdf_pagecontentmanager.h>
+#include <core/fpdfapi/edit/cpdf_stringarchivestream.h>
+#include <core/fpdfapi/font/cfx_cttgsubtable.h>
+#include <core/fpdfapi/font/cfx_stockfontarray.h>
+#include <core/fpdfapi/font/cpdf_cid2unicodemap.h>
+#include <core/fpdfapi/font/cpdf_cidfont.h>
+#include <core/fpdfapi/font/cpdf_cmap.h>
+#include <core/fpdfapi/font/cpdf_cmapparser.h>
+#include <core/fpdfapi/font/cpdf_font.h>
+#include <core/fpdfapi/font/cpdf_fontencoding.h>
+#include <core/fpdfapi/font/cpdf_fontglobals.h>
+#include <core/fpdfapi/font/cpdf_simplefont.h>
+#include <core/fpdfapi/font/cpdf_tounicodemap.h>
+#include <core/fpdfapi/font/cpdf_truetypefont.h>
+#include <core/fpdfapi/font/cpdf_type1font.h>
+#include <core/fpdfapi/font/cpdf_type3char.h>
+#include <core/fpdfapi/font/cpdf_type3font.h>
+#include <core/fpdfapi/page/cpdf_allstates.h>
+#include <core/fpdfapi/page/cpdf_annotcontext.h>
+#include <core/fpdfapi/page/cpdf_basedcs.h>
+#include <core/fpdfapi/page/cpdf_clippath.h>
+#include <core/fpdfapi/page/cpdf_color.h>
+#include <core/fpdfapi/page/cpdf_colorspace.h>
+#include <core/fpdfapi/page/cpdf_colorstate.h>
+#include <core/fpdfapi/page/cpdf_contentmarkitem.h>
+#include <core/fpdfapi/page/cpdf_contentmarks.h>
+#include <core/fpdfapi/page/cpdf_contentparser.h>
+#include <core/fpdfapi/page/cpdf_devicecs.h>
+#include <core/fpdfapi/page/cpdf_dib.h>
+#include <core/fpdfapi/page/cpdf_docpagedata.h>
+#include <core/fpdfapi/page/cpdf_expintfunc.h>
+#include <core/fpdfapi/page/cpdf_form.h>
+#include <core/fpdfapi/page/cpdf_formobject.h>
+#include <core/fpdfapi/page/cpdf_function.h>
+#include <core/fpdfapi/page/cpdf_generalstate.h>
+#include <core/fpdfapi/page/cpdf_graphicstates.h>
+#include <core/fpdfapi/page/cpdf_iccprofile.h>
+#include <core/fpdfapi/page/cpdf_image.h>
+#include <core/fpdfapi/page/cpdf_imageobject.h>
+#include <core/fpdfapi/page/cpdf_indexedcs.h>
+#include <core/fpdfapi/page/cpdf_meshstream.h>
+#include <core/fpdfapi/page/cpdf_occontext.h>
+#include <core/fpdfapi/page/cpdf_page.h>
+#include <core/fpdfapi/page/cpdf_pagemodule.h>
+#include <core/fpdfapi/page/cpdf_pageobject.h>
+#include <core/fpdfapi/page/cpdf_pageobjectholder.h>
+#include <core/fpdfapi/page/cpdf_path.h>
+#include <core/fpdfapi/page/cpdf_pathobject.h>
+#include <core/fpdfapi/page/cpdf_pattern.h>
+#include <core/fpdfapi/page/cpdf_patterncs.h>
+#include <core/fpdfapi/page/cpdf_psengine.h>
+#include <core/fpdfapi/page/cpdf_psfunc.h>
+#include <core/fpdfapi/page/cpdf_sampledfunc.h>
+#include <core/fpdfapi/page/cpdf_shadingobject.h>
+#include <core/fpdfapi/page/cpdf_shadingpattern.h>
+#include <core/fpdfapi/page/cpdf_stitchfunc.h>
+#include <core/fpdfapi/page/cpdf_streamcontentparser.h>
+#include <core/fpdfapi/page/cpdf_streamparser.h>
+#include <core/fpdfapi/page/cpdf_textobject.h>
+#include <core/fpdfapi/page/cpdf_textstate.h>
+#include <core/fpdfapi/page/cpdf_tilingpattern.h>
+#include <core/fpdfapi/page/cpdf_transferfunc.h>
+#include <core/fpdfapi/page/cpdf_transferfuncdib.h>
+#include <core/fpdfapi/page/cpdf_transparency.h>
+#include <core/fpdfapi/parser/cfdf_document.h>
+#include <core/fpdfapi/parser/cpdf_array.h>
+#include <core/fpdfapi/parser/cpdf_boolean.h>
+#include <core/fpdfapi/parser/cpdf_cross_ref_avail.h>
+#include <core/fpdfapi/parser/cpdf_cross_ref_table.h>
+#include <core/fpdfapi/parser/cpdf_crypto_handler.h>
+#include <core/fpdfapi/parser/cpdf_data_avail.h>
+#include <core/fpdfapi/parser/cpdf_dictionary.h>
+#include <core/fpdfapi/parser/cpdf_document.h>
+#include <core/fpdfapi/parser/cpdf_encryptor.h>
+#include <core/fpdfapi/parser/cpdf_flateencoder.h>
+#include <core/fpdfapi/parser/cpdf_hint_tables.h>
+#include <core/fpdfapi/parser/cpdf_indirect_object_holder.h>
+#include <core/fpdfapi/parser/cpdf_linearized_header.h>
+#include <core/fpdfapi/parser/cpdf_name.h>
+#include <core/fpdfapi/parser/cpdf_null.h>
+#include <core/fpdfapi/parser/cpdf_number.h>
+#include <core/fpdfapi/parser/cpdf_object.h>
+#include <core/fpdfapi/parser/cpdf_object_avail.h>
+#include <core/fpdfapi/parser/cpdf_object_stream.h>
+#include <core/fpdfapi/parser/cpdf_object_walker.h>
+#include <core/fpdfapi/parser/cpdf_page_object_avail.h>
+#include <core/fpdfapi/parser/cpdf_parser.h>
+#include <core/fpdfapi/parser/cpdf_read_validator.h>
+#include <core/fpdfapi/parser/cpdf_reference.h>
+#include <core/fpdfapi/parser/cpdf_security_handler.h>
+#include <core/fpdfapi/parser/cpdf_simple_parser.h>
+#include <core/fpdfapi/parser/cpdf_stream.h>
+#include <core/fpdfapi/parser/cpdf_stream_acc.h>
+#include <core/fpdfapi/parser/cpdf_string.h>
+#include <core/fpdfapi/parser/cpdf_syntax_parser.h>
+#include <core/fpdfapi/parser/fpdf_parser_decode.h>
+#include <core/fpdfapi/parser/fpdf_parser_utility.h>
+#include <core/fpdfapi/render/charposlist.h>
+#include <core/fpdfapi/render/cpdf_devicebuffer.h>
+#include <core/fpdfapi/render/cpdf_docrenderdata.h>
+#include <core/fpdfapi/render/cpdf_imagecacheentry.h>
+#include <core/fpdfapi/render/cpdf_imageloader.h>
+#include <core/fpdfapi/render/cpdf_imagerenderer.h>
+#include <core/fpdfapi/render/cpdf_pagerendercache.h>
+#include <core/fpdfapi/render/cpdf_pagerendercontext.h>
+#include <core/fpdfapi/render/cpdf_progressiverenderer.h>
+#include <core/fpdfapi/render/cpdf_rendercontext.h>
+#include <core/fpdfapi/render/cpdf_renderoptions.h>
+#include <core/fpdfapi/render/cpdf_rendershading.h>
+#include <core/fpdfapi/render/cpdf_renderstatus.h>
+#include <core/fpdfapi/render/cpdf_rendertiling.h>
+#include <core/fpdfapi/render/cpdf_scaledrenderbuffer.h>
+#include <core/fpdfapi/render/cpdf_textrenderer.h>
+#include <core/fpdfapi/render/cpdf_type3cache.h>
+#include <core/fpdfapi/render/cpdf_type3glyphmap.h>
+#include <core/fpdfdoc/cpdf_aaction.h>
+#include <core/fpdfdoc/cpdf_action.h>
+#include <core/fpdfdoc/cpdf_annot.h>
+#include <core/fpdfdoc/cpdf_annotlist.h>
+#include <core/fpdfdoc/cpdf_apsettings.h>
+#include <core/fpdfdoc/cpdf_bafontmap.h>
+#include <core/fpdfdoc/cpdf_bookmark.h>
+#include <core/fpdfdoc/cpdf_bookmarktree.h>
+#include <core/fpdfdoc/cpdf_color_utils.h>
+#include <core/fpdfdoc/cpdf_defaultappearance.h>
+#include <core/fpdfdoc/cpdf_dest.h>
+#include <core/fpdfdoc/cpdf_filespec.h>
+#include <core/fpdfdoc/cpdf_formcontrol.h>
+#include <core/fpdfdoc/cpdf_formfield.h>
+#include <core/fpdfdoc/cpdf_generateap.h>
+#include <core/fpdfdoc/cpdf_icon.h>
+#include <core/fpdfdoc/cpdf_iconfit.h>
+#include <core/fpdfdoc/cpdf_interactiveform.h>
+#include <core/fpdfdoc/cpdf_link.h>
+#include <core/fpdfdoc/cpdf_linklist.h>
+#include <core/fpdfdoc/cpdf_metadata.h>
+#include <core/fpdfdoc/cpdf_nametree.h>
+#include <core/fpdfdoc/cpdf_numbertree.h>
+#include <core/fpdfdoc/cpdf_pagelabel.h>
+#include <core/fpdfdoc/cpdf_structelement.h>
+#include <core/fpdfdoc/cpdf_structtree.h>
+#include <core/fpdfdoc/cpdf_viewerpreferences.h>
+#include <core/fpdfdoc/cpvt_fontmap.h>
+#include <core/fpdfdoc/cpvt_section.h>
+#include <core/fpdfdoc/cpvt_variabletext.h>
+#include <core/fpdfdoc/cpvt_word.h>
+#include <core/fpdfdoc/cpvt_wordinfo.h>
+#include <core/fpdfdoc/ipvt_fontmap.h>
+#include <core/fpdftext/cpdf_linkextract.h>
+#include <core/fpdftext/cpdf_textpage.h>
+#include <core/fpdftext/cpdf_textpagefind.h>
+#include <core/fpdftext/unicodenormalizationdata.h>
+#include <core/fxcodec/basic/basicmodule.h>
+#include <core/fxcodec/cfx_codec_memory.h>
+#include <core/fxcodec/fax/faxmodule.h>
+#include <core/fxcodec/flate/flatemodule.h>
+#include <core/fxcodec/fx_codec.h>
+#include <core/fxcodec/gif/cfx_gif.h>
+#include <core/fxcodec/gif/lzw_decompressor.h>
+#include <core/fxcodec/icc/icc_transform.h>
+#include <core/fxcodec/jbig2/JBig2_ArithDecoder.h>
+#include <core/fxcodec/jbig2/JBig2_ArithIntDecoder.h>
+#include <core/fxcodec/jbig2/JBig2_BitStream.h>
+#include <core/fxcodec/jbig2/JBig2_Context.h>
+#include <core/fxcodec/jbig2/JBig2_Define.h>
+#include <core/fxcodec/jbig2/JBig2_DocumentContext.h>
+#include <core/fxcodec/jbig2/JBig2_GrdProc.h>
+#include <core/fxcodec/jbig2/JBig2_GrrdProc.h>
+#include <core/fxcodec/jbig2/JBig2_HtrdProc.h>
+#include <core/fxcodec/jbig2/JBig2_HuffmanDecoder.h>
+#include <core/fxcodec/jbig2/JBig2_HuffmanTable.h>
+#include <core/fxcodec/jbig2/JBig2_Image.h>
+#include <core/fxcodec/jbig2/JBig2_PatternDict.h>
+#include <core/fxcodec/jbig2/JBig2_PddProc.h>
+#include <core/fxcodec/jbig2/JBig2_SddProc.h>
+#include <core/fxcodec/jbig2/JBig2_Segment.h>
+#include <core/fxcodec/jbig2/JBig2_SymbolDict.h>
+#include <core/fxcodec/jbig2/JBig2_TrdProc.h>
+#include <core/fxcodec/jbig2/jbig2_decoder.h>
+#include <core/fxcodec/jpeg/jpeg_common.h>
+#include <core/fxcodec/jpeg/jpegmodule.h>
+#include <core/fxcodec/jpx/cjpx_decoder.h>
+#include <core/fxcodec/jpx/jpx_decode_utils.h>
+#include <core/fxcodec/scanlinedecoder.h>
+#include <core/fxcrt/autonuller.h>
+#include <core/fxcrt/autorestorer.h>
+#include <core/fxcrt/bytestring.h>
+#include <core/fxcrt/cfx_binarybuf.h>
+#include <core/fxcrt/cfx_bitstream.h>
+#include <core/fxcrt/cfx_datetime.h>
+#include <core/fxcrt/cfx_fixedbufgrow.h>
+#include <core/fxcrt/cfx_memorystream.h>
+#include <core/fxcrt/cfx_readonlymemorystream.h>
+#include <core/fxcrt/cfx_seekablestreamproxy.h>
+#include <core/fxcrt/cfx_timer.h>
+#include <core/fxcrt/cfx_utf8decoder.h>
+#include <core/fxcrt/cfx_utf8encoder.h>
+#include <core/fxcrt/cfx_widetextbuf.h>
+#include <core/fxcrt/css/cfx_css.h>
+#include <core/fxcrt/css/cfx_csscolorvalue.h>
+#include <core/fxcrt/css/cfx_csscomputedstyle.h>
+#include <core/fxcrt/css/cfx_csscustomproperty.h>
+#include <core/fxcrt/css/cfx_cssdata.h>
+#include <core/fxcrt/css/cfx_cssdeclaration.h>
+#include <core/fxcrt/css/cfx_cssenumvalue.h>
+#include <core/fxcrt/css/cfx_cssinputtextbuf.h>
+#include <core/fxcrt/css/cfx_cssnumbervalue.h>
+#include <core/fxcrt/css/cfx_cssoutputtextbuf.h>
+#include <core/fxcrt/css/cfx_csspropertyholder.h>
+#include <core/fxcrt/css/cfx_cssrulecollection.h>
+#include <core/fxcrt/css/cfx_cssselector.h>
+#include <core/fxcrt/css/cfx_cssstringvalue.h>
+#include <core/fxcrt/css/cfx_cssstylerule.h>
+#include <core/fxcrt/css/cfx_cssstyleselector.h>
+#include <core/fxcrt/css/cfx_cssstylesheet.h>
+#include <core/fxcrt/css/cfx_csssyntaxparser.h>
+#include <core/fxcrt/css/cfx_cssvalue.h>
+#include <core/fxcrt/css/cfx_cssvaluelist.h>
+#include <core/fxcrt/css/cfx_cssvaluelistparser.h>
+#include <core/fxcrt/fileaccess_iface.h>
+#include <core/fxcrt/fx_bidi.h>
+#include <core/fxcrt/fx_codepage.h>
+#include <core/fxcrt/fx_coordinates.h>
+#include <core/fxcrt/fx_extension.h>
+#include <core/fxcrt/fx_folder.h>
+#include <core/fxcrt/fx_memory.h>
+#include <core/fxcrt/fx_memory_wrappers.h>
+#include <core/fxcrt/fx_number.h>
+#include <core/fxcrt/fx_random.h>
+#include <core/fxcrt/fx_safe_types.h>
+#include <core/fxcrt/fx_stream.h>
+#include <core/fxcrt/fx_string.h>
+#include <core/fxcrt/fx_string_wrappers.h>
+#include <core/fxcrt/fx_system.h>
+#include <core/fxcrt/fx_unicode.h>
+#include <core/fxcrt/maybe_owned.h>
+#include <core/fxcrt/observed_ptr.h>
+#include <core/fxcrt/pauseindicator_iface.h>
+#include <core/fxcrt/retain_ptr.h>
+#include <core/fxcrt/scoped_set_insertion.h>
+#include <core/fxcrt/span_util.h>
+#include <core/fxcrt/stl_util.h>
+#include <core/fxcrt/string_data_template.h>
+#include <core/fxcrt/string_pool_template.h>
+#include <core/fxcrt/unowned_ptr.h>
+#include <core/fxcrt/widestring.h>
+#include <core/fxcrt/xml/cfx_xmlchardata.h>
+#include <core/fxcrt/xml/cfx_xmldocument.h>
+#include <core/fxcrt/xml/cfx_xmlelement.h>
+#include <core/fxcrt/xml/cfx_xmlinstruction.h>
+#include <core/fxcrt/xml/cfx_xmlnode.h>
+#include <core/fxcrt/xml/cfx_xmlparser.h>
+#include <core/fxcrt/xml/cfx_xmltext.h>
+#include <core/fxge/agg/fx_agg_driver.h>
+#include <core/fxge/calculate_pitch.h>
+#include <core/fxge/cfx_cliprgn.h>
+#include <core/fxge/cfx_color.h>
+#include <core/fxge/cfx_defaultrenderdevice.h>
+#include <core/fxge/cfx_drawutils.h>
+#include <core/fxge/cfx_face.h>
+#include <core/fxge/cfx_fillrenderoptions.h>
+#include <core/fxge/cfx_folderfontinfo.h>
+#include <core/fxge/cfx_font.h>
+#include <core/fxge/cfx_fontcache.h>
+#include <core/fxge/cfx_fontmapper.h>
+#include <core/fxge/cfx_fontmgr.h>
+#include <core/fxge/cfx_gemodule.h>
+#include <core/fxge/cfx_glyphbitmap.h>
+#include <core/fxge/cfx_glyphcache.h>
+#include <core/fxge/cfx_graphstate.h>
+#include <core/fxge/cfx_graphstatedata.h>
+#include <core/fxge/cfx_path.h>
+#include <core/fxge/cfx_renderdevice.h>
+#include <core/fxge/cfx_substfont.h>
+#include <core/fxge/cfx_textrenderoptions.h>
+#include <core/fxge/cfx_unicodeencoding.h>
+#include <core/fxge/dib/cfx_bitmapcomposer.h>
+#include <core/fxge/dib/cfx_bitmapstorer.h>
+#include <core/fxge/dib/cfx_cmyk_to_srgb.h>
+#include <core/fxge/dib/cfx_dibbase.h>
+#include <core/fxge/dib/cfx_dibextractor.h>
+#include <core/fxge/dib/cfx_dibitmap.h>
+#include <core/fxge/dib/cfx_imagerenderer.h>
+#include <core/fxge/dib/cfx_imagestretcher.h>
+#include <core/fxge/dib/cfx_imagetransformer.h>
+#include <core/fxge/dib/cfx_scanlinecompositor.h>
+#include <core/fxge/dib/cstretchengine.h>
+#include <core/fxge/dib/fx_dib.h>
+#include <core/fxge/dib/scanlinecomposer_iface.h>
+#include <core/fxge/fontdata/chromefontdata/chromefontdata.h>
+#include <core/fxge/freetype/fx_freetype.h>
+#include <core/fxge/fx_font.h>
+#include <core/fxge/renderdevicedriver_iface.h>
+#include <core/fxge/scoped_font_transform.h>
+#include <core/fxge/systemfontinfo_iface.h>
+#include <core/fxge/text_char_pos.h>
+#include <core/fxge/text_glyph_pos.h>
+#include <fpdfsdk/cpdfsdk_annot.h>
+#include <fpdfsdk/cpdfsdk_annotiteration.h>
+#include <fpdfsdk/cpdfsdk_annotiterator.h>
+#include <fpdfsdk/cpdfsdk_appstream.h>
+#include <fpdfsdk/cpdfsdk_baannot.h>
+#include <fpdfsdk/cpdfsdk_customaccess.h>
+#include <fpdfsdk/cpdfsdk_filewriteadapter.h>
+#include <fpdfsdk/cpdfsdk_formfillenvironment.h>
+#include <fpdfsdk/cpdfsdk_helpers.h>
+#include <fpdfsdk/cpdfsdk_interactiveform.h>
+#include <fpdfsdk/cpdfsdk_pageview.h>
+#include <fpdfsdk/cpdfsdk_pauseadapter.h>
+#include <fpdfsdk/cpdfsdk_renderpage.h>
+#include <fpdfsdk/cpdfsdk_widget.h>
+#include <fpdfsdk/formfiller/cffl_button.h>
+#include <fpdfsdk/formfiller/cffl_checkbox.h>
+#include <fpdfsdk/formfiller/cffl_combobox.h>
+#include <fpdfsdk/formfiller/cffl_fieldaction.h>
+#include <fpdfsdk/formfiller/cffl_formfield.h>
+#include <fpdfsdk/formfiller/cffl_interactiveformfiller.h>
+#include <fpdfsdk/formfiller/cffl_listbox.h>
+#include <fpdfsdk/formfiller/cffl_perwindowdata.h>
+#include <fpdfsdk/formfiller/cffl_pushbutton.h>
+#include <fpdfsdk/formfiller/cffl_radiobutton.h>
+#include <fpdfsdk/formfiller/cffl_textfield.h>
+#include <fpdfsdk/formfiller/cffl_textobject.h>
+#include <fpdfsdk/pwl/cpwl_button.h>
+#include <fpdfsdk/pwl/cpwl_caret.h>
+#include <fpdfsdk/pwl/cpwl_cbbutton.h>
+#include <fpdfsdk/pwl/cpwl_cblistbox.h>
+#include <fpdfsdk/pwl/cpwl_combo_box.h>
+#include <fpdfsdk/pwl/cpwl_edit.h>
+#include <fpdfsdk/pwl/cpwl_edit_impl.h>
+#include <fpdfsdk/pwl/cpwl_list_box.h>
+#include <fpdfsdk/pwl/cpwl_list_ctrl.h>
+#include <fpdfsdk/pwl/cpwl_sbbutton.h>
+#include <fpdfsdk/pwl/cpwl_scroll_bar.h>
+#include <fpdfsdk/pwl/cpwl_special_button.h>
+#include <fpdfsdk/pwl/cpwl_wnd.h>
+#include <fpdfsdk/pwl/ipwl_fillernotify.h>
+#include <fxjs/cjs_event_context_stub.h>
+#include <fxjs/cjs_runtimestub.h>
+#include <fxjs/ijs_event_context.h>
+#include <fxjs/ijs_runtime.h>
+#include <public/fpdf_annot.h>
+#include <public/fpdf_attachment.h>
+#include <public/fpdf_catalog.h>
+#include <public/fpdf_dataavail.h>
+#include <public/fpdf_doc.h>
+#include <public/fpdf_edit.h>
+#include <public/fpdf_ext.h>
+#include <public/fpdf_flatten.h>
+#include <public/fpdf_formfill.h>
+#include <public/fpdf_fwlevent.h>
+#include <public/fpdf_progressive.h>
+#include <public/fpdf_save.h>
+#include <public/fpdf_searchex.h>
+#include <public/fpdf_signature.h>
+#include <public/fpdf_structtree.h>
+#include <public/fpdf_sysfontinfo.h>
+#include <public/fpdf_text.h>
+#include <public/fpdf_transformpage.h>
+#include <public/fpdfview.h>
+#include <third_party/abseil-cpp/absl/types/optional.h>
+#include <third_party/agg23/agg_clip_liang_barsky.h>
+#include <third_party/agg23/agg_conv_dash.h>
+#include <third_party/agg23/agg_conv_stroke.h>
+#include <third_party/agg23/agg_curves.h>
+#include <third_party/agg23/agg_path_storage.h>
+#include <third_party/agg23/agg_pixfmt_gray.h>
+#include <third_party/agg23/agg_rasterizer_scanline_aa.h>
+#include <third_party/agg23/agg_renderer_scanline.h>
+#include <third_party/agg23/agg_scanline_u.h>
+#include <third_party/base/allocator/partition_allocator/address_space_randomization.h>
+#include <third_party/base/allocator/partition_allocator/oom.h>
+#include <third_party/base/allocator/partition_allocator/oom_callback.h>
+#include <third_party/base/allocator/partition_allocator/page_allocator.h>
+#include <third_party/base/allocator/partition_allocator/page_allocator_internal.h>
+#include <third_party/base/allocator/partition_allocator/partition_alloc.h>
+#include <third_party/base/allocator/partition_allocator/partition_alloc_check.h>
+#include <third_party/base/allocator/partition_allocator/partition_alloc_constants.h>
+#include <third_party/base/allocator/partition_allocator/partition_bucket.h>
+#include <third_party/base/allocator/partition_allocator/partition_direct_map_extent.h>
+#include <third_party/base/allocator/partition_allocator/partition_oom.h>
+#include <third_party/base/allocator/partition_allocator/partition_page.h>
+#include <third_party/base/allocator/partition_allocator/partition_root_base.h>
+#include <third_party/base/allocator/partition_allocator/random.h>
+#include <third_party/base/allocator/partition_allocator/spin_lock.h>
+#include <third_party/base/bits.h>
+#include <third_party/base/check.h>
+#include <third_party/base/check_op.h>
+#include <third_party/base/compiler_specific.h>
+#include <third_party/base/containers/adapters.h>
+#include <third_party/base/containers/contains.h>
+#include <third_party/base/cxx17_backports.h>
+#include <third_party/base/debug/alias.h>
+#include <third_party/base/memory/aligned_memory.h>
+#include <third_party/base/no_destructor.h>
+#include <third_party/base/notreached.h>
+#include <third_party/base/numerics/safe_conversions.h>
+#include <third_party/base/numerics/safe_math.h>
+#include <third_party/base/ptr_util.h>
+#include <third_party/base/span.h>
+#include <third_party/skia_shared/SkFloatToDecimal.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/pdfium/include.patch b/external/pdfium/include.patch
new file mode 100644
index 000000000..75c0e3b92
--- /dev/null
+++ b/external/pdfium/include.patch
@@ -0,0 +1,11 @@
+--- constants/annotation_flags.h
++++ constants/annotation_flags.h
+@@ -5,6 +5,8 @@
+ #ifndef CONSTANTS_ANNOTATION_FLAGS_H_
+ #define CONSTANTS_ANNOTATION_FLAGS_H_
+
++#include <stdint.h>
++
+ namespace pdfium {
+ namespace annotation_flags {
+
diff --git a/external/pdfium/ubsan.patch b/external/pdfium/ubsan.patch
new file mode 100644
index 000000000..bc9868244
--- /dev/null
+++ b/external/pdfium/ubsan.patch
@@ -0,0 +1,24 @@
+--- core/fxcrt/string_data_template.cpp
++++ core/fxcrt/string_data_template.cpp
+@@ -82,7 +82,8 @@ void StringDataTemplate<CharType>::CopyContentsAt(size_t offset,
+ DCHECK_GE(offset, 0);
+ DCHECK_GE(nLen, 0);
+ DCHECK_LE(offset + nLen, m_nAllocLength);
+- memcpy(m_String + offset, pStr, nLen * sizeof(CharType));
++ if (nLen != 0)
++ memcpy(m_String + offset, pStr, nLen * sizeof(CharType));
+ m_String[offset + nLen] = 0;
+ }
+
+--- core/fxge/cfx_glyphcache.cpp
++++ core/fxge/cfx_glyphcache.cpp
+@@ -183,7 +183,8 @@ std::unique_ptr<CFX_GlyphBitmap> CFX_GlyphCache::RenderGlyph(
+ }
+ }
+ } else {
+- memset(pDestBuf, 0, dest_pitch * bmheight);
++ if (dest_pitch != 0 && bmheight != 0)
++ memset(pDestBuf, 0, dest_pitch * bmheight);
+ int rowbytes = std::min(abs(src_pitch), dest_pitch);
+ for (int row = 0; row < bmheight; row++)
+ memcpy(pDestBuf + row * dest_pitch, pSrcBuf + row * src_pitch, rowbytes);
diff --git a/external/pdfium/windows7.patch.1 b/external/pdfium/windows7.patch.1
new file mode 100644
index 000000000..d33f273ff
--- /dev/null
+++ b/external/pdfium/windows7.patch.1
@@ -0,0 +1,34 @@
+diff --git a/third_party/base/win/win_util.cc b/third_party/base/win/win_util.cc
+index ae2dba84d..7a3718848 100644
+--- a/third_party/base/win/win_util.cc
++++ b/third_party/base/win/win_util.cc
+@@ -12,28 +12,7 @@ namespace base {
+ namespace win {
+
+ bool IsUser32AndGdi32Available() {
+- static auto is_user32_and_gdi32_available = []() {
+- // If win32k syscalls aren't disabled, then user32 and gdi32 are available.
+-
+- typedef decltype(
+- GetProcessMitigationPolicy)* GetProcessMitigationPolicyType;
+- GetProcessMitigationPolicyType get_process_mitigation_policy_func =
+- reinterpret_cast<GetProcessMitigationPolicyType>(GetProcAddress(
+- GetModuleHandle(L"kernel32.dll"), "GetProcessMitigationPolicy"));
+-
+- if (!get_process_mitigation_policy_func)
+- return true;
+-
+- PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = {};
+- if (get_process_mitigation_policy_func(GetCurrentProcess(),
+- ProcessSystemCallDisablePolicy,
+- &policy, sizeof(policy))) {
+- return policy.DisallowWin32kSystemCalls == 0;
+- }
+-
+- return true;
+- }();
+- return is_user32_and_gdi32_available;
++ return true;
+ }
+
+ } // namespace win
diff --git a/external/poppler/ExternalPackage_poppler_data.mk b/external/poppler/ExternalPackage_poppler_data.mk
new file mode 100644
index 000000000..78024d3fe
--- /dev/null
+++ b/external/poppler/ExternalPackage_poppler_data.mk
@@ -0,0 +1,297 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,poppler_data,poppler_data))
+
+poppler_unicode-map-files = \
+ unicodeMap/Big5 \
+ unicodeMap/Big5ascii \
+ unicodeMap/EUC-CN \
+ unicodeMap/EUC-JP \
+ unicodeMap/GBK \
+ unicodeMap/ISO-2022-CN \
+ unicodeMap/ISO-2022-JP \
+ unicodeMap/ISO-2022-KR \
+ unicodeMap/ISO-8859-6 \
+ unicodeMap/ISO-8859-7 \
+ unicodeMap/ISO-8859-8 \
+ unicodeMap/ISO-8859-9 \
+ unicodeMap/KOI8-R \
+ unicodeMap/Latin2 \
+ unicodeMap/Shift-JIS \
+ unicodeMap/TIS-620 \
+ unicodeMap/Windows-1255
+
+
+poppler_cmap-files = \
+ cMap/Adobe-CNS1/Adobe-CNS1-0 \
+ cMap/Adobe-CNS1/Adobe-CNS1-1 \
+ cMap/Adobe-CNS1/Adobe-CNS1-2 \
+ cMap/Adobe-CNS1/Adobe-CNS1-3 \
+ cMap/Adobe-CNS1/Adobe-CNS1-4 \
+ cMap/Adobe-CNS1/Adobe-CNS1-5 \
+ cMap/Adobe-CNS1/Adobe-CNS1-6 \
+ cMap/Adobe-CNS1/Adobe-CNS1-7 \
+ cMap/Adobe-CNS1/Adobe-CNS1-B5pc \
+ cMap/Adobe-CNS1/Adobe-CNS1-ETen-B5 \
+ cMap/Adobe-CNS1/Adobe-CNS1-H-CID \
+ cMap/Adobe-CNS1/Adobe-CNS1-H-Host \
+ cMap/Adobe-CNS1/Adobe-CNS1-H-Mac \
+ cMap/Adobe-CNS1/Adobe-CNS1-UCS2 \
+ cMap/Adobe-CNS1/B5-H \
+ cMap/Adobe-CNS1/B5pc-H \
+ cMap/Adobe-CNS1/B5pc-UCS2 \
+ cMap/Adobe-CNS1/B5pc-UCS2C \
+ cMap/Adobe-CNS1/B5pc-V \
+ cMap/Adobe-CNS1/B5-V \
+ cMap/Adobe-CNS1/CNS1-H \
+ cMap/Adobe-CNS1/CNS1-V \
+ cMap/Adobe-CNS1/CNS2-H \
+ cMap/Adobe-CNS1/CNS2-V \
+ cMap/Adobe-CNS1/CNS-EUC-H \
+ cMap/Adobe-CNS1/CNS-EUC-V \
+ cMap/Adobe-CNS1/ETen-B5-H \
+ cMap/Adobe-CNS1/ETen-B5-UCS2 \
+ cMap/Adobe-CNS1/ETen-B5-V \
+ cMap/Adobe-CNS1/ETenms-B5-H \
+ cMap/Adobe-CNS1/ETenms-B5-V \
+ cMap/Adobe-CNS1/ETHK-B5-H \
+ cMap/Adobe-CNS1/ETHK-B5-V \
+ cMap/Adobe-CNS1/HKdla-B5-H \
+ cMap/Adobe-CNS1/HKdla-B5-V \
+ cMap/Adobe-CNS1/HKdlb-B5-H \
+ cMap/Adobe-CNS1/HKdlb-B5-V \
+ cMap/Adobe-CNS1/HKgccs-B5-H \
+ cMap/Adobe-CNS1/HKgccs-B5-V \
+ cMap/Adobe-CNS1/HKm314-B5-H \
+ cMap/Adobe-CNS1/HKm314-B5-V \
+ cMap/Adobe-CNS1/HKm471-B5-H \
+ cMap/Adobe-CNS1/HKm471-B5-V \
+ cMap/Adobe-CNS1/HKscs-B5-H \
+ cMap/Adobe-CNS1/HKscs-B5-V \
+ cMap/Adobe-CNS1/UCS2-B5pc \
+ cMap/Adobe-CNS1/UCS2-ETen-B5 \
+ cMap/Adobe-CNS1/UniCNS-UCS2-H \
+ cMap/Adobe-CNS1/UniCNS-UCS2-V \
+ cMap/Adobe-CNS1/UniCNS-UTF16-H \
+ cMap/Adobe-CNS1/UniCNS-UTF16-V \
+ cMap/Adobe-CNS1/UniCNS-UTF32-H \
+ cMap/Adobe-CNS1/UniCNS-UTF32-V \
+ cMap/Adobe-CNS1/UniCNS-UTF8-H \
+ cMap/Adobe-CNS1/UniCNS-UTF8-V \
+ cMap/Adobe-GB1/Adobe-GB1-0 \
+ cMap/Adobe-GB1/Adobe-GB1-1 \
+ cMap/Adobe-GB1/Adobe-GB1-2 \
+ cMap/Adobe-GB1/Adobe-GB1-3 \
+ cMap/Adobe-GB1/Adobe-GB1-4 \
+ cMap/Adobe-GB1/Adobe-GB1-5 \
+ cMap/Adobe-GB1/Adobe-GB1-GBK-EUC \
+ cMap/Adobe-GB1/Adobe-GB1-GBpc-EUC \
+ cMap/Adobe-GB1/Adobe-GB1-H-CID \
+ cMap/Adobe-GB1/Adobe-GB1-H-Host \
+ cMap/Adobe-GB1/Adobe-GB1-H-Mac \
+ cMap/Adobe-GB1/Adobe-GB1-UCS2 \
+ cMap/Adobe-GB1/GB-EUC-H \
+ cMap/Adobe-GB1/GB-EUC-V \
+ cMap/Adobe-GB1/GB-H \
+ cMap/Adobe-GB1/GBK2K-H \
+ cMap/Adobe-GB1/GBK2K-V \
+ cMap/Adobe-GB1/GBK-EUC-H \
+ cMap/Adobe-GB1/GBK-EUC-UCS2 \
+ cMap/Adobe-GB1/GBK-EUC-V \
+ cMap/Adobe-GB1/GBKp-EUC-H \
+ cMap/Adobe-GB1/GBKp-EUC-V \
+ cMap/Adobe-GB1/GBpc-EUC-H \
+ cMap/Adobe-GB1/GBpc-EUC-UCS2 \
+ cMap/Adobe-GB1/GBpc-EUC-UCS2C \
+ cMap/Adobe-GB1/GBpc-EUC-V \
+ cMap/Adobe-GB1/GBT-EUC-H \
+ cMap/Adobe-GB1/GBT-EUC-V \
+ cMap/Adobe-GB1/GBT-H \
+ cMap/Adobe-GB1/GBTpc-EUC-H \
+ cMap/Adobe-GB1/GBTpc-EUC-V \
+ cMap/Adobe-GB1/GBT-V \
+ cMap/Adobe-GB1/GB-V \
+ cMap/Adobe-GB1/UCS2-GBK-EUC \
+ cMap/Adobe-GB1/UCS2-GBpc-EUC \
+ cMap/Adobe-GB1/UniGB-UCS2-H \
+ cMap/Adobe-GB1/UniGB-UCS2-V \
+ cMap/Adobe-GB1/UniGB-UTF16-H \
+ cMap/Adobe-GB1/UniGB-UTF16-V \
+ cMap/Adobe-GB1/UniGB-UTF32-H \
+ cMap/Adobe-GB1/UniGB-UTF32-V \
+ cMap/Adobe-GB1/UniGB-UTF8-H \
+ cMap/Adobe-GB1/UniGB-UTF8-V \
+ cMap/Adobe-Japan1/78-EUC-H \
+ cMap/Adobe-Japan1/78-EUC-V \
+ cMap/Adobe-Japan1/78-H \
+ cMap/Adobe-Japan1/78ms-RKSJ-H \
+ cMap/Adobe-Japan1/78ms-RKSJ-V \
+ cMap/Adobe-Japan1/78-RKSJ-H \
+ cMap/Adobe-Japan1/78-RKSJ-V \
+ cMap/Adobe-Japan1/78-V \
+ cMap/Adobe-Japan1/83pv-RKSJ-H \
+ cMap/Adobe-Japan1/90msp-RKSJ-H \
+ cMap/Adobe-Japan1/90msp-RKSJ-V \
+ cMap/Adobe-Japan1/90ms-RKSJ-H \
+ cMap/Adobe-Japan1/90ms-RKSJ-UCS2 \
+ cMap/Adobe-Japan1/90ms-RKSJ-V \
+ cMap/Adobe-Japan1/90pv-RKSJ-H \
+ cMap/Adobe-Japan1/90pv-RKSJ-UCS2 \
+ cMap/Adobe-Japan1/90pv-RKSJ-UCS2C \
+ cMap/Adobe-Japan1/90pv-RKSJ-V \
+ cMap/Adobe-Japan1/Add-H \
+ cMap/Adobe-Japan1/Add-RKSJ-H \
+ cMap/Adobe-Japan1/Add-RKSJ-V \
+ cMap/Adobe-Japan1/Add-V \
+ cMap/Adobe-Japan1/Adobe-Japan1-0 \
+ cMap/Adobe-Japan1/Adobe-Japan1-1 \
+ cMap/Adobe-Japan1/Adobe-Japan1-2 \
+ cMap/Adobe-Japan1/Adobe-Japan1-3 \
+ cMap/Adobe-Japan1/Adobe-Japan1-4 \
+ cMap/Adobe-Japan1/Adobe-Japan1-5 \
+ cMap/Adobe-Japan1/Adobe-Japan1-6 \
+ cMap/Adobe-Japan1/Adobe-Japan1-7 \
+ cMap/Adobe-Japan1/Adobe-Japan1-90ms-RKSJ \
+ cMap/Adobe-Japan1/Adobe-Japan1-90pv-RKSJ \
+ cMap/Adobe-Japan1/Adobe-Japan1-H-CID \
+ cMap/Adobe-Japan1/Adobe-Japan1-H-Host \
+ cMap/Adobe-Japan1/Adobe-Japan1-H-Mac \
+ cMap/Adobe-Japan1/Adobe-Japan1-PS-H \
+ cMap/Adobe-Japan1/Adobe-Japan1-PS-V \
+ cMap/Adobe-Japan1/Adobe-Japan1-UCS2 \
+ cMap/Adobe-Japan1/EUC-H \
+ cMap/Adobe-Japan1/EUC-V \
+ cMap/Adobe-Japan1/Ext-H \
+ cMap/Adobe-Japan1/Ext-RKSJ-H \
+ cMap/Adobe-Japan1/Ext-RKSJ-V \
+ cMap/Adobe-Japan1/Ext-V \
+ cMap/Adobe-Japan1/H \
+ cMap/Adobe-Japan1/Hankaku \
+ cMap/Adobe-Japan1/Hiragana \
+ cMap/Adobe-Japan1/Hojo-EUC-H \
+ cMap/Adobe-Japan1/Hojo-EUC-V \
+ cMap/Adobe-Japan1/Hojo-H \
+ cMap/Adobe-Japan1/Hojo-V \
+ cMap/Adobe-Japan1/Katakana \
+ cMap/Adobe-Japan1/NWP-H \
+ cMap/Adobe-Japan1/NWP-V \
+ cMap/Adobe-Japan1/RKSJ-H \
+ cMap/Adobe-Japan1/RKSJ-V \
+ cMap/Adobe-Japan1/Roman \
+ cMap/Adobe-Japan1/UCS2-90ms-RKSJ \
+ cMap/Adobe-Japan1/UCS2-90pv-RKSJ \
+ cMap/Adobe-Japan1/UniHojo-UCS2-H \
+ cMap/Adobe-Japan1/UniHojo-UCS2-V \
+ cMap/Adobe-Japan1/UniHojo-UTF16-H \
+ cMap/Adobe-Japan1/UniHojo-UTF16-V \
+ cMap/Adobe-Japan1/UniHojo-UTF32-H \
+ cMap/Adobe-Japan1/UniHojo-UTF32-V \
+ cMap/Adobe-Japan1/UniHojo-UTF8-H \
+ cMap/Adobe-Japan1/UniHojo-UTF8-V \
+ cMap/Adobe-Japan1/UniJIS2004-UTF16-H \
+ cMap/Adobe-Japan1/UniJIS2004-UTF16-V \
+ cMap/Adobe-Japan1/UniJIS2004-UTF32-H \
+ cMap/Adobe-Japan1/UniJIS2004-UTF32-V \
+ cMap/Adobe-Japan1/UniJIS2004-UTF8-H \
+ cMap/Adobe-Japan1/UniJIS2004-UTF8-V \
+ cMap/Adobe-Japan1/UniJISPro-UCS2-HW-V \
+ cMap/Adobe-Japan1/UniJISPro-UCS2-V \
+ cMap/Adobe-Japan1/UniJISPro-UTF8-V \
+ cMap/Adobe-Japan1/UniJIS-UCS2-H \
+ cMap/Adobe-Japan1/UniJIS-UCS2-HW-H \
+ cMap/Adobe-Japan1/UniJIS-UCS2-HW-V \
+ cMap/Adobe-Japan1/UniJIS-UCS2-V \
+ cMap/Adobe-Japan1/UniJIS-UTF16-H \
+ cMap/Adobe-Japan1/UniJIS-UTF16-V \
+ cMap/Adobe-Japan1/UniJIS-UTF32-H \
+ cMap/Adobe-Japan1/UniJIS-UTF32-V \
+ cMap/Adobe-Japan1/UniJIS-UTF8-H \
+ cMap/Adobe-Japan1/UniJIS-UTF8-V \
+ cMap/Adobe-Japan1/UniJISX02132004-UTF32-H \
+ cMap/Adobe-Japan1/UniJISX02132004-UTF32-V \
+ cMap/Adobe-Japan1/UniJISX0213-UTF32-H \
+ cMap/Adobe-Japan1/UniJISX0213-UTF32-V \
+ cMap/Adobe-Japan1/V \
+ cMap/Adobe-Japan1/WP-Symbol \
+ cMap/Adobe-Japan2/Adobe-Japan2-0 \
+ cMap/Adobe-Korea1/Adobe-Korea1-0 \
+ cMap/Adobe-Korea1/Adobe-Korea1-1 \
+ cMap/Adobe-Korea1/Adobe-Korea1-2 \
+ cMap/Adobe-Korea1/Adobe-Korea1-H-CID \
+ cMap/Adobe-Korea1/Adobe-Korea1-H-Host \
+ cMap/Adobe-Korea1/Adobe-Korea1-H-Mac \
+ cMap/Adobe-Korea1/Adobe-Korea1-KSCms-UHC \
+ cMap/Adobe-Korea1/Adobe-Korea1-KSCpc-EUC \
+ cMap/Adobe-Korea1/Adobe-Korea1-UCS2 \
+ cMap/Adobe-Korea1/KSC-EUC-H \
+ cMap/Adobe-Korea1/KSC-EUC-V \
+ cMap/Adobe-Korea1/KSC-H \
+ cMap/Adobe-Korea1/KSC-Johab-H \
+ cMap/Adobe-Korea1/KSC-Johab-V \
+ cMap/Adobe-Korea1/KSCms-UHC-H \
+ cMap/Adobe-Korea1/KSCms-UHC-HW-H \
+ cMap/Adobe-Korea1/KSCms-UHC-HW-V \
+ cMap/Adobe-Korea1/KSCms-UHC-UCS2 \
+ cMap/Adobe-Korea1/KSCms-UHC-V \
+ cMap/Adobe-Korea1/KSCpc-EUC-H \
+ cMap/Adobe-Korea1/KSCpc-EUC-UCS2 \
+ cMap/Adobe-Korea1/KSCpc-EUC-UCS2C \
+ cMap/Adobe-Korea1/KSCpc-EUC-V \
+ cMap/Adobe-Korea1/KSC-V \
+ cMap/Adobe-Korea1/UCS2-KSCms-UHC \
+ cMap/Adobe-Korea1/UCS2-KSCpc-EUC \
+ cMap/Adobe-Korea1/UniKS-UCS2-H \
+ cMap/Adobe-Korea1/UniKS-UCS2-V \
+ cMap/Adobe-Korea1/UniKS-UTF16-H \
+ cMap/Adobe-Korea1/UniKS-UTF16-V \
+ cMap/Adobe-Korea1/UniKS-UTF32-H \
+ cMap/Adobe-Korea1/UniKS-UTF32-V \
+ cMap/Adobe-Korea1/UniKS-UTF8-H \
+ cMap/Adobe-Korea1/UniKS-UTF8-V \
+ cMap/Adobe-KR/Adobe-KR-0 \
+ cMap/Adobe-KR/Adobe-KR-1 \
+ cMap/Adobe-KR/Adobe-KR-2 \
+ cMap/Adobe-KR/Adobe-KR-3 \
+ cMap/Adobe-KR/Adobe-KR-4 \
+ cMap/Adobe-KR/Adobe-KR-5 \
+ cMap/Adobe-KR/Adobe-KR-6 \
+ cMap/Adobe-KR/Adobe-KR-7 \
+ cMap/Adobe-KR/Adobe-KR-8 \
+ cMap/Adobe-KR/Adobe-KR-9 \
+ cMap/Adobe-KR/Adobe-KR-UCS2 \
+ cMap/Adobe-KR/UniAKR-UTF16-H \
+ cMap/Adobe-KR/UniAKR-UTF32-H \
+ cMap/Adobe-KR/UniAKR-UTF8-H
+
+poppler_name-to-unicode-files = \
+ nameToUnicode/Bulgarian \
+ nameToUnicode/Greek \
+ nameToUnicode/Thai
+
+poppler_cid-to-unicode-files = \
+ cidToUnicode/Adobe-CNS1 \
+ cidToUnicode/Adobe-GB1 \
+ cidToUnicode/Adobe-Japan1 \
+ cidToUnicode/Adobe-Korea1
+
+poppler_DISTFILES = \
+ README \
+ COPYING \
+ COPYING.adobe \
+ COPYING.gpl2 \
+ $(poppler_unicode-map-files) \
+ $(poppler_cmap-files) \
+ $(poppler_name-to-unicode-files) \
+ $(poppler_cid-to-unicode-files)
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files_with_dir,poppler_data,$(LIBO_SHARE_FOLDER)/xpdfimport/poppler_data,\
+ $(poppler_DISTFILES)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/poppler/Makefile b/external/poppler/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/poppler/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/poppler/Module_poppler.mk b/external/poppler/Module_poppler.mk
new file mode 100644
index 000000000..a35bae436
--- /dev/null
+++ b/external/poppler/Module_poppler.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,poppler))
+
+$(eval $(call gb_Module_add_targets,poppler,\
+ StaticLibrary_poppler \
+ UnpackedTarball_poppler \
+ ExternalPackage_poppler_data \
+ UnpackedTarball_poppler_data \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/poppler/README b/external/poppler/README
new file mode 100644
index 000000000..35a640264
--- /dev/null
+++ b/external/poppler/README
@@ -0,0 +1 @@
+From [http://poppler.freedesktop.org/]. Not modified. PDF rendering library based on the xpdf-3.0 code base.
diff --git a/external/poppler/StaticLibrary_poppler.mk b/external/poppler/StaticLibrary_poppler.mk
new file mode 100644
index 000000000..2f6433f88
--- /dev/null
+++ b/external/poppler/StaticLibrary_poppler.mk
@@ -0,0 +1,146 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,poppler))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,poppler,poppler))
+
+$(eval $(call gb_StaticLibrary_set_precompiled_header,poppler,external/poppler/inc/pch/precompiled_poppler))
+
+$(eval $(call gb_StaticLibrary_use_external,poppler,libjpeg))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,poppler))
+
+$(eval $(call gb_StaticLibrary_set_include,poppler,\
+ -I$(WORKDIR)/UnpackedTarball/poppler \
+ -I$(WORKDIR)/UnpackedTarball/poppler/fofi \
+ -I$(WORKDIR)/UnpackedTarball/poppler/goo \
+ -I$(WORKDIR)/UnpackedTarball/poppler/poppler \
+ $$(INCLUDE) \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_StaticLibrary_add_defs,poppler,\
+ -DWIN32_LEAN_AND_MEAN \
+ -D_CRT_SECURE_NO_WARNINGS \
+))
+$(eval $(call gb_StaticLibrary_add_cxxflags,poppler,\
+ /Zc:wchar_t- \
+))
+endif
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,poppler,cc))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,poppler,\
+ UnpackedTarball/poppler/poppler/CourierWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/CourierBoldWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/CourierBoldObliqueWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/CourierObliqueWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/HelveticaWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/HelveticaBoldWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/HelveticaBoldObliqueWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/HelveticaObliqueWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/SymbolWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/TimesBoldWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/TimesBoldItalicWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/TimesItalicWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/TimesRomanWidths.pregenerated \
+ UnpackedTarball/poppler/poppler/ZapfDingbatsWidths.pregenerated \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,poppler,\
+ UnpackedTarball/poppler/goo/gfile \
+ UnpackedTarball/poppler/goo/GooTimer \
+ UnpackedTarball/poppler/goo/GooString \
+ UnpackedTarball/poppler/goo/NetPBMWriter \
+ UnpackedTarball/poppler/goo/PNGWriter \
+ UnpackedTarball/poppler/goo/TiffWriter \
+ UnpackedTarball/poppler/goo/JpegWriter \
+ UnpackedTarball/poppler/goo/ImgWriter \
+ UnpackedTarball/poppler/goo/gstrtod \
+ UnpackedTarball/poppler/goo/grandom \
+ UnpackedTarball/poppler/goo/glibc \
+ UnpackedTarball/poppler/goo/glibc_strtok_r \
+ UnpackedTarball/poppler/fofi/FoFiBase \
+ UnpackedTarball/poppler/fofi/FoFiEncodings \
+ UnpackedTarball/poppler/fofi/FoFiTrueType \
+ UnpackedTarball/poppler/fofi/FoFiType1 \
+ UnpackedTarball/poppler/fofi/FoFiType1C \
+ UnpackedTarball/poppler/fofi/FoFiIdentifier \
+ UnpackedTarball/poppler/poppler/Annot \
+ UnpackedTarball/poppler/poppler/AnnotStampImageHelper \
+ UnpackedTarball/poppler/poppler/Array \
+ UnpackedTarball/poppler/poppler/BBoxOutputDev \
+ UnpackedTarball/poppler/poppler/CachedFile \
+ UnpackedTarball/poppler/poppler/Catalog \
+ UnpackedTarball/poppler/poppler/CertificateInfo \
+ UnpackedTarball/poppler/poppler/CharCodeToUnicode \
+ UnpackedTarball/poppler/poppler/CMap \
+ UnpackedTarball/poppler/poppler/DateInfo \
+ UnpackedTarball/poppler/poppler/Decrypt \
+ UnpackedTarball/poppler/poppler/Dict \
+ UnpackedTarball/poppler/poppler/Error \
+ UnpackedTarball/poppler/poppler/FDPDFDocBuilder \
+ UnpackedTarball/poppler/poppler/FILECacheLoader \
+ UnpackedTarball/poppler/poppler/FileSpec \
+ UnpackedTarball/poppler/poppler/FontEncodingTables \
+ UnpackedTarball/poppler/poppler/Form \
+ UnpackedTarball/poppler/poppler/FontInfo \
+ UnpackedTarball/poppler/poppler/Function \
+ UnpackedTarball/poppler/poppler/Gfx \
+ UnpackedTarball/poppler/poppler/GfxFont \
+ UnpackedTarball/poppler/poppler/GfxState \
+ UnpackedTarball/poppler/poppler/GlobalParams \
+ UnpackedTarball/poppler/poppler/Hints \
+ UnpackedTarball/poppler/poppler/ImageEmbeddingUtils \
+ UnpackedTarball/poppler/poppler/JArithmeticDecoder \
+ UnpackedTarball/poppler/poppler/JBIG2Stream \
+ UnpackedTarball/poppler/poppler/JSInfo \
+ UnpackedTarball/poppler/poppler/Lexer \
+ UnpackedTarball/poppler/poppler/Link \
+ UnpackedTarball/poppler/poppler/Linearization \
+ UnpackedTarball/poppler/poppler/LocalPDFDocBuilder \
+ UnpackedTarball/poppler/poppler/MarkedContentOutputDev \
+ UnpackedTarball/poppler/poppler/NameToCharCode \
+ UnpackedTarball/poppler/poppler/Object \
+ UnpackedTarball/poppler/poppler/OptionalContent \
+ UnpackedTarball/poppler/poppler/Outline \
+ UnpackedTarball/poppler/poppler/OutputDev \
+ UnpackedTarball/poppler/poppler/Page \
+ UnpackedTarball/poppler/poppler/PageTransition \
+ UnpackedTarball/poppler/poppler/Parser \
+ UnpackedTarball/poppler/poppler/PDFDoc \
+ UnpackedTarball/poppler/poppler/PDFDocBuilder \
+ UnpackedTarball/poppler/poppler/PDFDocEncoding \
+ UnpackedTarball/poppler/poppler/PDFDocFactory \
+ UnpackedTarball/poppler/poppler/ProfileData \
+ UnpackedTarball/poppler/poppler/PreScanOutputDev \
+ UnpackedTarball/poppler/poppler/PSTokenizer \
+ UnpackedTarball/poppler/poppler/SignatureInfo \
+ UnpackedTarball/poppler/poppler/Stream \
+ UnpackedTarball/poppler/poppler/StructTreeRoot \
+ UnpackedTarball/poppler/poppler/StructElement \
+ UnpackedTarball/poppler/poppler/UnicodeMap \
+ UnpackedTarball/poppler/poppler/UnicodeMapFuncs \
+ UnpackedTarball/poppler/poppler/UnicodeTypeTable \
+ UnpackedTarball/poppler/poppler/UTF \
+ UnpackedTarball/poppler/poppler/XRef \
+ UnpackedTarball/poppler/poppler/PSOutputDev \
+ UnpackedTarball/poppler/poppler/TextOutputDev \
+ UnpackedTarball/poppler/poppler/PageLabelInfo \
+ UnpackedTarball/poppler/poppler/SecurityHandler \
+ UnpackedTarball/poppler/poppler/Sound \
+ UnpackedTarball/poppler/poppler/ViewerPreferences \
+ UnpackedTarball/poppler/poppler/Movie \
+ UnpackedTarball/poppler/poppler/Rendition \
+ UnpackedTarball/poppler/poppler/DCTStream \
+ UnpackedTarball/poppler/splash/SplashBitmap \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/poppler/UnpackedTarball_poppler.mk b/external/poppler/UnpackedTarball_poppler.mk
new file mode 100644
index 000000000..5726814fe
--- /dev/null
+++ b/external/poppler/UnpackedTarball_poppler.mk
@@ -0,0 +1,29 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,poppler))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,poppler,$(POPPLER_TARBALL),,poppler))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,poppler,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,poppler,\
+ external/poppler/poppler-config.patch.1 \
+ external/poppler/pch.patch.0 \
+ external/poppler/disable-freetype.patch.1 \
+ external/poppler/gcc7-EntityInfo.patch.1 \
+))
+
+ifneq ($(filter -fsanitize=%,$(CC)),)
+$(eval $(call gb_UnpackedTarball_add_patches,poppler, \
+ external/poppler/sanitizer.patch \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/poppler/UnpackedTarball_poppler_data.mk b/external/poppler/UnpackedTarball_poppler_data.mk
new file mode 100644
index 000000000..e0357df5a
--- /dev/null
+++ b/external/poppler/UnpackedTarball_poppler_data.mk
@@ -0,0 +1,13 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,poppler_data))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,poppler_data,$(POPPLER_DATA_TARBALL),,poppler_data))
+# vim: set noet sw=4 ts=4:
diff --git a/external/poppler/disable-freetype.patch.1 b/external/poppler/disable-freetype.patch.1
new file mode 100644
index 000000000..710742206
--- /dev/null
+++ b/external/poppler/disable-freetype.patch.1
@@ -0,0 +1,41 @@
+disable freetype dependent code
+
+--- poppler/poppler/Form.cc.orig 2022-09-14 15:46:48.588316681 +0200
++++ poppler/poppler/Form.cc 2022-09-14 15:48:01.468274551 +0200
+@@ -46,7 +46,7 @@
+ #include <cstdlib>
+ #include <cstring>
+ #include <cctype>
+-#include "goo/ft_utils.h"
++//#include "goo/ft_utils.h"
+ #include "goo/gmem.h"
+ #include "goo/gfile.h"
+ #include "goo/GooString.h"
+@@ -77,8 +77,8 @@
+ #include "fofi/FoFiTrueType.h"
+ #include "fofi/FoFiIdentifier.h"
+
+-#include <ft2build.h>
+-#include FT_FREETYPE_H
++//#include <ft2build.h>
++//#include FT_FREETYPE_H
+
+ // return a newly allocated char* containing an UTF16BE string of size length
+ char *pdfDocEncodingToUTF16(const std::string &orig, int *length)
+@@ -2743,6 +2743,8 @@
+
+ Form::AddFontResult Form::addFontToDefaultResources(const std::string &filepath, int faceIndex, const std::string &fontFamily, const std::string &fontStyle)
+ {
++ return {};
++#if 0
+ if (!GooString::endsWith(filepath, ".ttf") && !GooString::endsWith(filepath, ".ttc") && !GooString::endsWith(filepath, ".otf")) {
+ error(errIO, -1, "We only support embedding ttf/ttc/otf fonts for now. The font file for {0:s} {1:s} was {2:s}", fontFamily.c_str(), fontStyle.c_str(), filepath.c_str());
+ return {};
+@@ -2951,6 +2953,7 @@
+ }
+
+ return { dictFontName, fontDictRef };
++#endif
+ }
+
+ std::string Form::getFallbackFontForChar(Unicode uChar, const GfxFont &fontToEmulate) const
diff --git a/external/poppler/gcc7-EntityInfo.patch.1 b/external/poppler/gcc7-EntityInfo.patch.1
new file mode 100644
index 000000000..b450bff93
--- /dev/null
+++ b/external/poppler/gcc7-EntityInfo.patch.1
@@ -0,0 +1,48 @@
+gcc 7.3.1 says:
+
+workdir/UnpackedTarball/poppler/poppler/CertificateInfo.cc:42:34: error: function ‘X509CertificateInfo::EntityInfo& X509CertificateInfo::EntityInfo::operator=(X509CertificateInfo::EntityInfo&&)’ defaulted on its redeclaration with an exception-specification that differs from the implicit exception-specification ‘’
+
+--- poppler/poppler/CertificateInfo.h.orig 2022-09-14 19:32:12.426351385 +0200
++++ poppler/poppler/CertificateInfo.h 2022-09-14 19:32:18.947347812 +0200
+@@ -70,7 +70,7 @@
+ ~EntityInfo();
+
+ EntityInfo(EntityInfo &&) noexcept;
+- EntityInfo &operator=(EntityInfo &&) noexcept;
++ EntityInfo &operator=(EntityInfo &&) /*noexcept*/;
+
+ EntityInfo(const EntityInfo &) = delete;
+ EntityInfo &operator=(const EntityInfo &) = delete;
+--- poppler/poppler/CertificateInfo.cc.orig 2022-09-14 19:31:10.225385467 +0200
++++ poppler/poppler/CertificateInfo.cc 2022-09-14 19:31:12.572384182 +0200
+@@ -39,7 +39,7 @@
+
+ X509CertificateInfo::EntityInfo::EntityInfo(X509CertificateInfo::EntityInfo &&other) noexcept = default;
+
+-X509CertificateInfo::EntityInfo &X509CertificateInfo::EntityInfo::operator=(X509CertificateInfo::EntityInfo &&other) noexcept = default;
++X509CertificateInfo::EntityInfo &X509CertificateInfo::EntityInfo::operator=(X509CertificateInfo::EntityInfo &&other) /*noexcept*/ = default;
+
+ X509CertificateInfo::X509CertificateInfo() : ku_extensions(KU_NONE), cert_version(-1), is_self_signed(false) { }
+
+--- poppler/poppler/GfxFont.cc.orig 2022-09-14 20:24:32.569607333 +0200
++++ poppler/poppler/GfxFont.cc 2022-09-14 20:24:52.323596186 +0200
+@@ -180,7 +180,7 @@
+
+ GfxFontLoc::GfxFontLoc(GfxFontLoc &&other) noexcept = default;
+
+-GfxFontLoc &GfxFontLoc::operator=(GfxFontLoc &&other) noexcept = default;
++GfxFontLoc &GfxFontLoc::operator=(GfxFontLoc &&other) /*noexcept*/ = default;
+
+ void GfxFontLoc::setPath(GooString *pathA)
+ {
+--- poppler/poppler/GfxFont.h.orig 2022-09-14 20:24:30.784608340 +0200
++++ poppler/poppler/GfxFont.h 2022-09-14 20:25:08.850586861 +0200
+@@ -124,7 +124,7 @@
+ GfxFontLoc(const GfxFontLoc &) = delete;
+ GfxFontLoc(GfxFontLoc &&) noexcept;
+ GfxFontLoc &operator=(const GfxFontLoc &) = delete;
+- GfxFontLoc &operator=(GfxFontLoc &&other) noexcept;
++ GfxFontLoc &operator=(GfxFontLoc &&other) /*noexcept*/;
+
+ // Set the 'path' string from a GooString on the heap.
+ // Ownership of the object is taken.
diff --git a/external/poppler/inc/pch/precompiled_poppler.cxx b/external/poppler/inc/pch/precompiled_poppler.cxx
new file mode 100644
index 000000000..5b97c67a7
--- /dev/null
+++ b/external/poppler/inc/pch/precompiled_poppler.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_poppler.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/poppler/inc/pch/precompiled_poppler.hxx b/external/poppler/inc/pch/precompiled_poppler.hxx
new file mode 100644
index 000000000..0b2824d75
--- /dev/null
+++ b/external/poppler/inc/pch/precompiled_poppler.hxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2021-11-03 15:11:24 using:
+ ./bin/update_pch external/poppler poppler --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/poppler/inc/pch/precompiled_poppler.hxx "make external/poppler.build" --find-conflicts
+*/
+
+#include <sal/config.h>
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <cctype>
+#include <cerrno>
+#include <cfloat>
+#include <climits>
+#include <clocale>
+#include <cmath>
+#include <config.h>
+#include <csignal>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <gdir.h>
+#include <gfile.h>
+#include <glibc.h>
+#include <gmem.h>
+#include <grandom.h>
+#include <gstrtod.h>
+#include <limits>
+#include <memory>
+#include <poppler-config.h>
+#include <random>
+#include <regex>
+#include <set>
+#include <vector>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <fofi/FoFiIdentifier.h>
+#include <fofi/FoFiTrueType.h>
+#include <fofi/FoFiType1.h>
+#include <fofi/FoFiType1C.h>
+#include <goo/GooCheckedOps.h>
+#include <goo/GooLikely.h>
+#include <goo/GooString.h>
+#include <goo/GooTimer.h>
+#include <goo/gdir.h>
+#include <goo/gfile.h>
+#include <goo/glibc.h>
+#include <goo/gmem.h>
+#include <goo/grandom.h>
+#include <goo/gstrtod.h>
+#include <poppler/Error.h>
+#include <splash/SplashTypes.h>
+#include <sys/stat.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/poppler/pch.patch.0 b/external/poppler/pch.patch.0
new file mode 100644
index 000000000..9ffeeb842
--- /dev/null
+++ b/external/poppler/pch.patch.0
@@ -0,0 +1,11 @@
+--- ./goo/gdir.h.sav 2021-01-02 17:54:42.000000000 +0100
++++ ./goo/gdir.h 2021-11-03 15:16:04.306277081 +0100
+@@ -37,6 +37,8 @@
+
+ #include <memory>
+
++#include "gfile.h"
++
+ class GooString;
+
+ #if defined(_WIN32)
diff --git a/external/poppler/poppler-config.patch.1 b/external/poppler/poppler-config.patch.1
new file mode 100644
index 000000000..1e61b533d
--- /dev/null
+++ b/external/poppler/poppler-config.patch.1
@@ -0,0 +1,486 @@
+*three* poppler config headers
+
+note: to get the 3rd one, use -DENABLE_CPP=on
+
+mkdir build && cd build && cmake .. -DENABLE_DCTDECODER=libjpeg -DHAVE_CAIRO=off -DENABLE_LIBOPENJPEG=none -DENABLE_CMS=none -DENABLE_LIBCURL=off -DENABLE_ZLIB=off -DENABLE_ZLIB_UNCOMPRESS=off -DENABLE_NSS3=off -DENABLE_LIBPNG=off -DENABLE_LIBTIFF=off -DENABLE_SPLASH=off -DENABLE_UTILS=off -DENABLE_CPP=off -DENABLE_GLIB=off -DENABLE_GOBJECT_INTROSPECTION=off -DENABLE_GTK_DOC=off -DENABLE_QT5=off
+
+manually disabled these because cmake failed to do it:
+HAVE_CAIRO
+ENABLE_NSS3
+ENABLE_LIBPNG (twice!)
+ENABLE_LIBTIFF (twice!)
+ENABLE_LIBCURL
+
+diff --git a/config.h b/config.h
+new file mode 100644
+index 0fbd336a..451213f8 100644
+--- /dev/null
++++ b/config.h
+@@ -0,0 +1,220 @@
++/* config.h. Generated from config.h.cmake by cmake. */
++
++/* Build against libcurl. */
++/* #undef ENABLE_LIBCURL */
++
++/* Use libjpeg instead of builtin jpeg decoder. */
++#define ENABLE_LIBJPEG 1
++
++/* Use libopenjpeg instead of builtin jpeg2000 decoder. */
++/* #undef ENABLE_LIBOPENJPEG */
++
++/* Build against libtiff. */
++/* #define ENABLE_LIBTIFF 1 */
++
++/* Build against libpng. */
++/* #define ENABLE_LIBPNG 1 */
++
++/* Do not hardcode the library location */
++/* #undef ENABLE_RELOCATABLE */
++
++/* Build against zlib. */
++/* #undef ENABLE_ZLIB */
++
++/* Use zlib instead of builtin zlib decoder to uncompress flate streams. */
++/* #undef ENABLE_ZLIB_UNCOMPRESS */
++
++/* Build against libnss3 for digital signature validation */
++/* #define ENABLE_NSS3 1 */
++
++/* Use cairo for rendering. */
++/* #define HAVE_CAIRO 1 */
++
++/* Do we have any DCT decoder?. */
++#define HAVE_DCT_DECODER 1
++
++/* Do we have any JPX decoder?. */
++/* #undef HAVE_JPX_DECODER */
++
++#if !defined(_WIN32)
++/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
++ */
++#define HAVE_DIRENT_H 1
++#endif
++
++#if !defined(_WIN32)
++/* Define to 1 if you have the <dlfcn.h> header file. */
++#define HAVE_DLFCN_H 1
++#endif
++
++/* Define to 1 if you have the <fcntl.h> header file. */
++#define HAVE_FCNTL_H 1
++
++/* Define to 1 if you have the `fseek64' function. */
++/* #undef HAVE_FSEEK64 */
++
++#if !defined(_WIN32)
++/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
++#define HAVE_FSEEKO 1
++#endif
++
++/* Define to 1 if you have the `ftell64' function. */
++/* #undef HAVE_FTELL64 */
++
++#if !defined(__APPLE__) && !defined(_WIN32)
++/* Define to 1 if you have the `pread64' function. */
++#define HAVE_PREAD64 1
++#endif
++
++#if !defined(__APPLE__) && !defined(_WIN32)
++/* Define to 1 if you have the `lseek64' function. */
++#define HAVE_LSEEK64 1
++#endif
++
++#if !defined(_WIN32)
++/* Defines if gettimeofday is available on your system */
++#define HAVE_GETTIMEOFDAY 1
++#endif
++
++#if !defined(_WIN32)
++/* Defines if gmtime_r is available on your system */
++#define HAVE_GMTIME_R 1
++#endif
++
++#if !defined(_WIN32)
++/* Defines if timegm is available on your system */
++#define HAVE_TIMEGM 1
++#endif
++
++/* Define to 1 if you have the `z' library (-lz). */
++/* #undef HAVE_LIBZ */
++
++#if !defined(_WIN32)
++/* Defines if localtime_r is available on your system */
++#define HAVE_LOCALTIME_R 1
++#endif
++
++#if !defined(_WIN32)
++/* Define to 1 if you have the `mkstemp' function. */
++#define HAVE_MKSTEMP 1
++#endif
++
++#if !defined(_WIN32)
++/* Defines if strtok_r is available on your system */
++#define HAVE_STRTOK_R 1
++#endif
++
++/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
++/* #undef HAVE_NDIR_H */
++
++#if !defined(_WIN32)
++/* Define to 1 if you have the `popen' function. */
++#define HAVE_POPEN 1
++#endif
++
++#if !defined(__APPLE__) && !defined(_WIN32)
++/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
++ */
++#define HAVE_SYS_DIR_H 1
++#endif
++
++#if !defined(__APPLE__) && !defined(_WIN32)
++/* Define to 1 if you have the <sys/mman.h> header file. */
++#define HAVE_SYS_MMAN_H 1
++#endif
++
++/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
++ */
++/* #undef HAVE_SYS_NDIR_H */
++
++/* Define to 1 if you have the <sys/stat.h> header file. */
++#define HAVE_SYS_STAT_H 1
++
++#if !defined(_WIN32)
++/* Define to 1 if you have the <unistd.h> header file. */
++#define HAVE_UNISTD_H 1
++#endif
++
++/* Define to 1 if you have a big endian machine */
++/* #undef WORDS_BIGENDIAN */
++
++/* Define as const if the declaration of iconv() needs const. */
++#define ICONV_CONST
++
++/* Generate OPI comments in PS output. */
++#define OPI_SUPPORT 1
++
++/* Name of package */
++#define PACKAGE "poppler"
++
++/* Define to the address where bug reports for this package should be sent. */
++#define PACKAGE_BUGREPORT "https://bugs.freedesktop.org/enter_bug.cgi?product=poppler"
++
++/* Define to the full name of this package. */
++#define PACKAGE_NAME "poppler"
++
++/* Define to the full name and version of this package. */
++#define PACKAGE_STRING "poppler 22.12.0"
++
++/* Define to the one symbol short name of this package. */
++#define PACKAGE_TARNAME "poppler"
++
++/* Define to the home page for this package. */
++#define PACKAGE_URL ""
++
++/* Define to the version of this package. */
++#define PACKAGE_VERSION "22.12.0"
++
++/* Poppler data dir */
++#define POPPLER_DATADIR "/usr/local/share/poppler"
++
++/* Support for curl based doc builder is compiled in. */
++/* #undef POPPLER_HAS_CURL_SUPPORT */
++
++/* Enable word list support. */
++#define TEXTOUT_WORD_LIST 1
++
++/* Defines if use cms */
++/* #undef USE_CMS */
++
++/* Use single precision arithmetic in the Splash backend */
++/* #undef USE_FLOAT */
++
++/* Version number of package */
++#define VERSION "22.12.0"
++
++#if defined(__APPLE__)
++#elif defined (_WIN32)
++/* Use win32 font configuration backend */
++#define WITH_FONTCONFIGURATION_WIN32 1
++#else
++/* Use fontconfig font configuration backend */
++#define WITH_FONTCONFIGURATION_FONTCONFIG 1
++#endif
++
++/* OpenJPEG with the OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG flag */
++/* #undef WITH_OPENJPEG_IGNORE_PCLR_CMAP_CDEF_FLAG */
++
++/* MS defined snprintf as deprecated but then added it in Visual Studio 2015. */
++#if defined(_MSC_VER) && _MSC_VER < 1900
++#define snprintf _snprintf
++#endif
++
++//------------------------------------------------------------------------
++// popen
++//------------------------------------------------------------------------
++#if defined(_MSC_VER) || defined(__BORLANDC__)
++#define popen _popen
++#define pclose _pclose
++#define strncasecmp _strnicmp
++#define strcasecmp _stricmp
++#endif
++
++/* Number of bits in a file offset, on hosts where this is settable. */
++/* #undef _FILE_OFFSET_BITS */
++
++/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
++/* TODO This is wrong, port if needed #undef _LARGEFILE_SOURCE */
++
++/* Define for large files, on AIX-style hosts. */
++/* TODO This is wrong, port if needed #undef _LARGE_FILES */
+diff --git a/poppler/poppler-config.h b/poppler/poppler-config.h
+new file mode 100644
+index 0fbd336a..451213f8 100644
+--- /dev/null
++++ b/poppler/poppler-config.h
+@@ -0,0 +1,161 @@
++//================================================= -*- mode: c++ -*- ====
++//
++// poppler-config.h
++//
++// Copyright 1996-2011, 2022 Glyph & Cog, LLC
++//
++//========================================================================
++
++//========================================================================
++//
++// Modified under the Poppler project - http://poppler.freedesktop.org
++//
++// All changes made under the Poppler project to this file are licensed
++// under GPL version 2 or later
++//
++// Copyright (C) 2014 Bogdan Cristea <cristeab@gmail.com>
++// Copyright (C) 2014 Hib Eris <hib@hiberis.nl>
++// Copyright (C) 2016 Tor Lillqvist <tml@collabora.com>
++// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
++// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
++// Copyright (C) 2018 Stefan Brüns <stefan.bruens@rwth-aachen.de>
++// Copyright (C) 2020 Albert Astals Cid <aacid@kde.org>
++//
++// To see a description of the changes please see the Changelog file that
++// came with your tarball or type make ChangeLog if you are building from git
++//
++//========================================================================
++
++#ifndef POPPLER_CONFIG_H
++#define POPPLER_CONFIG_H
++
++// We duplicate some of the config.h #define's here since they are
++// used in some of the header files we install. The #ifndef/#endif
++// around #undef look odd, but it's to silence warnings about
++// redefining those symbols.
++
++/* Defines the poppler version. */
++#ifndef POPPLER_VERSION
++#define POPPLER_VERSION "22.12.0"
++#endif
++
++/* Use single precision arithmetic in the Splash backend */
++#ifndef USE_FLOAT
++/* #undef USE_FLOAT */
++#endif
++
++/* Include support for OPI comments. */
++#ifndef OPI_SUPPORT
++#define OPI_SUPPORT 1
++#endif
++
++/* Enable word list support. */
++#ifndef TEXTOUT_WORD_LIST
++#define TEXTOUT_WORD_LIST 1
++#endif
++
++/* Support for curl is compiled in. */
++#ifndef POPPLER_HAS_CURL_SUPPORT
++/* #undef POPPLER_HAS_CURL_SUPPORT */
++#endif
++
++/* Use libjpeg instead of builtin jpeg decoder. */
++#ifndef ENABLE_LIBJPEG
++#define ENABLE_LIBJPEG 1
++#endif
++
++/* Build against libtiff. */
++#ifndef ENABLE_LIBTIFF
++/* #define ENABLE_LIBTIFF 1 */
++#endif
++
++/* Build against libpng. */
++#ifndef ENABLE_LIBPNG
++/* #define ENABLE_LIBPNG 1 */
++#endif
++
++/* Use zlib instead of builtin zlib decoder. */
++#ifndef ENABLE_ZLIB
++/* #undef ENABLE_ZLIB */
++#endif
++
++/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
++ */
++#ifndef HAVE_DIRENT_H
++#if !defined(_WIN32)
++#define HAVE_DIRENT_H 1
++#endif
++#endif
++
++/* Defines if gettimeofday is available on your system */
++#ifndef HAVE_GETTIMEOFDAY
++#if !defined(_WIN32)
++#define HAVE_GETTIMEOFDAY 1
++#endif
++#endif
++
++/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
++#ifndef HAVE_NDIR_H
++/* #undef HAVE_NDIR_H */
++#endif
++
++/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
++ */
++#ifndef HAVE_SYS_DIR_H
++#if !defined(__APPLE__) && !defined(_WIN32)
++#define HAVE_SYS_DIR_H 1
++#endif
++#endif
++
++/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
++ */
++#ifndef HAVE_SYS_NDIR_H
++/* #undef HAVE_SYS_NDIR_H */
++#endif
++
++/* Defines if use cms */
++#ifndef USE_CMS
++/* #undef USE_CMS */
++#endif
++
++/* Use header-only classes from Boost in the Splash backend */
++#ifndef USE_BOOST_HEADERS
++/* #undef USE_BOOST_HEADERS */
++#endif
++
++//------------------------------------------------------------------------
++// version
++//------------------------------------------------------------------------
++
++// copyright notice
++#define popplerCopyright "Copyright 2005-2022 The Poppler Developers - http://poppler.freedesktop.org"
++#define xpdfCopyright "Copyright 1996-2011, 2022 Glyph & Cog, LLC"
++
++//------------------------------------------------------------------------
++// Win32 stuff
++//------------------------------------------------------------------------
++
++#if defined(_WIN32) && !defined(_MSC_VER)
++#include <windef.h>
++#else
++#define CDECL
++#endif
++
++//------------------------------------------------------------------------
++// Compiler
++//------------------------------------------------------------------------
++
++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
++#include <cstdio> // __MINGW_PRINTF_FORMAT is defined in the mingw stdio.h
++#ifdef __MINGW_PRINTF_FORMAT
++#define GCC_PRINTF_FORMAT(fmt_index, va_index) \
++ __attribute__((__format__(__MINGW_PRINTF_FORMAT, fmt_index, va_index)))
++#else
++#define GCC_PRINTF_FORMAT(fmt_index, va_index) \
++ __attribute__((__format__(__printf__, fmt_index, va_index)))
++#endif
++#else
++#define GCC_PRINTF_FORMAT(fmt_index, va_index)
++#endif
++
++#endif /* POPPLER_CONFIG_H */
+diff --git a/cpp/poppler-version.h b/cpp/poppler-version.h
+new file mode 100644
+index 0fbd336a..451213f8 100644
+--- /dev/null
++++ b/cpp/poppler-version.h
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (C) 2009, Pino Toscano <pino@kde.org>
++ *
++ * 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, 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
++ */
++
++#ifndef POPPLER_VERSION_H
++#define POPPLER_VERSION_H
++
++#include "poppler-global.h"
++
++#define POPPLER_VERSION "22.12.0"
++#define POPPLER_VERSION_MAJOR 22
++#define POPPLER_VERSION_MINOR 12
++#define POPPLER_VERSION_MICRO 0
++
++namespace poppler
++{
++
++POPPLER_CPP_EXPORT std::string version_string();
++POPPLER_CPP_EXPORT unsigned int version_major();
++POPPLER_CPP_EXPORT unsigned int version_minor();
++POPPLER_CPP_EXPORT unsigned int version_micro();
++
++}
++
++#endif
+diff --git a/poppler_private_export.h b/poppler_private_export.h
+new file mode 100644
+index 0fbd336a..451213f8 100644
+--- /dev/null
++++ b/poppler_private_export.h
+@@ -0,0 +1,11 @@
++
++#ifndef POPPLER_PRIVATE_EXPORT_H
++#define POPPLER_PRIVATE_EXPORT_H
++
++# define POPPLER_PRIVATE_EXPORT
++# define POPPLER_PRIVATE_NO_EXPORT
++# define POPPLER_PRIVATE_DEPRECATED
++# define POPPLER_PRIVATE_DEPRECATED_EXPORT
++# define POPPLER_PRIVATE_DEPRECATED_NO_EXPORT
++
++#endif /* POPPLER_PRIVATE_EXPORT_H */
+
+diff --git a/cpp/poppler_cpp_export.h b/cpp/poppler_cpp_export.h
+new file mode 100644
+index 0fbd336a..451213f8 100644
+--- /dev/null
++++ b/cpp/poppler_cpp_export.h
+@@ -0,0 +1,11 @@
++
++#ifndef POPPLER_CPP_EXPORT_H
++#define POPPLER_CPP_EXPORT_H
++
++# define POPPLER_CPP_EXPORT
++# define POPPLER_CPP_NO_EXPORT
++# define POPPLER_CPP_DEPRECATED
++# define POPPLER_CPP_DEPRECATED_EXPORT
++# define POPPLER_CPP_DEPRECATED_NO_EXPORT
++
++#endif /* POPPLER_CPP_EXPORT_H */
diff --git a/external/poppler/sanitizer.patch b/external/poppler/sanitizer.patch
new file mode 100644
index 000000000..c08e1b4e8
--- /dev/null
+++ b/external/poppler/sanitizer.patch
@@ -0,0 +1,18 @@
+--- poppler/PSOutputDev.cc
++++ poppler/PSOutputDev.cc
+@@ -3138,6 +3138,8 @@
+ bool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, int rotateA, bool useMediaBox, bool crop, int sliceX, int sliceY, int sliceW, int sliceH, bool printing, bool (*abortCheckCbk)(void *data),
+ void *abortCheckCbkData, bool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), void *annotDisplayDecideCbkData)
+ {
++ std::abort();
++#if 0
+ PreScanOutputDev *scan;
+ bool rasterize;
+ bool useFlate, useLZW;
+@@ -3623,5 +3625,6 @@
+
+ return false;
++#endif
+ }
+
+ void PSOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA)
diff --git a/external/postgresql/ExternalPackage_postgresql.mk b/external/postgresql/ExternalPackage_postgresql.mk
new file mode 100644
index 000000000..ada8c4f38
--- /dev/null
+++ b/external/postgresql/ExternalPackage_postgresql.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,postgresql,postgresql))
+
+$(eval $(call gb_ExternalPackage_use_external_project,postgresql,postgresql))
+
+$(eval $(call gb_ExternalPackage_add_file,postgresql,$(LIBO_LIB_FOLDER)/libpq.dll,$(gb_MSBUILD_CONFIG)/libpq/libpq.dll))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/postgresql/ExternalProject_postgresql.mk b/external/postgresql/ExternalProject_postgresql.mk
new file mode 100644
index 000000000..24e54adf3
--- /dev/null
+++ b/external/postgresql/ExternalProject_postgresql.mk
@@ -0,0 +1,86 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,postgresql))
+
+$(eval $(call gb_ExternalProject_use_externals,postgresql,\
+ $(if $(ENABLE_LDAP),openldap) \
+ openssl \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,postgresql,\
+ build \
+))
+
+ifeq ($(OS),WNT)
+
+$(eval $(call gb_ExternalProject_use_nmake,postgresql,build))
+
+$(call gb_ExternalProject_get_state_target,postgresql,build) :
+ $(call gb_Trace_StartRange,postgresql,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ MSBFLAGS="/p:Platform=$(gb_MSBUILD_PLATFORM) \
+ /p:PlatformToolset=$(VCTOOLSET) /p:VisualStudioVersion=$(VCVER) /ToolsVersion:Current \
+ $(if $(filter 10,$(WINDOWS_SDK_VERSION)),/p:WindowsTargetPlatformVersion=$(UCRTVERSION))" \
+ $(PERL) build.pl $(gb_MSBUILD_CONFIG) libpq \
+ ,src/tools/msvc)
+ $(call gb_Trace_EndRange,postgresql,EXTERNAL)
+
+else
+
+postgresql_CPPFLAGS := $(ZLIB_CFLAGS)
+postgresql_LDFLAGS := $(LDFLAGS)
+
+ifeq ($(SYSTEM_ZLIB),)
+postgresql_LDFLAGS += $(ZLIB_LIBS)
+endif
+
+ifeq ($(ENABLE_OPENSSL),TRUE)
+ifeq ($(SYSTEM_OPENSSL),)
+postgresql_CPPFLAGS += -I$(call gb_UnpackedTarball_get_dir,openssl)/include
+postgresql_LDFLAGS += -L$(call gb_UnpackedTarball_get_dir,openssl)/ $(if $(filter $(OS),LINUX),-pthread)
+endif
+endif
+
+ifeq ($(SYSTEM_OPENLDAP),)
+postgresql_CPPFLAGS += -I$(call gb_UnpackedTarball_get_dir,openldap)/include
+postgresql_LDFLAGS += \
+ -L$(call gb_UnpackedTarball_get_dir,openldap)/libraries/libldap_r/.libs \
+ -L$(call gb_UnpackedTarball_get_dir,openldap)/libraries/libldap/.libs \
+ -L$(call gb_UnpackedTarball_get_dir,openldap)/libraries/liblber/.libs \
+ $(if $(SYSTEM_NSS),,\
+ -L$(call gb_UnpackedTarball_get_dir,nss)/dist/out/lib) \
+
+endif
+
+# note: as of 13.1, zlib is not needed by libpq
+# passing MAKELEVEL=0 is required to find internal headers
+
+$(call gb_ExternalProject_get_state_target,postgresql,build) :
+ $(call gb_Trace_StartRange,postgresql,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(gb_RUN_CONFIGURE) ./configure \
+ --without-readline \
+ --without-zlib \
+ --with-ldap \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(ENABLE_OPENSSL),--with-openssl \
+ $(if $(WITH_GSSAPI),--with-gssapi)) \
+ $(if $(ENABLE_LDAP),,--with-ldap=no) \
+ CFLAGS="-fPIC" \
+ CPPFLAGS="$(postgresql_CPPFLAGS)" \
+ LDFLAGS="$(postgresql_LDFLAGS)" \
+ $(if $(ENABLE_LDAP),EXTRA_LDAP_LIBS="-llber -lssl3 -lsmime3 -lnss3 -lnssutil3 -lplds4 -lplc4 -lnspr4") \
+ && cd src/interfaces/libpq \
+ && MAKEFLAGS= && $(MAKE) MAKELEVEL=0 all-static-lib)
+ $(call gb_Trace_EndRange,postgresql,EXTERNAL)
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/postgresql/Makefile b/external/postgresql/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/postgresql/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/postgresql/Module_postgresql.mk b/external/postgresql/Module_postgresql.mk
new file mode 100644
index 000000000..7ea89dad3
--- /dev/null
+++ b/external/postgresql/Module_postgresql.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,postgresql))
+
+$(eval $(call gb_Module_add_targets,postgresql,\
+ ExternalProject_postgresql \
+ UnpackedTarball_postgresql \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_Module_add_targets,postgresql,\
+ ExternalPackage_postgresql \
+))
+endif # WNT
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/postgresql/README b/external/postgresql/README
new file mode 100644
index 000000000..edc3d5df2
--- /dev/null
+++ b/external/postgresql/README
@@ -0,0 +1,3 @@
+PostgreSQL object-relational database management system
+
+We use some pieces of this code for the postgresql database connector. \ No newline at end of file
diff --git a/external/postgresql/UnpackedTarball_postgresql.mk b/external/postgresql/UnpackedTarball_postgresql.mk
new file mode 100644
index 000000000..11fb603ef
--- /dev/null
+++ b/external/postgresql/UnpackedTarball_postgresql.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,postgresql))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,postgresql,$(POSTGRESQL_TARBALL),,postgresql))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,postgresql,config))
+
+$(eval $(call gb_UnpackedTarball_add_patches,postgresql, \
+ external/postgresql/windows.patch.0 \
+ external/postgresql/postgresql.exit.patch.0 \
+ external/postgresql/postgres-msvc-build.patch.1 \
+ $(if $(filter WNT_AARCH64,$(OS)_$(CPUNAME)), external/postgresql/arm64.patch.1) \
+))
+
+ifeq ($(CROSS_COMPILING),)
+$(eval $(call gb_UnpackedTarball_add_file,postgresql,src/tools/msvc/config.pl,external/postgresql/config.pl))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/postgresql/arm64.patch.1 b/external/postgresql/arm64.patch.1
new file mode 100644
index 000000000..db8a3ad0a
--- /dev/null
+++ b/external/postgresql/arm64.patch.1
@@ -0,0 +1,53 @@
+diff -ur postgresql.org/src/tools/msvc/Mkvcbuild.pm postgresql/src/tools/msvc/Mkvcbuild.pm
+--- postgresql.org/src/tools/msvc/Mkvcbuild.pm 2021-03-14 02:09:15.288060770 +0100
++++ postgresql/src/tools/msvc/Mkvcbuild.pm 2021-03-14 02:12:22.351726582 +0100
+@@ -107,13 +107,6 @@
+
+ push(@pgportfiles, 'strtof.c') if ($vsVersion < '14.00');
+
+- if ($vsVersion >= '9.00')
+- {
+- push(@pgportfiles, 'pg_crc32c_sse42_choose.c');
+- push(@pgportfiles, 'pg_crc32c_sse42.c');
+- push(@pgportfiles, 'pg_crc32c_sb8.c');
+- }
+- else
+ {
+ push(@pgportfiles, 'pg_crc32c_sb8.c');
+ }
+diff -ur postgresql.org/src/tools/msvc/MSBuildProject.pm postgresql/src/tools/msvc/MSBuildProject.pm
+--- postgresql.org/src/tools/msvc/MSBuildProject.pm 2021-03-14 02:09:15.288060770 +0100
++++ postgresql/src/tools/msvc/MSBuildProject.pm 2021-03-14 02:12:22.351726582 +0100
+@@ -307,8 +307,7 @@
+ : ($self->{type} eq "dll" ? 'DynamicLibrary' : 'StaticLibrary');
+ my $libs = $self->GetAdditionalLinkerDependencies($cfgname, ';');
+
+- my $targetmachine =
+- $self->{platform} eq 'Win32' ? 'MachineX86' : 'MachineX64';
++ my $targetmachine = "MachineARM64";
+
+ my $includes = $self->{includes};
+ unless ($includes eq '' or $includes =~ /;$/)
+@@ -347,7 +346,6 @@
+ <ProgramDatabaseFile>.\\$cfgname\\$self->{name}\\$self->{name}.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapFileName>.\\$cfgname\\$self->{name}\\$self->{name}.map</MapFileName>
+- <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <!-- Permit links to MinGW-built, 32-bit DLLs (default before VS2012). -->
+ <ImageHasSafeExceptionHandlers/>
+ <SubSystem>Console</SubSystem>
+diff -ur postgresql.org/src/tools/msvc/Solution.pm postgresql/src/tools/msvc/Solution.pm
+--- postgresql.org/src/tools/msvc/Solution.pm 2021-03-14 02:09:15.288060770 +0100
++++ postgresql/src/tools/msvc/Solution.pm 2021-03-14 02:12:22.351726582 +0100
+@@ -62,10 +62,7 @@
+ if (1) #($^O eq "MSWin32")
+ {
+ # Examine CL help output to determine if we are in 32 or 64-bit mode.
+- my $output = `cl /? 2>&1`;
+- $? >> 8 == 0 or die "cl command not found";
+- $self->{platform} =
+- ($output =~ /^\/favor:<.+AMD64/m) ? 'x64' : 'Win32';
++ $self->{platform} = 'ARM64';
+ }
+ else
+ {
diff --git a/external/postgresql/config.pl b/external/postgresql/config.pl
new file mode 100644
index 000000000..ae163ebbd
--- /dev/null
+++ b/external/postgresql/config.pl
@@ -0,0 +1 @@
+$config->{openssl} = "$ENV{WORKDIR}/UnpackedTarball/openssl";
diff --git a/external/postgresql/postgres-msvc-build.patch.1 b/external/postgresql/postgres-msvc-build.patch.1
new file mode 100644
index 000000000..dec317422
--- /dev/null
+++ b/external/postgresql/postgres-msvc-build.patch.1
@@ -0,0 +1,110 @@
+Cygwin perl calls /bin/sh which can't resolve to .exe
+
+Also Cygwin perl has $Config{osname} different from MSWin32, and why even check that?
+
+--- postgresql/src/tools/msvc/build.pl.orig 2021-01-19 17:36:09.801463500 +0100
++++ postgresql/src/tools/msvc/build.pl 2021-01-19 17:36:20.426821300 +0100
+@@ -55,13 +55,13 @@
+ if ($buildwhat)
+ {
+ system(
+- "msbuild $buildwhat.vcxproj /verbosity:normal $msbflags /p:Configuration=$bconf"
++ "msbuild.exe $buildwhat.vcxproj /verbosity:normal $msbflags /p:Configuration=$bconf"
+ );
+ }
+ else
+ {
+ system(
+- "msbuild pgsql.sln /verbosity:normal $msbflags /p:Configuration=$bconf"
++ "msbuild.exe pgsql.sln /verbosity:normal $msbflags /p:Configuration=$bconf"
+ );
+ }
+
+--- postgresql/src/tools/msvc/Project.pm.orig 2021-01-19 17:59:18.799237700 +0100
++++ postgresql/src/tools/msvc/Project.pm 2021-01-19 17:59:48.487711700 +0100
+@@ -22,7 +22,7 @@
+ my $self = {
+ name => $name,
+ type => $type,
+- guid => $^O eq "MSWin32" ? Win32::GuidGen() : 'FAKE',
++ guid => Win32::GuidGen(),
+ files => {},
+ references => [],
+ libraries => [],
+--- postgresql/src/tools/msvc/Solution.pm.orig 2021-01-19 18:03:04.594229100 +0100
++++ postgresql/src/tools/msvc/Solution.pm 2021-01-19 18:04:13.677610100 +0100
+@@ -59,7 +59,7 @@
+ {
+ my $self = shift;
+
+- if ($^O eq "MSWin32")
++ if (1) #($^O eq "MSWin32")
+ {
+ # Examine CL help output to determine if we are in 32 or 64-bit mode.
+ my $output = `cl /? 2>&1`;
+@@ -1100,7 +1100,7 @@
+ }
+ if ($fld ne "")
+ {
+- $flduid{$fld} = $^O eq "MSWin32" ? Win32::GuidGen() : 'FAKE';
++ $flduid{$fld} = Win32::GuidGen();
+ print $sln <<EOF;
+ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "$fld", "$fld", "$flduid{$fld}"
+ EndProject
+--- postgresql/src/tools/msvc/VSObjectFactory.pm.orig 2021-01-19 18:06:42.633421700 +0100
++++ postgresql/src/tools/msvc/VSObjectFactory.pm 2021-01-19 18:06:28.663523200 +0100
+@@ -131,7 +131,7 @@
+
+ sub DetermineVisualStudioVersion
+ {
+- if ($^O eq "MSWin32")
++ if (1) # ($^O eq "MSWin32")
+ {
+ # To determine version of Visual Studio we use nmake as it has
+ # existed for a long time and still exists in current Visual
+--- postgresql/src/tools/msvc/Mkvcbuild.pm.orig 2021-01-19 18:23:59.830153900 +0100
++++ postgresql/src/tools/msvc/Mkvcbuild.pm 2021-01-19 18:24:04.095411300 +0100
+@@ -9,7 +9,7 @@
+ use warnings;
+
+ use Carp;
+-use if ($^O eq "MSWin32"), 'Win32';
++use Win32;
+ use Project;
+ use Solution;
+ use Cwd;
+--- postgresql/src/tools/msvc/Solution.pm.orig 2021-01-19 20:27:21.366237600 +0100
++++ postgresql/src/tools/msvc/Solution.pm 2021-01-19 20:28:17.773662900 +0100
+@@ -126,7 +126,8 @@
+ # openssl.exe is in the specified directory.
+ # Quote the .exe name in case it has spaces
+ my $opensslcmd =
+- qq("$self->{options}->{openssl}\\bin\\openssl.exe" version 2>&1);
++ qq("$self->{options}->{openssl}\\apps\\openssl.exe" version 2>&1);
++ print "$opensslcmd";
+ my $sslout = `$opensslcmd`;
+
+ $? >> 8 == 0
+@@ -967,8 +967,8 @@
+ # On both Win32 and Win64 the same library
+ # names are used without a debugging context.
+ $dbgsuffix = 0;
+- $libsslpath = '\lib\libssl.lib';
+- $libcryptopath = '\lib\libcrypto.lib';
++ $libsslpath = '\libssl.lib';
++ $libcryptopath = '\libcrypto.lib';
+ }
+
+ $proj->AddLibrary($self->{options}->{openssl} . $libsslpath,
+@@ -993,9 +993,9 @@
+ # to be here, so don't ask for it in last
+ # parameter.
+ $proj->AddLibrary(
+- $self->{options}->{openssl} . '\lib\ssleay32.lib', 0);
++ $self->{options}->{openssl} . '\ssleay32.lib', 0);
+ $proj->AddLibrary(
+- $self->{options}->{openssl} . '\lib\libeay32.lib', 0);
++ $self->{options}->{openssl} . '\libeay32.lib', 0);
+ }
+ }
+ }
diff --git a/external/postgresql/postgresql.exit.patch.0 b/external/postgresql/postgresql.exit.patch.0
new file mode 100644
index 000000000..8eaa1ea52
--- /dev/null
+++ b/external/postgresql/postgresql.exit.patch.0
@@ -0,0 +1,19 @@
+# error: implicitly declaring library function 'exit' with type 'void (int) __attribute__((noreturn))' [-Werror,-Wimplicit-function-declaration]
+--- configure
++++ configure
+@@ -16997,6 +16997,7 @@
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
++#include <stdlib.h>
+ typedef long int ac_int64;
+
+ /*
+@@ -17081,6 +17082,7 @@
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
++#include <stdlib.h>
+ typedef long long int ac_int64;
+
+ /*
diff --git a/external/postgresql/windows.patch.0 b/external/postgresql/windows.patch.0
new file mode 100644
index 000000000..28fc9046c
--- /dev/null
+++ b/external/postgresql/windows.patch.0
@@ -0,0 +1,11 @@
+--- src/port/chklocale.c
++++ src/port/chklocale.c
+@@ -220,7 +220,7 @@
+ {
+ r = malloc(16); /* excess */
+ if (r != NULL)
+- sprintf(r, "CP%u", loct->locinfo->lc_codepage);
++ sprintf(r, "CP%u", ((struct __crt_locale_data_public *) loct->locinfo)->_locale_lc_codepage);
+ _free_locale(loct);
+ }
+ #else
diff --git a/external/python3/ExternalPackage_python3.mk b/external/python3/ExternalPackage_python3.mk
new file mode 100644
index 000000000..9987ab138
--- /dev/null
+++ b/external/python3/ExternalPackage_python3.mk
@@ -0,0 +1,892 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,python3,python3))
+
+$(eval $(call gb_ExternalPackage_use_external_project,python3,python3))
+
+ifeq ($(OS),WNT)
+ifeq ($(CPUNAME),X86_64)
+python_arch_subdir=amd64/
+else ifeq ($(CPUNAME),AARCH64)
+python_arch_subdir=arm64/
+else
+python_arch_subdir=win32/
+endif
+
+$(eval $(call gb_ExternalPackage_add_file,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/bin/python.exe,PCbuild/$(python_arch_subdir)python$(if $(MSVC_USE_DEBUG_RUNTIME),_d).exe))
+$(eval $(call gb_ExternalPackage_add_file,python3,$(LIBO_BIN_FOLDER)/python$(PYTHON_VERSION_MAJOR)$(PYTHON_VERSION_MINOR)$(if $(MSVC_USE_DEBUG_RUNTIME),_d).dll,PCbuild/$(python_arch_subdir)python$(PYTHON_VERSION_MAJOR)$(PYTHON_VERSION_MINOR)$(if $(MSVC_USE_DEBUG_RUNTIME),_d).dll))
+ifeq ($(MSVC_USE_DEBUG_RUNTIME),)
+$(eval $(call gb_ExternalPackage_add_file,python3,$(LIBO_BIN_FOLDER)/python$(PYTHON_VERSION_MAJOR).dll,PCbuild/$(python_arch_subdir)python$(PYTHON_VERSION_MAJOR).dll))
+endif
+python3_EXTENSION_MODULES= \
+ PCbuild/$(python_arch_subdir)_asyncio$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)_ctypes$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)_decimal$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)_elementtree$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)_msi$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)_multiprocessing$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)_overlapped$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)_queue$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)_socket$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)_ssl$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)pyexpat$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)select$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)unicodedata$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+ PCbuild/$(python_arch_subdir)winsound$(if $(MSVC_USE_DEBUG_RUNTIME),_d).pyd \
+
+$(eval $(call gb_ExternalPackage_add_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib,\
+ $(python3_EXTENSION_MODULES) \
+))
+else
+$(eval $(call gb_ExternalPackage_add_file,python3,$(LIBO_BIN_FOLDER)/python.bin,python))
+$(eval $(call gb_ExternalPackage_add_file,python3,$(LIBO_BIN_FOLDER)/libpython$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)$(if $(ENABLE_DBGUTIL),d).so,libpython$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)$(if $(ENABLE_DBGUTIL),d).so))
+$(eval $(call gb_ExternalPackage_add_file,python3,$(LIBO_BIN_FOLDER)/libpython$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)$(if $(ENABLE_DBGUTIL),d).so.1.0,libpython$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)$(if $(ENABLE_DBGUTIL),d).so))
+$(eval $(call gb_ExternalPackage_add_file,python3,$(LIBO_BIN_FOLDER)/python.bin-gdb.py,Tools/gdb/libpython.py))
+
+# Unfortunately the python build system does not allow to explicitly enable or
+# disable these, it just tries to build them and then prints which did not
+# build successfully without stopping; that's why ExternalProject_python3 explicitly checks for the
+# existence of all the files on the python3_EXTENSION_MODULES list at the end of the build.
+# Obviously this list should not contain stuff with external dependencies
+# that may not be available on baseline systems.
+
+ifneq ($(OS),AIX)
+python3_EXTENSION_MODULE_SUFFIX=cpython-$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)$(if $(ENABLE_DBGUTIL),d)
+python3_EXTENSION_MODULES= \
+ LO_lib/array.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_asyncio.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/audioop.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/binascii.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_bisect.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_blake2.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/cmath.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_codecs_cn.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_codecs_hk.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_codecs_iso2022.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_codecs_jp.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_codecs_kr.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_codecs_tw.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_contextvars.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_crypt.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_csv.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_ctypes.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_datetime.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_decimal.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_elementtree.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/fcntl.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/grp.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ $(if $(ENABLE_OPENSSL), \
+ LO_lib/_hashlib.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ ) \
+ LO_lib/_heapq.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_json.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_lsprof.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/math.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_md5.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/mmap.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_multibytecodec.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_multiprocessing.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_opcode.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/ossaudiodev.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/parser.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_pickle.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_posixshmem.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_posixsubprocess.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/pyexpat.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_queue.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_random.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/resource.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/select.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_sha1.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_sha256.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_sha3.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_sha512.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_socket.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/spwd.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ $(if $(ENABLE_OPENSSL), \
+ LO_lib/_ssl.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ ) \
+ LO_lib/_statistics.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_struct.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/syslog.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/termios.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/unicodedata.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ $(if $(ENABLE_DBGUTIL),, \
+ LO_lib/xxlimited.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ )\
+ LO_lib/_xxsubinterpreters.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/_xxtestfuzz.$(python3_EXTENSION_MODULE_SUFFIX).so \
+ LO_lib/zlib.$(python3_EXTENSION_MODULE_SUFFIX).so \
+
+$(eval $(call gb_ExternalPackage_add_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/lib-dynload,\
+ $(python3_EXTENSION_MODULES) \
+))
+endif
+endif
+
+# headers are not delivered, but used from unpacked dir Include/
+# (+ toplevel for pyconfig.h)
+
+ifeq ($(OS),LINUX)
+python3_MACHDEP=linux
+else
+ifeq ($(OS),MACOSX)
+python3_MACHDEP=darwin
+endif
+endif
+
+# that one is generated...
+# note: python configure overrides config.guess with something that doesn't
+# put -pc in its linux platform triplets, so filter that...
+ifneq ($(OS),WNT)
+ifeq ($(CPUNAME),ARM)
+$(eval $(call gb_ExternalPackage_add_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib,\
+ LO_lib/_sysconfigdata_$(if $(ENABLE_DBGUTIL),d)_$(python3_MACHDEP)_$(subst i686,i386,$(subst v7l-unknown,,$(HOST_PLATFORM))).py \
+))
+else
+$(eval $(call gb_ExternalPackage_add_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib,\
+ LO_lib/_sysconfigdata_$(if $(ENABLE_DBGUTIL),d)_$(python3_MACHDEP)_$(subst i686,i386,$(subst -pc,,$(HOST_PLATFORM))).py \
+))
+endif
+endif
+
+
+# packages not shipped:
+# dbm, sqlite3 - need some database stuff
+# curses - need curses to build the C module
+# idlelib, tkinter, turtledemo - need Tk to build the C module
+# test - probably unnecessary? was explicitly removed #i116738#
+# venv - why would we need virtual environments
+#
+# These lists are now sorted with "LC_COLLATE=C sort", by using
+# find Lib/ -name "*.py" | sort | sed -e 's/^/\t/' -e 's/$/ \\/'
+#
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib,\
+ LICENSE \
+ Lib/__future__.py \
+ Lib/__phello__.foo.py \
+ Lib/_bootlocale.py \
+ Lib/_collections_abc.py \
+ Lib/_compat_pickle.py \
+ Lib/_compression.py \
+ Lib/_dummy_thread.py \
+ Lib/_markupbase.py \
+ Lib/_osx_support.py \
+ Lib/_py_abc.py \
+ Lib/_pydecimal.py \
+ Lib/_pyio.py \
+ Lib/_sitebuiltins.py \
+ Lib/_strptime.py \
+ Lib/_threading_local.py \
+ Lib/_weakrefset.py \
+ Lib/abc.py \
+ Lib/aifc.py \
+ Lib/antigravity.py \
+ Lib/argparse.py \
+ Lib/ast.py \
+ Lib/asynchat.py \
+ Lib/asyncore.py \
+ Lib/base64.py \
+ Lib/bdb.py \
+ Lib/binhex.py \
+ Lib/bisect.py \
+ Lib/bz2.py \
+ Lib/cProfile.py \
+ Lib/calendar.py \
+ Lib/cgi.py \
+ Lib/cgitb.py \
+ Lib/chunk.py \
+ Lib/cmd.py \
+ Lib/code.py \
+ Lib/codecs.py \
+ Lib/codeop.py \
+ Lib/colorsys.py \
+ Lib/compileall.py \
+ Lib/configparser.py \
+ Lib/contextlib.py \
+ Lib/contextvars.py \
+ Lib/copy.py \
+ Lib/copyreg.py \
+ Lib/crypt.py \
+ Lib/csv.py \
+ Lib/dataclasses.py \
+ Lib/datetime.py \
+ Lib/decimal.py \
+ Lib/difflib.py \
+ Lib/dis.py \
+ Lib/doctest.py \
+ Lib/dummy_threading.py \
+ Lib/enum.py \
+ Lib/filecmp.py \
+ Lib/fileinput.py \
+ Lib/fnmatch.py \
+ Lib/formatter.py \
+ Lib/fractions.py \
+ Lib/ftplib.py \
+ Lib/functools.py \
+ Lib/genericpath.py \
+ Lib/getopt.py \
+ Lib/getpass.py \
+ Lib/gettext.py \
+ Lib/glob.py \
+ Lib/gzip.py \
+ Lib/hashlib.py \
+ Lib/heapq.py \
+ Lib/hmac.py \
+ Lib/imaplib.py \
+ Lib/imghdr.py \
+ Lib/imp.py \
+ Lib/inspect.py \
+ Lib/io.py \
+ Lib/ipaddress.py \
+ Lib/keyword.py \
+ Lib/linecache.py \
+ Lib/locale.py \
+ Lib/lzma.py \
+ Lib/mailbox.py \
+ Lib/mailcap.py \
+ Lib/mimetypes.py \
+ Lib/modulefinder.py \
+ Lib/netrc.py \
+ Lib/nntplib.py \
+ Lib/ntpath.py \
+ Lib/nturl2path.py \
+ Lib/numbers.py \
+ Lib/opcode.py \
+ Lib/operator.py \
+ Lib/optparse.py \
+ Lib/os.py \
+ Lib/pathlib.py \
+ Lib/pdb.py \
+ Lib/pickle.py \
+ Lib/pickletools.py \
+ Lib/pipes.py \
+ Lib/pkgutil.py \
+ Lib/platform.py \
+ Lib/plistlib.py \
+ Lib/poplib.py \
+ Lib/posixpath.py \
+ Lib/pprint.py \
+ Lib/profile.py \
+ Lib/pstats.py \
+ Lib/pty.py \
+ Lib/py_compile.py \
+ Lib/pyclbr.py \
+ Lib/pydoc.py \
+ Lib/queue.py \
+ Lib/quopri.py \
+ Lib/random.py \
+ Lib/re.py \
+ Lib/reprlib.py \
+ Lib/rlcompleter.py \
+ Lib/runpy.py \
+ Lib/sched.py \
+ Lib/secrets.py \
+ Lib/selectors.py \
+ Lib/shelve.py \
+ Lib/shlex.py \
+ Lib/shutil.py \
+ Lib/signal.py \
+ Lib/site.py \
+ Lib/smtpd.py \
+ Lib/smtplib.py \
+ Lib/sndhdr.py \
+ Lib/socket.py \
+ Lib/socketserver.py \
+ Lib/sre_compile.py \
+ Lib/sre_constants.py \
+ Lib/sre_parse.py \
+ Lib/ssl.py \
+ Lib/stat.py \
+ Lib/statistics.py \
+ Lib/string.py \
+ Lib/stringprep.py \
+ Lib/struct.py \
+ Lib/subprocess.py \
+ Lib/sunau.py \
+ Lib/symbol.py \
+ Lib/symtable.py \
+ Lib/sysconfig.py \
+ Lib/tabnanny.py \
+ Lib/tarfile.py \
+ Lib/telnetlib.py \
+ Lib/tempfile.py \
+ Lib/textwrap.py \
+ Lib/this.py \
+ Lib/threading.py \
+ Lib/timeit.py \
+ Lib/token.py \
+ Lib/tokenize.py \
+ Lib/trace.py \
+ Lib/traceback.py \
+ Lib/tracemalloc.py \
+ Lib/tty.py \
+ Lib/turtle.py \
+ Lib/types.py \
+ Lib/typing.py \
+ Lib/uu.py \
+ Lib/uuid.py \
+ Lib/warnings.py \
+ Lib/wave.py \
+ Lib/weakref.py \
+ Lib/webbrowser.py \
+ Lib/xdrlib.py \
+ Lib/zipapp.py \
+ Lib/zipfile.py \
+ Lib/zipimport.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/asyncio,\
+ Lib/asyncio/__init__.py \
+ Lib/asyncio/__main__.py \
+ Lib/asyncio/base_events.py \
+ Lib/asyncio/base_futures.py \
+ Lib/asyncio/base_subprocess.py \
+ Lib/asyncio/base_tasks.py \
+ Lib/asyncio/constants.py \
+ Lib/asyncio/coroutines.py \
+ Lib/asyncio/events.py \
+ Lib/asyncio/exceptions.py \
+ Lib/asyncio/format_helpers.py \
+ Lib/asyncio/futures.py \
+ Lib/asyncio/locks.py \
+ Lib/asyncio/log.py \
+ Lib/asyncio/proactor_events.py \
+ Lib/asyncio/protocols.py \
+ Lib/asyncio/queues.py \
+ Lib/asyncio/runners.py \
+ Lib/asyncio/selector_events.py \
+ Lib/asyncio/sslproto.py \
+ Lib/asyncio/staggered.py \
+ Lib/asyncio/streams.py \
+ Lib/asyncio/subprocess.py \
+ Lib/asyncio/tasks.py \
+ Lib/asyncio/transports.py \
+ Lib/asyncio/trsock.py \
+ Lib/asyncio/unix_events.py \
+ Lib/asyncio/windows_events.py \
+ Lib/asyncio/windows_utils.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/collections,\
+ Lib/collections/__init__.py \
+ Lib/collections/abc.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/concurrent,\
+ Lib/concurrent/__init__.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/concurrent/futures,\
+ Lib/concurrent/futures/__init__.py \
+ Lib/concurrent/futures/_base.py \
+ Lib/concurrent/futures/process.py \
+ Lib/concurrent/futures/thread.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/ctypes,\
+ Lib/ctypes/__init__.py \
+ Lib/ctypes/_aix.py \
+ Lib/ctypes/_endian.py \
+ Lib/ctypes/util.py \
+ Lib/ctypes/wintypes.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/ctypes/macholib,\
+ Lib/ctypes/macholib/README.ctypes \
+ Lib/ctypes/macholib/fetch_macholib \
+ Lib/ctypes/macholib/fetch_macholib.bat \
+ Lib/ctypes/macholib/__init__.py \
+ Lib/ctypes/macholib/dyld.py \
+ Lib/ctypes/macholib/dylib.py \
+ Lib/ctypes/macholib/framework.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/distutils,\
+ Lib/distutils/README \
+ Lib/distutils/__init__.py \
+ Lib/distutils/_msvccompiler.py \
+ Lib/distutils/archive_util.py \
+ Lib/distutils/bcppcompiler.py \
+ Lib/distutils/ccompiler.py \
+ Lib/distutils/cmd.py \
+ Lib/distutils/config.py \
+ Lib/distutils/core.py \
+ Lib/distutils/cygwinccompiler.py \
+ Lib/distutils/debug.py \
+ Lib/distutils/dep_util.py \
+ Lib/distutils/dir_util.py \
+ Lib/distutils/dist.py \
+ Lib/distutils/errors.py \
+ Lib/distutils/extension.py \
+ Lib/distutils/fancy_getopt.py \
+ Lib/distutils/file_util.py \
+ Lib/distutils/filelist.py \
+ Lib/distutils/log.py \
+ Lib/distutils/msvc9compiler.py \
+ Lib/distutils/msvccompiler.py \
+ Lib/distutils/spawn.py \
+ Lib/distutils/sysconfig.py \
+ Lib/distutils/text_file.py \
+ Lib/distutils/unixccompiler.py \
+ Lib/distutils/util.py \
+ Lib/distutils/version.py \
+ Lib/distutils/versionpredicate.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/distutils/command,\
+ Lib/distutils/command/__init__.py \
+ Lib/distutils/command/bdist.py \
+ Lib/distutils/command/bdist_dumb.py \
+ Lib/distutils/command/bdist_msi.py \
+ Lib/distutils/command/bdist_rpm.py \
+ Lib/distutils/command/bdist_wininst.py \
+ Lib/distutils/command/build.py \
+ Lib/distutils/command/build_clib.py \
+ Lib/distutils/command/build_ext.py \
+ Lib/distutils/command/build_py.py \
+ Lib/distutils/command/build_scripts.py \
+ Lib/distutils/command/check.py \
+ Lib/distutils/command/clean.py \
+ Lib/distutils/command/command_template \
+ Lib/distutils/command/config.py \
+ Lib/distutils/command/install.py \
+ Lib/distutils/command/install_data.py \
+ Lib/distutils/command/install_egg_info.py \
+ Lib/distutils/command/install_headers.py \
+ Lib/distutils/command/install_lib.py \
+ Lib/distutils/command/install_scripts.py \
+ Lib/distutils/command/register.py \
+ Lib/distutils/command/sdist.py \
+ Lib/distutils/command/upload.py \
+ Lib/distutils/command/wininst-10.0.exe \
+ Lib/distutils/command/wininst-10.0-amd64.exe \
+ Lib/distutils/command/wininst-14.0.exe \
+ Lib/distutils/command/wininst-14.0-amd64.exe \
+ Lib/distutils/command/wininst-6.0.exe \
+ Lib/distutils/command/wininst-7.1.exe \
+ Lib/distutils/command/wininst-8.0.exe \
+ Lib/distutils/command/wininst-9.0.exe \
+ Lib/distutils/command/wininst-9.0-amd64.exe \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/email,\
+ Lib/email/__init__.py \
+ Lib/email/_encoded_words.py \
+ Lib/email/_header_value_parser.py \
+ Lib/email/_parseaddr.py \
+ Lib/email/_policybase.py \
+ Lib/email/architecture.rst \
+ Lib/email/base64mime.py \
+ Lib/email/charset.py \
+ Lib/email/contentmanager.py \
+ Lib/email/encoders.py \
+ Lib/email/errors.py \
+ Lib/email/feedparser.py \
+ Lib/email/generator.py \
+ Lib/email/header.py \
+ Lib/email/headerregistry.py \
+ Lib/email/iterators.py \
+ Lib/email/message.py \
+ Lib/email/parser.py \
+ Lib/email/policy.py \
+ Lib/email/quoprimime.py \
+ Lib/email/utils.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/email/mime,\
+ Lib/email/mime/__init__.py \
+ Lib/email/mime/application.py \
+ Lib/email/mime/audio.py \
+ Lib/email/mime/base.py \
+ Lib/email/mime/image.py \
+ Lib/email/mime/message.py \
+ Lib/email/mime/multipart.py \
+ Lib/email/mime/nonmultipart.py \
+ Lib/email/mime/text.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/encodings,\
+ Lib/encodings/__init__.py \
+ Lib/encodings/aliases.py \
+ Lib/encodings/ascii.py \
+ Lib/encodings/base64_codec.py \
+ Lib/encodings/big5.py \
+ Lib/encodings/big5hkscs.py \
+ Lib/encodings/bz2_codec.py \
+ Lib/encodings/charmap.py \
+ Lib/encodings/cp037.py \
+ Lib/encodings/cp1006.py \
+ Lib/encodings/cp1026.py \
+ Lib/encodings/cp1125.py \
+ Lib/encodings/cp1140.py \
+ Lib/encodings/cp1250.py \
+ Lib/encodings/cp1251.py \
+ Lib/encodings/cp1252.py \
+ Lib/encodings/cp1253.py \
+ Lib/encodings/cp1254.py \
+ Lib/encodings/cp1255.py \
+ Lib/encodings/cp1256.py \
+ Lib/encodings/cp1257.py \
+ Lib/encodings/cp1258.py \
+ Lib/encodings/cp273.py \
+ Lib/encodings/cp424.py \
+ Lib/encodings/cp437.py \
+ Lib/encodings/cp500.py \
+ Lib/encodings/cp720.py \
+ Lib/encodings/cp737.py \
+ Lib/encodings/cp775.py \
+ Lib/encodings/cp850.py \
+ Lib/encodings/cp852.py \
+ Lib/encodings/cp855.py \
+ Lib/encodings/cp856.py \
+ Lib/encodings/cp857.py \
+ Lib/encodings/cp858.py \
+ Lib/encodings/cp860.py \
+ Lib/encodings/cp861.py \
+ Lib/encodings/cp862.py \
+ Lib/encodings/cp863.py \
+ Lib/encodings/cp864.py \
+ Lib/encodings/cp865.py \
+ Lib/encodings/cp866.py \
+ Lib/encodings/cp869.py \
+ Lib/encodings/cp874.py \
+ Lib/encodings/cp875.py \
+ Lib/encodings/cp932.py \
+ Lib/encodings/cp949.py \
+ Lib/encodings/cp950.py \
+ Lib/encodings/euc_jis_2004.py \
+ Lib/encodings/euc_jisx0213.py \
+ Lib/encodings/euc_jp.py \
+ Lib/encodings/euc_kr.py \
+ Lib/encodings/gb18030.py \
+ Lib/encodings/gb2312.py \
+ Lib/encodings/gbk.py \
+ Lib/encodings/hex_codec.py \
+ Lib/encodings/hp_roman8.py \
+ Lib/encodings/hz.py \
+ Lib/encodings/idna.py \
+ Lib/encodings/iso2022_jp.py \
+ Lib/encodings/iso2022_jp_1.py \
+ Lib/encodings/iso2022_jp_2.py \
+ Lib/encodings/iso2022_jp_2004.py \
+ Lib/encodings/iso2022_jp_3.py \
+ Lib/encodings/iso2022_jp_ext.py \
+ Lib/encodings/iso2022_kr.py \
+ Lib/encodings/iso8859_1.py \
+ Lib/encodings/iso8859_10.py \
+ Lib/encodings/iso8859_11.py \
+ Lib/encodings/iso8859_13.py \
+ Lib/encodings/iso8859_14.py \
+ Lib/encodings/iso8859_15.py \
+ Lib/encodings/iso8859_16.py \
+ Lib/encodings/iso8859_2.py \
+ Lib/encodings/iso8859_3.py \
+ Lib/encodings/iso8859_4.py \
+ Lib/encodings/iso8859_5.py \
+ Lib/encodings/iso8859_6.py \
+ Lib/encodings/iso8859_7.py \
+ Lib/encodings/iso8859_8.py \
+ Lib/encodings/iso8859_9.py \
+ Lib/encodings/johab.py \
+ Lib/encodings/koi8_r.py \
+ Lib/encodings/koi8_t.py \
+ Lib/encodings/koi8_u.py \
+ Lib/encodings/kz1048.py \
+ Lib/encodings/latin_1.py \
+ Lib/encodings/mac_arabic.py \
+ Lib/encodings/mac_centeuro.py \
+ Lib/encodings/mac_croatian.py \
+ Lib/encodings/mac_cyrillic.py \
+ Lib/encodings/mac_farsi.py \
+ Lib/encodings/mac_greek.py \
+ Lib/encodings/mac_iceland.py \
+ Lib/encodings/mac_latin2.py \
+ Lib/encodings/mac_roman.py \
+ Lib/encodings/mac_romanian.py \
+ Lib/encodings/mac_turkish.py \
+ Lib/encodings/mbcs.py \
+ Lib/encodings/oem.py \
+ Lib/encodings/palmos.py \
+ Lib/encodings/ptcp154.py \
+ Lib/encodings/punycode.py \
+ Lib/encodings/quopri_codec.py \
+ Lib/encodings/raw_unicode_escape.py \
+ Lib/encodings/rot_13.py \
+ Lib/encodings/shift_jis.py \
+ Lib/encodings/shift_jis_2004.py \
+ Lib/encodings/shift_jisx0213.py \
+ Lib/encodings/tis_620.py \
+ Lib/encodings/undefined.py \
+ Lib/encodings/unicode_escape.py \
+ Lib/encodings/utf_16.py \
+ Lib/encodings/utf_16_be.py \
+ Lib/encodings/utf_16_le.py \
+ Lib/encodings/utf_32.py \
+ Lib/encodings/utf_32_be.py \
+ Lib/encodings/utf_32_le.py \
+ Lib/encodings/utf_7.py \
+ Lib/encodings/utf_8.py \
+ Lib/encodings/utf_8_sig.py \
+ Lib/encodings/uu_codec.py \
+ Lib/encodings/zlib_codec.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/html,\
+ Lib/html/__init__.py \
+ Lib/html/entities.py \
+ Lib/html/parser.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/http,\
+ Lib/http/__init__.py \
+ Lib/http/client.py \
+ Lib/http/cookiejar.py \
+ Lib/http/cookies.py \
+ Lib/http/server.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/importlib,\
+ Lib/importlib/__init__.py \
+ Lib/importlib/_bootstrap.py \
+ Lib/importlib/_bootstrap_external.py \
+ Lib/importlib/abc.py \
+ Lib/importlib/machinery.py \
+ Lib/importlib/metadata.py \
+ Lib/importlib/resources.py \
+ Lib/importlib/util.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/json,\
+ Lib/json/__init__.py \
+ Lib/json/decoder.py \
+ Lib/json/encoder.py \
+ Lib/json/scanner.py \
+ Lib/json/tool.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/lib2to3,\
+ Lib/lib2to3/__init__.py \
+ Lib/lib2to3/__main__.py \
+ Lib/lib2to3/Grammar.txt \
+ Lib/lib2to3/PatternGrammar.txt \
+ Lib/lib2to3/btm_matcher.py \
+ Lib/lib2to3/btm_utils.py \
+ Lib/lib2to3/fixer_base.py \
+ Lib/lib2to3/fixer_util.py \
+ Lib/lib2to3/main.py \
+ Lib/lib2to3/patcomp.py \
+ Lib/lib2to3/pygram.py \
+ Lib/lib2to3/pytree.py \
+ Lib/lib2to3/refactor.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/lib2to3/fixes,\
+ Lib/lib2to3/fixes/__init__.py \
+ Lib/lib2to3/fixes/fix_apply.py \
+ Lib/lib2to3/fixes/fix_asserts.py \
+ Lib/lib2to3/fixes/fix_basestring.py \
+ Lib/lib2to3/fixes/fix_buffer.py \
+ Lib/lib2to3/fixes/fix_dict.py \
+ Lib/lib2to3/fixes/fix_except.py \
+ Lib/lib2to3/fixes/fix_exec.py \
+ Lib/lib2to3/fixes/fix_execfile.py \
+ Lib/lib2to3/fixes/fix_exitfunc.py \
+ Lib/lib2to3/fixes/fix_filter.py \
+ Lib/lib2to3/fixes/fix_funcattrs.py \
+ Lib/lib2to3/fixes/fix_future.py \
+ Lib/lib2to3/fixes/fix_getcwdu.py \
+ Lib/lib2to3/fixes/fix_has_key.py \
+ Lib/lib2to3/fixes/fix_idioms.py \
+ Lib/lib2to3/fixes/fix_import.py \
+ Lib/lib2to3/fixes/fix_imports.py \
+ Lib/lib2to3/fixes/fix_imports2.py \
+ Lib/lib2to3/fixes/fix_input.py \
+ Lib/lib2to3/fixes/fix_intern.py \
+ Lib/lib2to3/fixes/fix_isinstance.py \
+ Lib/lib2to3/fixes/fix_itertools.py \
+ Lib/lib2to3/fixes/fix_itertools_imports.py \
+ Lib/lib2to3/fixes/fix_long.py \
+ Lib/lib2to3/fixes/fix_map.py \
+ Lib/lib2to3/fixes/fix_metaclass.py \
+ Lib/lib2to3/fixes/fix_methodattrs.py \
+ Lib/lib2to3/fixes/fix_ne.py \
+ Lib/lib2to3/fixes/fix_next.py \
+ Lib/lib2to3/fixes/fix_nonzero.py \
+ Lib/lib2to3/fixes/fix_numliterals.py \
+ Lib/lib2to3/fixes/fix_operator.py \
+ Lib/lib2to3/fixes/fix_paren.py \
+ Lib/lib2to3/fixes/fix_print.py \
+ Lib/lib2to3/fixes/fix_raise.py \
+ Lib/lib2to3/fixes/fix_raw_input.py \
+ Lib/lib2to3/fixes/fix_reduce.py \
+ Lib/lib2to3/fixes/fix_reload.py \
+ Lib/lib2to3/fixes/fix_renames.py \
+ Lib/lib2to3/fixes/fix_repr.py \
+ Lib/lib2to3/fixes/fix_set_literal.py \
+ Lib/lib2to3/fixes/fix_standarderror.py \
+ Lib/lib2to3/fixes/fix_sys_exc.py \
+ Lib/lib2to3/fixes/fix_throw.py \
+ Lib/lib2to3/fixes/fix_tuple_params.py \
+ Lib/lib2to3/fixes/fix_types.py \
+ Lib/lib2to3/fixes/fix_unicode.py \
+ Lib/lib2to3/fixes/fix_urllib.py \
+ Lib/lib2to3/fixes/fix_ws_comma.py \
+ Lib/lib2to3/fixes/fix_xrange.py \
+ Lib/lib2to3/fixes/fix_xreadlines.py \
+ Lib/lib2to3/fixes/fix_zip.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/pgen2,\
+ Lib/lib2to3/pgen2/__init__.py \
+ Lib/lib2to3/pgen2/conv.py \
+ Lib/lib2to3/pgen2/driver.py \
+ Lib/lib2to3/pgen2/grammar.py \
+ Lib/lib2to3/pgen2/literals.py \
+ Lib/lib2to3/pgen2/parse.py \
+ Lib/lib2to3/pgen2/pgen.py \
+ Lib/lib2to3/pgen2/token.py \
+ Lib/lib2to3/pgen2/tokenize.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/logging,\
+ Lib/logging/__init__.py \
+ Lib/logging/config.py \
+ Lib/logging/handlers.py \
+))
+
+ifeq (WNT,$(OS))
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/msilib,\
+ Lib/msilib/__init__.py \
+ Lib/msilib/schema.py \
+ Lib/msilib/sequence.py \
+ Lib/msilib/text.py \
+))
+endif
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/multiprocessing,\
+ Lib/multiprocessing/__init__.py \
+ Lib/multiprocessing/connection.py \
+ Lib/multiprocessing/context.py \
+ Lib/multiprocessing/dummy/__init__.py \
+ Lib/multiprocessing/dummy/connection.py \
+ Lib/multiprocessing/forkserver.py \
+ Lib/multiprocessing/heap.py \
+ Lib/multiprocessing/managers.py \
+ Lib/multiprocessing/pool.py \
+ Lib/multiprocessing/popen_fork.py \
+ Lib/multiprocessing/popen_forkserver.py \
+ Lib/multiprocessing/popen_spawn_posix.py \
+ Lib/multiprocessing/popen_spawn_win32.py \
+ Lib/multiprocessing/process.py \
+ Lib/multiprocessing/queues.py \
+ Lib/multiprocessing/reduction.py \
+ Lib/multiprocessing/resource_sharer.py \
+ Lib/multiprocessing/resource_tracker.py \
+ Lib/multiprocessing/shared_memory.py \
+ Lib/multiprocessing/sharedctypes.py \
+ Lib/multiprocessing/spawn.py \
+ Lib/multiprocessing/synchronize.py \
+ Lib/multiprocessing/util.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/multiprocessing/dummy,\
+ Lib/multiprocessing/dummy/__init__.py \
+ Lib/multiprocessing/dummy/connection.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/pydoc_data,\
+ Lib/pydoc_data/__init__.py \
+ Lib/pydoc_data/_pydoc.css \
+ Lib/pydoc_data/topics.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/unittest,\
+ Lib/unittest/__init__.py \
+ Lib/unittest/__main__.py \
+ Lib/unittest/async_case.py \
+ Lib/unittest/case.py \
+ Lib/unittest/loader.py \
+ Lib/unittest/main.py \
+ Lib/unittest/mock.py \
+ Lib/unittest/result.py \
+ Lib/unittest/runner.py \
+ Lib/unittest/signals.py \
+ Lib/unittest/suite.py \
+ Lib/unittest/util.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/urllib,\
+ Lib/urllib/__init__.py \
+ Lib/urllib/error.py \
+ Lib/urllib/parse.py \
+ Lib/urllib/request.py \
+ Lib/urllib/response.py \
+ Lib/urllib/robotparser.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/wsgiref,\
+ Lib/wsgiref/__init__.py \
+ Lib/wsgiref/handlers.py \
+ Lib/wsgiref/headers.py \
+ Lib/wsgiref/simple_server.py \
+ Lib/wsgiref/util.py \
+ Lib/wsgiref/validate.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/xml,\
+ Lib/xml/__init__.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/xml/dom,\
+ Lib/xml/dom/__init__.py \
+ Lib/xml/dom/domreg.py \
+ Lib/xml/dom/expatbuilder.py \
+ Lib/xml/dom/minicompat.py \
+ Lib/xml/dom/minidom.py \
+ Lib/xml/dom/NodeFilter.py \
+ Lib/xml/dom/pulldom.py \
+ Lib/xml/dom/xmlbuilder.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/xml/etree,\
+ Lib/xml/etree/__init__.py \
+ Lib/xml/etree/cElementTree.py \
+ Lib/xml/etree/ElementInclude.py \
+ Lib/xml/etree/ElementPath.py \
+ Lib/xml/etree/ElementTree.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/xml/parsers,\
+ Lib/xml/parsers/__init__.py \
+ Lib/xml/parsers/expat.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/xml/sax,\
+ Lib/xml/sax/__init__.py \
+ Lib/xml/sax/_exceptions.py \
+ Lib/xml/sax/expatreader.py \
+ Lib/xml/sax/handler.py \
+ Lib/xml/sax/saxutils.py \
+ Lib/xml/sax/xmlreader.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/xmlrpc,\
+ Lib/xmlrpc/__init__.py \
+ Lib/xmlrpc/client.py \
+ Lib/xmlrpc/server.py \
+))
+
+$(eval $(call gb_ExternalPackage_add_unpacked_files,python3,$(LIBO_BIN_FOLDER)/python-core-$(PYTHON_VERSION)/lib/site-packages,\
+ Lib/site-packages/README.txt \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/python3/ExternalProject_python3.mk b/external/python3/ExternalProject_python3.mk
new file mode 100644
index 000000000..faa8e9738
--- /dev/null
+++ b/external/python3/ExternalProject_python3.mk
@@ -0,0 +1,213 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,python3))
+
+$(eval $(call gb_ExternalProject_use_externals,python3,\
+ expat \
+ $(if $(filter WNT LINUX,$(OS)),libffi) \
+ openssl \
+ zlib \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,python3,\
+ build \
+ $(if $(filter MACOSX,$(OS)),\
+ fixscripts \
+ fixinstallnames \
+ executables \
+ removeunnecessarystuff \
+ ) \
+))
+
+ifeq ($(OS),WNT)
+
+# TODO: using Debug configuration and related mangling of pyconfig.h
+
+# at least for MSVC 2008 it is necessary to clear MAKEFLAGS because
+# nmake is invoked
+$(call gb_ExternalProject_get_state_target,python3,build) :
+ $(call gb_Trace_StartRange,python3,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ MAKEFLAGS= MSBuild.exe pcbuild.sln /t:Build $(gb_MSBUILD_CONFIG_AND_PLATFORM) \
+ /p:opensslIncludeDir=$(call gb_UnpackedTarball_get_dir,openssl)/include \
+ /p:opensslOutDir=$(call gb_UnpackedTarball_get_dir,openssl) \
+ /p:zlibDir=$(call gb_UnpackedTarball_get_dir,zlib) \
+ /p:libffiOutDir=$(call gb_UnpackedTarball_get_dir,libffi)/$(HOST_PLATFORM)/.libs \
+ /p:libffiIncludeDir=$(call gb_UnpackedTarball_get_dir,libffi)/$(HOST_PLATFORM)/include \
+ /maxcpucount \
+ /p:PlatformToolset=$(VCTOOLSET) /p:VisualStudioVersion=$(VCVER) /ToolsVersion:Current \
+ $(if $(filter 10,$(WINDOWS_SDK_VERSION)),/p:WindowsTargetPlatformVersion=$(UCRTVERSION)) \
+ $(foreach i,$(python3_EXTENSION_MODULES), \
+ && { test -e ../$i || { printf 'Error: missing %s\n' $i; false; } }) \
+ ,PCBuild)
+ $(call gb_Trace_EndRange,python3,EXTERNAL)
+
+else
+
+# --with-system-expat: this should find the one in the workdir (or system)
+
+# OPENSSL_INCLUDES OPENSSL_LDFLAGS OPENSSL_LIBS cannot be set via commandline!
+# use --with-openssl instead, which requires include/ and lib/ subdirs.
+
+# libffi is not all that stable, with 3 different SONAMEs currently, so we
+# have to bundle it; --without-system-ffi does not work any more on Linux.
+# Unfortuantely (as of 3.7) pkg-config is used to locate libffi so we do some
+# hacks to find the libffi.pc in workdir by overriding PKG_CONFIG_LIBDIR.
+# Also, pkg-config is only used to find the headers, the libdir needs to be
+# passed extra.
+
+# create a symlink "LO_lib" because the .so are in a directory with platform
+# specific name like build/lib.linux-x86_64-3.3
+
+python3_cflags = $(ZLIB_CFLAGS)
+ifneq (,$(ENABLE_VALGRIND))
+ python3_cflags += $(VALGRIND_CFLAGS)
+endif
+
+# This happens to override the -O3 in the default OPT set in
+# workdir/UnpackedTarball/python3/configure.ac while keeping the other content of that OPT intact:
+ifeq ($(ENABLE_OPTIMIZED),)
+python3_cflags += $(gb_COMPILERNOOPTFLAGS)
+endif
+
+$(call gb_ExternalProject_get_state_target,python3,build) :
+ $(call gb_Trace_StartRange,python3,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(if $(filter MACOSX,$(OS)), \
+ $(if $(filter 10.8 10.9 10.10 10.11,$(MACOSX_DEPLOYMENT_TARGET)), \
+ ac_cv_func_getentropy=no \
+ ac_cv_func_clock_gettime=no \
+ ) \
+ ) \
+ $(gb_RUN_CONFIGURE) ./configure \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(ENABLE_VALGRIND),--with-valgrind) \
+ $(if $(ENABLE_DBGUTIL),--with-pydebug) \
+ --prefix=/python-inst \
+ --with-system-expat \
+ $(if $(filter AIX,$(OS)), \
+ --disable-ipv6 --with-threads OPT="-g0 -fwrapv -O3 -Wall") \
+ $(if $(filter MACOSX,$(OS)), \
+ $(if $(filter INTEL,$(CPUNAME)),--enable-universalsdk=$(MACOSX_SDK_PATH) \
+ --with-universal-archs=intel \
+ ) \
+ --enable-framework=/@__________________________________________________OOO --with-framework-name=LibreOfficePython, \
+ --enable-shared \
+ ) \
+ $(if $(ENABLE_OPENSSL),$(if $(SYSTEM_OPENSSL),,\
+ --with-openssl=$(call gb_UnpackedTarball_get_dir,openssl) \
+ ) ) \
+ $(if $(filter LINUX,$(OS)), \
+ PKG_CONFIG_LIBDIR="$(call gb_UnpackedTarball_get_dir,libffi)/$(HOST_PLATFORM)$${PKG_CONFIG_LIBDIR:+:$$PKG_CONFIG_LIBDIR}" \
+ ) \
+ CC="$(strip $(CC) \
+ $(if $(SYSTEM_EXPAT),,-I$(call gb_UnpackedTarball_get_dir,expat)/lib) \
+ $(if $(SYSBASE), -I$(SYSBASE)/usr/include) \
+ )" \
+ $(if $(python3_cflags),CFLAGS='$(python3_cflags)') \
+ $(if $(filter -fsanitize=%,$(CC)),LINKCC="$(CXX) -pthread") \
+ LDFLAGS="$(strip $(LDFLAGS) \
+ $(if $(filter LINUX,$(OS)),-L$(call gb_UnpackedTarball_get_dir,libffi)/$(HOST_PLATFORM)/.libs) \
+ $(if $(SYSTEM_EXPAT),,-L$(gb_StaticLibrary_WORKDIR)) \
+ $(if $(SYSTEM_ZLIB),,-L$(gb_StaticLibrary_WORKDIR)) \
+ $(if $(SYSBASE), -L$(SYSBASE)/usr/lib) \
+ $(gb_LTOFLAGS) \
+ )" \
+ && MAKEFLAGS= $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),DESTDIR=$(EXTERNAL_WORKDIR)/python-inst install) \
+ $(if $(SYSTEM_ZLIB),,ZLIB_INCDIR=$(WORKDIR)/UnpackedTarball/zlib) \
+ && ln -s build/lib.* LO_lib \
+ $(foreach i,$(python3_EXTENSION_MODULES), \
+ && { test -e $i || { printf 'Error: missing %s\n' $i; false; } }) \
+ )
+ $(call gb_Trace_EndRange,python3,EXTERNAL)
+
+endif
+
+# If you want to run Python's own unit tests, add this to the chain of commands above:
+# && MAKEFLAGS= $(MAKE) \
+# $(if $(filter MACOSX,$(OS)),DESTDIR=$(EXTERNAL_WORKDIR)/python-inst) \
+# $(if $(SYSTEM_ZLIB),,ZLIB_INCDIR=$(WORKDIR)/UnpackedTarball/zlib) \
+# test \
+
+ifeq ($(OS),MACOSX)
+
+python3_fw_prefix=$(call gb_UnpackedTarball_get_dir,python3)/python-inst/@__________________________________________________OOO/LibreOfficePython.framework
+
+# rule to allow relocating the whole framework, removing reference to buildinstallation directory
+# also scripts are not allowed to be signed as executables (with extended attributes), but need to
+# be treated as data/put into Resources folder, see also
+# https://developer.apple.com/library/archive/technotes/tn2206/_index.html
+$(call gb_ExternalProject_get_state_target,python3,fixscripts) : $(call gb_ExternalProject_get_state_target,python3,build)
+ $(call gb_Output_announce,python3 - remove reference to installroot from scripts,build,CUS,5)
+ $(COMMAND_ECHO)cd $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/bin/ && \
+ for file in \
+ 2to3-$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR) \
+ easy_install-$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR) \
+ idle$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR) \
+ pip$(PYTHON_VERSION_MAJOR) \
+ pip$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR) \
+ pydoc$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR) \
+ python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)-config \
+ ; do { rm "$$file" && $(gb_AWK) '\
+ BEGIN {print "#!/usr/bin/env bash\n\
+origpath=$$(pwd)\n\
+bindir=$$(cd $$(dirname \"$$0\") ; pwd)\n\
+cd \"$$origpath\"\n\
+\"$$bindir/../Resources/Python.app/Contents/MacOS/LibreOfficePython\" - $$@ <<EOF"} \
+ FNR==1{next} \
+ {print} \
+ END {print "EOF"}' > "../Resources/$$file" ; } < "$$file" && \
+ chmod +x "../Resources/$$file" && ln -s "../Resources/$$file" ; done
+ touch $@
+
+$(call gb_ExternalProject_get_state_target,python3,fixinstallnames) : $(call gb_ExternalProject_get_state_target,python3,build) \
+ | $(call gb_ExternalProject_get_state_target,python3,removeunnecessarystuff)
+ $(INSTALL_NAME_TOOL) -change \
+ $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/LibreOfficePython \
+ @executable_path/../../../../LibreOfficePython \
+ $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/Resources/Python.app/Contents/MacOS/LibreOfficePython
+ for file in $(shell $(FIND) $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib-dynload -name "*.so") ; do \
+ $(INSTALL_NAME_TOOL) -change \
+ $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/LibreOfficePython \
+ @loader_path/../../../LibreOfficePython $$file ; done
+ touch $@
+
+$(call gb_ExternalProject_get_state_target,python3,executables) : $(call gb_ExternalProject_get_state_target,python3,build)
+ cd $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/bin ; \
+ $(INSTALL_NAME_TOOL) -change \
+ $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/LibreOfficePython \
+ @executable_path/../LibreOfficePython python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)
+ touch $@
+
+# Remove modules (both Python and binary bits) of questionable usefulness that we don't ship on
+# other platforms either. See the "packages not shipped" comment in ExternalPackage_python3.mk.
+
+$(call gb_ExternalProject_get_state_target,python3,removeunnecessarystuff) : $(call gb_ExternalProject_get_state_target,python3,build)
+ $(call gb_Output_announce,python3 - remove the stuff we don't need to ship,build,CUS,5)
+ rm -r $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/dbm
+ rm -r $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/sqlite3
+ rm -r $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/curses
+ rm -r $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/idlelib
+ rm -r $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/tkinter
+ rm -r $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/turtledemo
+ rm -r $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/test
+ rm -r $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/venv
+ # Then the binary libraries
+ rm $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib-dynload/_dbm.cpython-$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)*.so
+ rm $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib-dynload/_sqlite3.cpython-$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)*.so
+ rm $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib-dynload/_curses.cpython-$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)*.so
+ rm $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib-dynload/_curses_panel.cpython-$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)*.so
+ rm $(python3_fw_prefix)/Versions/$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib/python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)/lib-dynload/_test*.cpython-$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)*.so
+ touch $@
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/python3/GeneratedPackage_python3.mk b/external/python3/GeneratedPackage_python3.mk
new file mode 100644
index 000000000..ffde38be5
--- /dev/null
+++ b/external/python3/GeneratedPackage_python3.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_GeneratedPackage_GeneratedPackage,python3,$(call gb_UnpackedTarball_get_dir,python3)/python-inst/@__________________________________________________OOO))
+
+$(eval $(call gb_GeneratedPackage_use_unpacked,python3,python3))
+
+$(eval $(call gb_GeneratedPackage_use_external_project,python3,python3))
+
+$(eval $(call gb_GeneratedPackage_add_dir,python3,$(INSTROOT)/Frameworks/LibreOfficePython.framework,LibreOfficePython.framework))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/python3/Makefile b/external/python3/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/python3/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/python3/Module_python3.mk b/external/python3/Module_python3.mk
new file mode 100644
index 000000000..5ef1deb21
--- /dev/null
+++ b/external/python3/Module_python3.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,python3))
+
+ifneq ($(DISABLE_PYTHON),TRUE)
+
+$(eval $(call gb_Module_add_targets,python3,\
+ UnpackedTarball_python3 \
+ ExternalProject_python3 \
+ $(if $(filter MACOSX,$(OS)),GeneratedPackage_python3,ExternalPackage_python3) \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/python3/README b/external/python3/README
new file mode 100644
index 000000000..edde023af
--- /dev/null
+++ b/external/python3/README
@@ -0,0 +1 @@
+CPython implementation of Python 3 from http://www.python.org
diff --git a/external/python3/UnpackedTarball_python3.mk b/external/python3/UnpackedTarball_python3.mk
new file mode 100644
index 000000000..06c64d7d5
--- /dev/null
+++ b/external/python3/UnpackedTarball_python3.mk
@@ -0,0 +1,52 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,python3))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,python3,$(PYTHON_TARBALL),,python3))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,python3,\
+ PCbuild/pcbuild.sln \
+))
+
+# For the configure part of external/python3/darwin.patch.0, see
+# <https://bugs.python.org/issue44065> "'configure: error: internal configure error for the platform
+# triplet' on macOS with Clang supporting --print-multiarch:"
+$(eval $(call gb_UnpackedTarball_add_patches,python3,\
+ external/python3/i100492-freebsd.patch.1 \
+ external/python3/python-3.3.0-darwin.patch.1 \
+ external/python3/python-3.8-msvc-sdk.patch.1 \
+ external/python3/python-3.7.6-msvc-ssl.patch.1 \
+ external/python3/python-3.5.4-msvc-disable.patch.1 \
+ external/python3/ubsan.patch.0 \
+ external/python3/python-3.5.tweak.strip.soabi.patch \
+ external/python3/darwin.patch.0 \
+ external/python3/macos-11.patch.0 \
+ external/python3/tsan.patch.0 \
+))
+
+ifneq ($(filter DRAGONFLY FREEBSD LINUX NETBSD OPENBSD SOLARIS,$(OS)),)
+$(eval $(call gb_UnpackedTarball_add_patches,python3,\
+ external/python3/python-3.3.3-elf-rpath.patch.1 \
+))
+endif
+
+ifneq ($(ENABLE_RUNTIME_OPTIMIZATIONS),TRUE)
+$(eval $(call gb_UnpackedTarball_add_patches,python3,\
+ external/python3/python-3.3.3-disable-obmalloc.patch.0 \
+))
+endif
+
+ifneq ($(SYSTEM_ZLIB),TRUE)
+$(eval $(call gb_UnpackedTarball_add_patches,python3, \
+ external/python3/internal-zlib.patch.0 \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/python3/darwin.patch.0 b/external/python3/darwin.patch.0
new file mode 100644
index 000000000..139cdc978
--- /dev/null
+++ b/external/python3/darwin.patch.0
@@ -0,0 +1,10 @@
+--- Modules/_ctypes/libffi_osx/x86/darwin64.S
++++ Modules/_ctypes/libffi_osx/x86/darwin64.S
+@@ -29,7 +29,6 @@
+ #include <fficonfig.h>
+ #include <ffi.h>
+
+- .file "darwin64.S"
+ .text
+
+ /* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
diff --git a/external/python3/i100492-freebsd.patch.1 b/external/python3/i100492-freebsd.patch.1
new file mode 100644
index 000000000..b2ca1ee71
--- /dev/null
+++ b/external/python3/i100492-freebsd.patch.1
@@ -0,0 +1,35 @@
+FreeBSD porting fixes, patch by maho@openoffice.org
+
+--- Python-3.3.0/Python/thread_pthread.h 2012-11-28 09:00:41.097955124 +0000
++++ Python-3.3.0/Python/thread_pthread.h 2012-11-28 09:01:13.018329351 +0000
+@@ -238,6 +238,9 @@
+ {
+ pthread_t th;
+ int status;
++#ifdef __FreeBSD__
++ sigset_t set, oset;
++#endif
+ #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+ pthread_attr_t attrs;
+ #endif
+@@ -277,6 +280,10 @@
+ callback->func = func;
+ callback->arg = arg;
+
++#ifdef __FreeBSD__
++ sigfillset(&set);
++ SET_THREAD_SIGMASK(SIG_BLOCK, &set, &oset);
++#endif
+ status = pthread_create(&th,
+ #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+ &attrs,
+@@ -285,6 +292,9 @@
+ #endif
+ pythread_wrapper, callback);
+
++#ifdef __FreeBSD__
++ SET_THREAD_SIGMASK(SIG_SETMASK, &oset, NULL);
++#endif
+ #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
+ pthread_attr_destroy(&attrs);
+ #endif
diff --git a/external/python3/internal-zlib.patch.0 b/external/python3/internal-zlib.patch.0
new file mode 100644
index 000000000..27bb737db
--- /dev/null
+++ b/external/python3/internal-zlib.patch.0
@@ -0,0 +1,55 @@
+--- configure
++++ configure
+@@ -11607,13 +11607,13 @@
+ ;;
+ esac
+
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5
+-$as_echo_n "checking for inflateCopy in -lz... " >&6; }
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lzlib" >&5
++$as_echo_n "checking for inflateCopy in -lzlib... " >&6; }
+ if ${ac_cv_lib_z_inflateCopy+:} false; then :
+ $as_echo_n "(cached) " >&6
+ else
+ ac_check_lib_save_LIBS=$LIBS
+-LIBS="-lz $LIBS"
++LIBS="-lzlib $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+--- setup.py
++++ setup.py
+@@ -1483,7 +1483,7 @@
+ #
+ # You can upgrade zlib to version 1.1.4 yourself by going to
+ # http://www.gzip.org/zlib/
+- zlib_inc = find_file('zlib.h', [], self.inc_dirs)
++ zlib_inc = [os.environ.get('ZLIB_INCDIR')]
+ have_zlib = False
+ if zlib_inc is not None:
+ zlib_h = zlib_inc[0] + '/zlib.h'
+@@ -1500,13 +1500,13 @@
+ version = line.split()[2]
+ break
+ if version >= version_req:
+- if (self.compiler.find_library_file(self.lib_dirs, 'z')):
++ if (self.compiler.find_library_file(self.lib_dirs, 'zlib')):
+ if MACOS:
+ zlib_extra_link_args = ('-Wl,-search_paths_first',)
+ else:
+ zlib_extra_link_args = ()
+ self.add(Extension('zlib', ['zlibmodule.c'],
+- libraries=['z'],
++ libraries=['zlib'],
+ extra_link_args=zlib_extra_link_args))
+ have_zlib = True
+ else:
+@@ -1520,7 +1520,7 @@
+ # crc32 if we have it. Otherwise binascii uses its own.
+ if have_zlib:
+ extra_compile_args = ['-DUSE_ZLIB_CRC32']
+- libraries = ['z']
++ libraries = ['zlib']
+ extra_link_args = zlib_extra_link_args
+ else:
+ extra_compile_args = []
diff --git a/external/python3/macos-11.patch.0 b/external/python3/macos-11.patch.0
new file mode 100644
index 000000000..2c8b419bb
--- /dev/null
+++ b/external/python3/macos-11.patch.0
@@ -0,0 +1,34 @@
+--- setup.py
++++ setup.py
+@@ -655,7 +655,10 @@
+ add_dir_to_list(self.compiler.include_dirs,
+ sysconfig.get_config_var("INCLUDEDIR"))
+
+- system_lib_dirs = ['/lib64', '/usr/lib64', '/lib', '/usr/lib']
++ if MACOS:
++ system_lib_dirs = ['/usr/lib', macosx_sdk_root()+'/usr/lib']
++ else:
++ system_lib_dirs = ['/lib64', '/usr/lib64', '/lib', '/usr/lib']
+ system_include_dirs = ['/usr/include']
+ # lib_dirs and inc_dirs are used to search for files;
+ # if a file is found in one of those directories, it can
+--- Modules/_posixsubprocess.c
++++ Modules/_posixsubprocess.c
+@@ -30,6 +30,8 @@
+ # define SYS_getdents64 __NR_getdents64
+ #endif
+
++#include <limits.h>
++
+ #if defined(__sun) && defined(__SVR4)
+ /* readdir64 is used to work around Solaris 9 bug 6395699. */
+ # define readdir readdir64
+@@ -201,7 +203,7 @@
+ #endif
+ #ifdef _SC_OPEN_MAX
+ local_max_fd = sysconf(_SC_OPEN_MAX);
+- if (local_max_fd == -1)
++ if (local_max_fd == -1 || local_max_fd == LONG_MAX)
+ #endif
+ local_max_fd = 256; /* Matches legacy Lib/subprocess.py behavior. */
+ return local_max_fd;
diff --git a/external/python3/python-3.3.0-darwin.patch.1 b/external/python3/python-3.3.0-darwin.patch.1
new file mode 100644
index 000000000..39d3c9180
--- /dev/null
+++ b/external/python3/python-3.3.0-darwin.patch.1
@@ -0,0 +1,65 @@
+-*- Mode: diff -*-
+
+LO needs to build both against MacOSX SDK and not produce universal binaries.
+
+diff -ru python3.orig/configure python3/configure
+--- python3.orig/configure 2015-07-26 17:36:11.808497783 +0200
++++ python3/configure 2015-07-26 17:38:49.016508337 +0200
+@@ -7385,7 +7385,20 @@
+ then
+ case "$UNIVERSAL_ARCHS" in
+ 32-bit)
+- UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386"
++ # LO does not use Universal Binaries (but the only way to set a SDK
++ # here implies that, so de-universalize here...)
++ case `/usr/bin/arch` in
++ i386)
++ UNIVERSAL_ARCH_FLAGS="-arch i386"
++ ;;
++ ppc)
++ UNIVERSAL_ARCH_FLAGS=""
++ ;;
++ *)
++ as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5
++ ;;
++ esac
++
+ LIPO_32BIT_FLAGS=""
+ ARCH_RUN_32BIT=""
+ ;;
+diff -ru python3.orig/Mac/Makefile.in python3/Mac/Makefile.in
+--- python3.orig/Mac/Makefile.in 2015-07-05 18:50:07.000000000 +0200
++++ python3/Mac/Makefile.in 2015-07-26 17:40:14.860514100 +0200
+@@ -44,7 +44,7 @@
+ INSTALL_SCRIPT= @INSTALL_SCRIPT@
+ INSTALL_DATA=@INSTALL_DATA@
+ LN=@LN@
+-STRIPFLAG=-s
++STRIPFLAG=
+ CPMAC=CpMac
+
+ APPTEMPLATE=$(srcdir)/Resources/app
+diff -ru python3.orig/Mac/Resources/app/Info.plist.in python3/Mac/Resources/app/Info.plist.in
+--- python3.orig/Mac/Resources/app/Info.plist.in 2015-07-05 18:50:07.000000000 +0200
++++ python3/Mac/Resources/app/Info.plist.in 2015-07-26 17:42:00.974521224 +0200
+@@ -18,7 +18,7 @@
+ </dict>
+ </array>
+ <key>CFBundleExecutable</key>
+- <string>Python</string>
++ <string>LibreOfficePython</string>
+ <key>CFBundleGetInfoString</key>
+ <string>%version%, (c) 2001-2020 Python Software Foundation.</string>
+ <key>CFBundleHelpBookFolder</key>
+diff -ru python3.orig/Mac/Resources/framework/Info.plist.in python3/Mac/Resources/framework/Info.plist.in
+--- python3.orig/Mac/Resources/framework/Info.plist.in 2015-07-05 18:50:07.000000000 +0200
++++ python3/Mac/Resources/framework/Info.plist.in 2015-07-26 17:41:15.996518204 +0200
+@@ -5,7 +5,7 @@
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+- <string>Python</string>
++ <string>@PYTHONFRAMEWORK@</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Python Runtime and Library</string>
+ <key>CFBundleIdentifier</key>
diff --git a/external/python3/python-3.3.3-disable-obmalloc.patch.0 b/external/python3/python-3.3.3-disable-obmalloc.patch.0
new file mode 100644
index 000000000..c4a1dea61
--- /dev/null
+++ b/external/python3/python-3.3.3-disable-obmalloc.patch.0
@@ -0,0 +1,21 @@
+--- Objects/obmalloc.c
++++ Objects/obmalloc.c
+@@ -712,8 +712,8 @@
+
+ #ifdef WITH_PYMALLOC
+
++#define WITH_VALGRIND
+ #ifdef WITH_VALGRIND
+-#include <valgrind/valgrind.h>
+
+ /* If we're using GCC, use __builtin_expect() to reduce overhead of
+ the valgrind checks */
+@@ -1430,7 +1430,7 @@
+
+ #ifdef WITH_VALGRIND
+ if (UNLIKELY(running_on_valgrind == -1)) {
+- running_on_valgrind = RUNNING_ON_VALGRIND;
++ running_on_valgrind = 1;
+ }
+ if (UNLIKELY(running_on_valgrind)) {
+ return NULL;
diff --git a/external/python3/python-3.3.3-elf-rpath.patch.1 b/external/python3/python-3.3.3-elf-rpath.patch.1
new file mode 100644
index 000000000..a408858f5
--- /dev/null
+++ b/external/python3/python-3.3.3-elf-rpath.patch.1
@@ -0,0 +1,25 @@
+set RPATH (only to be used on ELF platforms)
+
+(currently nothing in LO actually links libpython3.so)
+
+diff -ru python3.orig/Makefile.pre.in python3/Makefile.pre.in
+--- python3.orig/Makefile.pre.in 2015-07-26 20:29:07.126194320 +0200
++++ python3/Makefile.pre.in 2015-07-26 20:37:21.814227530 +0200
+@@ -566,7 +566,7 @@
+
+ # Build the interpreter
+ $(BUILDPYTHON): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY)
+- $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS)
++ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) -Wl,-rpath,\$$ORIGIN
+
+ platform: $(BUILDPYTHON) pybuilddir.txt
+ $(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform
+@@ -628,7 +628,7 @@
+ fi
+
+ libpython3.so: libpython$(LDVERSION).so
+- $(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^
++ $(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^ -Wl,-rpath,\$$ORIGIN
+
+ libpython$(LDVERSION).dylib: $(LIBRARY_OBJS)
+ $(CC) -dynamiclib -Wl,-single_module $(PY_CORE_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(DTRACE_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \
diff --git a/external/python3/python-3.5.4-msvc-disable.patch.1 b/external/python3/python-3.5.4-msvc-disable.patch.1
new file mode 100644
index 000000000..d5b4e3f62
--- /dev/null
+++ b/external/python3/python-3.5.4-msvc-disable.patch.1
@@ -0,0 +1,58 @@
+Disable some stuff LO does not need, especially stuff with external dependencies
+
+diff -ru python3.orig/PCbuild/pcbuild.sln python3/PCbuild/pcbuild.sln
+--- python3.orig/PCbuild/pcbuild.sln 2017-08-10 00:04:44.359879894 +0200
++++ python3/PCbuild/pcbuild.sln 2017-08-10 00:13:51.179873748 +0200
+@@ -15,8 +15,6 @@
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcxproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}"
+-EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcxproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}"
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_decimal", "_decimal.vcxproj", "{0E9791DB-593A-465F-98BC-681011311617}"
+@@ -31,34 +29,20 @@
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcxproj", "{86937F53-C189-40EF-8CE8-8759D8E7D480}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcxproj", "{13CECB97-4119-4316-9D42-8534019A5A44}"
+-EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcxproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}"
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcxproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}"
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testinternalcapi", "_testinternalcapi.vcxproj", "{900342D7-516A-4469-B1AD-59A66E49A25F}"
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcxproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcxproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}"
+-EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bz2", "_bz2.vcxproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}"
+-EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcxproj", "{18CAE28C-B454-46C1-87A0-493D91D97F03}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_lzma", "_lzma.vcxproj", "{F9D71780-F393-11E0-BE50-0800200C9A66}"
+-EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcxproj", "{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}"
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcxproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "..\PC\bdist_wininst\bdist_wininst.vcxproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
+-EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcxproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}"
+-EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}"
+-EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcxproj", "{9E48B300-37D1-11DD-8C41-005056C00008}"
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcxproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}"
+@@ -93,8 +77,6 @@
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_queue", "_queue.vcxproj", "{78D80A15-BD8C-44E2-B49E-1F05B0A0A687}"
+ EndProject
+-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma", "liblzma.vcxproj", "{12728250-16EC-4DC6-94D7-E21DD88947F8}"
+-EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python_uwp", "python_uwp.vcxproj", "{9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}"
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "venvlauncher", "venvlauncher.vcxproj", "{494BAC80-A60C-43A9-99E7-ACB691CE2C4D}"
diff --git a/external/python3/python-3.5.tweak.strip.soabi.patch b/external/python3/python-3.5.tweak.strip.soabi.patch
new file mode 100644
index 000000000..4c2bb2bb9
--- /dev/null
+++ b/external/python3/python-3.5.tweak.strip.soabi.patch
@@ -0,0 +1,12 @@
+diff -ru python3.orig/configure python3/configure
+--- misc/python3.orig/configure 2015-07-26 21:14:31.127377193 +0200
++++ misc/python3/configure 2015-07-26 21:21:34.975405648 +0200
+@@ -15229,7 +15229,7 @@
+ $as_echo "$ABIFLAGS" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking SOABI" >&5
+ $as_echo_n "checking SOABI... " >&6; }
+-SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET}
++SOABI='cpython-'`echo $VERSION$ABIFLAGS`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SOABI" >&5
+ $as_echo "$SOABI" >&6; }
+
diff --git a/external/python3/python-3.7.6-msvc-ssl.patch.1 b/external/python3/python-3.7.6-msvc-ssl.patch.1
new file mode 100644
index 000000000..17cc440f2
--- /dev/null
+++ b/external/python3/python-3.7.6-msvc-ssl.patch.1
@@ -0,0 +1,25 @@
+No use for applink.c OPENSSL_Applink, everything is compiled with the same MSVC
+
+--- python3/PCbuild/_ssl.vcxproj.orig2 2019-12-23 15:54:19.254298900 +0100
++++ python3/PCbuild/_ssl.vcxproj 2019-12-23 15:54:24.693251200 +0100
+@@ -99,9 +99,6 @@
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\Modules\_ssl.c" />
+- <ClCompile Include="$(opensslIncludeDir)\applink.c">
+- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(PreprocessorDefinitions)</PreprocessorDefinitions>
+- </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\PC\python_nt.rc" />
+--- python3/PCbuild/openssl.props.orig 2019-12-23 16:20:34.588135900 +0100
++++ python3/PCbuild/openssl.props 2019-12-23 16:20:51.074001300 +0100
+@@ -6,8 +6,6 @@
+ </ItemDefinitionGroup>
+ <PropertyGroup>
+ <_DLLSuffix>-1_1</_DLLSuffix>
+- <_DLLSuffix Condition="$(Platform) == 'ARM'">$(_DLLSuffix)-arm</_DLLSuffix>
+- <_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64</_DLLSuffix>
+ </PropertyGroup>
+ <ItemGroup>
+ <_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).dll" />
diff --git a/external/python3/python-3.8-msvc-sdk.patch.1 b/external/python3/python-3.8-msvc-sdk.patch.1
new file mode 100644
index 000000000..fabdbb53e
--- /dev/null
+++ b/external/python3/python-3.8-msvc-sdk.patch.1
@@ -0,0 +1,173 @@
+diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc
+index 92987af713..d21f9b6e9d 100644
+--- a/PC/pylauncher.rc
++++ b/PC/pylauncher.rc
+@@ -4,7 +4,6 @@
+
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+-#include <winuser.h>
+ 1 RT_MANIFEST "python.manifest"
+
+ #if defined(PY_ICON)
+diff --git a/PC/pyshellext.rc b/PC/pyshellext.rc
+index e5924a42da..fc607e9784 100644
+--- a/PC/pyshellext.rc
++++ b/PC/pyshellext.rc
+@@ -4,7 +4,6 @@
+
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+-#include <winuser.h>
+ 1 RT_MANIFEST "python.manifest"
+
+ /////////////////////////////////////////////////////////////////////////////
+diff --git a/PC/python_exe.rc b/PC/python_exe.rc
+index ae0b029b80..5eba89962b 100644
+--- a/PC/python_exe.rc
++++ b/PC/python_exe.rc
+@@ -4,7 +4,6 @@
+
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+-#include <winuser.h>
+ 1 RT_MANIFEST "python.manifest"
+
+ 1 ICON DISCARDABLE "icons\python.ico"
+diff --git a/PC/python_nt.rc b/PC/python_nt.rc
+index fac6105d8a..33cee42cb7 100644
+--- a/PC/python_nt.rc
++++ b/PC/python_nt.rc
+@@ -4,7 +4,6 @@
+
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+-#include <winuser.h>
+ 2 RT_MANIFEST "python.manifest"
+
+ // String Tables
+diff --git a/PC/pythonw_exe.rc b/PC/pythonw_exe.rc
+index 88bf3592e1..562652be18 100644
+--- a/PC/pythonw_exe.rc
++++ b/PC/pythonw_exe.rc
+@@ -4,7 +4,6 @@
+
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+-#include <winuser.h>
+ 1 RT_MANIFEST "python.manifest"
+
+ 1 ICON DISCARDABLE "icons\pythonw.ico"
+diff --git a/PC/sqlite3.rc b/PC/sqlite3.rc
+index 84bd87d9d5..d2c18f8add 100644
+--- a/PC/sqlite3.rc
++++ b/PC/sqlite3.rc
+@@ -4,7 +4,6 @@
+
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+-#include <winuser.h>
+ 2 RT_MANIFEST "python.manifest"
+
+ /////////////////////////////////////////////////////////////////////////////
+diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc
+index d21f9b6e9d..ff7e71e0fd 100644
+--- a/PC/pylauncher.rc
++++ b/PC/pylauncher.rc
+@@ -2,6 +2,11 @@
+
+ #include "python_ver_rc.h"
+
++#ifndef RT_MANIFEST
++// bpo-45220: Cannot reliably #include RT_MANIFEST from
++// anywhere, so we hardcode it
++#define RT_MANIFEST 24
++#endif
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+ 1 RT_MANIFEST "python.manifest"
+diff --git a/PC/pyshellext.rc b/PC/pyshellext.rc
+index fc607e9784..af797ce95d 100644
+--- a/PC/pyshellext.rc
++++ b/PC/pyshellext.rc
+@@ -2,6 +2,12 @@
+
+ #include "python_ver_rc.h"
+
++#ifndef RT_MANIFEST
++// bpo-45220: Cannot reliably #include RT_MANIFEST from
++// anywhere, so we hardcode it
++#define RT_MANIFEST 24
++#endif
++
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+ 1 RT_MANIFEST "python.manifest"
+diff --git a/PC/python_exe.rc b/PC/python_exe.rc
+index 5eba89962b..c3d3bff019 100644
+--- a/PC/python_exe.rc
++++ b/PC/python_exe.rc
+@@ -2,6 +2,12 @@
+
+ #include "python_ver_rc.h"
+
++#ifndef RT_MANIFEST
++// bpo-45220: Cannot reliably #include RT_MANIFEST from
++// anywhere, so we hardcode it
++#define RT_MANIFEST 24
++#endif
++
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+ 1 RT_MANIFEST "python.manifest"
+diff --git a/PC/python_nt.rc b/PC/python_nt.rc
+index 33cee42cb7..539362cdc2 100644
+--- a/PC/python_nt.rc
++++ b/PC/python_nt.rc
+@@ -2,6 +2,12 @@
+
+ #include "python_ver_rc.h"
+
++#ifndef RT_MANIFEST
++// bpo-45220: Cannot reliably #include RT_MANIFEST from
++// anywhere, so we hardcode it
++#define RT_MANIFEST 24
++#endif
++
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+ 2 RT_MANIFEST "python.manifest"
+diff --git a/PC/pythonw_exe.rc b/PC/pythonw_exe.rc
+index 562652be18..38570b74fa 100644
+--- a/PC/pythonw_exe.rc
++++ b/PC/pythonw_exe.rc
+@@ -2,6 +2,12 @@
+
+ #include "python_ver_rc.h"
+
++#ifndef RT_MANIFEST
++// bpo-45220: Cannot reliably #include RT_MANIFEST from
++// anywhere, so we hardcode it
++#define RT_MANIFEST 24
++#endif
++
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+ 1 RT_MANIFEST "python.manifest"
+diff --git a/PC/sqlite3.rc b/PC/sqlite3.rc
+index d2c18f8add..9ae2aa0f6f 100644
+--- a/PC/sqlite3.rc
++++ b/PC/sqlite3.rc
+@@ -2,6 +2,12 @@
+
+ #include <winver.h>
+
++#ifndef RT_MANIFEST
++// bpo-45220: Cannot reliably #include RT_MANIFEST from
++// anywhere, so we hardcode it
++#define RT_MANIFEST 24
++#endif
++
+ // Include the manifest file that indicates we support all
+ // current versions of Windows.
+ 2 RT_MANIFEST "python.manifest"
diff --git a/external/python3/tsan.patch.0 b/external/python3/tsan.patch.0
new file mode 100644
index 000000000..d599ec046
--- /dev/null
+++ b/external/python3/tsan.patch.0
@@ -0,0 +1,10 @@
+--- Python/ceval_gil.h
++++ Python/ceval_gil.h
+@@ -135,6 +135,7 @@
+
+ static void recreate_gil(struct _gil_runtime_state *gil)
+ {
++ _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, 1);
+ _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked);
+ /* XXX should we destroy the old OS resources here? */
+ create_gil(gil);
diff --git a/external/python3/ubsan.patch.0 b/external/python3/ubsan.patch.0
new file mode 100644
index 000000000..d44fbe055
--- /dev/null
+++ b/external/python3/ubsan.patch.0
@@ -0,0 +1,43 @@
+--- Modules/_ctypes/libffi_osx/x86/x86-ffi64.c
++++ Modules/_ctypes/libffi_osx/x86/x86-ffi64.c
+@@ -599,9 +599,15 @@
+ tramp = (volatile unsigned short*)&closure->tramp[0];
+
+ tramp[0] = 0xbb49; /* mov <code>, %r11 */
+- *(void* volatile*)&tramp[1] = ffi_closure_unix64;
++ tramp[1] = (unsigned short) ffi_closure_unix64;
++ tramp[2] = (unsigned short) (((unsigned long)ffi_closure_unix64) >> 16);
++ tramp[3] = (unsigned short) (((unsigned long)ffi_closure_unix64) >> 32);
++ tramp[4] = (unsigned short) (((unsigned long)ffi_closure_unix64) >> 48);
+ tramp[5] = 0xba49; /* mov <data>, %r10 */
+- *(void* volatile*)&tramp[6] = closure;
++ tramp[6] = (unsigned short) closure;
++ tramp[7] = (unsigned short) (((unsigned long)closure) >> 16);
++ tramp[8] = (unsigned short) (((unsigned long)closure) >> 32);
++ tramp[9] = (unsigned short) (((unsigned long)closure) >> 48);
+
+ /* Set the carry bit if the function uses any sse registers.
+ This is clc or stc, together with the first byte of the jmp. */
+--- Modules/posixmodule.c
++++ Modules/posixmodule.c
+@@ -13998,6 +13998,9 @@
+ };
+
+ static int
++#if defined __clang__
++__attribute__((no_sanitize("shift-base"))) // MFD_HUGE_16GB in /usr/include/linux/memfd.h
++#endif
+ all_ins(PyObject *m)
+ {
+ #ifdef F_OK
+--- Objects/listobject.c
++++ Objects/listobject.c
+@@ -554,7 +554,7 @@
+ dest[i] = v;
+ }
+ src = b->ob_item;
+- dest = np->ob_item + Py_SIZE(a);
++ dest = Py_SIZE(a) == 0 ? np->ob_item : np->ob_item + Py_SIZE(a);
+ for (i = 0; i < Py_SIZE(b); i++) {
+ PyObject *v = src[i];
+ Py_INCREF(v);
diff --git a/external/redland/ExternalPackage_raptor.mk b/external/redland/ExternalPackage_raptor.mk
new file mode 100644
index 000000000..119e52f9e
--- /dev/null
+++ b/external/redland/ExternalPackage_raptor.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,raptor,raptor))
+
+$(eval $(call gb_ExternalPackage_use_external_project,raptor,raptor))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,raptor,$(LIBO_LIB_FOLDER)/libraptor2-lo.$(RAPTOR_MAJOR).dylib,src/.libs/libraptor2-lo.$(RAPTOR_MAJOR).dylib))
+else ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalPackage_add_file,raptor,$(LIBO_LIB_FOLDER)/libraptor2.dll,src/.libs/libraptor2.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,raptor,$(LIBO_LIB_FOLDER)/libraptor2-lo.so.$(RAPTOR_MAJOR),src/.libs/libraptor2-lo.so.$(RAPTOR_MAJOR).0.0))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/ExternalPackage_rasqal.mk b/external/redland/ExternalPackage_rasqal.mk
new file mode 100644
index 000000000..57fe97c38
--- /dev/null
+++ b/external/redland/ExternalPackage_rasqal.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,rasqal,rasqal))
+
+$(eval $(call gb_ExternalPackage_use_external_project,rasqal,rasqal))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,rasqal,$(LIBO_LIB_FOLDER)/librasqal-lo.$(RASQAL_MAJOR).dylib,src/.libs/librasqal-lo.$(RASQAL_MAJOR).dylib))
+else ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalPackage_add_file,rasqal,$(LIBO_LIB_FOLDER)/librasqal.dll,src/.libs/librasqal.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,rasqal,$(LIBO_LIB_FOLDER)/librasqal-lo.so.$(RASQAL_MAJOR),src/.libs/librasqal-lo.so.$(RASQAL_MAJOR).0.0))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/ExternalPackage_redland.mk b/external/redland/ExternalPackage_redland.mk
new file mode 100644
index 000000000..8c35d850e
--- /dev/null
+++ b/external/redland/ExternalPackage_redland.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,redland,redland))
+
+$(eval $(call gb_ExternalPackage_use_external_project,redland,redland))
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,redland,$(LIBO_LIB_FOLDER)/librdf-lo.$(REDLAND_MAJOR).dylib,src/.libs/librdf-lo.$(REDLAND_MAJOR).dylib))
+else ifeq ($(COM),MSC)
+$(eval $(call gb_ExternalPackage_add_file,redland,$(LIBO_LIB_FOLDER)/librdf.dll,src/.libs/librdf.dll))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,redland,$(LIBO_LIB_FOLDER)/librdf-lo.so.$(REDLAND_MAJOR),src/.libs/librdf-lo.so.$(REDLAND_MAJOR).0.0))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/ExternalProject_raptor.mk b/external/redland/ExternalProject_raptor.mk
new file mode 100644
index 000000000..b3ae74c10
--- /dev/null
+++ b/external/redland/ExternalProject_raptor.mk
@@ -0,0 +1,47 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,raptor))
+
+$(eval $(call gb_ExternalProject_use_external,raptor,libxml2))
+
+$(eval $(call gb_ExternalProject_register_targets,raptor,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,raptor,build):
+ $(call gb_Trace_StartRange,raptor,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(if $(filter iOS,$(OS)),LIBS="-liconv") \
+ CFLAGS="$(CFLAGS) \
+ $(call gb_ExternalProject_get_build_flags,raptor) \
+ $(if $(filter TRUE,$(DISABLE_DYNLOADING)),-fvisibility=hidden) \
+ $(if $(filter GCCLINUXPOWERPC64,$(COM)$(OS)$(CPUNAME)),-mminimal-toc)" \
+ LDFLAGS=" \
+ $(if $(filter LINUX FREEBSD,$(OS)),-Wl$(COMMA)-z$(COMMA)origin -Wl$(COMMA)-rpath$(COMMA)\\"\$$\$$ORIGIN") \
+ $(if $(SYSBASE),$(if $(filter LINUX SOLARIS,$(OS)),-L$(SYSBASE)/lib -L$(SYSBASE)/usr/lib -lpthread -ldl))" \
+ CPPFLAGS="$(if $(SYSBASE),-I$(SYSBASE)/usr/include) $(gb_EMSCRIPTEN_CPPFLAGS)" \
+ $(gb_RUN_CONFIGURE) ./configure --disable-gtk-doc \
+ --enable-parsers="rdfxml ntriples turtle trig guess rss-tag-soup" \
+ --with-www=xml \
+ --without-xslt-config \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),$(if $(filter INTEL ARM,$(CPUNAME)),ac_cv_c_bigendian=no)) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ $(if $(SYSTEM_LIBXML),$(if $(filter-out MACOSX,$(OS)),--without-xml2-config),--with-xml2-config=$(call gb_UnpackedTarball_get_dir,libxml2)/xml2-config) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,raptor,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/ExternalProject_rasqal.mk b/external/redland/ExternalProject_rasqal.mk
new file mode 100644
index 000000000..e7d1fdb11
--- /dev/null
+++ b/external/redland/ExternalProject_rasqal.mk
@@ -0,0 +1,54 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,rasqal))
+
+$(eval $(call gb_ExternalProject_use_external,rasqal,libxml2))
+
+$(eval $(call gb_ExternalProject_use_package,rasqal,raptor))
+
+$(eval $(call gb_ExternalProject_register_targets,rasqal,\
+ build \
+))
+
+# note: this can intentionally only build against internal raptor (not system)
+
+$(call gb_ExternalProject_get_state_target,rasqal,build):
+ $(call gb_Trace_StartRange,rasqal,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ CFLAGS="$(CFLAGS) $(if $(filter TRUE,$(DISABLE_DYNLOADING)),-fvisibility=hidden) $(call gb_ExternalProject_get_build_flags,rasqal) $(gb_EMSCRIPTEN_CPPFLAGS)" \
+ LDFLAGS=" \
+ $(if $(filter LINUX FREEBSD,$(OS)),-Wl$(COMMA)-z$(COMMA)origin -Wl$(COMMA)-rpath$(COMMA)\\"\$$\$$ORIGIN") \
+ $(if $(SYSBASE),$(if $(filter LINUX SOLARIS,$(OS)),-L$(SYSBASE)/lib -L$(SYSBASE)/usr/lib -lpthread -ldl))" \
+ $(if $(SYSBASE),CPPFLAGS="-I$(SYSBASE)/usr/include") \
+ PKG_CONFIG="" \
+ RAPTOR2_CFLAGS="-I$(call gb_UnpackedTarball_get_dir,raptor)/src" \
+ RAPTOR2_LIBS="-L$(call gb_UnpackedTarball_get_dir,raptor)/src/.libs -lraptor2" \
+ $(gb_RUN_CONFIGURE) ./configure --disable-gtk-doc \
+ --with-regex-library=posix \
+ --with-decimal=none \
+ --with-uuid-library=internal \
+ --with-digest-library=internal \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),$(if $(filter INTEL ARM,$(CPUNAME)),ac_cv_c_bigendian=no)) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ $(if $(SYSTEM_LIBXML),,--with-xml2-config=$(call gb_UnpackedTarball_get_dir,libxml2)/xml2-config) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),&& $(PERL) \
+ $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/.libs/librasqal-lo.$(RASQAL_MAJOR).dylib) \
+ )
+ $(call gb_Trace_EndRange,rasqal,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/ExternalProject_redland.mk b/external/redland/ExternalProject_redland.mk
new file mode 100644
index 000000000..d92c642b9
--- /dev/null
+++ b/external/redland/ExternalProject_redland.mk
@@ -0,0 +1,57 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,redland))
+
+$(eval $(call gb_ExternalProject_use_packages,redland, \
+ raptor \
+ rasqal \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,redland,\
+ build \
+))
+
+# note: this can intentionally only build against internal raptor/rasqal
+
+$(call gb_ExternalProject_get_state_target,redland,build):
+ $(call gb_Trace_StartRange,redland,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ CFLAGS="$(CFLAGS) $(if $(filter TRUE,$(DISABLE_DYNLOADING)),-fvisibility=hidden) $(call gb_ExternalProject_get_build_flags,redland) $(gb_EMSCRIPTEN_CPPFLAGS)" \
+ LDFLAGS=" \
+ $(if $(filter LINUX FREEBSD,$(OS)),-Wl$(COMMA)-z$(COMMA)origin -Wl$(COMMA)-rpath$(COMMA)\\"\$$\$$ORIGIN") \
+ $(if $(SYSBASE),$(if $(filter LINUX SOLARIS,$(OS)),-L$(SYSBASE)/lib -L$(SYSBASE)/usr/lib -lpthread -ldl))" \
+ CPPFLAGS="$(if $(SYSBASE),-I$(SYSBASE)/usr/include)" \
+ PKG_CONFIG="" \
+ RAPTOR2_CFLAGS="-I$(call gb_UnpackedTarball_get_dir,raptor)/src" \
+ RAPTOR2_LIBS="-L$(call gb_UnpackedTarball_get_dir,raptor)/src/.libs -lraptor2 $(LIBXML_LIBS)" \
+ RASQAL_CFLAGS="-I$(call gb_UnpackedTarball_get_dir,rasqal)/src" \
+ RASQAL_LIBS="-L$(call gb_UnpackedTarball_get_dir,rasqal)/src/.libs -lrasqal" \
+ $(gb_RUN_CONFIGURE) ./configure --disable-gtk-doc \
+ --disable-modular \
+ --without-threads \
+ --without-bdb --without-sqlite --without-mysql \
+ --without-postgresql --without-threestone --without-virtuoso \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(CROSS_COMPILING),$(if $(filter INTEL ARM,$(CPUNAME)),ac_cv_c_bigendian=no)) \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(ENABLE_DEBUG),--enable-debug) \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ && $(MAKE) \
+ $(if $(filter MACOSX,$(OS)),&& $(PERL) \
+ $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/src/.libs/librdf-lo.$(REDLAND_MAJOR).dylib) \
+ )
+ $(call gb_Trace_EndRange,redland,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/Library_raptor.mk b/external/redland/Library_raptor.mk
new file mode 100644
index 000000000..b2779f7de
--- /dev/null
+++ b/external/redland/Library_raptor.mk
@@ -0,0 +1,88 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,raptor2))
+
+$(eval $(call gb_Library_set_include,raptor2, \
+ -I$(call gb_UnpackedTarball_get_dir,raptor)/src \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_use_unpacked,raptor2,raptor))
+
+$(eval $(call gb_Library_use_externals,raptor2,\
+ libxml2 \
+ libxslt \
+))
+
+$(eval $(call gb_Library_set_warnings_disabled,raptor2))
+
+$(eval $(call gb_Library_add_defs,raptor2,\
+ -DHAVE_CONFIG_H \
+ -DRAPTOR_INTERNAL \
+ -DWIN32 \
+ -DNDEBUG \
+ -D_WINDOWS \
+ -D_USRDLL \
+ -DWIN32_EXPORTS \
+ -DYY_NO_UNISTD_H \
+ -DHAVE__ACCESS \
+ -UHAVE_ACCESS \
+))
+
+$(eval $(call gb_Library_add_generated_cobjects,raptor2,\
+ UnpackedTarball/raptor/src/ntriples_parse \
+ UnpackedTarball/raptor/src/parsedate \
+ UnpackedTarball/raptor/src/raptor_abbrev \
+ UnpackedTarball/raptor/src/raptor_avltree \
+ UnpackedTarball/raptor/src/raptor_concepts \
+ UnpackedTarball/raptor/src/raptor_escaped \
+ UnpackedTarball/raptor/src/raptor_general \
+ UnpackedTarball/raptor/src/raptor_guess \
+ UnpackedTarball/raptor/src/raptor_iostream \
+ UnpackedTarball/raptor/src/raptor_json_writer \
+ UnpackedTarball/raptor/src/raptor_libxml \
+ UnpackedTarball/raptor/src/raptor_locator \
+ UnpackedTarball/raptor/src/raptor_log \
+ UnpackedTarball/raptor/src/raptor_memstr \
+ UnpackedTarball/raptor/src/raptor_namespace \
+ UnpackedTarball/raptor/src/raptor_ntriples \
+ UnpackedTarball/raptor/src/raptor_option \
+ UnpackedTarball/raptor/src/raptor_parse \
+ UnpackedTarball/raptor/src/raptor_qname \
+ UnpackedTarball/raptor/src/raptor_rdfxml \
+ UnpackedTarball/raptor/src/raptor_rfc2396 \
+ UnpackedTarball/raptor/src/raptor_sax2 \
+ UnpackedTarball/raptor/src/raptor_sequence \
+ UnpackedTarball/raptor/src/raptor_serialize \
+ UnpackedTarball/raptor/src/raptor_serialize_ntriples \
+ UnpackedTarball/raptor/src/raptor_serialize_rdfxml \
+ UnpackedTarball/raptor/src/raptor_serialize_rdfxmla \
+ UnpackedTarball/raptor/src/raptor_serialize_turtle \
+ UnpackedTarball/raptor/src/raptor_set \
+ UnpackedTarball/raptor/src/raptor_statement \
+ UnpackedTarball/raptor/src/raptor_stringbuffer \
+ UnpackedTarball/raptor/src/raptor_syntax_description \
+ UnpackedTarball/raptor/src/raptor_term \
+ UnpackedTarball/raptor/src/raptor_turtle_writer \
+ UnpackedTarball/raptor/src/raptor_unicode \
+ UnpackedTarball/raptor/src/raptor_uri \
+ UnpackedTarball/raptor/src/raptor_www \
+ UnpackedTarball/raptor/src/raptor_xml \
+ UnpackedTarball/raptor/src/raptor_xml_writer \
+ UnpackedTarball/raptor/src/snprintf \
+ UnpackedTarball/raptor/src/sort_r \
+ UnpackedTarball/raptor/src/strcasecmp \
+ UnpackedTarball/raptor/src/turtle_common \
+ UnpackedTarball/raptor/src/turtle_lexer \
+ UnpackedTarball/raptor/src/turtle_parser \
+))
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/Library_rasqal.mk b/external/redland/Library_rasqal.mk
new file mode 100644
index 000000000..79171d904
--- /dev/null
+++ b/external/redland/Library_rasqal.mk
@@ -0,0 +1,127 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,rasqal))
+
+$(eval $(call gb_Library_use_unpacked,rasqal,rasqal))
+
+$(eval $(call gb_Library_set_warnings_disabled,rasqal))
+
+$(eval $(call gb_Library_use_external,rasqal,raptor_headers))
+
+$(eval $(call gb_Library_use_libraries,rasqal,raptor2))
+
+$(eval $(call gb_Library_add_defs,rasqal,\
+ -DSV_CONFIG \
+ -DRASQAL_INTERNAL \
+ -DWIN32 \
+ -DNDEBUG \
+ -D_WINDOWS \
+ -D_USRDLL \
+ -DWIN32_EXPORTS \
+ -D_MT \
+ -DHAVE_STDLIB_H \
+ -DHAVE_STDINT_H \
+ -DHAVE_TIME_H \
+ -DHAVE_MATH_H \
+ -DHAVE_FLOAT_H \
+ -DHAVE___FUNCTION__ \
+))
+
+$(eval $(call gb_Library_set_include,rasqal,\
+ -I$(call gb_UnpackedTarball_get_dir,rasqal)/libmtwist \
+ -I$(call gb_UnpackedTarball_get_dir,rasqal)/libsv \
+ -I$(call gb_UnpackedTarball_get_dir,rasqal)/src \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_generated_cobjects,rasqal,\
+ UnpackedTarball/rasqal/libmtwist/mt \
+ UnpackedTarball/rasqal/libmtwist/seed \
+ UnpackedTarball/rasqal/libsv/sv \
+ UnpackedTarball/rasqal/src/rasqal_algebra \
+ UnpackedTarball/rasqal/src/rasqal_bindings \
+ UnpackedTarball/rasqal/src/rasqal_data_graph \
+ UnpackedTarball/rasqal/src/rasqal_dataset \
+ UnpackedTarball/rasqal/src/rasqal_datetime \
+ UnpackedTarball/rasqal/src/rasqal_decimal \
+ UnpackedTarball/rasqal/src/rasqal_digest \
+ UnpackedTarball/rasqal/src/rasqal_digest_md5 \
+ UnpackedTarball/rasqal/src/rasqal_digest_sha1 \
+ UnpackedTarball/rasqal/src/rasqal_double \
+ UnpackedTarball/rasqal/src/rasqal_engine \
+ UnpackedTarball/rasqal/src/rasqal_engine_algebra \
+ UnpackedTarball/rasqal/src/rasqal_engine_sort \
+ UnpackedTarball/rasqal/src/rasqal_expr \
+ UnpackedTarball/rasqal/src/rasqal_expr_datetimes \
+ UnpackedTarball/rasqal/src/rasqal_expr_evaluate \
+ UnpackedTarball/rasqal/src/rasqal_expr_numerics \
+ UnpackedTarball/rasqal/src/rasqal_expr_strings \
+ UnpackedTarball/rasqal/src/rasqal_feature \
+ UnpackedTarball/rasqal/src/rasqal_format_html \
+ UnpackedTarball/rasqal/src/rasqal_format_json \
+ UnpackedTarball/rasqal/src/rasqal_format_rdf \
+ UnpackedTarball/rasqal/src/rasqal_format_sparql_xml \
+ UnpackedTarball/rasqal/src/rasqal_format_sv \
+ UnpackedTarball/rasqal/src/rasqal_format_table \
+ UnpackedTarball/rasqal/src/rasqal_formula \
+ UnpackedTarball/rasqal/src/rasqal_general \
+ UnpackedTarball/rasqal/src/rasqal_graph_pattern \
+ UnpackedTarball/rasqal/src/rasqal_iostream \
+ UnpackedTarball/rasqal/src/rasqal_literal \
+ UnpackedTarball/rasqal/src/rasqal_map \
+ UnpackedTarball/rasqal/src/rasqal_ntriples \
+ UnpackedTarball/rasqal/src/rasqal_prefix \
+ UnpackedTarball/rasqal/src/rasqal_projection \
+ UnpackedTarball/rasqal/src/rasqal_query \
+ UnpackedTarball/rasqal/src/rasqal_query_results \
+ UnpackedTarball/rasqal/src/rasqal_query_transform \
+ UnpackedTarball/rasqal/src/rasqal_query_write \
+ UnpackedTarball/rasqal/src/rasqal_random \
+ UnpackedTarball/rasqal/src/rasqal_raptor \
+ UnpackedTarball/rasqal/src/rasqal_regex \
+ UnpackedTarball/rasqal/src/rasqal_result_formats \
+ UnpackedTarball/rasqal/src/rasqal_results_compare \
+ UnpackedTarball/rasqal/src/rasqal_row \
+ UnpackedTarball/rasqal/src/rasqal_row_compatible \
+ UnpackedTarball/rasqal/src/rasqal_rowsource \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_aggregation \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_assignment \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_bindings \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_distinct \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_empty \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_filter \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_graph \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_groupby \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_having \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_join \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_project \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_rowsequence \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_service \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_slice \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_sort \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_triples \
+ UnpackedTarball/rasqal/src/rasqal_rowsource_union \
+ UnpackedTarball/rasqal/src/rasqal_service \
+ UnpackedTarball/rasqal/src/rasqal_solution_modifier \
+ UnpackedTarball/rasqal/src/rasqal_sort \
+ UnpackedTarball/rasqal/src/rasqal_triple \
+ UnpackedTarball/rasqal/src/rasqal_triples_source \
+ UnpackedTarball/rasqal/src/rasqal_update \
+ UnpackedTarball/rasqal/src/rasqal_variable \
+ UnpackedTarball/rasqal/src/rasqal_xsd_datatypes \
+ UnpackedTarball/rasqal/src/snprintf \
+ UnpackedTarball/rasqal/src/sparql_lexer \
+ UnpackedTarball/rasqal/src/sparql_parser \
+ UnpackedTarball/rasqal/src/timegm \
+ UnpackedTarball/rasqal/src/gettimeofday \
+))
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/Library_rdf.mk b/external/redland/Library_rdf.mk
new file mode 100644
index 000000000..cc427b339
--- /dev/null
+++ b/external/redland/Library_rdf.mk
@@ -0,0 +1,78 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,rdf))
+
+$(eval $(call gb_Library_set_include,rdf, \
+ -I$(call gb_UnpackedTarball_get_dir,redland)/src \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_use_unpacked,rdf,redland))
+
+$(eval $(call gb_Library_set_warnings_disabled,rdf))
+
+$(eval $(call gb_Library_use_libraries,rdf,\
+ raptor2 \
+ rasqal \
+))
+
+$(eval $(call gb_Library_use_externals,rdf,\
+ raptor_headers \
+ rasqal_headers \
+))
+
+$(eval $(call gb_Library_add_defs,rdf,\
+ -DLIBRDF_INTERNAL \
+ -DWIN32 \
+ -DNDEBUG \
+ -D_WINDOWS \
+ -D_USRDLL \
+ -DWIN32_EXPORTS \
+))
+
+$(eval $(call gb_Library_add_generated_cobjects,rdf,\
+ UnpackedTarball/redland/src/rdf_concepts \
+ UnpackedTarball/redland/src/rdf_digest \
+ UnpackedTarball/redland/src/rdf_digest_md5 \
+ UnpackedTarball/redland/src/rdf_digest_sha1 \
+ UnpackedTarball/redland/src/rdf_files \
+ UnpackedTarball/redland/src/rdf_hash \
+ UnpackedTarball/redland/src/rdf_hash_cursor \
+ UnpackedTarball/redland/src/rdf_hash_memory \
+ UnpackedTarball/redland/src/rdf_heuristics \
+ UnpackedTarball/redland/src/rdf_init \
+ UnpackedTarball/redland/src/rdf_iterator \
+ UnpackedTarball/redland/src/rdf_list \
+ UnpackedTarball/redland/src/rdf_log \
+ UnpackedTarball/redland/src/rdf_model \
+ UnpackedTarball/redland/src/rdf_model_storage \
+ UnpackedTarball/redland/src/rdf_node \
+ UnpackedTarball/redland/src/rdf_node_common \
+ UnpackedTarball/redland/src/rdf_parser \
+ UnpackedTarball/redland/src/rdf_parser_raptor \
+ UnpackedTarball/redland/src/rdf_raptor \
+ UnpackedTarball/redland/src/rdf_query \
+ UnpackedTarball/redland/src/rdf_query_rasqal \
+ UnpackedTarball/redland/src/rdf_query_results \
+ UnpackedTarball/redland/src/rdf_serializer \
+ UnpackedTarball/redland/src/rdf_serializer_raptor \
+ UnpackedTarball/redland/src/rdf_statement \
+ UnpackedTarball/redland/src/rdf_statement_common \
+ UnpackedTarball/redland/src/rdf_storage \
+ UnpackedTarball/redland/src/rdf_storage_file \
+ UnpackedTarball/redland/src/rdf_storage_list \
+ UnpackedTarball/redland/src/rdf_storage_hashes \
+ UnpackedTarball/redland/src/rdf_storage_trees \
+ UnpackedTarball/redland/src/rdf_stream \
+ UnpackedTarball/redland/src/rdf_uri \
+ UnpackedTarball/redland/src/rdf_utf8 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/Makefile b/external/redland/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/redland/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/Module_redland.mk b/external/redland/Module_redland.mk
new file mode 100644
index 000000000..adc81b462
--- /dev/null
+++ b/external/redland/Module_redland.mk
@@ -0,0 +1,34 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,redland))
+
+$(eval $(call gb_Module_add_targets,redland,\
+ UnpackedTarball_raptor \
+ UnpackedTarball_rasqal \
+ UnpackedTarball_redland \
+))
+ifeq ($(COM),MSC)
+$(eval $(call gb_Module_add_targets,redland,\
+ Library_raptor \
+ Library_rasqal \
+ Library_rdf \
+))
+else
+$(eval $(call gb_Module_add_targets,redland,\
+ ExternalPackage_raptor \
+ ExternalPackage_rasqal \
+ ExternalPackage_redland \
+ ExternalProject_raptor \
+ ExternalProject_rasqal \
+ ExternalProject_redland \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/README b/external/redland/README
new file mode 100644
index 000000000..591e93398
--- /dev/null
+++ b/external/redland/README
@@ -0,0 +1,24 @@
+Redland RDF library (librdf) from [http://librdf.org/]
+
+== License ==
+[git:redland/LICENSE.txt]
+Triple-licensed: LGPL v2+/GPL v2+/Apache v2
+
+== Description ==
+This module contains the third-party Redland RDF / librdf library, which
+is needed to support data in RDF (Resource Description Framework) format.
+It consists of 3 parts:
+- raptor: parsers and serializers for numerous RDF file formats
+- rasqal: query engine which supports SPARQL queries
+- redland: librdf integrates raptor and rasqal, and provides numerous storage
+ engines for storing RDF graphs (in memory, SQL, ...)
+
+Libraries: libraptor, librasqal, librdf
+
+== Patches ==
+There are several patches, most of which contain only hacks to get it to
+build with the LO build system.
+
+Upstream may merge patches that are attached to the bug tracker, but don't
+send patches to the mailing list, those will most likely be ignored.
+
diff --git a/external/redland/UnpackedTarball_raptor.mk b/external/redland/UnpackedTarball_raptor.mk
new file mode 100644
index 000000000..fbdc8b6f5
--- /dev/null
+++ b/external/redland/UnpackedTarball_raptor.mk
@@ -0,0 +1,35 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,raptor))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,raptor,$(RAPTOR_TARBALL),,redland))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,raptor,build))
+
+# configure generated files for MSVC
+$(eval $(call gb_UnpackedTarball_add_file,raptor,src/raptor2.h,external/redland/raptor/raptor2.h))
+$(eval $(call gb_UnpackedTarball_add_file,raptor,src/raptor_config.h,external/redland/raptor/raptor_config.h))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,raptor,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,raptor,\
+ external/redland/raptor/raptor-freebsd.patch.1 \
+ external/redland/raptor/raptor-msvc.patch.1 \
+ $(if $(filter-out WNT,$(OS)),external/redland/raptor/raptor-bundled-soname.patch.1) \
+ $(if $(filter ANDROID,$(OS)),external/redland/raptor/raptor-android.patch.1) \
+ external/redland/raptor/ubsan.patch \
+ $(if $(SYSTEM_LIBXML),,external/redland/raptor/rpath.patch) \
+ external/redland/raptor/xml2-config.patch \
+ external/redland/raptor/0001-Calcualte-max-nspace-declarations-correctly-for-XML-.patch.1 \
+ external/redland/raptor/0001-CVE-2020-25713-raptor2-malformed-input-file-can-lead.patch.1 \
+ external/redland/raptor/libtool.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/UnpackedTarball_rasqal.mk b/external/redland/UnpackedTarball_rasqal.mk
new file mode 100644
index 000000000..bb44f39a6
--- /dev/null
+++ b/external/redland/UnpackedTarball_rasqal.mk
@@ -0,0 +1,34 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,rasqal))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,rasqal,$(RASQAL_TARBALL),,redland))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,rasqal,build))
+
+# configure generated files for MSVC
+$(eval $(call gb_UnpackedTarball_add_file,rasqal,src/rasqal.h,external/redland/rasqal/rasqal.h))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,rasqal,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,rasqal,\
+ external/redland/rasqal/rasqal-pkgconfig.patch.1 \
+ external/redland/rasqal/rasqal-freebsd.patch.1 \
+ external/redland/rasqal/rasqal-msvc.patch.1 \
+ external/redland/rasqal/rasqal-aix.patch.1 \
+ $(if $(filter-out WNT,$(OS)),external/redland/rasqal/rasqal-bundled-soname.patch.1) \
+ $(if $(filter ANDROID,$(OS)),external/redland/rasqal/rasqal-android.patch.1) \
+ $(if $(CROSS_COMPILING),external/redland/rasqal/rasqal-xcompile.patch.1) \
+ external/redland/rasqal/rpath.patch \
+ external/redland/rasqal/clang-cl.patch \
+ external/redland/rasqal/libtool.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/UnpackedTarball_redland.mk b/external/redland/UnpackedTarball_redland.mk
new file mode 100644
index 000000000..66e766d20
--- /dev/null
+++ b/external/redland/UnpackedTarball_redland.mk
@@ -0,0 +1,38 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,redland))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,redland,$(REDLAND_TARBALL),,redland))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,redland,\
+ build \
+ libltdl/config \
+))
+
+# configure generated files for MSVC
+$(eval $(call gb_UnpackedTarball_add_file,redland,src/librdf.h,external/redland/redland/librdf.h))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,redland,0))
+
+# redland-format.patch.0 sent upstream as
+# <https://github.com/dajobe/librdf/pull/6>
+$(eval $(call gb_UnpackedTarball_add_patches,redland,\
+ external/redland/redland/redland-freebsd.patch.1 \
+ external/redland/redland/redland-msvc.patch.1 \
+ $(if $(filter-out WNT,$(OS)),external/redland/redland/redland-bundled-soname.patch.1) \
+ $(if $(filter ANDROID,$(OS)),external/redland/redland/redland-android.patch.1) \
+ $(if $(CROSS_COMPILING),external/redland/redland/redland-xcompile.patch.1) \
+ external/redland/redland/redland-format.patch.0 \
+ external/redland/redland/rpath.patch \
+ external/redland/redland/clang-cl.patch \
+ external/redland/redland/libtool.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/redland/raptor/0001-CVE-2020-25713-raptor2-malformed-input-file-can-lead.patch.1 b/external/redland/raptor/0001-CVE-2020-25713-raptor2-malformed-input-file-can-lead.patch.1
new file mode 100644
index 000000000..1fb279df3
--- /dev/null
+++ b/external/redland/raptor/0001-CVE-2020-25713-raptor2-malformed-input-file-can-lead.patch.1
@@ -0,0 +1,33 @@
+From a549457461874157c8c8e8e8a6e0eec06da4fbd0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
+Date: Tue, 24 Nov 2020 10:30:20 +0000
+Subject: [PATCH] CVE-2020-25713 raptor2: malformed input file can lead to a
+ segfault
+
+due to an out of bounds array access in
+raptor_xml_writer_start_element_common
+
+See:
+https://bugs.mageia.org/show_bug.cgi?id=27605
+https://www.openwall.com/lists/oss-security/2020/11/13/1
+https://gerrit.libreoffice.org/c/core/+/106249
+---
+ src/raptor_xml_writer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/raptor_xml_writer.c b/src/raptor_xml_writer.c
+index 56993dc3..4426d38c 100644
+--- a/src/raptor_xml_writer.c
++++ b/src/raptor_xml_writer.c
+@@ -227,7 +227,7 @@ raptor_xml_writer_start_element_common(raptor_xml_writer* xml_writer,
+
+ /* check it wasn't an earlier declaration too */
+ for(j = 0; j < nspace_declarations_count; j++)
+- if(nspace_declarations[j].nspace == element->attributes[j]->nspace) {
++ if(nspace_declarations[j].nspace == element->attributes[i]->nspace) {
+ declare_me = 0;
+ break;
+ }
+--
+2.28.0
+
diff --git a/external/redland/raptor/0001-Calcualte-max-nspace-declarations-correctly-for-XML-.patch.1 b/external/redland/raptor/0001-Calcualte-max-nspace-declarations-correctly-for-XML-.patch.1
new file mode 100644
index 000000000..6fa726cae
--- /dev/null
+++ b/external/redland/raptor/0001-Calcualte-max-nspace-declarations-correctly-for-XML-.patch.1
@@ -0,0 +1,43 @@
+From 590681e546cd9aa18d57dc2ea1858cb734a3863f Mon Sep 17 00:00:00 2001
+From: Dave Beckett <dave@dajobe.org>
+Date: Sun, 16 Apr 2017 23:15:12 +0100
+Subject: [PATCH] Calcualte max nspace declarations correctly for XML writer
+
+(raptor_xml_writer_start_element_common): Calculate max including for
+each attribute a potential name and value.
+
+Fixes Issues #0000617 http://bugs.librdf.org/mantis/view.php?id=617
+and #0000618 http://bugs.librdf.org/mantis/view.php?id=618
+---
+ src/raptor_xml_writer.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/src/raptor_xml_writer.c b/src/raptor_xml_writer.c
+index 693b946..0d3a36a 100644
+--- a/src/raptor_xml_writer.c
++++ b/src/raptor_xml_writer.c
+@@ -181,9 +181,10 @@ raptor_xml_writer_start_element_common(raptor_xml_writer* xml_writer,
+ size_t nspace_declarations_count = 0;
+ unsigned int i;
+
+- /* max is 1 per element and 1 for each attribute + size of declared */
+ if(nstack) {
+- int nspace_max_count = element->attribute_count+1;
++ int nspace_max_count = element->attribute_count * 2; /* attr and value */
++ if(element->name->nspace)
++ nspace_max_count++;
+ if(element->declared_nspaces)
+ nspace_max_count += raptor_sequence_size(element->declared_nspaces);
+ if(element->xml_language)
+@@ -237,7 +238,7 @@ raptor_xml_writer_start_element_common(raptor_xml_writer* xml_writer,
+ }
+ }
+
+- /* Add the attribute + value */
++ /* Add the attribute's value */
+ nspace_declarations[nspace_declarations_count].declaration=
+ raptor_qname_format_as_xml(element->attributes[i],
+ &nspace_declarations[nspace_declarations_count].length);
+--
+2.9.3
+
diff --git a/external/redland/raptor/libtool.patch b/external/redland/raptor/libtool.patch
new file mode 100644
index 000000000..b0baae661
--- /dev/null
+++ b/external/redland/raptor/libtool.patch
@@ -0,0 +1,27 @@
+--- build/ltmain.sh
++++ build/ltmain.sh
+@@ -5301,6 +5301,12 @@
+ prev=
+ continue
+ ;;
++ mllvm)
++ # Clang does not use LLVM to link, so we can simply discard any
++ # '-mllvm $arg' options when doing the link step.
++ prev=
++ continue
++ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+@@ -5639,6 +5645,11 @@
+ continue
+ ;;
+
++ -mllvm)
++ prev=mllvm
++ continue
++ ;;
++
+ -module)
+ module=yes
+ continue
diff --git a/external/redland/raptor/raptor-android.patch.1 b/external/redland/raptor/raptor-android.patch.1
new file mode 100644
index 000000000..cb843839c
--- /dev/null
+++ b/external/redland/raptor/raptor-android.patch.1
@@ -0,0 +1,13 @@
+No sonames on Android
+
+--- a/configure 2013-03-29 19:46:34.922901756 +0100
++++ b/configure 2013-03-29 19:46:56.051901574 +0100
+@@ -9866,7 +9866,7 @@
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
diff --git a/external/redland/raptor/raptor-bundled-soname.patch.1 b/external/redland/raptor/raptor-bundled-soname.patch.1
new file mode 100644
index 000000000..cce2482d1
--- /dev/null
+++ b/external/redland/raptor/raptor-bundled-soname.patch.1
@@ -0,0 +1,13 @@
+rhbz#809466 change soname of bundled redland libs
+
+--- a/src/Makefile.in 2013-03-29 19:11:27.944919859 +0100
++++ b/src/Makefile.in 2013-03-29 19:17:42.173916644 +0100
+@@ -507,7 +507,7 @@
+ $(am__append_21) $(am__append_22) $(am__append_23) \
+ $(am__append_24) $(am__append_25) $(am__append_26)
+ libraptor2_la_LIBADD = $(am__append_29) @LTLIBOBJS@
+-libraptor2_la_LDFLAGS = -version-info @RAPTOR_LIBTOOL_VERSION@ \
++libraptor2_la_LDFLAGS = -version-info @RAPTOR_LIBTOOL_VERSION@ -release lo \
+ @RAPTOR_LDFLAGS@ $(MEM_LIBS)
+
+ EXTRA_DIST = \
diff --git a/external/redland/raptor/raptor-freebsd.patch.1 b/external/redland/raptor/raptor-freebsd.patch.1
new file mode 100644
index 000000000..349f3a197
--- /dev/null
+++ b/external/redland/raptor/raptor-freebsd.patch.1
@@ -0,0 +1,28 @@
+Usual patch to produce Linux-like .so files on FreeBSD
+
+--- a/build/ltmain.sh 2008-02-02 22:28:24.000000000 +0900
++++ b/build/ltmain.sh 2008-07-08 11:58:42.000000000 +0900
+@@ -7341,9 +7341,9 @@
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+- current="$number_major"
+- revision="$number_minor"
+- age="0"
++ current=`expr $number_major + $number_minor`
++ age="$number_minor"
++ revision="$number_revision"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+@@ -7420,8 +7420,8 @@
+ ;;
+
+ freebsd-elf)
+- major=".$current"
+- versuffix=".$current"
++ major=.`expr $current - $age`
++ versuffix="$major.$age.$revision"
+ ;;
+
+ irix | nonstopux)
diff --git a/external/redland/raptor/raptor-msvc.patch.1 b/external/redland/raptor/raptor-msvc.patch.1
new file mode 100644
index 000000000..245b19bdc
--- /dev/null
+++ b/external/redland/raptor/raptor-msvc.patch.1
@@ -0,0 +1,23 @@
+--- raptor/src/raptor2.h.in.orig 2016-08-26 23:45:34.543400074 +0200
++++ raptor/src/raptor2.h.in 2016-08-26 23:45:40.479399614 +0200
+@@ -2176,6 +2176,7 @@
+ void* raptor_avltree_iterator_get(raptor_avltree_iterator* iterator);
+
+ /* utility methods */
++RAPTOR_API
+ void raptor_sort_r(void *base, size_t nel, size_t width, raptor_data_compare_arg_handler compar, void *user_data);
+
+
+--- raptor/src/raptor_uri.c 2016-08-26 23:45:34.543400074 +0200
++++ raptor/src/raptor_uri.c 2016-08-26 23:45:40.479399614 +0200
+@@ -51,6 +51,10 @@
+ #include <sys/stat.h>
+ #endif
+
++#if !defined(HAVE_ACCESS) && defined(HAVE__ACCESS)
++#include <io.h>
++#endif
++
+ /* Raptor includes */
+ #include "raptor2.h"
+ #include "raptor_internal.h"
diff --git a/external/redland/raptor/raptor2.h b/external/redland/raptor/raptor2.h
new file mode 100644
index 000000000..4929117e7
--- /dev/null
+++ b/external/redland/raptor/raptor2.h
@@ -0,0 +1,2187 @@
+/* -*- Mode: c; c-basic-offset: 2 -*-
+ *
+ * raptor.h - Redland Parser Toolkit for RDF (Raptor) - public API
+ *
+ * Copyright (C) 2000-2013, David Beckett http://www.dajobe.org/
+ * Copyright (C) 2000-2005, University of Bristol, UK http://www.bristol.ac.uk/
+ *
+ * This package is Free Software and part of Redland http://librdf.org/
+ *
+ * It is licensed under the following three licenses as alternatives:
+ * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
+ * 2. GNU General Public License (GPL) V2 or any newer version
+ * 3. Apache License, V2.0 or any newer version
+ *
+ * You may not use this file except in compliance with at least one of
+ * the above three licenses.
+ *
+ * See LICENSE.html or LICENSE.txt at the top of this package for the
+ * complete terms and further detail along with the license texts for
+ * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
+ *
+ *
+ */
+
+
+
+#ifndef RAPTOR_H
+#define RAPTOR_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+/* Required for va_list in raptor_vsnprintf */
+#include <stdarg.h>
+
+
+/**
+ * RAPTOR_V2_AVAILABLE
+ *
+ * Flag for marking raptor2 API availability.
+ */
+#define RAPTOR_V2_AVAILABLE 1
+
+
+/**
+ * RAPTOR_VERSION:
+ *
+ * Raptor library version number
+ *
+ * Format: major * 10000 + minor * 100 + release
+ */
+#define RAPTOR_VERSION 20015
+
+/**
+ * RAPTOR_VERSION_STRING:
+ *
+ * Raptor library version string
+ */
+#define RAPTOR_VERSION_STRING "2.0.15"
+
+/**
+ * RAPTOR_VERSION_MAJOR:
+ *
+ * Raptor library major version
+ */
+#define RAPTOR_VERSION_MAJOR 2
+
+/**
+ * RAPTOR_VERSION_MINOR:
+ *
+ * Raptor library minor version
+ */
+#define RAPTOR_VERSION_MINOR 0
+
+/**
+ * RAPTOR_VERSION_RELEASE:
+ *
+ * Raptor library release
+ */
+#define RAPTOR_VERSION_RELEASE 15
+
+/**
+ * RAPTOR_API:
+ *
+ * Macro for wrapping API function call declarations.
+ *
+ */
+#ifndef RAPTOR_API
+# ifdef _WIN32
+# ifdef __GNUC__
+# undef _declspec
+# define _declspec(x) __declspec(x)
+# endif
+# ifdef RAPTOR_STATIC
+# define RAPTOR_API
+# else
+# ifdef RAPTOR_INTERNAL
+# define RAPTOR_API _declspec(dllexport)
+# else
+# define RAPTOR_API _declspec(dllimport)
+# endif
+# endif
+# else
+# define RAPTOR_API
+# endif
+#endif
+
+/* Use gcc 3.1+ feature to allow marking of deprecated API calls.
+ * This gives a warning during compiling.
+ */
+#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#define RAPTOR_DEPRECATED __attribute__((deprecated))
+#define RAPTOR_NORETURN __attribute__((__noreturn__))
+#else
+#define RAPTOR_DEPRECATED
+#define RAPTOR_NORETURN
+#endif
+
+/**
+ * RAPTOR_PRINTF_FORMAT:
+ * @string_index: ignore me
+ * @first_to_check_index: ignore me
+ *
+ * Internal macro
+ */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
+#define RAPTOR_PRINTF_FORMAT(string_index, first_to_check_index) \
+ __attribute__((__format__(__printf__, string_index, first_to_check_index)))
+#else
+#define RAPTOR_PRINTF_FORMAT(string_index, first_to_check_index)
+#endif
+
+/**
+ * raptor_uri:
+ *
+ * Raptor URI Class.
+ */
+typedef struct raptor_uri_s raptor_uri;
+
+
+/* Public statics */
+
+/**
+ * raptor_short_copyright_string:
+ *
+ * Short copyright string (one line).
+ */
+RAPTOR_API
+extern const char * const raptor_short_copyright_string;
+
+/**
+ * raptor_copyright_string:
+ *
+ * Copyright string (multiple lines).
+ */
+RAPTOR_API
+extern const char * const raptor_copyright_string;
+
+/**
+ * raptor_version_string:
+ *
+ * Raptor version as a string.
+ */
+RAPTOR_API
+extern const char * const raptor_version_string;
+
+/**
+ * raptor_version_major:
+ *
+ * Raptor major version number.
+ */
+RAPTOR_API
+extern const unsigned int raptor_version_major;
+
+/**
+ * raptor_version_minor:
+ *
+ * Raptor minor version number.
+ */
+RAPTOR_API
+extern const unsigned int raptor_version_minor;
+
+/**
+ * raptor_version_release:
+ *
+ * Raptor release version number.
+ */
+RAPTOR_API
+extern const unsigned int raptor_version_release;
+
+/**
+ * raptor_version_decimal:
+ *
+ * Raptor version as a decimal number.
+ *
+ * Format: major * 10000 + minor * 100 + release
+ */
+RAPTOR_API
+extern const unsigned int raptor_version_decimal;
+
+/**
+ * raptor_license_string:
+ *
+ * Raptor license string.
+ */
+RAPTOR_API
+extern const char * const raptor_license_string;
+
+/**
+ * raptor_home_url_string:
+ *
+ * Raptor home page URL.
+ */
+RAPTOR_API
+extern const char * const raptor_home_url_string;
+
+/**
+ * raptor_xml_namespace_uri:
+ *
+ * XML Namespace (xml:) URI string.
+ */
+RAPTOR_API
+extern const unsigned char * const raptor_xml_namespace_uri;
+
+
+/**
+ * raptor_rdf_namespace_uri:
+ *
+ * RDF Namespace (rdf:) URI string.
+ */
+RAPTOR_API
+extern const unsigned char * const raptor_rdf_namespace_uri;
+
+/**
+ * raptor_rdf_namespace_uri_len:
+ *
+ * Length of #raptor_rdf_namespace_uri string
+ */
+RAPTOR_API
+extern const unsigned int raptor_rdf_namespace_uri_len;
+
+/**
+ * raptor_rdf_schema_namespace_uri:
+ *
+ * RDF Schema (rdfs:) Namespace URI string.
+ */
+RAPTOR_API
+extern const unsigned char * const raptor_rdf_schema_namespace_uri;
+
+/**
+ * raptor_xmlschema_datatypes_namespace_uri:
+ *
+ * XML Schema datatypes (xsd:) namespace URI string.
+ */
+RAPTOR_API
+extern const unsigned char * const raptor_xmlschema_datatypes_namespace_uri;
+
+/**
+ * raptor_owl_namespace_uri:
+ *
+ * OWL (owl:) Namespace URI string.
+ */
+RAPTOR_API
+extern const unsigned char * const raptor_owl_namespace_uri;
+
+/**
+ * raptor_xml_literal_datatype_uri_string:
+ *
+ * XML Literal datatype (rdf:XMLLiteral) URI string.
+ */
+RAPTOR_API
+extern const unsigned char * const raptor_xml_literal_datatype_uri_string;
+
+/**
+ * raptor_xml_literal_datatype_uri_string_len:
+ *
+ * Length of #raptor_xml_literal_datatype_uri_string
+ */
+RAPTOR_API
+extern const unsigned int raptor_xml_literal_datatype_uri_string_len;
+
+
+/* Public structure */
+/**
+ * raptor_world:
+ *
+ * Raptor world class.
+ */
+typedef struct raptor_world_s raptor_world;
+/**
+ * raptor_parser:
+ *
+ * Raptor Parser class
+ */
+typedef struct raptor_parser_s raptor_parser;
+/**
+ * raptor_serializer:
+ *
+ * Raptor Serializer class
+ */
+typedef struct raptor_serializer_s raptor_serializer;
+
+/**
+ * raptor_www:
+ *
+ * Raptor WWW class
+ */
+typedef struct raptor_www_s raptor_www;
+/**
+ * raptor_iostream:
+ *
+ * Raptor I/O Stream class
+ */
+typedef struct raptor_iostream_s raptor_iostream;
+/**
+ * raptor_xml_element:
+ *
+ * Raptor XML Element class
+ */
+typedef struct raptor_xml_element_s raptor_xml_element;
+/**
+ * raptor_xml_writer:
+ *
+ * Raptor XML Writer class
+ */
+typedef struct raptor_xml_writer_s raptor_xml_writer;
+/**
+ * raptor_qname:
+ *
+ * Raptor XML qname class
+ */
+typedef struct raptor_qname_s raptor_qname;
+/**
+ * raptor_namespace:
+ *
+ * Raptor XML Namespace class
+ */
+typedef struct raptor_namespace_s raptor_namespace;
+/**
+ * raptor_namespace_stack:
+ *
+ * Raptor XML Namespace Stack class
+ */
+typedef struct raptor_namespace_stack_s raptor_namespace_stack;
+
+/**
+ * raptor_sax2:
+ *
+ * Raptor SAX2 class
+ */
+typedef struct raptor_sax2_s raptor_sax2;
+
+
+/**
+ * raptor_type_q:
+ * @mime_type: MIME type string
+ * @mime_type_len: length of @mime_type
+ * @q: Q value 0-10 standing for decimal 0.0-1.0
+ *
+ * (MIME Type, Q) pair
+ */
+typedef struct {
+ const char* mime_type;
+ size_t mime_type_len;
+ unsigned char q;
+} raptor_type_q;
+
+
+/**
+ * raptor_syntax_bitflags:
+ * @RAPTOR_SYNTAX_NEED_BASE_URI: the syntax requires a base URI
+ *
+ * Bit flags for #raptor_syntax_description flags field
+ */
+typedef enum {
+ RAPTOR_SYNTAX_NEED_BASE_URI = 1
+} raptor_syntax_bitflags;
+
+
+/**
+ * raptor_syntax_description:
+ * @names: array of syntax names - the first one (required) is the public name, the rest are aliases. The array is NULL terminated.
+ * @names_count: size of @names array
+ * @label: long descriptive label for syntax
+ * @mime_types: Array of (MIME type, Q) values associated with the syntax (or NULL). If present the array is NULL terminated.
+ * @mime_types_count: size of @mime_types array
+ * @uri_strings: array of URIs identifying the syntax (or NULL). The first one if present is the main URI, the rest are aliases. The array is NULL terminated.
+ * @uri_strings_count: size of @uri_strings array
+ * @flags: See #raptor_syntax_bitflags for the bits
+ *
+ * Description of a syntax or file format.
+ *
+ */
+typedef struct {
+ const char* const* names;
+ unsigned int names_count;
+
+ const char* label;
+
+ const raptor_type_q* mime_types;
+ unsigned int mime_types_count;
+
+ const char* const* uri_strings;
+ unsigned int uri_strings_count;
+
+ unsigned int flags;
+} raptor_syntax_description;
+
+
+/**
+ * raptor_term_type:
+ * @RAPTOR_TERM_TYPE_URI: RDF URI
+ * @RAPTOR_TERM_TYPE_LITERAL: RDF literal
+ * @RAPTOR_TERM_TYPE_BLANK: RDF blank node
+ * @RAPTOR_TERM_TYPE_UNKNOWN: Internal
+ *
+ * Type of term in a #raptor_statement
+ *
+ * Node type 3 is unused but exists to preserve numeric compatibility
+ * with librdf_node_type values.
+ */
+typedef enum {
+ RAPTOR_TERM_TYPE_UNKNOWN = 0,
+ RAPTOR_TERM_TYPE_URI = 1,
+ RAPTOR_TERM_TYPE_LITERAL = 2,
+ /* unused type 3 */
+ RAPTOR_TERM_TYPE_BLANK = 4
+} raptor_term_type;
+
+
+/**
+ * raptor_locator:
+ * @uri: URI of location (or NULL)
+ * @file: Filename of location (or NULL)
+ * @line: Line number of location (or <0 for no line)
+ * @column: Column number of location (or <0 for no column)
+ * @byte: Byte number of location (or <0 for no byte)
+ *
+ * Location information for an error, warning or information message.
+ */
+typedef struct {
+ raptor_uri *uri;
+ const char *file;
+ int line;
+ int column;
+ int byte;
+} raptor_locator;
+
+/**
+ * raptor_option:
+ * @RAPTOR_OPTION_SCANNING: If true (default false), the RDF/XML
+ * parser will look for embedded rdf:RDF elements inside the XML
+ * content, and not require that the XML start with an rdf:RDF root
+ * element.
+ * @RAPTOR_OPTION_ALLOW_NON_NS_ATTRIBUTES: If true (default true)
+ * then the RDF/XML parser will allow non-XML namespaced attributes
+ * to be accepted as well as rdf: namespaced ones. For example,
+ * 'about' and 'ID' will be interpreted as if they were rdf:about
+ * and rdf:ID respectively.
+ * @RAPTOR_OPTION_ALLOW_OTHER_PARSETYPES: If true (default true)
+ * then the RDF/XML parser will allow unknown parsetypes to be
+ * present and will pass them on to the user. Unimplemented at
+ * present.
+ * @RAPTOR_OPTION_ALLOW_BAGID: If true (default true) then the
+ * RDF/XML parser will support the rdf:bagID attribute that was
+ * removed from the RDF/XML language when it was revised. This
+ * support may be removed in future.
+ * @RAPTOR_OPTION_ALLOW_RDF_TYPE_RDF_LIST: If true (default false)
+ * then the RDF/XML parser will generate the idList rdf:type
+ * rdf:List triple in the handling of rdf:parseType="Collection".
+ * This triple was removed during the revising of RDF/XML after
+ * collections were initially added.
+ * @RAPTOR_OPTION_NORMALIZE_LANGUAGE: If true (default true) then
+ * XML language values such as from xml:lang will be normalized to
+ * lowercase.
+ * @RAPTOR_OPTION_NON_NFC_FATAL: If true (default false) then
+ * illegal Unicode Normal Form C in literals will give a fatal
+ * error, otherwise just a warning.
+ * @RAPTOR_OPTION_WARN_OTHER_PARSETYPES: If true (default true) then
+ * the RDF/XML parser will warn about unknown rdf:parseType values.
+ * @RAPTOR_OPTION_CHECK_RDF_ID: If true (default true) then the
+ * RDF/XML will check rdf:ID attribute values for duplicates and
+ * cause an error if any are found.
+ * @RAPTOR_OPTION_RELATIVE_URIS: If true (default true) then
+ * relative URIs will be used wherever possible when serializing.
+ * @RAPTOR_OPTION_WRITER_AUTO_INDENT: Automatically indent elements when
+ * seriailizing.
+ * @RAPTOR_OPTION_WRITER_AUTO_EMPTY: Automatically detect and
+ * abbreviate empty elements when serializing.
+ * @RAPTOR_OPTION_WRITER_INDENT_WIDTH: Integer number of spaces to use
+ * for each indent level when serializing with auto indent.
+ * @RAPTOR_OPTION_WRITER_XML_VERSION: Integer XML version XML 1.0 (10) or XML 1.1 (11)
+ * @RAPTOR_OPTION_WRITER_XML_DECLARATION: Write XML 1.0 or 1.1 declaration.
+ * @RAPTOR_OPTION_NO_NET: Deny network requests inside other requests.
+ * @RAPTOR_OPTION_RESOURCE_BORDER: Border color of resource
+ * nodes for GraphViz DOT serializer.
+ * @RAPTOR_OPTION_LITERAL_BORDER: Border color of literal nodes
+ * for GraphViz DOT serializer.
+ * @RAPTOR_OPTION_BNODE_BORDER: Border color of blank nodes for
+ * GraphViz DOT serializer.
+ * @RAPTOR_OPTION_RESOURCE_FILL: Fill color of resource nodes
+ * for GraphViz DOT serializer.
+ * @RAPTOR_OPTION_LITERAL_FILL: Fill color of literal nodes for
+ * GraphViz DOT serializer.
+ * @RAPTOR_OPTION_BNODE_FILL: Fill color of blank nodes for
+ * GraphViz DOT serializer.
+ * @RAPTOR_OPTION_HTML_TAG_SOUP: Use a lax HTML parser if an XML parser
+ * fails when read HTML for GRDDL parser.
+ * @RAPTOR_OPTION_MICROFORMATS: Look for microformats for GRDDL parser.
+ * @RAPTOR_OPTION_HTML_LINK: Look for head &lt;link&gt; to type rdf/xml
+ * for GRDDL parser.
+ * @RAPTOR_OPTION_WWW_TIMEOUT: Set timeout for internal WWW URI requests
+ * for GRDDL parser.
+ * @RAPTOR_OPTION_WRITE_BASE_URI: Write @base directive for Turtle/N3.
+ * @RAPTOR_OPTION_WWW_HTTP_CACHE_CONTROL: HTTP Cache-Control: header
+ * @RAPTOR_OPTION_WWW_HTTP_USER_AGENT: HTTP User-Agent: header
+ * @RAPTOR_OPTION_JSON_CALLBACK: JSON serializer callback function.
+ * @RAPTOR_OPTION_JSON_EXTRA_DATA: JSON serializer extra top-level data
+ * @RAPTOR_OPTION_RSS_TRIPLES: Atom/RSS serializer writes extra RDF triples it finds (none, rdf-xml, atom-triples)
+ * @RAPTOR_OPTION_ATOM_ENTRY_URI: Atom entry URI. If given, generate an Atom Entry Document with the item having the given URI, otherwise generate an Atom Feed Document with any items found.
+ * @RAPTOR_OPTION_PREFIX_ELEMENTS: Integer. If set, generate Atom/RSS1.0 documents with prefixed elements, otherwise unprefixed.
+ * @RAPTOR_OPTION_STRICT: Boolean. If set, operate in strict conformance mode.
+ * @RAPTOR_OPTION_WWW_CERT_FILENAME: String. SSL client certificate filename
+ * @RAPTOR_OPTION_WWW_CERT_TYPE: String. SSL client certificate type
+ * @RAPTOR_OPTION_WWW_CERT_PASSPHRASE: String. SSL client certificate passphrase
+ * @RAPTOR_OPTION_WWW_SSL_VERIFY_PEER: Integer. SSL verify peer - non-0 to verify peer SSL certificate (default)
+ * @RAPTOR_OPTION_WWW_SSL_VERIFY_HOST: Integer. SSL verify host - 0 none, 1 CN match, 2 host match (default). Other values are ignored.
+ * @RAPTOR_OPTION_NO_FILE: Deny file reading requests inside other requests.
+ * @RAPTOR_OPTION_LOAD_EXTERNAL_ENTITIES: When reading XML, load external entities.
+ * @RAPTOR_OPTION_LAST: Internal
+ *
+ * Raptor parser, serializer or XML writer options.
+ */
+typedef enum {
+ RAPTOR_OPTION_SCANNING,
+ RAPTOR_OPTION_ALLOW_NON_NS_ATTRIBUTES,
+ RAPTOR_OPTION_ALLOW_OTHER_PARSETYPES,
+ RAPTOR_OPTION_ALLOW_BAGID,
+ RAPTOR_OPTION_ALLOW_RDF_TYPE_RDF_LIST,
+ RAPTOR_OPTION_NORMALIZE_LANGUAGE,
+ RAPTOR_OPTION_NON_NFC_FATAL,
+ RAPTOR_OPTION_WARN_OTHER_PARSETYPES,
+ RAPTOR_OPTION_CHECK_RDF_ID,
+ RAPTOR_OPTION_RELATIVE_URIS,
+ RAPTOR_OPTION_WRITER_AUTO_INDENT,
+ RAPTOR_OPTION_WRITER_AUTO_EMPTY,
+ RAPTOR_OPTION_WRITER_INDENT_WIDTH,
+ RAPTOR_OPTION_WRITER_XML_VERSION,
+ RAPTOR_OPTION_WRITER_XML_DECLARATION,
+ RAPTOR_OPTION_NO_NET,
+ RAPTOR_OPTION_RESOURCE_BORDER,
+ RAPTOR_OPTION_LITERAL_BORDER,
+ RAPTOR_OPTION_BNODE_BORDER,
+ RAPTOR_OPTION_RESOURCE_FILL,
+ RAPTOR_OPTION_LITERAL_FILL,
+ RAPTOR_OPTION_BNODE_FILL,
+ RAPTOR_OPTION_HTML_TAG_SOUP,
+ RAPTOR_OPTION_MICROFORMATS,
+ RAPTOR_OPTION_HTML_LINK,
+ RAPTOR_OPTION_WWW_TIMEOUT,
+ RAPTOR_OPTION_WRITE_BASE_URI,
+ RAPTOR_OPTION_WWW_HTTP_CACHE_CONTROL,
+ RAPTOR_OPTION_WWW_HTTP_USER_AGENT,
+ RAPTOR_OPTION_JSON_CALLBACK,
+ RAPTOR_OPTION_JSON_EXTRA_DATA,
+ RAPTOR_OPTION_RSS_TRIPLES,
+ RAPTOR_OPTION_ATOM_ENTRY_URI,
+ RAPTOR_OPTION_PREFIX_ELEMENTS,
+ RAPTOR_OPTION_STRICT,
+ RAPTOR_OPTION_WWW_CERT_FILENAME,
+ RAPTOR_OPTION_WWW_CERT_TYPE,
+ RAPTOR_OPTION_WWW_CERT_PASSPHRASE,
+ RAPTOR_OPTION_NO_FILE,
+ RAPTOR_OPTION_WWW_SSL_VERIFY_PEER,
+ RAPTOR_OPTION_WWW_SSL_VERIFY_HOST,
+ RAPTOR_OPTION_LOAD_EXTERNAL_ENTITIES,
+ RAPTOR_OPTION_LAST = RAPTOR_OPTION_LOAD_EXTERNAL_ENTITIES
+} raptor_option;
+
+
+/**
+ * raptor_term_literal_value:
+ * @string: literal string
+ * @string_len: length of string
+ * @datatype: datatype URI (or NULL)
+ * @language: literal language (or NULL)
+ * @language_len: length of language
+ *
+ * Literal term value - this typedef exists solely for use in #raptor_term
+ *
+ * Either @datatype or @language may be non-NULL but not both.
+ */
+typedef struct {
+ unsigned char *string;
+ unsigned int string_len;
+
+ raptor_uri *datatype;
+
+ unsigned char *language;
+ unsigned char language_len;
+} raptor_term_literal_value;
+
+
+/**
+ * raptor_term_blank_value:
+ * @string: literal string
+ * @string_len: length of string
+ *
+ * Blank term value - this typedef exists solely for use in #raptor_term
+ *
+ */
+typedef struct {
+ unsigned char *string;
+ unsigned int string_len;
+} raptor_term_blank_value;
+
+
+/**
+ * raptor_term_value:
+ * @uri: uri value when term type is #RAPTOR_TERM_TYPE_URI
+ * @literal: literal value when term type is #RAPTOR_TERM_TYPE_LITERAL
+ * @blank: blank value when term type is #RAPTOR_TERM_TYPE_BLANK
+ *
+ * Term value - this typedef exists solely for use in #raptor_term
+ *
+ **/
+typedef union {
+ raptor_uri *uri;
+
+ raptor_term_literal_value literal;
+
+ raptor_term_blank_value blank;
+} raptor_term_value;
+
+
+/**
+ * raptor_term:
+ * @world: world
+ * @usage: usage reference count (if >0)
+ * @type: term type
+ * @value: term values per type
+ *
+ * An RDF statement term
+ *
+ */
+typedef struct {
+ raptor_world* world;
+
+ int usage;
+
+ raptor_term_type type;
+
+ raptor_term_value value;
+
+} raptor_term;
+
+
+/**
+ * raptor_statement:
+ * @world: world pointer
+ * @usage: usage count
+ * @subject: statement subject
+ * @predicate: statement predicate
+ * @object: statement object
+ * @graph: statement graph name (or NULL if not present)
+ *
+ * An RDF triple with optional graph name (quad)
+ *
+ * See #raptor_term for a description of how the fields may be used.
+ * As returned by a parser statement_handler.
+ */
+typedef struct {
+ raptor_world* world;
+ int usage;
+ raptor_term* subject;
+ raptor_term* predicate;
+ raptor_term* object;
+ raptor_term* graph;
+} raptor_statement;
+
+
+/**
+ * raptor_log_level:
+ * @RAPTOR_LOG_LEVEL_NONE: Internal
+ * @RAPTOR_LOG_LEVEL_TRACE: very fine-grained tracing messages information
+ * @RAPTOR_LOG_LEVEL_DEBUG: fine-grained tracing messages suitable for debugging
+ * @RAPTOR_LOG_LEVEL_INFO: coarse-grained information messages
+ * @RAPTOR_LOG_LEVEL_WARN: warning messages of potentially harmful problems
+ * @RAPTOR_LOG_LEVEL_ERROR: error messages where the application can continue
+ * @RAPTOR_LOG_LEVEL_FATAL: fatal error message where the application will likely abort
+ * @RAPTOR_LOG_LEVEL_LAST: Internal
+ *
+ * Log levels
+ */
+typedef enum {
+ RAPTOR_LOG_LEVEL_NONE,
+ RAPTOR_LOG_LEVEL_TRACE,
+ RAPTOR_LOG_LEVEL_DEBUG,
+ RAPTOR_LOG_LEVEL_INFO,
+ RAPTOR_LOG_LEVEL_WARN,
+ RAPTOR_LOG_LEVEL_ERROR,
+ RAPTOR_LOG_LEVEL_FATAL,
+ RAPTOR_LOG_LEVEL_LAST = RAPTOR_LOG_LEVEL_FATAL
+} raptor_log_level;
+
+
+/**
+ * raptor_domain:
+ * @RAPTOR_DOMAIN_IOSTREAM: I/O stream
+ * @RAPTOR_DOMAIN_NAMESPACE: XML Namespace / namespace stack
+ * @RAPTOR_DOMAIN_PARSER: RDF Parser
+ * @RAPTOR_DOMAIN_QNAME: XML QName
+ * @RAPTOR_DOMAIN_SAX2: XML SAX2
+ * @RAPTOR_DOMAIN_SERIALIZER: RDF Serializer
+ * @RAPTOR_DOMAIN_TERM: RDF Term
+ * @RAPTOR_DOMAIN_TURTLE_WRITER: Turtle Writer
+ * @RAPTOR_DOMAIN_URI: RDF Uri
+ * @RAPTOR_DOMAIN_WORLD: RDF world
+ * @RAPTOR_DOMAIN_WWW: WWW
+ * @RAPTOR_DOMAIN_XML_WRITER: XML Writer
+ * @RAPTOR_DOMAIN_NONE: Internal
+ * @RAPTOR_DOMAIN_LAST: Internal
+ *
+ * Log domain
+ */
+typedef enum {
+ RAPTOR_DOMAIN_NONE,
+ RAPTOR_DOMAIN_IOSTREAM,
+ RAPTOR_DOMAIN_NAMESPACE,
+ RAPTOR_DOMAIN_PARSER,
+ RAPTOR_DOMAIN_QNAME,
+ RAPTOR_DOMAIN_SAX2,
+ RAPTOR_DOMAIN_SERIALIZER,
+ RAPTOR_DOMAIN_TERM,
+ RAPTOR_DOMAIN_TURTLE_WRITER,
+ RAPTOR_DOMAIN_URI,
+ RAPTOR_DOMAIN_WORLD,
+ RAPTOR_DOMAIN_WWW,
+ RAPTOR_DOMAIN_XML_WRITER,
+ RAPTOR_DOMAIN_LAST = RAPTOR_DOMAIN_XML_WRITER
+} raptor_domain;
+
+
+/**
+ * raptor_log_message:
+ * @code: error code or < 0 if not used or known
+ * @domain: message domain or #RAPTOR_DOMAIN_NONE if not used or known
+ * @level: log message level
+ * @locator: location associated with message or NULL if not known
+ * @text: message string
+ *
+ * Log message.
+ */
+typedef struct {
+ int code;
+ raptor_domain domain;
+ raptor_log_level level;
+ raptor_locator *locator;
+ const char *text;
+} raptor_log_message;
+
+
+/**
+ * raptor_log_handler:
+ * @user_data: user data
+ * @message: log message
+ *
+ * Handler function for log messages with location
+ *
+ * Used during parsing and serializing for errors and warnings that
+ * may include location information. Handlers may be set
+ * by raptor_world_set_log_handler().
+ *
+ */
+typedef void (*raptor_log_handler)(void *user_data, raptor_log_message *message);
+
+
+/**
+ * raptor_statement_handler:
+ * @user_data: user data
+ * @statement: statement to report
+ *
+ * Statement (triple) reporting handler function.
+ *
+ * This handler function set with
+ * raptor_parser_set_statement_handler() on a parser receives
+ * statements as the parsing proceeds. The @statement argument to the
+ * handler is shared and must be copied by the caller with
+ * raptor_statement_copy().
+ */
+typedef void (*raptor_statement_handler)(void *user_data, raptor_statement *statement);
+
+/**
+ * raptor_graph_mark_flags:
+ * @RAPTOR_GRAPH_MARK_START: mark is start of graph (otherwise is end)
+ * @RAPTOR_GRAPH_MARK_DECLARED: mark was declared in syntax rather than implict
+ *
+ * Graph mark handler bitmask flags
+ */
+typedef enum {
+ RAPTOR_GRAPH_MARK_START = 1,
+ RAPTOR_GRAPH_MARK_DECLARED = 2
+} raptor_graph_mark_flags;
+
+
+/**
+ * raptor_graph_mark_handler:
+ * @user_data: user data
+ * @graph: graph to report, NULL for the default graph
+ * @flags: bitmask of #raptor_graph_mark_flags flags
+ *
+ * Graph start/end mark handler function.
+ *
+ * Records start and end of graphs happening in a stream of generated
+ * #raptor_statement via the statement handler. The callback starts a
+ * graph when @flags has #RAPTOR_GRAPH_MARK_START bit set.
+ *
+ * The start and ends may be either declared in the syntax via some
+ * keyword or mechanism such as TRiG {} syntax when @flags has bit
+ * #RAPTOR_GRAPH_MARK_DECLARED set, or be implied by the start/end of
+ * the data in other syntaxes, and the bit will be unset.
+ */
+typedef void (*raptor_graph_mark_handler)(void *user_data, raptor_uri *graph, int flags);
+
+/**
+ * raptor_generate_bnodeid_handler:
+ * @user_data: user data
+ * @user_bnodeid: a user-specified ID or NULL if none available.
+ *
+ * Generate a blank node identifier handler function.
+ *
+ * Return value: new blank node ID to use
+ */
+typedef unsigned char* (*raptor_generate_bnodeid_handler)(void *user_data, unsigned char* user_bnodeid);
+
+/**
+ * raptor_namespace_handler:
+ * @user_data: user data
+ * @nspace: #raptor_namespace declared
+ *
+ * XML Namespace declaration reporting handler set by
+ * raptor_parser_set_namespace_handler().
+ */
+typedef void (*raptor_namespace_handler)(void* user_data, raptor_namespace *nspace);
+
+
+/**
+ * raptor_www_write_bytes_handler:
+ * @www: WWW object
+ * @userdata: user data
+ * @ptr: data pointer
+ * @size: size of individual item
+ * @nmemb: number of items
+ *
+ * Receiving bytes of data from WWW retrieval handler.
+ *
+ * Set by raptor_www_set_write_bytes_handler().
+ */
+typedef void (*raptor_www_write_bytes_handler)(raptor_www* www, void *userdata, const void *ptr, size_t size, size_t nmemb);
+
+/**
+ * raptor_www_content_type_handler:
+ * @www: WWW object
+ * @userdata: user data
+ * @content_type: content type seen
+ *
+ * Receiving Content-Type: header from WWW retrieval handler.
+ *
+ * Set by raptor_www_set_content_type_handler().
+ */
+typedef void (*raptor_www_content_type_handler)(raptor_www* www, void *userdata, const char *content_type);
+
+/**
+ * raptor_www_final_uri_handler:
+ * @www: WWW object
+ * @userdata: user data
+ * @final_uri: final URI seen
+ *
+ * Receiving the final resolved URI from a WWW retrieval
+ *
+ * Set by raptor_www_set_final_uri_handler().
+ */
+typedef void (*raptor_www_final_uri_handler)(raptor_www* www, void *userdata, raptor_uri *final_uri);
+
+/**
+ * raptor_uri_filter_func:
+ * @user_data: user data
+ * @uri: #raptor_uri URI to check
+ *
+ * Callback function for #raptor_www_set_uri_filter
+ *
+ * Return value: non-0 to filter the URI
+ */
+typedef int (*raptor_uri_filter_func)(void *user_data, raptor_uri* uri);
+
+
+/**
+ * raptor_world_flag:
+ * @RAPTOR_WORLD_FLAG_LIBXML_GENERIC_ERROR_SAVE: if set (non-0 value) - save/restore the libxml generic error handler when raptor library initializes (default set)
+ * @RAPTOR_WORLD_FLAG_LIBXML_STRUCTURED_ERROR_SAVE: if set (non-0 value) - save/restore the libxml structured error handler when raptor library terminates (default set)
+ * @RAPTOR_WORLD_FLAG_URI_INTERNING: if set (non-0 value) - each URI is saved interned in-memory and reused (default set)
+ * @RAPTOR_WORLD_FLAG_WWW_SKIP_INIT_FINISH: if set (non-0 value) the raptor will neither initialise or terminate the lower level WWW library. Usually in raptor initialising either curl_global_init (for libcurl) are called and in raptor cleanup, curl_global_cleanup is called. This flag allows the application finer control over these libraries such as setting other global options or potentially calling and terminating raptor several times. It does mean that applications which use this call must do their own extra work in order to allocate and free all resources to the system.
+ *
+ * Raptor world flags
+ *
+ * These are used by raptor_world_set_flags() to control raptor-wide
+ * options across classes. These must be set before
+ * raptor_world_open() is called explicitly or implicitly (by
+ * creating a raptor object). There is no enumeration function for
+ * these flags because they are not user options and must be set
+ * before the library is initialised. For similar reasons, there is
+ * no get function.
+ *
+ * If any libxml handler saving/restoring is enabled, any existing
+ * handler and context is saved before parsing and restored
+ * afterwards. Otherwise, no saving/restoring is performed.
+ *
+ */
+typedef enum {
+ RAPTOR_WORLD_FLAG_LIBXML_GENERIC_ERROR_SAVE = 1,
+ RAPTOR_WORLD_FLAG_LIBXML_STRUCTURED_ERROR_SAVE = 2,
+ RAPTOR_WORLD_FLAG_URI_INTERNING = 3,
+ RAPTOR_WORLD_FLAG_WWW_SKIP_INIT_FINISH = 4
+} raptor_world_flag;
+
+
+/**
+ * raptor_data_compare_arg_handler:
+ * @data1: first object
+ * @data2: second object
+ * @user_data: user data argument
+ *
+ * Function to compare two data objects with a user data argument
+ *
+ * Designed to be used with raptor_sort_r() and compatible functions
+ * such as raptor_sequence_sort_r() which uses it.
+ *
+ * Return value: compare value <0 if @data1 is before @data2, =0 if equal, >0 if @data1 is after @data2
+ */
+typedef int (*raptor_data_compare_arg_handler)(const void *data1, const void *data2, void *user_data);
+
+
+/**
+ * raptor_data_compare_handler:
+ * @data1: first data object
+ * @data2: second data object
+ *
+ * Function to compare two data objects - signature like strcmp() and function pssed to qsort()
+ *
+ * Designed to be passed into generic data structure constructors
+ * like raptor_new_avltree().
+ *
+ * Return value: compare value <0 if @data1 is before @data2, =0 if equal, >0 if @data1 is after @data2
+ */
+typedef int (*raptor_data_compare_handler)(const void* data1, const void* data2);
+
+
+/**
+ * raptor_data_malloc_handler:
+ * @size: data size
+ *
+ * Typedef for a function to allocate memory - signature like malloc()
+ *
+ * Designed to be passed into constructors
+ * like raptor_www_fetch_to_string
+ *
+ * Return value: pointer to newly allocated memory or NULL on failure
+ */
+typedef void* (*raptor_data_malloc_handler)(size_t size);
+
+
+/**
+ * raptor_data_free_handler:
+ * @data: data object or NULL
+ *
+ * Typedef for function to free a data object - signature like free()
+ *
+ * Designed to be passed into generic data structure constructors
+ * like raptor_new_avltree(). If @data is NULL, nothing should be done.
+ */
+typedef void (*raptor_data_free_handler)(void* data);
+
+
+/**
+ * raptor_data_context_free_handler:
+ * @context: context data for the free function
+ * @object: object to free
+ *
+ * Handler function for freeing a sequence item with a contextual pointer.
+ *
+ * Set by raptor_new_sequence_with_context().
+*/
+typedef void (*raptor_data_context_free_handler)(void* context, void* object);
+
+/**
+ * raptor_data_print_handler:
+ * @object: object to print
+ * @fh: FILE* to print to
+ *
+ * Handler function for printing an object to a stream.
+ *
+ * Set by raptor_new_sequence()
+ *
+ * Return value: non-0 on failure
+ */
+typedef int (*raptor_data_print_handler)(void *object, FILE *fh);
+
+/**
+ * raptor_data_context_print_handler:
+ * @context: context data for the print function
+ * @object: object to print
+ * @fh: FILE* to print to
+ *
+ * Function function for printing an object with data context to a stream.
+ *
+ * Set by raptor_new_sequence_with_context()
+ *
+ * Return value: non-0 on failure
+ */
+typedef int (*raptor_data_context_print_handler)(void *context, void *object, FILE *fh);
+
+/**
+ * raptor_stringbuffer:
+ *
+ * Raptor string buffer class
+ */
+typedef struct raptor_stringbuffer_s raptor_stringbuffer;
+
+
+/* Public functions */
+
+#define raptor_new_world() raptor_new_world_internal(RAPTOR_VERSION)
+/* The real target of the raptor_new_world() macro */
+RAPTOR_API
+raptor_world *raptor_new_world_internal(unsigned int version_decimal);
+RAPTOR_API
+int raptor_world_open(raptor_world* world);
+RAPTOR_API
+void raptor_free_world(raptor_world* world);
+RAPTOR_API
+int raptor_world_set_libxslt_security_preferences(raptor_world *world, void *security_preferences);
+RAPTOR_API
+int raptor_world_set_flag(raptor_world *world, raptor_world_flag flag, int value);
+RAPTOR_API
+int raptor_world_set_log_handler(raptor_world *world, void *user_data, raptor_log_handler handler);
+RAPTOR_API
+void raptor_world_set_generate_bnodeid_handler(raptor_world* world, void *user_data, raptor_generate_bnodeid_handler handler);
+RAPTOR_API
+unsigned char* raptor_world_generate_bnodeid(raptor_world *world);
+RAPTOR_API
+void raptor_world_set_generate_bnodeid_parameters(raptor_world* world, char *prefix, int base);
+RAPTOR_API
+const char* raptor_log_level_get_label(raptor_log_level level);
+RAPTOR_API
+const char* raptor_domain_get_label(raptor_domain domain);
+
+/* Names */
+RAPTOR_API
+int raptor_world_is_parser_name(raptor_world* world, const char *name);
+RAPTOR_API
+const char* raptor_world_guess_parser_name(raptor_world* world, raptor_uri *uri, const char *mime_type, const unsigned char *buffer, size_t len, const unsigned char *identifier);
+RAPTOR_API
+int raptor_world_is_serializer_name(raptor_world* world, const char *name);
+
+/* Syntax descriptions */
+RAPTOR_API
+int raptor_world_get_parsers_count(raptor_world* world);
+RAPTOR_API
+int raptor_world_get_serializers_count(raptor_world* world);
+RAPTOR_API
+const raptor_syntax_description* raptor_world_get_parser_description(raptor_world* world, unsigned int counter);
+RAPTOR_API
+const raptor_syntax_description* raptor_world_get_serializer_description(raptor_world* world, unsigned int counter);
+RAPTOR_API
+int raptor_syntax_description_validate(raptor_syntax_description* desc);
+
+RAPTOR_API
+raptor_option raptor_world_get_option_from_uri(raptor_world* world, raptor_uri *uri);
+
+
+/* Term Class */
+RAPTOR_API
+raptor_term* raptor_new_term_from_uri(raptor_world* world, raptor_uri* uri);
+RAPTOR_API
+raptor_term* raptor_new_term_from_counted_uri_string(raptor_world* world, const unsigned char *uri_string, size_t length);
+RAPTOR_API
+raptor_term* raptor_new_term_from_uri_string(raptor_world* world, const unsigned char *uri_string);
+RAPTOR_API
+raptor_term* raptor_new_term_from_literal(raptor_world* world, const unsigned char* literal, raptor_uri* datatype, const unsigned char* language);
+RAPTOR_API
+raptor_term* raptor_new_term_from_counted_literal(raptor_world* world, const unsigned char* literal, size_t literal_len, raptor_uri* datatype, const unsigned char* language, unsigned char language_len);
+RAPTOR_API
+raptor_term* raptor_new_term_from_blank(raptor_world* world, const unsigned char* blank);
+RAPTOR_API
+raptor_term* raptor_new_term_from_counted_blank(raptor_world* world, const unsigned char* blank, size_t length);
+RAPTOR_API
+raptor_term* raptor_new_term_from_counted_string(raptor_world* world, unsigned char* string, size_t length);
+RAPTOR_API
+raptor_term* raptor_term_copy(raptor_term* term);
+RAPTOR_API
+int raptor_term_compare(const raptor_term *t1, const raptor_term *t2);
+RAPTOR_API
+int raptor_term_equals(raptor_term* t1, raptor_term* t2);
+RAPTOR_API
+void raptor_free_term(raptor_term *term);
+
+RAPTOR_API
+unsigned char* raptor_term_to_counted_string(raptor_term *term, size_t* len_p);
+RAPTOR_API
+unsigned char* raptor_term_to_string(raptor_term *term);
+RAPTOR_API
+int raptor_term_escaped_write(const raptor_term *term, unsigned int flags, raptor_iostream* iostr);
+RAPTOR_API RAPTOR_DEPRECATED
+int raptor_term_ntriples_write(const raptor_term *term, raptor_iostream* iostr);
+RAPTOR_API
+int raptor_uri_turtle_write(raptor_world *world, raptor_iostream* iostr, raptor_uri* uri, raptor_namespace_stack *nstack, raptor_uri *base_uri);
+RAPTOR_API
+int raptor_term_turtle_write(raptor_iostream* iostr, raptor_term* term, raptor_namespace_stack *nstack, raptor_uri *base_uri);
+RAPTOR_API
+unsigned char* raptor_uri_to_turtle_counted_string(raptor_world *world, raptor_uri* uri, raptor_namespace_stack *nstack, raptor_uri *base_uri, size_t *len_p);
+RAPTOR_API
+unsigned char* raptor_uri_to_turtle_string(raptor_world *world, raptor_uri* uri, raptor_namespace_stack *nstack, raptor_uri *base_uri);
+RAPTOR_API
+unsigned char* raptor_term_to_turtle_counted_string(raptor_term* term, raptor_namespace_stack *nstack, raptor_uri *base_uri, size_t *len_p);
+RAPTOR_API
+unsigned char* raptor_term_to_turtle_string(raptor_term* term, raptor_namespace_stack *nstack, raptor_uri *base_uri);
+
+
+/* Statement Class */
+RAPTOR_API
+void raptor_statement_init(raptor_statement *statement, raptor_world *world);
+RAPTOR_API
+void raptor_statement_clear(raptor_statement *statement);
+RAPTOR_API
+raptor_statement* raptor_new_statement(raptor_world *world);
+RAPTOR_API
+raptor_statement* raptor_new_statement_from_nodes(raptor_world* world, raptor_term *subject, raptor_term *predicate, raptor_term *object, raptor_term *graph);
+RAPTOR_API
+raptor_statement* raptor_statement_copy(raptor_statement *statement);
+RAPTOR_API
+void raptor_free_statement(raptor_statement *statement);
+
+RAPTOR_API
+int raptor_statement_print(const raptor_statement * statement, FILE *stream);
+RAPTOR_API
+int raptor_statement_print_as_ntriples(const raptor_statement * statement, FILE *stream);
+RAPTOR_API
+int raptor_statement_compare(const raptor_statement *s1, const raptor_statement *s2);
+RAPTOR_API
+int raptor_statement_equals(const raptor_statement* s1, const raptor_statement* s2);
+
+
+/* Parser Class */
+RAPTOR_API
+raptor_parser* raptor_new_parser(raptor_world* world, const char *name);
+RAPTOR_API
+raptor_parser* raptor_new_parser_for_content(raptor_world* world, raptor_uri *uri, const char *mime_type, const unsigned char *buffer, size_t len, const unsigned char *identifier);
+RAPTOR_API
+void raptor_free_parser(raptor_parser* parser);
+
+/* methods */
+
+/* Handlers */
+RAPTOR_API
+void raptor_parser_set_statement_handler(raptor_parser* parser, void *user_data, raptor_statement_handler handler);
+RAPTOR_API
+void raptor_parser_set_graph_mark_handler(raptor_parser* parser, void *user_data, raptor_graph_mark_handler handler);
+RAPTOR_API
+void raptor_parser_set_namespace_handler(raptor_parser* parser, void *user_data, raptor_namespace_handler handler);
+RAPTOR_API
+void raptor_parser_set_uri_filter(raptor_parser* parser, raptor_uri_filter_func filter, void* user_data);
+RAPTOR_API
+raptor_locator* raptor_parser_get_locator(raptor_parser* rdf_parser);
+
+
+/* Parsing functions */
+RAPTOR_API
+int raptor_parser_parse_start(raptor_parser *rdf_parser, raptor_uri *uri);
+RAPTOR_API
+int raptor_parser_parse_chunk(raptor_parser* rdf_parser, const unsigned char *buffer, size_t len, int is_end);
+RAPTOR_API
+int raptor_parser_parse_file_stream(raptor_parser* rdf_parser, FILE *stream, const char *filename, raptor_uri *base_uri);
+RAPTOR_API
+int raptor_parser_parse_file(raptor_parser* rdf_parser, raptor_uri *uri, raptor_uri *base_uri);
+RAPTOR_API
+int raptor_parser_parse_uri(raptor_parser* rdf_parser, raptor_uri *uri, raptor_uri *base_uri);
+RAPTOR_API
+int raptor_parser_parse_uri_with_connection(raptor_parser* rdf_parser, raptor_uri *uri, raptor_uri *base_uri, void *connection);
+RAPTOR_API
+int raptor_parser_parse_iostream(raptor_parser* rdf_parser, raptor_iostream *iostr, raptor_uri *base_uri);
+RAPTOR_API
+void raptor_parser_parse_abort(raptor_parser* rdf_parser);
+RAPTOR_API
+const char* raptor_parser_get_name(raptor_parser *rdf_parser);
+RAPTOR_API
+const raptor_syntax_description* raptor_parser_get_description(raptor_parser *rdf_parser);
+
+/* parser option methods */
+RAPTOR_API
+int raptor_parser_set_option(raptor_parser *parser, raptor_option option, const char* string, int integer);
+RAPTOR_API
+int raptor_parser_get_option(raptor_parser *parser, raptor_option option, char** string_p, int* integer_p);
+
+/* parser utility methods */
+RAPTOR_API
+const char* raptor_parser_get_accept_header(raptor_parser* rdf_parser);
+RAPTOR_API
+raptor_world* raptor_parser_get_world(raptor_parser* rdf_parser);
+RAPTOR_API
+raptor_uri* raptor_parser_get_graph(raptor_parser* rdf_parser);
+
+
+/* Locator Class */
+/* methods */
+RAPTOR_API
+int raptor_locator_print(raptor_locator* locator, FILE *stream);
+RAPTOR_API
+int raptor_locator_format(char *buffer, size_t length, raptor_locator* locator);
+RAPTOR_API
+int raptor_locator_line(raptor_locator *locator);
+RAPTOR_API
+int raptor_locator_column(raptor_locator *locator);
+RAPTOR_API
+int raptor_locator_byte(raptor_locator *locator);
+RAPTOR_API
+const char* raptor_locator_file(raptor_locator *locator);
+RAPTOR_API
+const char* raptor_locator_uri(raptor_locator *locator);
+
+
+/* Serializer Class */
+RAPTOR_API
+raptor_serializer* raptor_new_serializer(raptor_world* world, const char *name);
+RAPTOR_API
+void raptor_free_serializer(raptor_serializer* rdf_serializer);
+
+/* methods */
+RAPTOR_API
+int raptor_serializer_start_to_iostream(raptor_serializer *rdf_serializer, raptor_uri *uri, raptor_iostream *iostream);
+RAPTOR_API
+int raptor_serializer_start_to_filename(raptor_serializer *rdf_serializer, const char *filename);
+RAPTOR_API
+int raptor_serializer_start_to_string(raptor_serializer *rdf_serializer, raptor_uri *uri, void **string_p, size_t *length_p);
+RAPTOR_API
+int raptor_serializer_start_to_file_handle(raptor_serializer *rdf_serializer, raptor_uri *uri, FILE *fh);
+RAPTOR_API
+int raptor_serializer_set_namespace(raptor_serializer* rdf_serializer, raptor_uri *uri, const unsigned char *prefix);
+RAPTOR_API
+int raptor_serializer_set_namespace_from_namespace(raptor_serializer* rdf_serializer, raptor_namespace *nspace);
+RAPTOR_API
+int raptor_serializer_serialize_statement(raptor_serializer* rdf_serializer, raptor_statement *statement);
+RAPTOR_API
+int raptor_serializer_serialize_end(raptor_serializer *rdf_serializer);
+RAPTOR_API
+raptor_iostream* raptor_serializer_get_iostream(raptor_serializer *serializer);
+RAPTOR_API
+raptor_locator* raptor_serializer_get_locator(raptor_serializer *rdf_serializer);
+RAPTOR_API
+int raptor_serializer_flush(raptor_serializer *rdf_serializer);
+RAPTOR_API
+const raptor_syntax_description* raptor_serializer_get_description(raptor_serializer *rdf_serializer);
+
+/* serializer option methods */
+RAPTOR_API
+int raptor_serializer_set_option(raptor_serializer *serializer, raptor_option option, const char* string, int integer);
+RAPTOR_API
+int raptor_serializer_get_option(raptor_serializer *serializer, raptor_option option, char** string_p, int* integer_p);
+
+/* utility methods */
+RAPTOR_API
+raptor_world* raptor_serializer_get_world(raptor_serializer* rdf_serializer);
+
+
+/* memory functions */
+RAPTOR_API
+void raptor_free_memory(void *ptr);
+RAPTOR_API
+void* raptor_alloc_memory(size_t size);
+RAPTOR_API
+void* raptor_calloc_memory(size_t nmemb, size_t size);
+
+
+/* URI Class */
+RAPTOR_API
+raptor_uri* raptor_new_uri_from_counted_string(raptor_world* world, const unsigned char *uri_string, size_t length);
+RAPTOR_API
+raptor_uri* raptor_new_uri(raptor_world* world, const unsigned char *uri_string);
+RAPTOR_API
+raptor_uri* raptor_new_uri_from_uri_local_name(raptor_world* world, raptor_uri *uri, const unsigned char *local_name);
+RAPTOR_API
+raptor_uri* raptor_new_uri_relative_to_base(raptor_world* world, raptor_uri *base_uri, const unsigned char *uri_string);
+RAPTOR_API
+raptor_uri* raptor_new_uri_relative_to_base_counted(raptor_world* world, raptor_uri *base_uri, const unsigned char *uri_string, size_t uri_len);
+RAPTOR_API
+raptor_uri* raptor_new_uri_from_id(raptor_world* world, raptor_uri *base_uri, const unsigned char *id);
+RAPTOR_API
+raptor_uri* raptor_new_uri_from_uri_or_file_string(raptor_world* world, raptor_uri* base_uri, const unsigned char* uri_or_file_string);
+RAPTOR_API
+raptor_uri* raptor_new_uri_for_rdf_concept(raptor_world* world, const unsigned char *name);
+RAPTOR_API
+raptor_uri* raptor_new_uri_for_xmlbase(raptor_uri* old_uri);
+RAPTOR_API
+raptor_uri* raptor_new_uri_for_retrieval(raptor_uri* old_uri);
+RAPTOR_API
+void raptor_free_uri(raptor_uri *uri);
+
+/* methods */
+RAPTOR_API
+int raptor_uri_equals(raptor_uri* uri1, raptor_uri* uri2);
+RAPTOR_API
+int raptor_uri_compare(raptor_uri* uri1, raptor_uri* uri2);
+RAPTOR_API
+raptor_uri* raptor_uri_copy(raptor_uri *uri);
+RAPTOR_API
+unsigned char* raptor_uri_as_string(raptor_uri *uri);
+RAPTOR_API
+unsigned char* raptor_uri_as_counted_string(raptor_uri *uri, size_t* len_p);
+RAPTOR_API
+unsigned char* raptor_uri_to_relative_counted_uri_string(raptor_uri *base_uri, raptor_uri *reference_uri, size_t *length_p);
+RAPTOR_API
+unsigned char* raptor_uri_to_relative_uri_string(raptor_uri *base_uri, raptor_uri *reference_uri);
+RAPTOR_API
+int raptor_uri_print(const raptor_uri* uri, FILE *stream);
+RAPTOR_API
+unsigned char* raptor_uri_to_counted_string(raptor_uri *uri, size_t *len_p);
+RAPTOR_API
+unsigned char* raptor_uri_to_string(raptor_uri *uri);
+RAPTOR_API
+raptor_world* raptor_uri_get_world(raptor_uri *uri);
+RAPTOR_API
+int raptor_uri_file_exists(raptor_uri* uri);
+RAPTOR_API
+int raptor_uri_escaped_write(raptor_uri* uri, raptor_uri* base_uri, unsigned int flags, raptor_iostream *iostr);
+
+/* XML utility functions */
+RAPTOR_API
+int raptor_xml_escape_string_any(raptor_world* world, const unsigned char *string, size_t len, unsigned char *buffer, size_t length, char quote, int xml_version);
+RAPTOR_API
+int raptor_xml_escape_string_any_write(const unsigned char *string, size_t len, char quote, int xml_version, raptor_iostream* iostr);
+RAPTOR_API
+int raptor_xml_escape_string(raptor_world *world, const unsigned char *string, size_t len, unsigned char *buffer, size_t length, char quote);
+RAPTOR_API
+int raptor_xml_escape_string_write(const unsigned char *string, size_t len, char quote, raptor_iostream* iostr);
+RAPTOR_API
+int raptor_xml_name_check(const unsigned char *string, size_t length, int xml_version);
+
+
+/* portable vsnprintf utility function */
+RAPTOR_API RAPTOR_DEPRECATED
+char* raptor_vsnprintf(const char *format, va_list arguments) RAPTOR_PRINTF_FORMAT(1, 0);
+RAPTOR_API
+int raptor_vsnprintf2(char *buffer, size_t size, const char *format, va_list arguments) RAPTOR_PRINTF_FORMAT(3, 0);
+RAPTOR_API
+int raptor_snprintf(char *buffer, size_t size, const char *format, ...) RAPTOR_PRINTF_FORMAT(3, 4);
+RAPTOR_API
+int raptor_vasprintf(char **ret, const char *format, va_list arguments) RAPTOR_PRINTF_FORMAT(2, 0);
+
+/* RFC2396 URI resolving functions */
+RAPTOR_API
+size_t raptor_uri_resolve_uri_reference(const unsigned char *base_uri, const unsigned char *reference_uri, unsigned char* buffer, size_t length);
+
+/* URI String utility functions */
+RAPTOR_API
+unsigned char* raptor_uri_counted_filename_to_uri_string(const char *filename, size_t filename_len);
+RAPTOR_API
+unsigned char* raptor_uri_filename_to_uri_string(const char *filename);
+RAPTOR_API
+int raptor_uri_filename_exists(const unsigned char* path);
+RAPTOR_API
+char* raptor_uri_uri_string_to_filename(const unsigned char *uri_string);
+RAPTOR_API
+char* raptor_uri_uri_string_to_filename_fragment(const unsigned char *uri_string, unsigned char **fragment_p);
+RAPTOR_API
+int raptor_uri_uri_string_is_file_uri(const unsigned char* uri_string);
+RAPTOR_API
+int raptor_stringbuffer_append_uri_escaped_counted_string(raptor_stringbuffer* sb, const char* string, size_t length, int space_is_plus);
+RAPTOR_API
+char* raptor_uri_uri_string_to_counted_filename_fragment(const unsigned char *uri_string, size_t* len_p, unsigned char **fragment_p, size_t* fragment_len_p);
+RAPTOR_API
+int raptor_uri_uri_string_is_absolute(const unsigned char* uri_string);
+
+
+/**
+ * RAPTOR_RDF_MS_URI:
+ *
+ * RDF Namespace URI (rdf:).
+ *
+ * Copy with raptor_uri_copy() to use.
+ */
+#define RAPTOR_RDF_MS_URI raptor_rdf_namespace_uri
+
+/**
+ * RAPTOR_RDF_SCHEMA_URI:
+ *
+ * RDF Schema Namespace URI (rdfs:).
+ *
+ * Copy with raptor_uri_copy() to use.
+ */
+#define RAPTOR_RDF_SCHEMA_URI raptor_rdf_schema_namespace_uri
+
+/**
+ * RAPTOR_XMLSCHEMA_DATATYPES_URI:
+ *
+ * XML Schema Datatypes URI (xsd:).
+ *
+ * Copy with raptor_uri_copy() to use.
+ */
+#define RAPTOR_XMLSCHEMA_DATATYPES_URI raptor_xmlschema_datatypes_namespace_uri
+
+/**
+ * RAPTOR_OWL_URI:
+ *
+ * OWL Namespace URI (owl:).
+ *
+ * Copy with raptor_uri_copy() to use.
+ */
+#define RAPTOR_OWL_URI raptor_owl_namespace_uri
+
+
+/* raptor_www */
+RAPTOR_API
+raptor_www* raptor_new_www(raptor_world* world);
+RAPTOR_API
+raptor_www* raptor_new_www_with_connection(raptor_world* world, void* connection);
+RAPTOR_API
+void raptor_free_www(raptor_www *www);
+RAPTOR_API
+int raptor_www_set_ssl_cert_options(raptor_www* www, const char* cert_filename, const char* cert_type, const char* cert_passphrase);
+RAPTOR_API
+int raptor_www_set_ssl_verify_options(raptor_www* www, int verify_peer, int verify_host);
+RAPTOR_API
+void raptor_www_set_user_agent(raptor_www *www, const char *user_agent);
+RAPTOR_API
+void raptor_www_set_proxy(raptor_www *www, const char *proxy);
+RAPTOR_API
+void raptor_www_set_http_accept(raptor_www *www, const char *value);
+RAPTOR_API
+void raptor_www_set_write_bytes_handler(raptor_www *www, raptor_www_write_bytes_handler handler, void *user_data);
+RAPTOR_API
+void raptor_www_set_content_type_handler(raptor_www *www, raptor_www_content_type_handler handler, void *user_data);
+RAPTOR_API
+void raptor_www_set_final_uri_handler(raptor_www* www, raptor_www_final_uri_handler handler, void *user_data);
+RAPTOR_API
+void raptor_www_set_uri_filter(raptor_www* www, raptor_uri_filter_func filter, void* user_data);
+RAPTOR_API
+void raptor_www_set_connection_timeout(raptor_www* www, int timeout);
+RAPTOR_API
+int raptor_www_set_http_cache_control(raptor_www* www, const char* cache_control);
+RAPTOR_API
+int raptor_www_fetch(raptor_www *www, raptor_uri *uri);
+RAPTOR_API
+int raptor_www_fetch_to_string(raptor_www *www, raptor_uri *uri, void **string_p, size_t *length_p, raptor_data_malloc_handler const malloc_handler);
+RAPTOR_API
+void* raptor_www_get_connection(raptor_www *www);
+RAPTOR_API
+void raptor_www_abort(raptor_www *www, const char *reason);
+RAPTOR_API
+raptor_uri* raptor_www_get_final_uri(raptor_www* www);
+
+
+/* XML QNames Class */
+RAPTOR_API
+raptor_qname* raptor_new_qname(raptor_namespace_stack *nstack, const unsigned char *name, const unsigned char *value);
+RAPTOR_API
+raptor_qname* raptor_new_qname_from_namespace_local_name(raptor_world* world, raptor_namespace *ns, const unsigned char *local_name, const unsigned char *value);
+
+/* methods */
+RAPTOR_API
+raptor_qname* raptor_qname_copy(raptor_qname *qname);
+RAPTOR_API
+void raptor_free_qname(raptor_qname* name);
+RAPTOR_API
+int raptor_qname_equal(raptor_qname *name1, raptor_qname *name2);
+RAPTOR_API
+unsigned char* raptor_qname_to_counted_name(raptor_qname *qname, size_t* length_p);
+RAPTOR_API
+const raptor_namespace* raptor_qname_get_namespace(raptor_qname* name);
+RAPTOR_API
+const unsigned char* raptor_qname_get_local_name(raptor_qname* name);
+RAPTOR_API
+const unsigned char* raptor_qname_get_value(raptor_qname* name);
+RAPTOR_API
+const unsigned char* raptor_qname_get_counted_value(raptor_qname* name, size_t* length_p);
+RAPTOR_API
+int raptor_qname_write(raptor_qname *qname, raptor_iostream* iostr);
+
+/* QName String utility functions */
+RAPTOR_API
+raptor_uri* raptor_qname_string_to_uri(raptor_namespace_stack *nstack, const unsigned char *name, size_t name_len);
+RAPTOR_API
+unsigned char* raptor_qname_format_as_xml(const raptor_qname *qname, size_t *length_p);
+
+/* XML Namespaces Stack class */
+RAPTOR_API
+raptor_namespace* raptor_new_namespace_from_uri(raptor_namespace_stack *nstack, const unsigned char *prefix, raptor_uri* ns_uri, int depth);
+RAPTOR_API
+raptor_namespace_stack* raptor_new_namespaces(raptor_world* world, int defaults);
+RAPTOR_API
+int raptor_namespaces_init(raptor_world* world, raptor_namespace_stack *nstack, int defaults);
+RAPTOR_API
+void raptor_namespaces_clear(raptor_namespace_stack *nstack);
+RAPTOR_API
+void raptor_free_namespaces(raptor_namespace_stack *nstack);
+
+/* methods */
+RAPTOR_API
+void raptor_namespaces_start_namespace(raptor_namespace_stack *nstack, raptor_namespace *nspace);
+RAPTOR_API
+int raptor_namespaces_start_namespace_full(raptor_namespace_stack *nstack, const unsigned char *prefix, const unsigned char *ns_uri_string, int depth);
+RAPTOR_API
+void raptor_namespaces_end_for_depth(raptor_namespace_stack *nstack, int depth);
+RAPTOR_API
+raptor_namespace* raptor_namespaces_get_default_namespace(raptor_namespace_stack *nstack);
+RAPTOR_API
+raptor_namespace* raptor_namespaces_find_namespace(raptor_namespace_stack *nstack, const unsigned char *prefix, int prefix_length);
+RAPTOR_API
+raptor_namespace* raptor_namespaces_find_namespace_by_uri(raptor_namespace_stack *nstack, raptor_uri *ns_uri);
+RAPTOR_API
+int raptor_namespaces_namespace_in_scope(raptor_namespace_stack *nstack, const raptor_namespace *nspace);
+RAPTOR_API
+raptor_qname* raptor_new_qname_from_namespace_uri(raptor_namespace_stack *nstack, raptor_uri *uri, int xml_version);
+
+
+/* XML Namespace Class */
+RAPTOR_API
+raptor_namespace* raptor_new_namespace(raptor_namespace_stack *nstack, const unsigned char *prefix, const unsigned char *ns_uri_string, int depth);
+RAPTOR_API
+void raptor_free_namespace(raptor_namespace *ns);
+RAPTOR_API
+int raptor_namespace_stack_start_namespace(raptor_namespace_stack *nstack, raptor_namespace *ns, int new_depth);
+RAPTOR_API
+raptor_uri* raptor_namespace_get_uri(const raptor_namespace *ns);
+RAPTOR_API
+const unsigned char* raptor_namespace_get_prefix(const raptor_namespace *ns);
+RAPTOR_API
+const unsigned char* raptor_namespace_get_counted_prefix(const raptor_namespace *ns, size_t *length_p);
+RAPTOR_API
+unsigned char* raptor_namespace_format_as_xml(const raptor_namespace *ns, size_t *length_p);
+RAPTOR_API
+int raptor_namespace_write(raptor_namespace *ns, raptor_iostream* iostr);
+
+/* namespace string utility function */
+RAPTOR_API
+int raptor_xml_namespace_string_parse(const unsigned char *string, unsigned char **prefix, unsigned char **uri_string);
+
+/* Sequence class */
+/**
+ * raptor_sequence:
+ *
+ * Raptor sequence class
+ */
+typedef struct raptor_sequence_s raptor_sequence;
+
+/* Sequence Class */
+RAPTOR_API
+raptor_sequence* raptor_new_sequence(raptor_data_free_handler free_handler, raptor_data_print_handler print_handler);
+RAPTOR_API
+raptor_sequence* raptor_new_sequence_with_context(raptor_data_context_free_handler free_handler, raptor_data_context_print_handler print_handler, void* handler_context);
+RAPTOR_API
+void raptor_free_sequence(raptor_sequence* seq);
+
+/* methods */
+RAPTOR_API
+int raptor_sequence_size(raptor_sequence* seq);
+RAPTOR_API
+int raptor_sequence_set_at(raptor_sequence* seq, int idx, void *data);
+RAPTOR_API
+int raptor_sequence_push(raptor_sequence* seq, void *data);
+RAPTOR_API
+int raptor_sequence_shift(raptor_sequence* seq, void *data);
+RAPTOR_API
+void* raptor_sequence_get_at(raptor_sequence* seq, int idx);
+RAPTOR_API
+void* raptor_sequence_pop(raptor_sequence* seq);
+RAPTOR_API
+void* raptor_sequence_unshift(raptor_sequence* seq);
+RAPTOR_API
+void* raptor_sequence_delete_at(raptor_sequence* seq, int idx);
+
+RAPTOR_API
+void raptor_sequence_sort(raptor_sequence* seq, raptor_data_compare_handler compare);
+RAPTOR_API
+void raptor_sequence_sort_r(raptor_sequence* seq, raptor_data_compare_arg_handler compare, void* user_data);
+RAPTOR_API
+int raptor_sequence_swap(raptor_sequence* seq, int i, int j);
+RAPTOR_API
+int raptor_sequence_reverse(raptor_sequence* seq, int start_index, int length);
+RAPTOR_API
+int raptor_sequence_next_permutation(raptor_sequence *seq, raptor_data_compare_handler compare);
+
+/* helper for printing sequences of strings */
+RAPTOR_API
+int raptor_sequence_print(raptor_sequence* seq, FILE* fh);
+RAPTOR_API
+int raptor_sequence_join(raptor_sequence* dest, raptor_sequence *src);
+
+
+/* Unicode and UTF8 */
+
+/**
+ * raptor_unichar:
+ *
+ * raptor Unicode codepoint
+ */
+typedef unsigned long raptor_unichar;
+RAPTOR_API
+int raptor_unicode_utf8_string_put_char(raptor_unichar c, unsigned char *output, size_t length);
+RAPTOR_API
+int raptor_unicode_utf8_string_get_char(const unsigned char *input, size_t length, raptor_unichar *output);
+RAPTOR_API
+int raptor_unicode_is_xml11_namestartchar(raptor_unichar c);
+RAPTOR_API
+int raptor_unicode_is_xml10_namestartchar(raptor_unichar c);
+RAPTOR_API
+int raptor_unicode_is_xml11_namechar(raptor_unichar c);
+RAPTOR_API
+int raptor_unicode_is_xml10_namechar(raptor_unichar c);
+RAPTOR_API
+int raptor_unicode_check_utf8_string(const unsigned char *string, size_t length);
+RAPTOR_API
+int raptor_unicode_utf8_strlen(const unsigned char *string, size_t length);
+RAPTOR_API
+size_t raptor_unicode_utf8_substr(unsigned char* dest, size_t* dest_length_p, const unsigned char* src, size_t src_length, int startingLoc, int length);
+
+/* Stringbuffer Class */
+RAPTOR_API
+raptor_stringbuffer* raptor_new_stringbuffer(void);
+RAPTOR_API
+void raptor_free_stringbuffer(raptor_stringbuffer *stringbuffer);
+
+/* methods */
+RAPTOR_API
+int raptor_stringbuffer_append_counted_string(raptor_stringbuffer* stringbuffer, const unsigned char *string, size_t length, int do_copy);
+RAPTOR_API
+int raptor_stringbuffer_append_string(raptor_stringbuffer* stringbuffer, const unsigned char *string, int do_copy);
+RAPTOR_API
+int raptor_stringbuffer_append_decimal(raptor_stringbuffer* stringbuffer, int integer);
+RAPTOR_API
+int raptor_stringbuffer_append_hexadecimal(raptor_stringbuffer* stringbuffer, int hex);
+RAPTOR_API
+int raptor_stringbuffer_append_stringbuffer(raptor_stringbuffer* stringbuffer, raptor_stringbuffer* append);
+RAPTOR_API
+int raptor_stringbuffer_prepend_counted_string(raptor_stringbuffer* stringbuffer, const unsigned char *string, size_t length, int do_copy);
+RAPTOR_API
+int raptor_stringbuffer_prepend_string(raptor_stringbuffer* stringbuffer, const unsigned char *string, int do_copy);
+RAPTOR_API
+unsigned char* raptor_stringbuffer_as_string(raptor_stringbuffer* stringbuffer);
+RAPTOR_API
+size_t raptor_stringbuffer_length(raptor_stringbuffer* stringbuffer);
+RAPTOR_API
+int raptor_stringbuffer_copy_to_string(raptor_stringbuffer* stringbuffer, unsigned char *string, size_t length);
+
+/**
+ * raptor_iostream_init_func:
+ * @context: stream context data
+ *
+ * Handler function for #raptor_iostream initialising.
+ *
+ * Return value: non-0 on failure.
+ */
+typedef int (*raptor_iostream_init_func) (void *context);
+
+/**
+ * raptor_iostream_finish_func:
+ * @context: stream context data
+ *
+ * Handler function for #raptor_iostream terminating.
+ *
+ */
+typedef void (*raptor_iostream_finish_func) (void *context);
+
+/**
+ * raptor_iostream_write_byte_func
+ * @context: stream context data
+ * @byte: byte to write
+ *
+ * Handler function for implementing raptor_iostream_write_byte().
+ *
+ * Return value: non-0 on failure.
+ */
+typedef int (*raptor_iostream_write_byte_func) (void *context, const int byte);
+
+/**
+ * raptor_iostream_write_bytes_func:
+ * @context: stream context data
+ * @ptr: pointer to bytes to write
+ * @size: size of item
+ * @nmemb: number of items
+ *
+ * Handler function for implementing raptor_iostream_write_bytes().
+ *
+ * Return value: non-0 on failure.
+ */
+typedef int (*raptor_iostream_write_bytes_func) (void *context, const void *ptr, size_t size, size_t nmemb);
+
+/**
+ * raptor_iostream_write_end_func:
+ * @context: stream context data
+ *
+ * Handler function for implementing raptor_iostream_write_end().
+ *
+ * Return value: non-0 on failure.
+ */
+typedef int (*raptor_iostream_write_end_func) (void *context);
+
+/**
+ * raptor_iostream_read_bytes_func:
+ * @context: stream context data
+ * @ptr: pointer to buffer to read into
+ * @size: size of buffer
+ * @nmemb: number of items
+ *
+ * Handler function for implementing raptor_iostream_read_bytes().
+ *
+ * Return value: number of items read, 0 or < @size on EOF, <0 on failure
+ */
+typedef int (*raptor_iostream_read_bytes_func) (void *context, void *ptr, size_t size, size_t nmemb);
+
+/**
+ * raptor_iostream_read_eof_func:
+ * @context: stream context data
+ *
+ * Handler function for implementing raptor_iostream_read_eof().
+ *
+ * Return value: non-0 if EOF
+ */
+typedef int (*raptor_iostream_read_eof_func) (void *context);
+
+/**
+ * raptor_iostream_handler:
+ * @version: interface version. Presently 1 or 2.
+ * @init: initialisation handler - optional, called at most once (V1)
+ * @finish: finishing handler - optional, called at most once (V1)
+ * @write_byte: write byte handler - required (for writing) (V1)
+ * @write_bytes: write bytes handler - required (for writing) (V1)
+ * @write_end: write end handler - optional (for writing), called at most once (V1)
+ * @read_bytes: read bytes handler - required (for reading) (V2)
+ * @read_eof: read EOF handler - required (for reading) (V2)
+ *
+ * I/O stream implementation handler structure.
+ *
+ */
+typedef struct {
+ int version;
+
+ /* V1 functions */
+ raptor_iostream_init_func init;
+ raptor_iostream_finish_func finish;
+ raptor_iostream_write_byte_func write_byte;
+ raptor_iostream_write_bytes_func write_bytes;
+ raptor_iostream_write_end_func write_end;
+
+ /* V2 functions */
+ raptor_iostream_read_bytes_func read_bytes;
+ raptor_iostream_read_eof_func read_eof;
+} raptor_iostream_handler;
+
+
+/* I/O Stream Class */
+RAPTOR_API
+raptor_iostream* raptor_new_iostream_from_handler(raptor_world* world, void *user_data, const raptor_iostream_handler* const handler);
+RAPTOR_API
+raptor_iostream* raptor_new_iostream_to_sink(raptor_world* world);
+RAPTOR_API
+raptor_iostream* raptor_new_iostream_to_filename(raptor_world* world, const char *filename);
+RAPTOR_API
+raptor_iostream* raptor_new_iostream_to_file_handle(raptor_world* world, FILE *handle);
+RAPTOR_API
+raptor_iostream* raptor_new_iostream_to_string(raptor_world* world, void **string_p, size_t *length_p, raptor_data_malloc_handler const malloc_handler);
+RAPTOR_API
+raptor_iostream* raptor_new_iostream_from_sink(raptor_world* world);
+RAPTOR_API
+raptor_iostream* raptor_new_iostream_from_filename(raptor_world* world, const char *filename);
+RAPTOR_API
+raptor_iostream* raptor_new_iostream_from_file_handle(raptor_world* world, FILE *handle);
+RAPTOR_API
+raptor_iostream* raptor_new_iostream_from_string(raptor_world* world, void *string, size_t length);
+RAPTOR_API
+void raptor_free_iostream(raptor_iostream *iostr);
+
+RAPTOR_API
+int raptor_iostream_write_bytes(const void *ptr, size_t size, size_t nmemb, raptor_iostream *iostr);
+RAPTOR_API
+int raptor_iostream_write_byte(const int byte, raptor_iostream *iostr);
+RAPTOR_API
+int raptor_iostream_write_end(raptor_iostream *iostr);
+RAPTOR_API
+int raptor_iostream_string_write(const void *string, raptor_iostream *iostr);
+RAPTOR_API
+int raptor_iostream_counted_string_write(const void *string, size_t len, raptor_iostream *iostr);
+RAPTOR_API
+unsigned long raptor_iostream_tell(raptor_iostream *iostr);
+RAPTOR_API
+int raptor_iostream_decimal_write(int integer, raptor_iostream* iostr);
+RAPTOR_API
+int raptor_iostream_hexadecimal_write(unsigned int integer, int width, raptor_iostream* iostr);
+RAPTOR_API
+int raptor_stringbuffer_write(raptor_stringbuffer *sb, raptor_iostream* iostr);
+RAPTOR_API
+int raptor_uri_write(raptor_uri *uri, raptor_iostream *iostr);
+RAPTOR_API
+int raptor_iostream_read_bytes(void *ptr, size_t size, size_t nmemb, raptor_iostream* iostr);
+RAPTOR_API
+int raptor_iostream_read_eof(raptor_iostream *iostr);
+
+/* I/O Stream utility functions */
+
+/**
+ * raptor_escaped_write_bitflags:
+ * @RAPTOR_ESCAPED_WRITE_BITFLAG_BS_ESCAPES_BF : Allow \b \f,
+ * @RAPTOR_ESCAPED_WRITE_BITFLAG_BS_ESCAPES_TNRU : ALlow \t \n \r \u
+ * @RAPTOR_ESCAPED_WRITE_BITFLAG_UTF8 : Allow UTF-8 for printable U *
+ * @RAPTOR_ESCAPED_WRITE_BITFLAG_SPARQL_URI_ESCAPES: Must escape #x00-#x20<>\"{}|^` in URIs
+ * @RAPTOR_ESCAPED_WRITE_NTRIPLES_LITERAL: N-Triples literal
+ * @RAPTOR_ESCAPED_WRITE_NTRIPLES_URI: N-Triples URI
+ * @RAPTOR_ESCAPED_WRITE_SPARQL_LITERAL: SPARQL literal: allows raw UTF8 for printable literals
+ * @RAPTOR_ESCAPED_WRITE_SPARQL_LONG_LITERAL: SPARQL long literal: no BS-escapes allowed
+ * @RAPTOR_ESCAPED_WRITE_SPARQL_URI: SPARQL uri: have to escape certain characters
+ * @RAPTOR_ESCAPED_WRITE_TURTLE_URI: Turtle 2013 URIs (like SPARQL)
+ * @RAPTOR_ESCAPED_WRITE_TURTLE_LITERAL: Turtle 2013 literals (like SPARQL)
+ * @RAPTOR_ESCAPED_WRITE_TURTLE_LONG_LITERAL: Turtle 2013 long literals (like SPARQL)
+ * @RAPTOR_ESCAPED_WRITE_JSON_LITERAL: JSON literals: \b \f \t \r \n and \u \U
+ *
+ * Bit flags for raptor_string_escaped_write() and friends.
+ */
+typedef enum {
+ RAPTOR_ESCAPED_WRITE_BITFLAG_BS_ESCAPES_BF = 1,
+ RAPTOR_ESCAPED_WRITE_BITFLAG_BS_ESCAPES_TNRU = 2,
+ RAPTOR_ESCAPED_WRITE_BITFLAG_UTF8 = 4,
+ RAPTOR_ESCAPED_WRITE_BITFLAG_SPARQL_URI_ESCAPES = 8,
+
+ /* N-Triples - favour writing \u, \U over UTF8 */
+ RAPTOR_ESCAPED_WRITE_NTRIPLES_LITERAL = RAPTOR_ESCAPED_WRITE_BITFLAG_BS_ESCAPES_TNRU | RAPTOR_ESCAPED_WRITE_BITFLAG_BS_ESCAPES_BF,
+ RAPTOR_ESCAPED_WRITE_NTRIPLES_URI = RAPTOR_ESCAPED_WRITE_BITFLAG_SPARQL_URI_ESCAPES,
+
+ /* SPARQL literal: allows raw UTF8 for printable literals */
+ RAPTOR_ESCAPED_WRITE_SPARQL_LITERAL = RAPTOR_ESCAPED_WRITE_BITFLAG_UTF8,
+
+ /* SPARQL long literal: no BS-escapes allowed */
+ RAPTOR_ESCAPED_WRITE_SPARQL_LONG_LITERAL = RAPTOR_ESCAPED_WRITE_BITFLAG_UTF8,
+
+ /* SPARQL uri: have to escape certain characters */
+ RAPTOR_ESCAPED_WRITE_SPARQL_URI = RAPTOR_ESCAPED_WRITE_BITFLAG_UTF8 | RAPTOR_ESCAPED_WRITE_BITFLAG_SPARQL_URI_ESCAPES,
+
+ /* Turtle (2013) escapes are like SPARQL */
+ RAPTOR_ESCAPED_WRITE_TURTLE_URI = RAPTOR_ESCAPED_WRITE_SPARQL_URI,
+ RAPTOR_ESCAPED_WRITE_TURTLE_LITERAL = RAPTOR_ESCAPED_WRITE_SPARQL_LITERAL,
+ RAPTOR_ESCAPED_WRITE_TURTLE_LONG_LITERAL = RAPTOR_ESCAPED_WRITE_SPARQL_LONG_LITERAL,
+
+ /* JSON literals: \b \f \t \r \n and \u \U */
+ RAPTOR_ESCAPED_WRITE_JSON_LITERAL = RAPTOR_ESCAPED_WRITE_BITFLAG_BS_ESCAPES_TNRU | RAPTOR_ESCAPED_WRITE_BITFLAG_BS_ESCAPES_BF
+} raptor_escaped_write_bitflags;
+
+
+RAPTOR_API
+int raptor_string_ntriples_write(const unsigned char *string, size_t len, const char delim, raptor_iostream *iostr);
+RAPTOR_API
+int raptor_bnodeid_ntriples_write(const unsigned char *bnodeid, size_t len, raptor_iostream *iostr);
+RAPTOR_API RAPTOR_DEPRECATED
+int raptor_string_python_write(const unsigned char *string, size_t len, const char delim, unsigned int mode, raptor_iostream *iostr);
+RAPTOR_API
+int raptor_statement_ntriples_write(const raptor_statement *statement, raptor_iostream* iostr, int write_graph_term);
+RAPTOR_API
+int raptor_string_escaped_write(const unsigned char *string, size_t len, const char delim, unsigned int flags, raptor_iostream *iostr);
+
+
+/* Parser and Serializer options */
+
+/**
+ * raptor_option_value_type:
+ * @RAPTOR_OPTION_VALUE_TYPE_BOOL: Boolean integer value. Non-0 is true
+ * @RAPTOR_OPTION_VALUE_TYPE_INT: Decimal integer value
+ * @RAPTOR_OPTION_VALUE_TYPE_STRING: String value
+ * @RAPTOR_OPTION_VALUE_TYPE_URI: URI String value.
+ * @RAPTOR_OPTION_VALUE_TYPE_LAST: internal
+ *
+ * Option value types.
+ */
+typedef enum {
+ RAPTOR_OPTION_VALUE_TYPE_BOOL,
+ RAPTOR_OPTION_VALUE_TYPE_INT,
+ RAPTOR_OPTION_VALUE_TYPE_STRING,
+ RAPTOR_OPTION_VALUE_TYPE_URI,
+ RAPTOR_OPTION_VALUE_TYPE_LAST = RAPTOR_OPTION_VALUE_TYPE_URI
+} raptor_option_value_type;
+
+
+/**
+ * raptor_option_description:
+ * @domain: domain ID
+ * @option: option ID
+ * @value_type: data type of option value
+ * @name: short name for option
+ * @name_len: length of @name
+ * @label: description of option
+ * @uri: URI identifying option
+ *
+ * Description of an option for a domain.
+ */
+typedef struct {
+ raptor_domain domain;
+ raptor_option option;
+ raptor_option_value_type value_type;
+ const char* name;
+ size_t name_len;
+ const char* label;
+ raptor_uri* uri;
+} raptor_option_description;
+
+
+RAPTOR_API
+unsigned int raptor_option_get_count(void);
+RAPTOR_API
+const char* raptor_option_get_value_type_label(const raptor_option_value_type type);
+RAPTOR_API
+void raptor_free_option_description(raptor_option_description* option_description);
+RAPTOR_API
+raptor_option_description* raptor_world_get_option_description(raptor_world* world, const raptor_domain domain, const raptor_option option);
+
+
+/* SAX2 element Class (raptor_xml_element) */
+RAPTOR_API
+raptor_xml_element* raptor_new_xml_element(raptor_qname* name, const unsigned char* xml_language, raptor_uri* xml_base);
+RAPTOR_API
+raptor_xml_element* raptor_new_xml_element_from_namespace_local_name(raptor_namespace *ns, const unsigned char *name, const unsigned char *xml_language, raptor_uri *xml_base);
+RAPTOR_API
+void raptor_free_xml_element(raptor_xml_element *element);
+
+/* methods */
+RAPTOR_API
+raptor_qname* raptor_xml_element_get_name(raptor_xml_element *xml_element);
+RAPTOR_API
+void raptor_xml_element_set_attributes(raptor_xml_element* xml_element, raptor_qname **attributes, int count);
+RAPTOR_API
+raptor_qname** raptor_xml_element_get_attributes(raptor_xml_element* xml_element);
+RAPTOR_API
+int raptor_xml_element_get_attributes_count(raptor_xml_element* xml_element);
+RAPTOR_API
+int raptor_xml_element_declare_namespace(raptor_xml_element* xml_element, raptor_namespace *nspace);
+RAPTOR_API
+int raptor_xml_element_write(raptor_xml_element *element, raptor_namespace_stack *nstack, int is_empty, int is_end, int depth, raptor_iostream *iostr);
+RAPTOR_API
+int raptor_xml_element_is_empty(raptor_xml_element* xml_element);
+RAPTOR_API
+const unsigned char* raptor_xml_element_get_language(raptor_xml_element* xml_element);
+
+
+/* XML Writer Class (raptor_xml_writer) */
+RAPTOR_API
+raptor_xml_writer* raptor_new_xml_writer(raptor_world* world, raptor_namespace_stack *nstack, raptor_iostream* iostr);
+RAPTOR_API
+void raptor_free_xml_writer(raptor_xml_writer* xml_writer);
+
+/* methods */
+RAPTOR_API
+void raptor_xml_writer_empty_element(raptor_xml_writer* xml_writer, raptor_xml_element *element);
+RAPTOR_API
+void raptor_xml_writer_start_element(raptor_xml_writer* xml_writer, raptor_xml_element *element);
+RAPTOR_API
+void raptor_xml_writer_end_element(raptor_xml_writer* xml_writer, raptor_xml_element *element);
+RAPTOR_API
+void raptor_xml_writer_newline(raptor_xml_writer* xml_writer);
+RAPTOR_API
+void raptor_xml_writer_cdata(raptor_xml_writer* xml_writer, const unsigned char *s);
+RAPTOR_API
+void raptor_xml_writer_cdata_counted(raptor_xml_writer* xml_writer, const unsigned char *s, unsigned int len);
+RAPTOR_API
+void raptor_xml_writer_raw(raptor_xml_writer* xml_writer, const unsigned char *s);
+RAPTOR_API
+void raptor_xml_writer_raw_counted(raptor_xml_writer* xml_writer, const unsigned char *s, unsigned int len);
+RAPTOR_API
+void raptor_xml_writer_comment(raptor_xml_writer* xml_writer, const unsigned char *s);
+RAPTOR_API
+void raptor_xml_writer_comment_counted(raptor_xml_writer* xml_writer, const unsigned char *s, unsigned int len);
+RAPTOR_API
+void raptor_xml_writer_flush(raptor_xml_writer* xml_writer);
+RAPTOR_API
+int raptor_xml_writer_set_option(raptor_xml_writer *xml_writer, raptor_option option, char* string, int integer);
+RAPTOR_API
+int raptor_xml_writer_get_option(raptor_xml_writer *xml_writer, raptor_option option, char** string_p, int* integer_p);
+RAPTOR_API
+int raptor_xml_writer_get_depth(raptor_xml_writer *xml_writer);
+
+/**
+ * raptor_sax2_start_element_handler:
+ * @user_data: user data
+ * @xml_element: XML element
+ *
+ * SAX2 start element handler
+ */
+typedef void (*raptor_sax2_start_element_handler)(void *user_data, raptor_xml_element *xml_element);
+
+/**
+ * raptor_sax2_end_element_handler:
+ * @user_data: user data
+ * @xml_element: XML element
+ *
+ * SAX2 end element handler
+ */
+typedef void (*raptor_sax2_end_element_handler)(void *user_data, raptor_xml_element* xml_element);
+
+/**
+ * raptor_sax2_characters_handler:
+ * @user_data: user data
+ * @xml_element: XML element
+ * @s: string
+ * @len: string len
+ *
+ * SAX2 characters handler
+ */
+typedef void (*raptor_sax2_characters_handler)(void *user_data, raptor_xml_element* xml_element, const unsigned char *s, int len);
+
+/**
+ * raptor_sax2_cdata_handler:
+ * @user_data: user data
+ * @xml_element: XML element
+ * @s: string
+ * @len: string len
+
+ * SAX2 CDATA section handler
+ */
+typedef void (*raptor_sax2_cdata_handler)(void *user_data, raptor_xml_element* xml_element, const unsigned char *s, int len);
+
+/**
+ * raptor_sax2_comment_handler:
+ * @user_data: user data
+ * @xml_element: XML element
+ * @s: string
+ *
+ * SAX2 XML comment handler
+ */
+typedef void (*raptor_sax2_comment_handler)(void *user_data, raptor_xml_element* xml_element, const unsigned char *s);
+
+/**
+ * raptor_sax2_unparsed_entity_decl_handler:
+ * @user_data: user data
+ * @entityName: entity name
+ * @base: base URI
+ * @systemId: system ID
+ * @publicId: public ID
+ * @notationName: notation name
+ *
+ * SAX2 unparsed entity (NDATA) handler
+ */
+typedef void (*raptor_sax2_unparsed_entity_decl_handler)(void *user_data, const unsigned char* entityName, const unsigned char* base, const unsigned char* systemId, const unsigned char* publicId, const unsigned char* notationName);
+
+/**
+ * raptor_sax2_external_entity_ref_handler:
+ * @user_data: user data
+ * @context: context
+ * @base: base URI
+ * @systemId: system ID
+ * @publicId: public ID
+ *
+ * SAX2 external entity reference handler
+ *
+ * Return value: 0 if processing should not continue because of a
+ * fatal error in the handling of the external entity.
+ */
+typedef int (*raptor_sax2_external_entity_ref_handler)(void *user_data, const unsigned char* context, const unsigned char* base, const unsigned char* systemId, const unsigned char* publicId);
+
+
+/* SAX2 API */
+RAPTOR_API
+raptor_sax2* raptor_new_sax2(raptor_world *world, raptor_locator *locator, void* user_data);
+RAPTOR_API
+void raptor_free_sax2(raptor_sax2 *sax2);
+
+/* methods */
+RAPTOR_API
+void raptor_sax2_set_start_element_handler(raptor_sax2* sax2, raptor_sax2_start_element_handler handler);
+RAPTOR_API
+void raptor_sax2_set_end_element_handler(raptor_sax2* sax2, raptor_sax2_end_element_handler handler);
+RAPTOR_API
+void raptor_sax2_set_characters_handler(raptor_sax2* sax2, raptor_sax2_characters_handler handler);
+RAPTOR_API
+void raptor_sax2_set_cdata_handler(raptor_sax2* sax2, raptor_sax2_cdata_handler handler);
+RAPTOR_API
+void raptor_sax2_set_comment_handler(raptor_sax2* sax2, raptor_sax2_comment_handler handler);
+RAPTOR_API
+void raptor_sax2_set_unparsed_entity_decl_handler(raptor_sax2* sax2, raptor_sax2_unparsed_entity_decl_handler handler);
+RAPTOR_API
+void raptor_sax2_set_external_entity_ref_handler(raptor_sax2* sax2, raptor_sax2_external_entity_ref_handler handler);
+RAPTOR_API
+void raptor_sax2_set_namespace_handler(raptor_sax2* sax2, raptor_namespace_handler handler);
+RAPTOR_API
+void raptor_sax2_set_uri_filter(raptor_sax2* sax2, raptor_uri_filter_func filter, void *user_data);
+RAPTOR_API
+void raptor_sax2_parse_start(raptor_sax2 *sax2, raptor_uri *base_uri);
+RAPTOR_API
+int raptor_sax2_parse_chunk(raptor_sax2* sax2, const unsigned char *buffer, size_t len, int is_end);
+RAPTOR_API
+const unsigned char* raptor_sax2_inscope_xml_language(raptor_sax2* sax2);
+RAPTOR_API
+raptor_uri* raptor_sax2_inscope_base_uri(raptor_sax2* sax2);
+
+
+
+/* AVL Trees */
+
+/**
+ * raptor_avltree:
+ *
+ * AVL Tree
+ */
+typedef struct raptor_avltree_s raptor_avltree;
+
+/**
+ * raptor_avltree_iterator:
+ *
+ * AVL Tree Iterator as created by raptor_new_avltree_iterator()
+ */
+typedef struct raptor_avltree_iterator_s raptor_avltree_iterator;
+
+/**
+ * raptor_avltree_visit_handler:
+ * @depth: depth of object in tree
+ * @data: data object being visited
+ * @user_data: user data arg to raptor_avltree_visit()
+ *
+ * AVL Tree visitor function as given to raptor_avltree_visit()
+ *
+ * Return value: non-0 to terminate visit early.
+ */
+typedef int (*raptor_avltree_visit_handler)(int depth, void* data, void *user_data);
+
+
+/**
+ * raptor_avltree_bitflags:
+ * @RAPTOR_AVLTREE_FLAG_REPLACE_DUPLICATES: If set raptor_avltree_add() will replace any duplicate items. If not set, raptor_avltree_add() will not replace them and will return status >0 when adding a duplicate. (Default is not set)
+ *
+ * Bit flags for AVL Tree class constructor raptor_new_avltree()
+ **/
+typedef enum {
+ RAPTOR_AVLTREE_FLAG_REPLACE_DUPLICATES = 1
+} raptor_avltree_bitflags;
+
+
+RAPTOR_API
+raptor_avltree* raptor_new_avltree(raptor_data_compare_handler compare_handler, raptor_data_free_handler free_handler, unsigned int flags);
+RAPTOR_API
+void raptor_free_avltree(raptor_avltree* tree);
+
+/* methods */
+RAPTOR_API
+int raptor_avltree_add(raptor_avltree* tree, void* p_data);
+RAPTOR_API
+void* raptor_avltree_remove(raptor_avltree* tree, void* p_data);
+RAPTOR_API
+int raptor_avltree_delete(raptor_avltree* tree, void* p_data);
+RAPTOR_API
+void* raptor_avltree_search(raptor_avltree* tree, const void* p_data);
+RAPTOR_API
+int raptor_avltree_visit(raptor_avltree* tree, raptor_avltree_visit_handler visit_handler, void* user_data);
+RAPTOR_API
+int raptor_avltree_size(raptor_avltree* tree);
+RAPTOR_API
+void raptor_avltree_set_print_handler(raptor_avltree* tree, raptor_data_print_handler print_handler);
+RAPTOR_API
+int raptor_avltree_print(raptor_avltree* tree, FILE* stream);
+
+RAPTOR_API
+raptor_avltree_iterator* raptor_new_avltree_iterator(raptor_avltree* tree, void* range, raptor_data_free_handler range_free_handler, int direction);
+RAPTOR_API
+void raptor_free_avltree_iterator(raptor_avltree_iterator* iterator);
+
+RAPTOR_API
+int raptor_avltree_iterator_is_end(raptor_avltree_iterator* iterator);
+RAPTOR_API
+int raptor_avltree_iterator_next(raptor_avltree_iterator* iterator);
+RAPTOR_API
+void* raptor_avltree_iterator_get(raptor_avltree_iterator* iterator);
+
+/* utility methods */
+RAPTOR_API
+void raptor_sort_r(void *base, size_t nel, size_t width, raptor_data_compare_arg_handler compar, void *user_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/external/redland/raptor/raptor_config.h b/external/redland/raptor/raptor_config.h
new file mode 100644
index 000000000..74f58de95
--- /dev/null
+++ b/external/redland/raptor/raptor_config.h
@@ -0,0 +1,402 @@
+/* src/raptor_config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* have to check C99 vsnprintf at runtime because cross compiling */
+#undef CHECK_VSNPRINTF_RUNTIME
+
+/* vsnprintf has C99 compatible return value */
+#undef HAVE_C99_VSNPRINTF
+
+/* Have curl/curl.h */
+#undef HAVE_CURL_CURL_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the <fetch.h> header file. */
+#undef HAVE_FETCH_H
+
+/* Define to 1 if you have the `getopt' function. */
+#undef HAVE_GETOPT
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* Define to 1 if you have the `getopt_long' function. */
+#undef HAVE_GETOPT_LONG
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* INN parsedate function present */
+#undef HAVE_INN_PARSEDATE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `isascii' function. */
+#undef HAVE_ISASCII
+
+/* Define to 1 if you have the <libxml/hash.h> header file. */
+#define HAVE_LIBXML_HASH_H 1
+
+/* Define to 1 if you have the <libxml/HTMLparser.h> header file. */
+#define HAVE_LIBXML_HTMLPARSER_H 1
+
+/* Define to 1 if you have the <libxml/nanohttp.h> header file. */
+#define HAVE_LIBXML_NANOHTTP_H 1
+
+/* Define to 1 if you have the <libxml/parser.h> header file. */
+#define HAVE_LIBXML_PARSER_H 1
+
+/* Define to 1 if you have the <libxml/SAX2.h> header file. */
+#define HAVE_LIBXML_SAX2_H 1
+
+/* Define to 1 if you have the <libxslt/xslt.h> header file. */
+#define HAVE_LIBXSLT_XSLT_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <math.h> header file. */
+#define HAVE_MATH_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `qsort_r' function. */
+#undef HAVE_QSORT_R
+
+/* Define to 1 if you have the `qsort_s' function. */
+/* note: MSVC has qsort_s but the sort_r.h code uses advanced features like
+ * "inline" that MSVC 2013 doesn't understand; fortunately there's another
+ * level of fallback... */
+#undef HAVE_QSORT_S
+
+/* Raptor raptor_parse_date available */
+#undef HAVE_RAPTOR_PARSE_DATE
+
+/* Define to 1 if you have the `setjmp' function. */
+#undef HAVE_SETJMP
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#undef HAVE_SETJMP_H
+
+/* Define to 1 if you have the `stat' function. */
+#undef HAVE_STAT
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `stricmp' function. */
+#define HAVE_STRICMP 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strtok_r' function. */
+#undef HAVE_STRTOK_R
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vasprintf' function. */
+#undef HAVE_VASPRINTF
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Flex version as a decimal */
+#define FLEX_VERSION_DECIMAL 20539
+
+/* Define to 1 if you have the `xmlCtxtUseOptions' function. */
+#define HAVE_XMLCTXTUSEOPTIONS 1
+
+/* Define to 1 if you have the `xmlSAX2InternalSubset' function. */
+#define HAVE_XMLSAX2INTERNALSUBSET 1
+
+/* YAJL has API version 2 */
+#undef HAVE_YAJL2
+
+/* Define to 1 if you have the <yajl/yajl_parse.h> header file. */
+#undef HAVE_YAJL_YAJL_PARSE_H
+
+/* Is __FUNCTION__ available */
+#define HAVE___FUNCTION__ 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Define to 1 if maintainer mode is enabled. */
+#undef MAINTAINER_MODE
+
+/* need 'extern int optind' declaration? */
+#undef NEED_OPTIND_DECLARATION
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if debug messages are enabled. */
+#undef RAPTOR_DEBUG
+
+/* Use ICU for Unicode NFC check */
+#undef RAPTOR_ICU_NFC
+
+/* does libxml struct xmlEntity have a field etype */
+#define RAPTOR_LIBXML_ENTITY_ETYPE 1
+
+/* does libxml struct xmlEntity have a field name_length */
+#undef RAPTOR_LIBXML_ENTITY_NAME_LENGTH
+
+/* does libxml have HTML_PARSE_NONET */
+#define RAPTOR_LIBXML_HTML_PARSE_NONET 1
+
+/* does libxml xmlSAXHandler have externalSubset field */
+#define RAPTOR_LIBXML_XMLSAXHANDLER_EXTERNALSUBSET 1
+
+/* does libxml xmlSAXHandler have initialized field */
+#define RAPTOR_LIBXML_XMLSAXHANDLER_INITIALIZED 1
+
+/* does libxml have XML_PARSE_NONET */
+#define RAPTOR_LIBXML_XML_PARSE_NONET 1
+
+/* Minimum supported package version */
+#define RAPTOR_MIN_VERSION_DECIMAL 20000
+
+/* Building GRDDL parser */
+#undef RAPTOR_PARSER_GRDDL
+
+/* Building guess parser */
+#undef RAPTOR_PARSER_GUESS
+
+/* Building JSON parser */
+#undef RAPTOR_PARSER_JSON
+
+/* Building N-Quads parser */
+#undef RAPTOR_PARSER_NQUADS
+
+/* Building N-Triples parser */
+#define RAPTOR_PARSER_NTRIPLES 1
+
+/* Building RDFA parser */
+#undef RAPTOR_PARSER_RDFA
+
+/* Building RDF/XML parser */
+#define RAPTOR_PARSER_RDFXML 1
+
+/* Building RSS Tag Soup parser */
+#undef RAPTOR_PARSER_RSS
+
+/* Building TRiG parser */
+#undef RAPTOR_PARSER_TRIG
+
+/* Building Turtle parser */
+#undef RAPTOR_PARSER_TURTLE
+
+/* Building Atom 1.0 serializer */
+#undef RAPTOR_SERIALIZER_ATOM
+
+/* Building GraphViz DOT serializer */
+#undef RAPTOR_SERIALIZER_DOT
+
+/* Building HTML Table serializer */
+#undef RAPTOR_SERIALIZER_HTML
+
+/* Building JSON serializer */
+#undef RAPTOR_SERIALIZER_JSON
+
+/* Building N-Quads serializer */
+#undef RAPTOR_SERIALIZER_NQUADS
+
+/* Building N-Triples serializer */
+#define RAPTOR_SERIALIZER_NTRIPLES 1
+
+/* Building RDF/XML serializer */
+#define RAPTOR_SERIALIZER_RDFXML 1
+
+/* Building RDF/XML-abbreviated serializer */
+#define RAPTOR_SERIALIZER_RDFXML_ABBREV 1
+
+/* Building RSS 1.0 serializer */
+#undef RAPTOR_SERIALIZER_RSS_1_0
+
+/* Building Turtle serializer */
+#undef RAPTOR_SERIALIZER_TURTLE
+
+/* Release version as a decimal */
+#define RAPTOR_VERSION_DECIMAL 20015
+
+/* Major version number */
+#define RAPTOR_VERSION_MAJOR 2
+
+/* Minor version number */
+#define RAPTOR_VERSION_MINOR 0
+
+/* Release version number */
+#define RAPTOR_VERSION_RELEASE 15
+
+/* Have libcurl WWW library */
+#undef RAPTOR_WWW_LIBCURL
+
+/* Have libfetch WWW library */
+#undef RAPTOR_WWW_LIBFETCH
+
+/* Have libxml available as a WWW library */
+#undef RAPTOR_WWW_LIBXML
+
+/* No WWW library */
+#define RAPTOR_WWW_NONE
+
+/* Check XML 1.1 Names */
+#undef RAPTOR_XML_1_1
+
+/* Use libxml XML parser */
+#define RAPTOR_XML_LIBXML 1
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#define VERSION "2.0.15"
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Enable large inode numbers on macOS 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+// from raptor_config_cmake.h.in ////////////////////////////////////////////
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+# ifndef _CRT_NONSTDC_NO_DEPRECATE
+# define _CRT_NONSTDC_NO_DEPRECATE
+# endif
+# ifndef _CRT_SECURE_NO_DEPRECATE
+# define _CRT_SECURE_NO_DEPRECATE
+# endif
+
+# ifdef _MSC_VER
+# define __func__ __FUNCTION__
+# endif
+
+# define RAPTOR_INLINE __inline
+
+# define S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask))
+# define S_ISDIR(mode) S_ISTYPE((mode), _S_IFDIR)
+# define S_ISREG(mode) S_ISTYPE((mode), _S_IFREG)
+
+ /* Mode bits for access() */
+# define R_OK 04
+# define W_OK 02
+
+# if !defined(HAVE_ACCESS) && defined(HAVE__ACCESS)
+# define access(p,m) _access(p,m)
+# endif
+# ifndef HAVE_STRCASECMP
+# if defined(HAVE__STRICMP)
+# define strcasecmp(a,b) _stricmp(a,b)
+# elif defined(HAVE_STRICMP)
+# define strcasecmp(a,b) stricmp(a,b)
+# endif
+# endif
+# if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)
+# define snprintf _snprintf
+# endif
+# if !defined(HAVE_VSNPRINTF) && defined(HAVE__VSNPRINTF)
+# define vsnprintf _vsnprintf
+# endif
+
+ /* These prevent parsedate.c from declaring malloc() and free() */
+# define YYMALLOC malloc
+# define YYFREE free
+#endif
+
+
diff --git a/external/redland/raptor/rpath.patch b/external/redland/raptor/rpath.patch
new file mode 100644
index 000000000..7863f61cd
--- /dev/null
+++ b/external/redland/raptor/rpath.patch
@@ -0,0 +1,21 @@
+--- configure
++++ configure
+@@ -9892,6 +9892,7 @@
+ else
+ ld_shlibs=no
+ fi
++hardcode_libdir_flag_spec=
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+--- utils/Makefile.in
++++ utils/Makefile.in
+@@ -343,7 +343,7 @@
+ rapper_LDADD = $(top_builddir)/src/libraptor2.la
+ rdfdiff_SOURCES = rdfdiff.c $(am__append_2)
+ rdfdiff_LDADD = $(top_builddir)/src/libraptor2.la
+-all: all-am
++all:
+
+ .SUFFIXES:
+ .SUFFIXES: .c .lo .o .obj
diff --git a/external/redland/raptor/ubsan.patch b/external/redland/raptor/ubsan.patch
new file mode 100644
index 000000000..641d60bb7
--- /dev/null
+++ b/external/redland/raptor/ubsan.patch
@@ -0,0 +1,25 @@
+--- src/raptor_rfc2396.c
++++ src/raptor_rfc2396.c
+@@ -386,7 +386,7 @@
+ }
+
+
+- if(prev && s == (cur+2) && cur[0] == '.' && cur[1] == '.') {
++ if(prev && cur && s == (cur+2) && cur[0] == '.' && cur[1] == '.') {
+ /* Remove <component>/.. at the end of the path */
+ *prev = '\0';
+ path_len -= (s-prev);
+--- src/raptor_uri.c
++++ src/raptor_uri.c
+@@ -1336,9 +1336,9 @@
+ !strncmp((const char*)base_detail->scheme,
+ (const char*)reference_detail->scheme,
+ base_detail->scheme_len) &&
+- !strncmp((const char*)base_detail->authority,
++ (base_detail->authority_len == 0 || !strncmp((const char*)base_detail->authority,
+ (const char*)reference_detail->authority,
+- base_detail->authority_len)) {
++ base_detail->authority_len))) {
+
+ if(!base_detail->path) {
+ if(reference_detail->path) {
diff --git a/external/redland/raptor/xml2-config.patch b/external/redland/raptor/xml2-config.patch
new file mode 100644
index 000000000..2550acee0
--- /dev/null
+++ b/external/redland/raptor/xml2-config.patch
@@ -0,0 +1,22 @@
+--- configure
++++ configure
+@@ -14197,6 +14197,11 @@
+ test -n "$XML_CONFIG" && break
+ done
+
++ if test -n "$XML_CONFIG"; then
++ if ! "$XML_CONFIG" --version; then
++ XML_CONFIG=
++ fi
++ fi
+ fi
+ fi
+
+@@ -14481,6 +14481,7 @@
+
+ LIBXML_VERSION=`$PKG_CONFIG libxml-2.0 --modversion`
+ libxml_source="pkg-config"
++ XML_CONFIG="$PKG_CONFIG libxml-2.0"
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxml via pkg-config" >&5
diff --git a/external/redland/rasqal/clang-cl.patch b/external/redland/rasqal/clang-cl.patch
new file mode 100644
index 000000000..e35a2b4ee
--- /dev/null
+++ b/external/redland/rasqal/clang-cl.patch
@@ -0,0 +1,11 @@
+--- src/rasqal.h
++++ src/rasqal.h
+@@ -99,7 +99,7 @@
+ /* Use gcc 3.1+ feature to allow marking of deprecated API calls.
+ * This gives a warning during compiling.
+ */
+-#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
++#if (defined __GNUC__ && (( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3)) || defined __clang__
+ #define RASQAL_DEPRECATED __attribute__((deprecated))
+ #else
+ #define RASQAL_DEPRECATED
diff --git a/external/redland/rasqal/libtool.patch b/external/redland/rasqal/libtool.patch
new file mode 100644
index 000000000..b0baae661
--- /dev/null
+++ b/external/redland/rasqal/libtool.patch
@@ -0,0 +1,27 @@
+--- build/ltmain.sh
++++ build/ltmain.sh
+@@ -5301,6 +5301,12 @@
+ prev=
+ continue
+ ;;
++ mllvm)
++ # Clang does not use LLVM to link, so we can simply discard any
++ # '-mllvm $arg' options when doing the link step.
++ prev=
++ continue
++ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+@@ -5639,6 +5645,11 @@
+ continue
+ ;;
+
++ -mllvm)
++ prev=mllvm
++ continue
++ ;;
++
+ -module)
+ module=yes
+ continue
diff --git a/external/redland/rasqal/rasqal-aix.patch.1 b/external/redland/rasqal/rasqal-aix.patch.1
new file mode 100644
index 000000000..d755aa2e5
--- /dev/null
+++ b/external/redland/rasqal/rasqal-aix.patch.1
@@ -0,0 +1,25 @@
+--- a/src/rasqal_literal.c 2013-03-29 21:22:57.413852072 +0100
++++ b/src/rasqal_literal.c 2013-03-29 21:23:34.092851757 +0100
+@@ -46,10 +46,22 @@
+ #include <stddef.h>
+ #endif
+ #include <stdarg.h>
++#ifdef _AIX
++# ifndef isnan
++# define isnan(x) \
++ (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
++ : sizeof (x) == sizeof (double) ? isnan_d (x) \
++ : isnan_f (x))
++ static inline int isnan_f (float x) { return x != x; }
++ static inline int isnan_d (double x) { return x != x; }
++ static inline int isnan_ld (long double x) { return x != x; }
++# endif
++#else
+ /* for isnan() */
+ #ifdef HAVE_MATH_H
+ #include <math.h>
+ #endif
++#endif
+ /* for INT_MIN and INT_MAX */
+ #ifdef HAVE_LIMITS_H
+ #include <limits.h>
diff --git a/external/redland/rasqal/rasqal-android.patch.1 b/external/redland/rasqal/rasqal-android.patch.1
new file mode 100644
index 000000000..b14aa5758
--- /dev/null
+++ b/external/redland/rasqal/rasqal-android.patch.1
@@ -0,0 +1,14 @@
+No sonames on Android
+
+--- a/configure 2013-03-29 19:46:34.922901756 +0100
++++ b/configure 2013-03-29 19:46:56.051901574 +0100
+@@ -9809,7 +9809,7 @@
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+
diff --git a/external/redland/rasqal/rasqal-bundled-soname.patch.1 b/external/redland/rasqal/rasqal-bundled-soname.patch.1
new file mode 100644
index 000000000..2c674516d
--- /dev/null
+++ b/external/redland/rasqal/rasqal-bundled-soname.patch.1
@@ -0,0 +1,13 @@
+rhbz#809466 change soname of bundled redland libs
+
+--- a/src/Makefile.in 2013-03-29 21:44:58.115840724 +0100
++++ b/src/Makefile.in 2013-03-29 21:45:01.252840697 +0100
+@@ -621,7 +621,7 @@
+ $(am__append_2) $(am__append_3) $(am__append_4) \
+ $(am__append_5) $(am__append_6) $(am__append_7)
+ nodist_librasqal_la_SOURCES = $(am__append_8)
+-librasqal_la_LDFLAGS = -version-info @RASQAL_LIBTOOL_VERSION@
++librasqal_la_LDFLAGS = -version-info @RASQAL_LIBTOOL_VERSION@ -release lo
+ librasqal_la_LIBADD = @LTLIBOBJS@ @RASQAL_INTERNAL_LIBS@ \
+ @RASQAL_EXTERNAL_LIBS@ $(MEM_LIBS) \
+ $(top_builddir)/libsv/libsv.la $(am__append_10)
diff --git a/external/redland/rasqal/rasqal-freebsd.patch.1 b/external/redland/rasqal/rasqal-freebsd.patch.1
new file mode 100644
index 000000000..349f3a197
--- /dev/null
+++ b/external/redland/rasqal/rasqal-freebsd.patch.1
@@ -0,0 +1,28 @@
+Usual patch to produce Linux-like .so files on FreeBSD
+
+--- a/build/ltmain.sh 2008-02-02 22:28:24.000000000 +0900
++++ b/build/ltmain.sh 2008-07-08 11:58:42.000000000 +0900
+@@ -7341,9 +7341,9 @@
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+- current="$number_major"
+- revision="$number_minor"
+- age="0"
++ current=`expr $number_major + $number_minor`
++ age="$number_minor"
++ revision="$number_revision"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+@@ -7420,8 +7420,8 @@
+ ;;
+
+ freebsd-elf)
+- major=".$current"
+- versuffix=".$current"
++ major=.`expr $current - $age`
++ versuffix="$major.$age.$revision"
+ ;;
+
+ irix | nonstopux)
diff --git a/external/redland/rasqal/rasqal-msvc.patch.1 b/external/redland/rasqal/rasqal-msvc.patch.1
new file mode 100644
index 000000000..f32f6720b
--- /dev/null
+++ b/external/redland/rasqal/rasqal-msvc.patch.1
@@ -0,0 +1,64 @@
+diff -ru rasqal.orig/src/win32_rasqal_config.h rasqal/src/win32_rasqal_config.h
+--- rasqal.orig/src/win32_rasqal_config.h 2015-09-02 23:12:00.733125322 +0200
++++ rasqal/src/win32_rasqal_config.h 2015-09-02 23:28:10.152190403 +0200
+@@ -31,7 +31,6 @@
+ /* MS names for these functions */
+ // next line breaks build on wntmsci12
+ //#define vsnprintf _vsnprintf
+-#define snprintf _snprintf
+ #define access _access
+ #define stricmp _stricmp
+ #define strnicmp _strnicmp
+@@ -42,10 +43,10 @@
+ int rasqal_gettimeofday(struct timeval *tv, struct timezone *tz);
+ #undef HAVE_GETTIMEOFDAY
+
+-#include <float.h>
+-#define isnan(n) _isnan(n)
+-/* no round function available */
+-#define round(x) floor(x+0.5)
++// #include <float.h>
++// #define isnan(n) _isnan(n)
++// /* no round function available */
++// #define round(x) floor(x+0.5)
+
+ /* These are SPARQL token definitions */
+ #ifdef OPTIONAL
+--- rasqal/src/rasqal_ntriples.c.orig 2016-08-26 23:29:58.343472683 +0200
++++ rasqal/src/rasqal_ntriples.c 2016-08-26 23:30:10.553471736 +0200
+@@ -25,6 +25,10 @@
+ #include <rasqal_config.h>
+ #endif
+
++#ifdef _WIN32
++#include <win32_rasqal_config.h>
++#endif
++
+ #include <stdio.h>
+ #include <string.h>
+ #include <ctype.h>
+--- rasqal/src/sv_config.h.orig 2016-08-26 23:29:42.408473919 +0200
++++ rasqal/src/sv_config.h 2016-08-26 23:29:44.760473737 +0200
+@@ -29,7 +29,11 @@
+ extern "C" {
+ #endif
+
++#ifdef _WIN32
++#include <win32_rasqal_config.h>
++#else
+ #include <rasqal_config.h>
++#endif
+
+ #define sv_new rasqal_sv_new
+ #define sv_free rasqal_sv_free
+--- rasqal/src/rasqal.h.in.orig 2016-08-26 23:42:23.198414915 +0200
++++ rasqal/src/rasqal.h.in 2016-08-26 23:42:34.627414028 +0200
+@@ -1473,7 +1473,7 @@
+
+ RASQAL_API
+ int rasqal_query_results_formats_check2(rasqal_world* world, const char *name, raptor_uri* uri, const char *mime_type, int flags);
+-RASQAL_API RASQAL_API RASQAL_DEPRECATED
++RASQAL_API RASQAL_DEPRECATED
+ int rasqal_query_results_formats_check(rasqal_world* world, const char *name, raptor_uri* uri, const char *mime_type, int flags);
+ RASQAL_API
+ rasqal_query_results_formatter* rasqal_new_query_results_formatter(rasqal_world* world, const char *name, const char *mime_type, raptor_uri* format_uri);
diff --git a/external/redland/rasqal/rasqal-pkgconfig.patch.1 b/external/redland/rasqal/rasqal-pkgconfig.patch.1
new file mode 100644
index 000000000..ac3eab07c
--- /dev/null
+++ b/external/redland/rasqal/rasqal-pkgconfig.patch.1
@@ -0,0 +1,14 @@
+Let the pkg-config stuff be overridden by variables
+
+--- a/configure
++++ b/configure
+@@ -14119,7 +14119,7 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ $as_echo "yes" >&6; }
+
+- RAPTOR_VERSION=`$PKG_CONFIG raptor2 --modversion 2>/dev/null`
++ RAPTOR_VERSION=2.0.15
+ raptor_too_old=0
+ as_arg_v1=$RAPTOR_VERSION
+ as_arg_v2=$RAPTOR_MIN_VERSION
+
diff --git a/external/redland/rasqal/rasqal-xcompile.patch.1 b/external/redland/rasqal/rasqal-xcompile.patch.1
new file mode 100644
index 000000000..65efc3047
--- /dev/null
+++ b/external/redland/rasqal/rasqal-xcompile.patch.1
@@ -0,0 +1,16 @@
+No point in creating util or test executables when cross-compiling.
+(Especially as doing it anyway wouldn't work without tweaks to have it find
+libxml2 and libm, at least for Android.)
+
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -358,7 +358,7 @@
+ top_srcdir = @top_srcdir@
+ noinst_SCRIPTS = rasqal-src-config
+ ACLOCAL_AMFLAGS = -I build
+-SUBDIRS = libsv $(am__append_1) $(am__append_2) src utils tests docs \
++SUBDIRS = libsv $(am__append_1) $(am__append_2) src docs \
+ data win32 scripts
+ DIST_SUBDIRS = libsv libmtwist getopt src utils tests docs data win32 scripts
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = rasqal.pc
diff --git a/external/redland/rasqal/rasqal.h b/external/redland/rasqal/rasqal.h
new file mode 100644
index 000000000..cd5d64604
--- /dev/null
+++ b/external/redland/rasqal/rasqal.h
@@ -0,0 +1,2259 @@
+/* -*- Mode: c; c-basic-offset: 2 -*-
+ *
+ * rasqal.h - Rasqal RDF Query library interfaces and definition
+ *
+ * Copyright (C) 2003-2010, David Beckett http://www.dajobe.org/
+ * Copyright (C) 2003-2005, University of Bristol, UK http://www.bristol.ac.uk/
+ *
+ * This package is Free Software and part of Redland http://librdf.org/
+ *
+ * It is licensed under the following three licenses as alternatives:
+ * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
+ * 2. GNU General Public License (GPL) V2 or any newer version
+ * 3. Apache License, V2.0 or any newer version
+ *
+ * You may not use this file except in compliance with at least one of
+ * the above three licenses.
+ *
+ * See LICENSE.html or LICENSE.txt at the top of this package for the
+ * complete terms and further detail along with the license texts for
+ * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
+ *
+ */
+
+
+
+#ifndef RASQAL_H
+#define RASQAL_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * RASQAL_VERSION:
+ *
+ * Rasqal library version number
+ *
+ * Format: major * 10000 + minor * 100 + release
+ */
+#define RASQAL_VERSION 933
+
+/**
+ * RASQAL_VERSION_STRING:
+ *
+ * Rasqal library version string
+ */
+#define RASQAL_VERSION_STRING "0.9.33"
+
+/**
+ * RASQAL_VERSION_MAJOR:
+ *
+ * Rasqal library major version
+ */
+#define RASQAL_VERSION_MAJOR 0
+
+/**
+ * RASQAL_VERSION_MINOR:
+ *
+ * Rasqal library minor version
+ */
+#define RASQAL_VERSION_MINOR 9
+
+/**
+ * RASQAL_VERSION_RELEASE:
+ *
+ * Rasqal library release
+ */
+#define RASQAL_VERSION_RELEASE 33
+
+
+/**
+ * RASQAL_API:
+ *
+ * Macro for wrapping API function call declarations.
+ *
+ */
+#ifndef RASQAL_API
+# ifdef _WIN32
+# ifdef __GNUC__
+# undef _declspec
+# define _declspec(x) __declspec(x)
+# endif
+# ifdef RASQAL_STATIC
+# define RASQAL_API
+# else
+# ifdef RASQAL_INTERNAL
+# define RASQAL_API _declspec(dllexport)
+# else
+# define RASQAL_API _declspec(dllimport)
+# endif
+# endif
+# else
+# define RASQAL_API
+# endif
+#endif
+
+/* Use gcc 3.1+ feature to allow marking of deprecated API calls.
+ * This gives a warning during compiling.
+ */
+#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
+#define RASQAL_DEPRECATED __attribute__((deprecated))
+#else
+#define RASQAL_DEPRECATED
+#endif
+
+
+#ifndef LIBRDF_OBJC_FRAMEWORK
+#include <raptor.h>
+#else
+#include <Redland/raptor.h>
+#endif
+
+#if 0
+#include <sys/time.h>
+#endif
+#if 1
+#include <time.h>
+#endif
+
+/* Public statics */
+
+/**
+ * rasqal_short_copyright_string:
+ *
+ * Short copyright string (one line).
+ */
+RASQAL_API
+extern const char * const rasqal_short_copyright_string;
+
+/**
+ * rasqal_copyright_string:
+ *
+ * Copyright string (multiple lines).
+ */
+RASQAL_API
+extern const char * const rasqal_copyright_string;
+
+/**
+ * rasqal_version_string:
+ *
+ * Rasqal version as a string.
+ */
+RASQAL_API
+extern const char * const rasqal_version_string;
+
+/**
+ * rasqal_version_major:
+ *
+ * Rasqal major version number.
+ */
+RASQAL_API
+extern const unsigned int rasqal_version_major;
+
+/**
+ * rasqal_version_minor:
+ *
+ * Rasqal minor version number.
+ */
+RASQAL_API
+extern const unsigned int rasqal_version_minor;
+
+/**
+ * rasqal_version_release:
+ *
+ * Rasqal release version number.
+ */
+RASQAL_API
+extern const unsigned int rasqal_version_release;
+
+/**
+ * rasqal_version_decimal:
+ *
+ * Rasqal version as a decimal number.
+ *
+ * Format: major * 10000 + minor * 100 + release
+ */
+RASQAL_API
+extern const unsigned int rasqal_version_decimal;
+
+/**
+ * rasqal_license_string:
+ *
+ * Rasqal license string.
+ */
+RASQAL_API
+extern const char * const rasqal_license_string;
+
+/**
+ * rasqal_home_url_string:
+ *
+ * Rasqal home page URL.
+ */
+RASQAL_API
+extern const char * const rasqal_home_url_string;
+
+
+
+/**
+ * RASQAL_RAPTOR_VERSION:
+ *
+ * Version of Raptor that Rasqal was configured against.
+ */
+#define RASQAL_RAPTOR_VERSION 20015
+
+
+/* Public structures */
+
+#ifndef RASQAL_WORLD_DECLARED
+#define RASQAL_WORLD_DECLARED 1
+/**
+ * rasqal_world:
+ *
+ * Rasqal world class.
+ */
+typedef struct rasqal_world_s rasqal_world;
+#endif
+
+/**
+ * rasqal_query:
+ *
+ * Rasqal query class.
+ */
+typedef struct rasqal_query_s rasqal_query;
+
+/**
+ * rasqal_query_results:
+ *
+ * Rasqal query results class.
+ */
+typedef struct rasqal_query_results_s rasqal_query_results;
+
+
+#ifndef RASQAL_QUERY_RESULTS_FORMATTER_DECLARED
+#define RASQAL_QUERY_RESULTS_FORMATTER_DECLARED 1
+/**
+ * rasqal_query_results_formatter:
+ *
+ * Rasqal query results formatter class.
+ */
+typedef struct rasqal_query_results_formatter_s rasqal_query_results_formatter;
+#endif
+
+
+typedef struct rasqal_literal_s rasqal_literal;
+
+/**
+ * rasqal_graph_pattern:
+ *
+ * Rasqal graph pattern class.
+ */
+typedef struct rasqal_graph_pattern_s rasqal_graph_pattern;
+
+
+/**
+ * rasqal_variables_table:
+ *
+ * Rasqal variables table class.
+ */
+typedef struct rasqal_variables_table_s rasqal_variables_table;
+
+
+/**
+ * rasqal_feature:
+ * @RASQAL_FEATURE_NO_NET: Deny network requests.
+ * @RASQAL_FEATURE_RAND_SEED: Set rand() / rand_r() seed
+ * @RASQAL_FEATURE_LAST: Internal.
+ *
+ * Query features.
+ *
+ * None currently defined.
+ */
+typedef enum {
+ RASQAL_FEATURE_NO_NET,
+ RASQAL_FEATURE_RAND_SEED,
+ RASQAL_FEATURE_LAST = RASQAL_FEATURE_RAND_SEED
+} rasqal_feature;
+
+
+/**
+ * rasqal_prefix:
+ * @world: rasqal_world object
+ * @prefix: short prefix string
+ * @uri: URI associated with the prefix.
+ * @declared: Internal flag.
+ * @depth: Internal flag.
+ *
+ * Namespace (prefix, uri) pair.
+ *
+ * Includes internal flags used for marking when prefixes are
+ * declared and at what XML element depth when used in XML formats.
+ */
+typedef struct {
+ rasqal_world* world;
+ const unsigned char *prefix;
+ raptor_uri* uri;
+ int declared;
+ int depth;
+} rasqal_prefix;
+
+
+/**
+ * rasqal_variable_type:
+ * @RASQAL_VARIABLE_TYPE_NORMAL: The regular variable type.
+ * @RASQAL_VARIABLE_TYPE_ANONYMOUS: Anonymous variable type.
+ * @RASQAL_VARIABLE_TYPE_UNKNOWN: Internal.
+ *
+ * Rasqal variable types.
+ *
+ * ANONYMOUS can be used in queries but cannot be returned in a
+ * result.
+ */
+typedef enum {
+ RASQAL_VARIABLE_TYPE_UNKNOWN = 0,
+ RASQAL_VARIABLE_TYPE_NORMAL = 1,
+ RASQAL_VARIABLE_TYPE_ANONYMOUS = 2
+} rasqal_variable_type;
+
+
+/* forward reference */
+struct rasqal_expression_s;
+
+/**
+ * rasqal_variable:
+ * @vars_table: variables table that owns this variable
+ * @name: Variable name.
+ * @value: Variable value or NULL if unbound.
+ * @offset: Internal.
+ * @type: Variable type.
+ * @expression: Expression when the variable is a computed SELECT expression
+ * @user_data: Pointer to user data associated with a variable. This is not used by rasqal.
+ * @usage: reference count
+ *
+ * Binding between a variable name and a value.
+ *
+ * Includes internal field @offset for recording the offset into the
+ * (internal) rasqal_query variables array.
+ */
+typedef struct {
+ rasqal_variables_table* vars_table;
+ const unsigned char *name;
+ rasqal_literal* value;
+ int offset;
+ rasqal_variable_type type;
+ struct rasqal_expression_s* expression;
+ void *user_data;
+ int usage;
+} rasqal_variable;
+
+
+/**
+ * rasqal_data_graph_flags:
+ * @RASQAL_DATA_GRAPH_NONE: Internal.
+ * @RASQAL_DATA_GRAPH_NAMED: Graphs with a source and name.
+ * @RASQAL_DATA_GRAPH_BACKGROUND: Graphs with a source only.
+ *
+ * Flags for the type of #rasqal_data_graph.
+ *
+ * These are used by rasqal_new_data_graph_from_uri() and
+ * rasqal_new_data_graph_from_iostream(). See #rasqal_data_graph.
+ */
+typedef enum {
+ RASQAL_DATA_GRAPH_NONE = 0,
+ RASQAL_DATA_GRAPH_NAMED = 1,
+ RASQAL_DATA_GRAPH_BACKGROUND = 2
+} rasqal_data_graph_flags;
+
+
+/**
+ * rasqal_data_graph:
+ * @world: rasqal_world object
+ * @uri: source URI
+ * @name_uri: name of graph for %RASQAL_DATA_GRAPH_NAMED
+ * @flags: %RASQAL_DATA_GRAPH_NAMED or %RASQAL_DATA_GRAPH_BACKGROUND
+ * @format_type: MIME Type of data format at @uri (or NULL)
+ * @format_name: Raptor parser Name of data format at @uri (or NULL)
+ * @format_uri: URI of data format at @uri (or NULL)
+ * @iostr: Raptor iostream for content, overriding @uri if present (or NULL)
+ * @base_uri: base URI for reading from iostream
+ * @usage: usage count of this object
+ *
+ * A source of RDF data for querying.
+ *
+ * If @iostr is present, the graph can be constructed by parsing the
+ * iostream and using @base_uri as a base uri. Otherwise the graph
+ * can be constructed from the graph at URI @uri.
+ *
+ * In either case the @name_uri is the graph name as long as @flags
+ * is %RASQAL_DATA_GRAPH_NAMED
+ */
+typedef struct {
+ rasqal_world* world;
+ raptor_uri* uri;
+ raptor_uri* name_uri;
+ unsigned int flags;
+ char* format_type;
+ char* format_name;
+ raptor_uri* format_uri;
+ raptor_iostream* iostr;
+ raptor_uri* base_uri;
+ int usage;
+} rasqal_data_graph;
+
+
+/**
+ * rasqal_literal_type:
+ * @RASQAL_LITERAL_BLANK: RDF blank node literal (SPARQL r:bNode)
+ * @RASQAL_LITERAL_URI: RDF URI Literal (SPARQL r:URI)
+ * @RASQAL_LITERAL_STRING: RDF Plain Literal - no datatype (SPARQL r:Literal)
+ * @RASQAL_LITERAL_XSD_STRING: String xsd:string
+ * @RASQAL_LITERAL_BOOLEAN: Boolean literal xsd:boolean.
+ * @RASQAL_LITERAL_INTEGER: Integer literal xsd:integer.
+ * @RASQAL_LITERAL_DOUBLE: Double floating point literal xsd:double.
+ * @RASQAL_LITERAL_FLOAT: Floating point literal xsd:float.
+ * @RASQAL_LITERAL_DECIMAL: Decimal integer xsd:decimal.
+ * @RASQAL_LITERAL_DATETIME: Date/Time literal xsd:dateTime.
+ * @RASQAL_LITERAL_UDT: User defined typed literal with unknown datatype URI
+ * @RASQAL_LITERAL_PATTERN: Pattern literal for a regex.
+ * @RASQAL_LITERAL_QNAME: XML Qname literal.
+ * @RASQAL_LITERAL_VARIABLE: Variable literal.
+ * @RASQAL_LITERAL_DATE: Date literal xsd:date.
+ * @RASQAL_LITERAL_INTEGER_SUBTYPE: Internal.
+ * @RASQAL_LITERAL_UNKNOWN: Internal.
+ * @RASQAL_LITERAL_FIRST_XSD: Internal.
+ * @RASQAL_LITERAL_LAST_XSD: Internal.
+ * @RASQAL_LITERAL_LAST: Internal.
+ *
+ * Types of literal.
+ *
+ * The order in the enumeration is significant as it encodes
+ * the SPARQL term ordering conditions:
+ *
+ * Blank Nodes << IRIs << RDF literals << typed literals
+ *
+ * which coresponds to in enum values
+ *
+ * BLANK << URI << STRING <<
+ * (BOOLEAN | INTEGER | DOUBLE | FLOAT | DECIMAL | DATETIME | XSD_STRING)
+ *
+ * (RASQAL_LITERAL_FIRST_XSD ... RASQAL_LITERAL_LAST_XSD)
+ *
+ * Not used (internal): PATTERN, QNAME, VARIABLE
+ *
+ * See rasqal_literal_compare() when used with flags
+ * %RASQAL_COMPARE_XQUERY
+ */
+typedef enum {
+ /* internal */
+ RASQAL_LITERAL_UNKNOWN,
+ RASQAL_LITERAL_BLANK,
+ RASQAL_LITERAL_URI,
+ RASQAL_LITERAL_STRING,
+ RASQAL_LITERAL_XSD_STRING,
+ RASQAL_LITERAL_BOOLEAN,
+ RASQAL_LITERAL_INTEGER,
+ RASQAL_LITERAL_FLOAT,
+ RASQAL_LITERAL_DOUBLE,
+ RASQAL_LITERAL_DECIMAL,
+ RASQAL_LITERAL_DATETIME,
+ /* internal */
+ RASQAL_LITERAL_FIRST_XSD = RASQAL_LITERAL_XSD_STRING,
+ /* internal */
+ RASQAL_LITERAL_LAST_XSD = RASQAL_LITERAL_DATETIME,
+ RASQAL_LITERAL_UDT,
+ RASQAL_LITERAL_PATTERN,
+ RASQAL_LITERAL_QNAME,
+ RASQAL_LITERAL_VARIABLE,
+ /* internal */
+ RASQAL_LITERAL_INTEGER_SUBTYPE,
+ RASQAL_LITERAL_DATE,
+ /* internal */
+ RASQAL_LITERAL_LAST = RASQAL_LITERAL_DATE
+} rasqal_literal_type;
+
+#define RASQAL_LITERAL_UDT_DEFINED 1
+
+
+/**
+ * rasqal_row:
+ *
+ * Rasqal Result Row class.
+ */
+typedef struct rasqal_row_s rasqal_row;
+
+
+/**
+ * rasqal_xsd_decimal:
+ *
+ * Rasqal XSD Decimal class.
+ */
+typedef struct rasqal_xsd_decimal_s rasqal_xsd_decimal;
+
+
+/**
+ * RASQAL_XSD_DATETIME_NO_TZ:
+ *
+ * Sentinel XSD Decimal timezone value indicating no timezone is present.
+ */
+#define RASQAL_XSD_DATETIME_NO_TZ (9999)
+
+/**
+ * rasqal_xsd_date:
+ * @year: year
+ * @month: month 1-12
+ * @day: 1-31
+ * @timezone_minutes: minutes +/- against UTC or RASQAL_XSD_DATETIME_NO_TZ if there is no timezone in the dateTime.
+ * @time_on_timeline: time on timeline of first instant of date in timezone
+ * @have_tz: timezone flag: 'Z' if Zulu, 'Y' if has other timezone offset in @timezone_minutes, 'N' if there is no timezone
+ *
+ * XML schema date datatype (xsd:date)
+ *
+ * Examples of timezone fields:
+ * "2010-01-02" : timezone_minutes RASQAL_XSD_DATETIME_NO_TZ, have_tz 'N'
+ * "2010-01-02Z" : timezone_minutes 0, have_tz 'Z'
+ * "2010-01-02+00:00" : timezone_minutes 0, have_tz 'Y'
+ * "2010-01-02-01:00" : timezone_minutes -60, have_tz 'Y'
+ */
+typedef struct {
+ signed int year;
+ /* the following fields are integer values not characters */
+ unsigned char month;
+ unsigned char day;
+ signed short timezone_minutes;
+ time_t time_on_timeline;
+ char have_tz;
+} rasqal_xsd_date;
+
+
+/**
+ * rasqal_xsd_datetime:
+ * @year: year
+ * @month: month 1-12
+ * @day: 1-31
+ * @hour: hour 0-23
+ * @minute: minute 0-59
+ * @second: second 0-60 (yes 60 is allowed for leap seconds)
+ * @microseconds: microseconds
+ * @timezone_minutes: minutes +/- against UTC or RASQAL_XSD_DATETIME_NO_TZ if there is no timezone in the dateTime.
+ * @time_on_timeline: time on timeline
+ * @have_tz: timezone flag: 'Z' if Zulu, 'Y' if has other timezone offset in @timezone_minutes, 'N' if there is no timezone
+ *
+ * XML Schema dateTime datatype (xsd:dateTime)
+ *
+ * Signed types are required for normalization process where a value
+ * can be negative temporarily.
+ *
+ * Examples of timezone fields:
+ * "2010-01-02T01:02:03" : timezone_minutes RASQAL_XSD_DATETIME_NO_TZ, have_tz 'N'
+ * "2010-01-02T01:02:03Z" : timezone_minutes 0, have_tz 'Z'
+ * "2010-01-02T01:02:03+00:00" : timezone_minutes 0, have_tz 'Y'
+ * "2010-01-02T01:02:03-01:00" : timezone_minutes -60, have_tz 'Y'
+ */
+typedef struct {
+ signed int year;
+ unsigned char month;
+ unsigned char day;
+ /* the following fields are integer values not characters */
+ signed char hour;
+ signed char minute;
+ signed char second;
+ signed int microseconds;
+ signed short timezone_minutes;
+ time_t time_on_timeline;
+ char have_tz;
+} rasqal_xsd_datetime;
+
+
+/**
+ * rasqal_literal:
+ * @world: world object pointer
+ * @usage: Usage count.
+ * @type: Type of literal.
+ * @string: String form of literal for literal types UTF-8 string, pattern, qname, blank, double, float, decimal, datetime.
+ * @string_len: Length of @string.
+ * @value: Alternate value content.
+ * @language: Language for string literal type.
+ * @datatype: Datatype for string literal type.
+ * @flags: Flags for literal types
+ * @parent_type: parent XSD type if any or RASQAL_LITERAL_UNKNOWN
+ * @valid: >0 if literal format is a valid lexical form for this datatype. 0 if not valid. <0 if this has not been checked yet
+ *
+ * Rasqal literal class.
+ *
+ */
+struct rasqal_literal_s {
+ rasqal_world *world;
+
+ int usage;
+
+ rasqal_literal_type type;
+
+ /* UTF-8 string, pattern, qname, blank, double, float, decimal, datetime */
+ const unsigned char *string;
+ unsigned int string_len;
+
+ union {
+ /* integer and boolean types */
+ int integer;
+ /* double and float */
+ double floating;
+ /* uri (can be temporarily NULL if a qname, see flags below) */
+ raptor_uri* uri;
+ /* variable */
+ rasqal_variable* variable;
+ /* decimal */
+ rasqal_xsd_decimal* decimal;
+ /* datetime */
+ rasqal_xsd_datetime* datetime;
+ /* date */
+ rasqal_xsd_date* date;
+ } value;
+
+ /* for string */
+ char *language;
+ raptor_uri *datatype;
+
+ /* various flags for literal types:
+ * pattern regex flags
+ * string datatype of qname
+ * uri qname of URI not yet expanded (temporary)
+ */
+ const unsigned char *flags;
+
+ rasqal_literal_type parent_type;
+
+ int valid;
+};
+
+
+/**
+ * rasqal_op:
+ * @RASQAL_EXPR_AND: Expression for AND(A, B)
+ * @RASQAL_EXPR_OR: Expression for OR(A, B)
+ * @RASQAL_EXPR_EQ: Expression for A equals B
+ * @RASQAL_EXPR_NEQ: Expression for A not equals B.
+ * @RASQAL_EXPR_LT: Expression for A less than B.
+ * @RASQAL_EXPR_GT: Expression for A greather than B.
+ * @RASQAL_EXPR_LE: Expression for A less than or equal to B.
+ * @RASQAL_EXPR_GE: Expression for A greater than or equal to B.
+ * @RASQAL_EXPR_UMINUS: Expression for -A.
+ * @RASQAL_EXPR_PLUS: Expression for +A.
+ * @RASQAL_EXPR_MINUS: Expression for A-B.
+ * @RASQAL_EXPR_STAR: Expression for A*B.
+ * @RASQAL_EXPR_SLASH: Expression for A/B.
+ * @RASQAL_EXPR_REM: Expression for A/B remainder.
+ * @RASQAL_EXPR_STR_EQ: Expression for A string equals B.
+ * @RASQAL_EXPR_STR_NEQ: Expression for A string not-equals B.
+ * @RASQAL_EXPR_STR_MATCH: Expression for string A matches literal regex B with flags.
+ * @RASQAL_EXPR_STR_NMATCH: Expression for string A not-matches literal regex B with flags.
+ * @RASQAL_EXPR_REGEX: Expression for string A matches expression regex B with flags.
+ * @RASQAL_EXPR_TILDE: Expression for binary not A.
+ * @RASQAL_EXPR_BANG: Expression for logical not A.
+ * @RASQAL_EXPR_LITERAL: Expression for a #rasqal_literal.
+ * @RASQAL_EXPR_FUNCTION: Expression for a function A with arguments (B...).
+ * @RASQAL_EXPR_BOUND: Expression for SPARQL ISBOUND(A).
+ * @RASQAL_EXPR_STR: Expression for SPARQL STR(A).
+ * @RASQAL_EXPR_LANG: Expression for SPARQL LANG(A).
+ * @RASQAL_EXPR_LANGMATCHES: Expression for SPARQL LANGMATCHES(A, B).
+ * @RASQAL_EXPR_DATATYPE: Expression for SPARQL DATATYPE(A).
+ * @RASQAL_EXPR_ISURI: Expression for SPARQL ISURI(A).
+ * @RASQAL_EXPR_ISBLANK: Expression for SPARQL ISBLANK(A).
+ * @RASQAL_EXPR_ISLITERAL: Expression for SPARQL ISLITERAL(A).
+ * @RASQAL_EXPR_CAST: Expression for cast literal A to type B.
+ * @RASQAL_EXPR_ORDER_COND_ASC: Expression for SPARQL order condition ascending.
+ * @RASQAL_EXPR_ORDER_COND_DESC: Expression for SPARQL order condition descending.
+ * @RASQAL_EXPR_GROUP_COND_ASC: Obsolete - not used
+ * @RASQAL_EXPR_GROUP_COND_DESC: Obsolete - not used
+ * @RASQAL_EXPR_COUNT: Expression for LAQRS select COUNT() aggregate function
+ * @RASQAL_EXPR_VARSTAR: Expression for LAQRS select Variable *
+ * @RASQAL_EXPR_SAMETERM: Expression for SPARQL sameTerm
+ * @RASQAL_EXPR_SUM: Expression for LAQRS select SUM() aggregate function
+ * @RASQAL_EXPR_AVG: Expression for LAQRS select AVG() aggregate function
+ * @RASQAL_EXPR_MIN: Expression for LAQRS select MIN() aggregate function
+ * @RASQAL_EXPR_MAX: Expression for LAQRS select MAX() aggregate function
+ * @RASQAL_EXPR_COALESCE: Expression for LAQRS COALESCE(Expr+)
+ * @RASQAL_EXPR_IF: Expression for LAQRS IF(expr, expr, expr)
+ * @RASQAL_EXPR_URI: Expression for LAQRS URI(expr)
+ * @RASQAL_EXPR_IRI: Expression for LAQRS IRI(expr)
+ * @RASQAL_EXPR_STRLANG: Expression for LAQRS STRLANG(expr, expr)
+ * @RASQAL_EXPR_STRDT: Expression for LAQRS STRDT(expr, expr)
+ * @RASQAL_EXPR_BNODE: Expression for LAQRS BNODE() and BNODE(expr)
+ * @RASQAL_EXPR_GROUP_CONCAT: Expression for LAQRS GROUP_CONCAT(arglist) aggregate function
+ * @RASQAL_EXPR_SAMPLE: Expression for LAQRS SAMPLE(expr) aggregate function
+ * @RASQAL_EXPR_IN: Expression for LAQRS expr IN ( list of expr )
+ * @RASQAL_EXPR_NOT_IN: Expression for LAQRS expr NOT IN ( list of expr )
+ * @RASQAL_EXPR_ISNUMERIC: Expression for SPARQL 1.1 isNUMERIC(expr)
+ * @RASQAL_EXPR_YEAR: Expression for SPARQL 1.1 YEAR(datetime)
+ * @RASQAL_EXPR_MONTH: Expression for SPARQL 1.1 MONTH(datetime)
+ * @RASQAL_EXPR_DAY: Expression for SPARQL 1.1 DAY(datetime)
+ * @RASQAL_EXPR_HOURS: Expression for SPARQL 1.1 HOURS(datetime)
+ * @RASQAL_EXPR_MINUTES: Expression for SPARQL 1.1 MINUTES(datetime)
+ * @RASQAL_EXPR_SECONDS: Expression for SPARQL 1.1 SECONDS(datetime)
+ * @RASQAL_EXPR_TIMEZONE: Expression for SPARQL 1.1 TIMEZONE(datetime)
+ * @RASQAL_EXPR_CURRENT_DATETIME: Expression for LAQRS CURRENT_DATETIME( void )
+ * @RASQAL_EXPR_NOW: Expression for LAQRS NOW( void )
+ * @RASQAL_EXPR_FROM_UNIXTIME: Expression for LAQRS FROM_UNIXTIME(int)
+ * @RASQAL_EXPR_TO_UNIXTIME: Expression for LAQRS TO_UNIXTIME(datetime)
+ * @RASQAL_EXPR_CONCAT: Expression for SPARQL 1.1 CONCAT(strings)
+ * @RASQAL_EXPR_STRLEN: Expression for SPARQL 1.1 STRLEN(str)
+ * @RASQAL_EXPR_SUBSTR: Expression for SPARQL 1.1 SUBSTR(str, start[,offset])
+ * @RASQAL_EXPR_UCASE: Expression for SPARQL 1.1 UCASE(str)
+ * @RASQAL_EXPR_LCASE: Expression for SPARQL 1.1 LCASE(str)
+ * @RASQAL_EXPR_STRSTARTS: Expression for SPARQL 1.1 STRSTARTS(str, str)
+ * @RASQAL_EXPR_STRENDS: Expression for SPARQL 1.1 STRENDS(str, str)
+ * @RASQAL_EXPR_CONTAINS: Expression for SPARQL 1.1 CONTAINS(str, str)
+ * @RASQAL_EXPR_ENCODE_FOR_URI: Expression for SPARQL 1.1 ENCODE_FOR_URI(str)
+ * @RASQAL_EXPR_TZ: Expression for SPARQL 1.1 TZ()
+ * @RASQAL_EXPR_RAND: Expression for SPARQL 1.1 RAND()
+ * @RASQAL_EXPR_ABS: Expression for SPARQL 1.1 ABS()
+ * @RASQAL_EXPR_ROUND: Expression for SPARQL 1.1 ROUND()
+ * @RASQAL_EXPR_CEIL: Expression for SPARQL 1.1 CEIL()
+ * @RASQAL_EXPR_FLOOR: Expression for SPARQL 1.1 FLOOR()
+ * @RASQAL_EXPR_MD5: Expression for SPARQL 1.1 MD5()
+ * @RASQAL_EXPR_SHA1: Expression for SPARQL 1.1 SHA1()
+ * @RASQAL_EXPR_SHA224: Expression for SPARQL 1.1 SHA224()
+ * @RASQAL_EXPR_SHA256: Expression for SPARQL 1.1 SHA256()
+ * @RASQAL_EXPR_SHA384: Expression for SPARQL 1.1 SHA384()
+ * @RASQAL_EXPR_SHA512: Expression for SPARQL 1.1 SHA512()
+ * @RASQAL_EXPR_STRBEFORE: Expression for SPARQL 1.1 STRBEFORE()
+ * @RASQAL_EXPR_STRAFTER: Expression for SPARQL 1.1 STRAFTER()
+ * @RASQAL_EXPR_REPLACE: Expression for SPARQL 1.1 REPLACE()
+ * @RASQAL_EXPR_UUID: Expression for SPARQL 1.1 UUID()
+ * @RASQAL_EXPR_STRUUID: Expression for SPARQL 1.1 STRUUID()
+ * @RASQAL_EXPR_UNKNOWN: Internal
+ * @RASQAL_EXPR_LAST: Internal
+ *
+ * Rasqal expression operators. A mixture of unary, binary and
+ * tertiary operators (string matches). Also includes casting and
+ * two ordering operators from ORDER BY in SPARQL.
+ */
+typedef enum {
+ /* internal */
+ RASQAL_EXPR_UNKNOWN,
+ RASQAL_EXPR_AND,
+ RASQAL_EXPR_OR,
+ RASQAL_EXPR_EQ,
+ RASQAL_EXPR_NEQ,
+ RASQAL_EXPR_LT,
+ RASQAL_EXPR_GT,
+ RASQAL_EXPR_LE,
+ RASQAL_EXPR_GE,
+ RASQAL_EXPR_UMINUS,
+ RASQAL_EXPR_PLUS,
+ RASQAL_EXPR_MINUS,
+ RASQAL_EXPR_STAR,
+ RASQAL_EXPR_SLASH,
+ RASQAL_EXPR_REM,
+ RASQAL_EXPR_STR_EQ,
+ RASQAL_EXPR_STR_NEQ,
+ RASQAL_EXPR_STR_MATCH,
+ RASQAL_EXPR_STR_NMATCH,
+ RASQAL_EXPR_TILDE,
+ RASQAL_EXPR_BANG,
+ RASQAL_EXPR_LITERAL,
+ RASQAL_EXPR_FUNCTION,
+ RASQAL_EXPR_BOUND,
+ RASQAL_EXPR_STR,
+ RASQAL_EXPR_LANG,
+ RASQAL_EXPR_DATATYPE,
+ RASQAL_EXPR_ISURI,
+ RASQAL_EXPR_ISBLANK,
+ RASQAL_EXPR_ISLITERAL,
+ RASQAL_EXPR_CAST,
+ RASQAL_EXPR_ORDER_COND_ASC,
+ RASQAL_EXPR_ORDER_COND_DESC,
+ RASQAL_EXPR_LANGMATCHES,
+ RASQAL_EXPR_REGEX,
+ RASQAL_EXPR_GROUP_COND_ASC,
+ RASQAL_EXPR_GROUP_COND_DESC,
+ RASQAL_EXPR_COUNT,
+ RASQAL_EXPR_VARSTAR,
+ RASQAL_EXPR_SAMETERM,
+ RASQAL_EXPR_SUM,
+ RASQAL_EXPR_AVG,
+ RASQAL_EXPR_MIN,
+ RASQAL_EXPR_MAX,
+ RASQAL_EXPR_COALESCE,
+ RASQAL_EXPR_IF,
+ RASQAL_EXPR_URI,
+ RASQAL_EXPR_IRI,
+ RASQAL_EXPR_STRLANG,
+ RASQAL_EXPR_STRDT,
+ RASQAL_EXPR_BNODE,
+ RASQAL_EXPR_GROUP_CONCAT,
+ RASQAL_EXPR_SAMPLE,
+ RASQAL_EXPR_IN,
+ RASQAL_EXPR_NOT_IN,
+ RASQAL_EXPR_ISNUMERIC,
+ RASQAL_EXPR_YEAR,
+ RASQAL_EXPR_MONTH,
+ RASQAL_EXPR_DAY,
+ RASQAL_EXPR_HOURS,
+ RASQAL_EXPR_MINUTES,
+ RASQAL_EXPR_SECONDS,
+ RASQAL_EXPR_TIMEZONE,
+ RASQAL_EXPR_CURRENT_DATETIME,
+ RASQAL_EXPR_NOW,
+ RASQAL_EXPR_FROM_UNIXTIME,
+ RASQAL_EXPR_TO_UNIXTIME,
+ RASQAL_EXPR_CONCAT,
+ RASQAL_EXPR_STRLEN,
+ RASQAL_EXPR_SUBSTR,
+ RASQAL_EXPR_UCASE,
+ RASQAL_EXPR_LCASE,
+ RASQAL_EXPR_STRSTARTS,
+ RASQAL_EXPR_STRENDS,
+ RASQAL_EXPR_CONTAINS,
+ RASQAL_EXPR_ENCODE_FOR_URI,
+ RASQAL_EXPR_TZ,
+ RASQAL_EXPR_RAND,
+ RASQAL_EXPR_ABS,
+ RASQAL_EXPR_ROUND,
+ RASQAL_EXPR_CEIL,
+ RASQAL_EXPR_FLOOR,
+ RASQAL_EXPR_MD5,
+ RASQAL_EXPR_SHA1,
+ RASQAL_EXPR_SHA224,
+ RASQAL_EXPR_SHA256,
+ RASQAL_EXPR_SHA384,
+ RASQAL_EXPR_SHA512,
+ RASQAL_EXPR_STRBEFORE,
+ RASQAL_EXPR_STRAFTER,
+ RASQAL_EXPR_REPLACE,
+ RASQAL_EXPR_UUID,
+ RASQAL_EXPR_STRUUID,
+ /* internal */
+ RASQAL_EXPR_LAST = RASQAL_EXPR_STRUUID
+} rasqal_op;
+
+
+/**
+ * rasqal_expression_flags:
+ * @RASQAL_EXPR_FLAG_DISTINCT: Distinct
+ * @RASQAL_EXPR_FLAG_AGGREGATE: Aggregate function expression
+ *
+ * Flags for expressions.
+ */
+typedef enum {
+ RASQAL_EXPR_FLAG_DISTINCT = 1,
+ RASQAL_EXPR_FLAG_AGGREGATE = 2
+} rasqal_expression_flags;
+
+
+/**
+ * rasqal_expression:
+ * @world: rasqal_world object
+ * @usage: reference count - 1 for itself
+ * @op: expression operation
+ * @arg1: first argument
+ * @arg2: second argument
+ * @arg3: third argument (for #RASQAL_EXPR_REGEX )
+ * @literal: literal argument
+ * @value: UTF-8 value
+ * @name: name for extension function qname(args...) and cast-to-uri
+ * @args: args for extension function qname(args...), cast-to-uri and COALESCE
+ * @params: args for extension function parameters (SPARQL 1.1) (Rasqal 0.9.20+)
+ * @flags: bitflags from #rasqal_expression_flags for expressions (Rasqal 0.9.20+)
+ * @arg4: fourth argument (for #RASQAL_EXPR_REPLACE )
+ *
+ * Expression with arguments
+ *
+ */
+struct rasqal_expression_s {
+ rasqal_world* world;
+
+ int usage;
+
+ rasqal_op op;
+
+ struct rasqal_expression_s* arg1;
+ struct rasqal_expression_s* arg2;
+ struct rasqal_expression_s* arg3;
+ rasqal_literal* literal;
+ unsigned char *value;
+
+ raptor_uri* name;
+ raptor_sequence* args;
+
+ raptor_sequence* params;
+ unsigned int flags;
+ struct rasqal_expression_s* arg4;
+};
+typedef struct rasqal_expression_s rasqal_expression;
+
+
+/**
+ * rasqal_triple:
+ * @subject: Triple subject.
+ * @predicate: Triple predicate.
+ * @object: Triple object.
+ * @origin: Triple origin.
+ * @flags: Or of enum #rasqal_triple_flags bits.
+ *
+ * A triple pattern or RDF triple.
+ *
+ * This is used as a triple pattern in queries and
+ * an RDF triple when generating RDF triples such as with SPARQL CONSTRUCT.
+ */
+typedef struct {
+ rasqal_literal* subject;
+ rasqal_literal* predicate;
+ rasqal_literal* object;
+ rasqal_literal* origin;
+ unsigned int flags;
+} rasqal_triple;
+
+
+/**
+ * rasqal_pattern_flags:
+ * @RASQAL_PATTERN_FLAGS_OPTIONAL: True when the graph pattern is an optional match.
+ * @RASQAL_PATTERN_FLAGS_LAST: Internal
+ *
+ * Flags for #rasqal_graph_pattern.
+ */
+typedef enum {
+ RASQAL_PATTERN_FLAGS_OPTIONAL = 1,
+
+ RASQAL_PATTERN_FLAGS_LAST = RASQAL_PATTERN_FLAGS_OPTIONAL
+} rasqal_pattern_flags;
+
+
+/**
+ * rasqal_generate_bnodeid_handler:
+ * @world: world arg
+ * @user_data: user data given to
+ * @user_bnodeid: user blank node ID string passed in
+ *
+ * User handler used with rasqal_world_set_generate_bnodeid_handler() to set method for generating a blank node ID.
+ *
+ * Return value: blank node ID string or NULL on failure.
+ */
+typedef unsigned char* (*rasqal_generate_bnodeid_handler)(rasqal_world* world, void *user_data, unsigned char *user_bnodeid);
+
+
+/**
+ * rasqal_query_verb:
+ * @RASQAL_QUERY_VERB_SELECT: SPARQL query select verb.
+ * @RASQAL_QUERY_VERB_CONSTRUCT: SPARQL query construct verb.
+ * @RASQAL_QUERY_VERB_DESCRIBE: SPARQL query describe verb.
+ * @RASQAL_QUERY_VERB_ASK: SPARQL query ask verb.
+ * @RASQAL_QUERY_VERB_DELETE: LAQRS query delete verb.
+ * @RASQAL_QUERY_VERB_INSERT: LAQRS query insert verb.
+ * @RASQAL_QUERY_VERB_UPDATE: SPARQL 1.1 (draft) update operation
+ * @RASQAL_QUERY_VERB_UNKNOWN: Internal
+ * @RASQAL_QUERY_VERB_LAST: Internal
+ *
+ * Query main operation verbs describing the major type of query
+ * being performed.
+ */
+typedef enum {
+ /* internal */
+ RASQAL_QUERY_VERB_UNKNOWN = 0,
+ RASQAL_QUERY_VERB_SELECT = 1,
+ RASQAL_QUERY_VERB_CONSTRUCT = 2,
+ RASQAL_QUERY_VERB_DESCRIBE = 3,
+ RASQAL_QUERY_VERB_ASK = 4,
+ RASQAL_QUERY_VERB_DELETE = 5,
+ RASQAL_QUERY_VERB_INSERT = 6,
+ RASQAL_QUERY_VERB_UPDATE = 7,
+
+ /* internal */
+ RASQAL_QUERY_VERB_LAST = RASQAL_QUERY_VERB_UPDATE
+} rasqal_query_verb;
+
+
+/**
+ * rasqal_query_results_type:
+ * @RASQAL_QUERY_RESULTS_BINDINGS: variable binding
+ * @RASQAL_QUERY_RESULTS_BOOLEAN: a single boolean
+ * @RASQAL_QUERY_RESULTS_GRAPH: an RDF graph
+ * @RASQAL_QUERY_RESULTS_SYNTAX: a syntax
+ * @RASQAL_QUERY_RESULTS_UNKNOWN: unknown type
+ * @RASQAL_QUERY_RESULTS_LAST: internal
+ *
+ * Query result type.
+ */
+
+typedef enum {
+ RASQAL_QUERY_RESULTS_BINDINGS,
+ RASQAL_QUERY_RESULTS_BOOLEAN,
+ RASQAL_QUERY_RESULTS_GRAPH,
+ RASQAL_QUERY_RESULTS_SYNTAX,
+ RASQAL_QUERY_RESULTS_UNKNOWN,
+ RASQAL_QUERY_RESULTS_LAST = RASQAL_QUERY_RESULTS_UNKNOWN
+} rasqal_query_results_type;
+
+
+/**
+ * rasqal_update_type:
+ * @RASQAL_UPDATE_TYPE_CLEAR: Clear graph.
+ * @RASQAL_UPDATE_TYPE_CREATE: Create graph.
+ * @RASQAL_UPDATE_TYPE_DROP: Drop graph.
+ * @RASQAL_UPDATE_TYPE_LOAD: Load graph.
+ * @RASQAL_UPDATE_TYPE_UPDATE: Insert or Delete graph or triples.
+ * @RASQAL_UPDATE_TYPE_ADD: Add graph to another graph.
+ * @RASQAL_UPDATE_TYPE_MOVE: Move graph to another grpah.
+ * @RASQAL_UPDATE_TYPE_COPY: Copy graph to another graph.
+ * @RASQAL_UPDATE_TYPE_UNKNOWN: Internal
+ * @RASQAL_UPDATE_TYPE_LAST: Internal
+ *
+ * Update type being performed.
+ *
+ */
+typedef enum {
+ /* internal */
+ RASQAL_UPDATE_TYPE_UNKNOWN = 0,
+ RASQAL_UPDATE_TYPE_CLEAR = 1,
+ RASQAL_UPDATE_TYPE_CREATE = 2,
+ RASQAL_UPDATE_TYPE_DROP = 3,
+ RASQAL_UPDATE_TYPE_LOAD = 4,
+ RASQAL_UPDATE_TYPE_UPDATE = 5,
+ RASQAL_UPDATE_TYPE_ADD = 6,
+ RASQAL_UPDATE_TYPE_MOVE = 7,
+ RASQAL_UPDATE_TYPE_COPY = 8,
+
+ /* internal */
+ RASQAL_UPDATE_TYPE_LAST = RASQAL_UPDATE_TYPE_COPY
+} rasqal_update_type;
+
+
+/**
+ * rasqal_update_flags:
+ * @RASQAL_UPDATE_FLAGS_SILENT: the update operation should be silent
+ * @RASQAL_UPDATE_FLAGS_DATA: the update operation is triple data not templates
+ *
+ * Bitflags for graph update operations
+ */
+typedef enum {
+ RASQAL_UPDATE_FLAGS_SILENT = 1,
+ RASQAL_UPDATE_FLAGS_DATA = 2
+} rasqal_update_flags;
+
+
+/**
+ * rasqal_update_graph_applies:
+ * @RASQAL_UPDATE_GRAPH_ONE: the update operation applies to 1 graph
+ * @RASQAL_UPDATE_GRAPH_DEFAULT: the update operation applies to the default graph
+ * @RASQAL_UPDATE_GRAPH_NAMED: the update operation applies to all named graphs
+ * @RASQAL_UPDATE_GRAPH_ALL: the update operation applies ALL graphs
+ *
+ * The graph(s) that the update operation applies to.
+ */
+typedef enum {
+ RASQAL_UPDATE_GRAPH_ONE = 0,
+ RASQAL_UPDATE_GRAPH_DEFAULT = 1,
+ RASQAL_UPDATE_GRAPH_NAMED = 2,
+ RASQAL_UPDATE_GRAPH_ALL = 3
+} rasqal_update_graph_applies;
+
+
+/**
+ * rasqal_update_operation:
+ * @type: type of update
+ * @graph_uri: optional graph URI (clear, drop, load, with ... delete, insert); source graph (add, move, copy)
+ * @document_uri: optional document URI (load); destination graph (add, move, copy)
+ * @insert_templates: optional sequence of #rasqal_triple to insert. Data triples if @flags is #RASQAL_UPDATE_FLAGS_DATA set, templates otherwise.
+ * @delete_templates: optional sequence of #rasqal_triple templates to delete
+ * @where: optional where template (insert/delete)
+ * @flags: update flags - bit-or of flags defined in #rasqal_update_flags
+ * @applies: the graph(s) that the update operation applies to, or @graph_uri if #RASQAL_UPDATE_GRAPH_ONE
+ *
+ * Update operation - changing the dataset
+ *
+ * For LOAD and CLEAR if @applies is set (not 0) then the operation
+ * applies to just those graph(), otherwise it applies to the @graph_uri.
+ *
+ * For ADD, MOVE and COPY the source graph is stored in @graph_uri
+ * field and the destination graph in the @document_uri field. The
+ * field names have no meaning in this case since both values are
+ * always present, always graphs and a NULL value signifies the
+ * default graph.
+ *
+ */
+typedef struct {
+ rasqal_update_type type;
+
+ raptor_uri* graph_uri;
+
+ raptor_uri* document_uri;
+
+ raptor_sequence* insert_templates;
+
+ raptor_sequence* delete_templates;
+
+ rasqal_graph_pattern* where;
+
+ int flags;
+
+ rasqal_update_graph_applies applies;
+} rasqal_update_operation;
+
+
+/**
+ * rasqal_graph_pattern_operator:
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_BASIC: Just triple patterns and constraints.
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_OPTIONAL: Set of graph patterns (ANDed) and constraints.
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_UNION: Set of graph patterns (UNIONed) and constraints.
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_GROUP: Set of graph patterns (ANDed) and constraints.
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_GRAPH: A graph term + a graph pattern and constraints.
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_FILTER: A filter graph pattern with an expression
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_LET: LET ?var := Expression (LAQRS)
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_SELECT: SELECT graph pattern
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_SERVICE: SERVICE graph pattern
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_MINUS: MINUS graph pattern
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_VALUES: VALUES graph pattern
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_UNKNOWN: Internal.
+ * @RASQAL_GRAPH_PATTERN_OPERATOR_LAST: Internal.
+ *
+ * Graph pattern operators
+ */
+typedef enum {
+ RASQAL_GRAPH_PATTERN_OPERATOR_UNKNOWN = 0,
+ RASQAL_GRAPH_PATTERN_OPERATOR_BASIC = 1,
+ RASQAL_GRAPH_PATTERN_OPERATOR_OPTIONAL = 2,
+ RASQAL_GRAPH_PATTERN_OPERATOR_UNION = 3,
+ RASQAL_GRAPH_PATTERN_OPERATOR_GROUP = 4,
+ RASQAL_GRAPH_PATTERN_OPERATOR_GRAPH = 5,
+ RASQAL_GRAPH_PATTERN_OPERATOR_FILTER = 6,
+ RASQAL_GRAPH_PATTERN_OPERATOR_LET = 7,
+ RASQAL_GRAPH_PATTERN_OPERATOR_SELECT = 8,
+ RASQAL_GRAPH_PATTERN_OPERATOR_SERVICE = 9,
+ RASQAL_GRAPH_PATTERN_OPERATOR_MINUS = 10,
+ RASQAL_GRAPH_PATTERN_OPERATOR_VALUES = 11,
+
+ RASQAL_GRAPH_PATTERN_OPERATOR_LAST = RASQAL_GRAPH_PATTERN_OPERATOR_VALUES
+} rasqal_graph_pattern_operator;
+
+
+/**
+ * rasqal_graph_pattern_visit_fn:
+ * @query: #rasqal_query containing the graph pattern
+ * @gp: current graph_pattern
+ * @user_data: user data passed in
+ *
+ * User function to visit a graph_pattern and operate on it with
+ * rasqal_graph_pattern_visit() or rasqal_query_graph_pattern_visit()
+ *
+ * Return value: non-0 to truncate the visit
+ */
+typedef int (*rasqal_graph_pattern_visit_fn)(rasqal_query* query, rasqal_graph_pattern* gp, void *user_data);
+
+
+/* RASQAL API */
+
+/* Public functions */
+
+RASQAL_API
+rasqal_world *rasqal_new_world(void);
+RASQAL_API
+int rasqal_world_open(rasqal_world* world);
+RASQAL_API
+void rasqal_free_world(rasqal_world* world);
+
+RASQAL_API
+void rasqal_world_set_raptor(rasqal_world* world, raptor_world* raptor_world_ptr);
+RASQAL_API
+raptor_world *rasqal_world_get_raptor(rasqal_world* world);
+
+RASQAL_API
+void rasqal_world_set_log_handler(rasqal_world* world, void *user_data, raptor_log_handler handler);
+
+RASQAL_API
+int rasqal_world_set_default_generate_bnodeid_parameters(rasqal_world* world, char *prefix, int base);
+RASQAL_API
+int rasqal_world_set_generate_bnodeid_handler(rasqal_world* world, void *user_data, rasqal_generate_bnodeid_handler handler);
+
+RASQAL_API
+int rasqal_world_set_warning_level(rasqal_world* world, unsigned int warning_level);
+
+RASQAL_API
+const raptor_syntax_description* rasqal_world_get_query_results_format_description(rasqal_world* world, unsigned int counter);
+
+RASQAL_API
+const char* rasqal_world_guess_query_results_format_name(rasqal_world* world, raptor_uri *uri, const char *mime_type, const unsigned char *buffer, size_t len, const unsigned char *identifier);
+
+/* Features */
+RASQAL_API
+int rasqal_features_enumerate(rasqal_world* world, const rasqal_feature feature, const char **name, raptor_uri **uri, const char **label);
+RASQAL_API
+unsigned int rasqal_get_feature_count(void);
+RASQAL_API
+rasqal_feature rasqal_feature_from_uri(rasqal_world* world, raptor_uri *uri);
+RASQAL_API
+int rasqal_feature_value_type(const rasqal_feature feature);
+
+
+RASQAL_API
+const raptor_syntax_description* rasqal_world_get_query_language_description(rasqal_world* world, unsigned int counter);
+
+RASQAL_API RASQAL_DEPRECATED
+int rasqal_languages_enumerate(rasqal_world* world, unsigned int counter, const char **name, const char **label, const unsigned char **uri_string);
+
+RASQAL_API
+int rasqal_language_name_check(rasqal_world* world, const char *name);
+
+
+/* Query class */
+
+/* Create */
+RASQAL_API
+rasqal_query* rasqal_new_query(rasqal_world* world, const char *name, const unsigned char *uri);
+
+/* Destroy */
+RASQAL_API
+void rasqal_free_query(rasqal_query* query);
+
+/* Methods */
+RASQAL_API
+const char* rasqal_query_get_name(rasqal_query* query);
+RASQAL_API
+const char* rasqal_query_get_label(rasqal_query* query);
+
+
+RASQAL_API
+int rasqal_query_set_feature(rasqal_query* query, rasqal_feature feature, int value);
+RASQAL_API
+int rasqal_query_set_feature_string(rasqal_query *query, rasqal_feature feature, const unsigned char *value);
+RASQAL_API
+int rasqal_query_get_feature(rasqal_query *query, rasqal_feature feature);
+RASQAL_API
+const unsigned char* rasqal_query_get_feature_string(rasqal_query *query, rasqal_feature feature);
+
+RASQAL_API
+rasqal_query_verb rasqal_query_get_verb(rasqal_query* query);
+RASQAL_API
+int rasqal_query_get_wildcard(rasqal_query* query);
+RASQAL_API
+void rasqal_query_set_wildcard(rasqal_query* query, int wildcard);
+RASQAL_API
+int rasqal_query_get_distinct(rasqal_query* query);
+RASQAL_API
+void rasqal_query_set_distinct(rasqal_query* query, int distinct_mode);
+RASQAL_API
+int rasqal_query_get_explain(rasqal_query* query);
+RASQAL_API
+void rasqal_query_set_explain(rasqal_query* query, int is_explain);
+RASQAL_API
+int rasqal_query_get_limit(rasqal_query* query);
+RASQAL_API
+void rasqal_query_set_limit(rasqal_query* query, int limit);
+RASQAL_API
+int rasqal_query_get_offset(rasqal_query* query);
+RASQAL_API
+void rasqal_query_set_offset(rasqal_query* query, int offset);
+
+RASQAL_API
+int rasqal_query_add_data_graph(rasqal_query* query, rasqal_data_graph* data_graph);
+RASQAL_API
+int rasqal_query_add_data_graphs(rasqal_query* query, raptor_sequence* data_graphs);
+
+RASQAL_API
+raptor_sequence* rasqal_query_get_data_graph_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_data_graph* rasqal_query_get_data_graph(rasqal_query* query, int idx);
+RASQAL_API
+int rasqal_query_dataset_contains_named_graph(rasqal_query* query, raptor_uri *graph_uri);
+
+RASQAL_API
+int rasqal_query_add_variable(rasqal_query* query, rasqal_variable* var);
+RASQAL_API
+raptor_sequence* rasqal_query_get_bound_variable_sequence(rasqal_query* query);
+RASQAL_API
+raptor_sequence* rasqal_query_get_describe_sequence(rasqal_query* query);
+RASQAL_API
+raptor_sequence* rasqal_query_get_anonymous_variable_sequence(rasqal_query* query);
+RASQAL_API
+raptor_sequence* rasqal_query_get_all_variable_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_variable* rasqal_query_get_variable(rasqal_query* query, int idx);
+RASQAL_API
+int rasqal_query_has_variable2(rasqal_query* query, rasqal_variable_type type, const unsigned char *name);
+RASQAL_API RASQAL_DEPRECATED
+int rasqal_query_has_variable(rasqal_query* query, const unsigned char *name);
+RASQAL_API
+int rasqal_query_set_variable2(rasqal_query* query, rasqal_variable_type type, const unsigned char *name, rasqal_literal* value);
+RASQAL_API RASQAL_DEPRECATED
+int rasqal_query_set_variable(rasqal_query* query, const unsigned char *name, rasqal_literal* value);
+RASQAL_API
+raptor_sequence* rasqal_query_get_triple_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_triple* rasqal_query_get_triple(rasqal_query* query, int idx);
+RASQAL_API
+int rasqal_query_add_prefix(rasqal_query* query, rasqal_prefix* prefix);
+RASQAL_API
+raptor_sequence* rasqal_query_get_prefix_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_prefix* rasqal_query_get_prefix(rasqal_query* query, int idx);
+RASQAL_API
+raptor_sequence* rasqal_query_get_order_conditions_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_expression* rasqal_query_get_order_condition(rasqal_query* query, int idx);
+RASQAL_API
+raptor_sequence* rasqal_query_get_group_conditions_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_expression* rasqal_query_get_group_condition(rasqal_query* query, int idx);
+RASQAL_API
+raptor_sequence* rasqal_query_get_having_conditions_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_expression* rasqal_query_get_having_condition(rasqal_query* query, int idx);
+RASQAL_API
+raptor_sequence* rasqal_query_get_construct_triples_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_triple* rasqal_query_get_construct_triple(rasqal_query* query, int idx);
+RASQAL_API RASQAL_DEPRECATED
+void rasqal_query_graph_pattern_visit(rasqal_query* query, rasqal_graph_pattern_visit_fn visit_fn, void* data);
+RASQAL_API
+int rasqal_query_graph_pattern_visit2(rasqal_query* query, rasqal_graph_pattern_visit_fn visit_fn, void* data);
+RASQAL_API
+int rasqal_query_write(raptor_iostream* iostr, rasqal_query* query, raptor_uri* format_uri, raptor_uri* base_uri);
+
+/* update */
+RASQAL_API
+raptor_sequence* rasqal_query_get_update_operations_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_update_operation* rasqal_query_get_update_operation(rasqal_query* query, int idx);
+
+/* results */
+int rasqal_query_set_store_results(rasqal_query* query, int store_results);
+
+/* graph patterns */
+RASQAL_API
+rasqal_graph_pattern* rasqal_query_get_query_graph_pattern(rasqal_query* query);
+RASQAL_API
+raptor_sequence* rasqal_query_get_graph_pattern_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_graph_pattern* rasqal_query_get_graph_pattern(rasqal_query* query, int idx);
+RASQAL_API
+int rasqal_graph_pattern_add_sub_graph_pattern(rasqal_graph_pattern* graph_pattern, rasqal_graph_pattern* sub_graph_pattern);
+RASQAL_API
+rasqal_triple* rasqal_graph_pattern_get_triple(rasqal_graph_pattern* graph_pattern, int idx);
+RASQAL_API
+raptor_sequence* rasqal_graph_pattern_get_sub_graph_pattern_sequence(rasqal_graph_pattern* graph_pattern);
+RASQAL_API
+rasqal_graph_pattern* rasqal_graph_pattern_get_sub_graph_pattern(rasqal_graph_pattern* graph_pattern, int idx);
+RASQAL_API
+rasqal_graph_pattern_operator rasqal_graph_pattern_get_operator(rasqal_graph_pattern* graph_pattern);
+RASQAL_API
+const char* rasqal_graph_pattern_operator_as_string(rasqal_graph_pattern_operator op);
+RASQAL_API
+int rasqal_graph_pattern_print(rasqal_graph_pattern* gp, FILE* fh);
+RASQAL_API
+int rasqal_graph_pattern_set_filter_expression(rasqal_graph_pattern* gp, rasqal_expression* expr);
+RASQAL_API
+rasqal_expression* rasqal_graph_pattern_get_filter_expression(rasqal_graph_pattern* gp);
+RASQAL_API
+int rasqal_graph_pattern_visit(rasqal_query* query, rasqal_graph_pattern *gp, rasqal_graph_pattern_visit_fn fn, void* user_data);
+RASQAL_API
+int rasqal_graph_pattern_get_index(rasqal_graph_pattern* gp);
+RASQAL_API
+int rasqal_graph_pattern_variable_bound_in(rasqal_graph_pattern *gp, rasqal_variable *v);
+RASQAL_API
+rasqal_literal* rasqal_graph_pattern_get_origin(rasqal_graph_pattern* graph_pattern);
+RASQAL_API
+rasqal_variable* rasqal_graph_pattern_get_variable(rasqal_graph_pattern* graph_pattern);
+RASQAL_API
+rasqal_literal* rasqal_graph_pattern_get_service(rasqal_graph_pattern* graph_pattern);
+RASQAL_API
+raptor_sequence* rasqal_graph_pattern_get_flattened_triples(rasqal_query* query, rasqal_graph_pattern* graph_pattern);
+RASQAL_API
+raptor_sequence* rasqal_graph_pattern_get_triples(rasqal_query* query, rasqal_graph_pattern* graph_pattern);
+
+
+/* Utility methods */
+RASQAL_API
+const char* rasqal_query_verb_as_string(rasqal_query_verb verb);
+RASQAL_API
+int rasqal_query_print(rasqal_query* query, FILE* fh);
+
+/* Query */
+RASQAL_API
+int rasqal_query_prepare(rasqal_query* query, const unsigned char *query_string, raptor_uri *base_uri);
+RASQAL_API
+rasqal_query_results* rasqal_query_execute(rasqal_query* query);
+
+RASQAL_API
+void* rasqal_query_get_user_data(rasqal_query* query);
+RASQAL_API
+void rasqal_query_set_user_data(rasqal_query* query, void *user_data);
+
+RASQAL_API
+raptor_sequence* rasqal_query_get_bindings_variables_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_variable* rasqal_query_get_bindings_variable(rasqal_query* query, int idx);
+RASQAL_API
+raptor_sequence* rasqal_query_get_bindings_rows_sequence(rasqal_query* query);
+RASQAL_API
+rasqal_row* rasqal_query_get_bindings_row(rasqal_query* query, int idx);
+RASQAL_API
+rasqal_query_results_type rasqal_query_get_result_type(rasqal_query* query);
+
+/* query results */
+RASQAL_API
+rasqal_query_results* rasqal_new_query_results2(rasqal_world* world, rasqal_query* query, rasqal_query_results_type type);
+RASQAL_API RASQAL_DEPRECATED
+rasqal_query_results* rasqal_new_query_results(rasqal_world* world, rasqal_query* query, rasqal_query_results_type type, rasqal_variables_table* vars_table);
+RASQAL_API
+rasqal_query_results* rasqal_new_query_results_from_string(rasqal_world* world, rasqal_query_results_type type, raptor_uri* base_uri, const char* string, size_t string_len);
+RASQAL_API
+void rasqal_free_query_results(rasqal_query_results *query_results);
+
+RASQAL_API
+rasqal_query* rasqal_query_results_get_query(rasqal_query_results* query_results);
+
+/* Bindings result format */
+RASQAL_API
+rasqal_query_results_type rasqal_query_results_get_type(rasqal_query_results* query_results);
+RASQAL_API
+const char* rasqal_query_results_type_label(rasqal_query_results_type type);
+RASQAL_API
+int rasqal_query_results_is_bindings(rasqal_query_results *query_results);
+RASQAL_API
+int rasqal_query_results_get_count(rasqal_query_results *query_results);
+RASQAL_API
+int rasqal_query_results_next(rasqal_query_results *query_results);
+RASQAL_API
+int rasqal_query_results_finished(rasqal_query_results *query_results);
+RASQAL_API
+int rasqal_query_results_get_bindings(rasqal_query_results *query_results, const unsigned char ***names, rasqal_literal ***values);
+RASQAL_API
+rasqal_literal* rasqal_query_results_get_binding_value(rasqal_query_results *query_results, int offset);
+RASQAL_API
+const unsigned char* rasqal_query_results_get_binding_name(rasqal_query_results *query_results, int offset);
+RASQAL_API
+rasqal_literal* rasqal_query_results_get_binding_value_by_name(rasqal_query_results *query_results, const unsigned char *name);
+RASQAL_API
+int rasqal_query_results_get_bindings_count(rasqal_query_results *query_results);
+RASQAL_API
+int rasqal_query_results_add_row(rasqal_query_results* query_results, rasqal_row* row);
+RASQAL_API
+rasqal_row* rasqal_query_results_get_row_by_offset(rasqal_query_results* query_results, int result_offset);
+
+/* Boolean result format */
+RASQAL_API
+int rasqal_query_results_is_boolean(rasqal_query_results *query_results);
+RASQAL_API
+int rasqal_query_results_get_boolean(rasqal_query_results *query_results);
+
+/* Graph result format */
+RASQAL_API
+int rasqal_query_results_is_graph(rasqal_query_results *query_results);
+RASQAL_API
+raptor_statement* rasqal_query_results_get_triple(rasqal_query_results *query_results);
+RASQAL_API
+int rasqal_query_results_next_triple(rasqal_query_results *query_results);
+
+/* Syntax result format */
+RASQAL_API
+int rasqal_query_results_is_syntax(rasqal_query_results* query_results);
+
+RASQAL_API
+int rasqal_query_results_write(raptor_iostream *iostr, rasqal_query_results *results, const char* name, const char* mime_type, raptor_uri *format_uri, raptor_uri *base_uri);
+RASQAL_API
+int rasqal_query_results_read(raptor_iostream *iostr, rasqal_query_results *results, const char* name, const char* mime_type, raptor_uri *format_uri, raptor_uri *base_uri);
+
+/* One more time */
+RASQAL_API
+int rasqal_query_results_rewind(rasqal_query_results* query_results);
+
+
+/**
+ * rasqal_query_results_format_flags:
+ * @RASQAL_QUERY_RESULTS_FORMAT_FLAG_READER: format can be read.
+ * @RASQAL_QUERY_RESULTS_FORMAT_FLAG_WRITER: format can be written.
+ *
+ * Bitflags for rasqal_query_results_formats_check() to find formats with features.
+ */
+typedef enum {
+ RASQAL_QUERY_RESULTS_FORMAT_FLAG_READER = 1,
+ RASQAL_QUERY_RESULTS_FORMAT_FLAG_WRITER = 2
+} rasqal_query_results_format_flags;
+
+
+RASQAL_API
+int rasqal_query_results_formats_check2(rasqal_world* world, const char *name, raptor_uri* uri, const char *mime_type, int flags);
+RASQAL_API RASQAL_DEPRECATED
+int rasqal_query_results_formats_check(rasqal_world* world, const char *name, raptor_uri* uri, const char *mime_type, int flags);
+RASQAL_API
+rasqal_query_results_formatter* rasqal_new_query_results_formatter(rasqal_world* world, const char *name, const char *mime_type, raptor_uri* format_uri);
+RASQAL_API
+rasqal_query_results_formatter* rasqal_new_query_results_formatter_for_content(rasqal_world* world, raptor_uri *uri, const char *mime_type, const unsigned char *buffer, size_t len, const unsigned char *identifier);
+RASQAL_API
+void rasqal_free_query_results_formatter(rasqal_query_results_formatter* formatter);
+RASQAL_API
+int rasqal_query_results_formatter_write(raptor_iostream *iostr, rasqal_query_results_formatter* formatter, rasqal_query_results* results, raptor_uri *base_uri);
+RASQAL_API
+int rasqal_query_results_formatter_read(rasqal_world* world, raptor_iostream *iostr, rasqal_query_results_formatter* formatter, rasqal_query_results* results, raptor_uri *base_uri);
+
+RASQAL_API
+int rasqal_query_iostream_write_escaped_counted_string(rasqal_query* query, raptor_iostream* iostr, const unsigned char* string, size_t len);
+RASQAL_API
+unsigned char* rasqal_query_escape_counted_string(rasqal_query* query, const unsigned char *string, size_t len, size_t* output_len_p);
+
+
+/* Data graph class */
+RASQAL_API
+rasqal_data_graph* rasqal_new_data_graph_from_uri(rasqal_world* world, raptor_uri* uri, raptor_uri* name_uri, unsigned int flags, const char* format_type, const char* format_name, raptor_uri* format_uri);
+RASQAL_API
+rasqal_data_graph* rasqal_new_data_graph_from_iostream(rasqal_world* world, raptor_iostream* iostr, raptor_uri* base_uri, raptor_uri* name_uri, unsigned int flags, const char* format_type, const char* format_name, raptor_uri* format_uri);
+RASQAL_API
+rasqal_data_graph* rasqal_new_data_graph_from_data_graph(rasqal_data_graph* dg);
+RASQAL_API
+void rasqal_free_data_graph(rasqal_data_graph* dg);
+RASQAL_API
+int rasqal_data_graph_print(rasqal_data_graph* dg, FILE* fh);
+
+
+/**
+ * rasqal_compare_flags:
+ * @RASQAL_COMPARE_NOCASE: String comparisons are case independent.
+ * @RASQAL_COMPARE_XQUERY: XQuery comparsion rules apply.
+ * @RASQAL_COMPARE_RDF: RDF Term comparsion rules apply.
+ * @RASQAL_COMPARE_URI: Allow comparison of URIs and allow strings to have a boolean value (unused; was for RDQL)
+ * @RASQAL_COMPARE_SAMETERM: SPARQL sameTerm() builtin rules apply.
+ *
+ * Flags for rasqal_expression_evaluate(), rasqal_literal_compare() or
+ * rasqal_literal_as_string_flags()
+ */
+typedef enum {
+ RASQAL_COMPARE_NOCASE = 1,
+ RASQAL_COMPARE_XQUERY = 2,
+ RASQAL_COMPARE_RDF = 4,
+ RASQAL_COMPARE_URI = 8,
+ RASQAL_COMPARE_SAMETERM = 16
+} rasqal_compare_flags;
+
+
+/**
+ * rasqal_random:
+ *
+ * Internal
+ */
+typedef struct rasqal_random_s rasqal_random;
+
+
+/**
+ * rasqal_evaluation_context:
+ * @world: rasqal world
+ * @base_uri: base URI of expression context (or NULL)
+ * @locator: locator or NULL
+ * @flags: expression comparison flags
+ * @seed: random seeed
+ * @random: random number generator object
+ *
+ * A context for evaluating an expression such as with
+ * rasqal_expression_evaluate2()
+ */
+typedef struct {
+ rasqal_world *world;
+ raptor_uri* base_uri;
+ raptor_locator *locator;
+ int flags;
+ unsigned int seed;
+ rasqal_random* random;
+} rasqal_evaluation_context;
+
+
+/* Expression class */
+RASQAL_API
+rasqal_expression* rasqal_new_0op_expression(rasqal_world* world, rasqal_op op);
+RASQAL_API
+rasqal_expression* rasqal_new_1op_expression(rasqal_world* world, rasqal_op op, rasqal_expression* arg);
+RASQAL_API
+rasqal_expression* rasqal_new_2op_expression(rasqal_world* world, rasqal_op op, rasqal_expression* arg1, rasqal_expression* arg2);
+RASQAL_API
+rasqal_expression* rasqal_new_3op_expression(rasqal_world* world, rasqal_op op, rasqal_expression* arg1, rasqal_expression* arg2, rasqal_expression* arg3);
+RASQAL_API
+rasqal_expression* rasqal_new_4op_expression(rasqal_world* world, rasqal_op op, rasqal_expression* arg1, rasqal_expression* arg2, rasqal_expression* arg3, rasqal_expression* arg4);
+RASQAL_API
+rasqal_expression* rasqal_new_string_op_expression(rasqal_world* world, rasqal_op op, rasqal_expression* arg1, rasqal_literal* literal);
+RASQAL_API
+rasqal_expression* rasqal_new_literal_expression(rasqal_world* world, rasqal_literal* literal);
+RASQAL_API
+rasqal_expression* rasqal_new_function_expression(rasqal_world* world, raptor_uri* name, raptor_sequence* args, raptor_sequence* params, unsigned int flags);
+RASQAL_API
+rasqal_expression* rasqal_new_aggregate_function_expression(rasqal_world* world, rasqal_op op, rasqal_expression* arg1, raptor_sequence* params, unsigned int flags);
+RASQAL_API
+rasqal_expression* rasqal_new_cast_expression(rasqal_world* world, raptor_uri* name, rasqal_expression *value);
+RASQAL_API
+rasqal_expression* rasqal_new_expr_seq_expression(rasqal_world* world, rasqal_op op, raptor_sequence* args);
+RASQAL_API
+rasqal_expression* rasqal_new_set_expression(rasqal_world* world, rasqal_op op, rasqal_expression* arg1, raptor_sequence* args);
+RASQAL_API
+rasqal_expression* rasqal_new_group_concat_expression(rasqal_world* world, unsigned int flags, raptor_sequence* args, rasqal_literal* separator);
+RASQAL_API
+rasqal_expression* rasqal_new_expression_from_expression(rasqal_expression* e);
+
+RASQAL_API
+void rasqal_free_expression(rasqal_expression* e);
+RASQAL_API
+void rasqal_expression_print_op(rasqal_expression* e, FILE* fh);
+RASQAL_API
+int rasqal_expression_print(rasqal_expression* e, FILE* fh);
+RASQAL_API RASQAL_DEPRECATED
+rasqal_literal* rasqal_expression_evaluate(rasqal_world *world, raptor_locator *locator, rasqal_expression* e, int flags);
+RASQAL_API
+rasqal_literal* rasqal_expression_evaluate2(rasqal_expression *e, rasqal_evaluation_context* eval_context, int *error_p);
+RASQAL_API
+const char* rasqal_expression_op_label(rasqal_op op);
+RASQAL_API
+int rasqal_expression_compare(rasqal_expression* e1, rasqal_expression* e2, int flags, int* error_p);
+
+/**
+ * rasqal_expression_visit_fn:
+ * @user_data: user data passed in with rasqal_expression_visit()
+ * @e: current expression
+ *
+ * User function to visit an expression and operate on it with
+ * rasqal_expression_visit()
+ *
+ * Return value: non-0 to truncate the visit
+ */
+typedef int (*rasqal_expression_visit_fn)(void *user_data, rasqal_expression *e);
+RASQAL_API
+int rasqal_expression_visit(rasqal_expression* e, rasqal_expression_visit_fn fn, void *user_data);
+
+RASQAL_API
+rasqal_evaluation_context* rasqal_new_evaluation_context(rasqal_world* world, raptor_locator* locator, int flags);
+RASQAL_API
+void rasqal_free_evaluation_context(rasqal_evaluation_context* eval_context);
+RASQAL_API
+int rasqal_evaluation_context_set_base_uri(rasqal_evaluation_context* eval_context, raptor_uri *base_uri);
+RASQAL_API
+int rasqal_evaluation_context_set_rand_seed(rasqal_evaluation_context* eval_context, unsigned int seed);
+
+
+/* Literal class */
+RASQAL_API
+rasqal_literal* rasqal_new_integer_literal(rasqal_world* world, rasqal_literal_type type, int integer);
+RASQAL_API
+rasqal_literal* rasqal_new_numeric_literal_from_long(rasqal_world* world, rasqal_literal_type type, long value);
+RASQAL_API
+rasqal_literal* rasqal_new_typed_literal(rasqal_world* world, rasqal_literal_type type, const unsigned char* string);
+RASQAL_API
+rasqal_literal* rasqal_new_double_literal(rasqal_world* world, double d);
+RASQAL_API
+rasqal_literal* rasqal_new_floating_literal(rasqal_world *world, rasqal_literal_type type, double d);
+RASQAL_API RASQAL_DEPRECATED
+rasqal_literal* rasqal_new_float_literal(rasqal_world* world, float f);
+RASQAL_API
+rasqal_literal* rasqal_new_uri_literal(rasqal_world* world, raptor_uri* uri);
+RASQAL_API
+rasqal_literal* rasqal_new_pattern_literal(rasqal_world* world, const unsigned char *pattern, const char *flags);
+RASQAL_API
+rasqal_literal* rasqal_new_string_literal(rasqal_world* world, const unsigned char *string, const char *language, raptor_uri *datatype, const unsigned char *datatype_qname);
+RASQAL_API
+rasqal_literal* rasqal_new_simple_literal(rasqal_world* world, rasqal_literal_type type, const unsigned char *string);
+RASQAL_API
+rasqal_literal* rasqal_new_boolean_literal(rasqal_world* world, int value);
+RASQAL_API
+rasqal_literal* rasqal_new_variable_literal(rasqal_world* world, rasqal_variable *variable);
+RASQAL_API
+rasqal_literal* rasqal_new_decimal_literal(rasqal_world* world, const unsigned char *string);
+RASQAL_API
+rasqal_literal* rasqal_new_decimal_literal_from_decimal(rasqal_world* world, const unsigned char *string, rasqal_xsd_decimal* decimal);
+RASQAL_API
+rasqal_literal* rasqal_new_datetime_literal_from_datetime(rasqal_world* world, rasqal_xsd_datetime* dt);
+
+
+RASQAL_API
+rasqal_literal* rasqal_new_literal_from_literal(rasqal_literal* l);
+RASQAL_API
+void rasqal_free_literal(rasqal_literal* l);
+RASQAL_API
+int rasqal_literal_print(rasqal_literal* l, FILE* fh);
+RASQAL_API
+const char* rasqal_literal_type_label(rasqal_literal_type type);
+RASQAL_API
+void rasqal_literal_print_type(rasqal_literal* l, FILE* fh);
+RASQAL_API
+rasqal_variable* rasqal_literal_as_variable(rasqal_literal* l);
+RASQAL_API
+const unsigned char* rasqal_literal_as_counted_string(rasqal_literal* l, size_t *len_p, int flags, int *error_p);
+RASQAL_API
+const unsigned char* rasqal_literal_as_string(rasqal_literal* l);
+RASQAL_API
+const unsigned char* rasqal_literal_as_string_flags(rasqal_literal* l, int flags, int *error_p);
+RASQAL_API
+rasqal_literal* rasqal_literal_as_node(rasqal_literal* l);
+RASQAL_API
+raptor_uri* rasqal_literal_datatype(rasqal_literal* l);
+RASQAL_API
+rasqal_literal* rasqal_literal_value(rasqal_literal* l);
+
+RASQAL_API
+int rasqal_literal_compare(rasqal_literal* l1, rasqal_literal* l2, int flags, int *error_p);
+RASQAL_API
+int rasqal_literal_equals(rasqal_literal* l1, rasqal_literal* l2);
+RASQAL_API
+int rasqal_literal_same_term(rasqal_literal* l1, rasqal_literal* l2);
+RASQAL_API
+rasqal_literal_type rasqal_literal_get_rdf_term_type(rasqal_literal* l);
+RASQAL_API
+rasqal_literal_type rasqal_literal_get_type(rasqal_literal* l);
+RASQAL_API
+char* rasqal_literal_get_language(rasqal_literal* l);
+RASQAL_API
+int rasqal_literal_is_rdf_literal(rasqal_literal* l);
+
+
+RASQAL_API
+rasqal_prefix* rasqal_new_prefix(rasqal_world* world, const unsigned char* prefix, raptor_uri* uri);
+RASQAL_API
+void rasqal_free_prefix(rasqal_prefix* p);
+RASQAL_API
+int rasqal_prefix_print(rasqal_prefix* p, FILE* fh);
+
+
+/* Row class */
+RASQAL_API
+rasqal_row* rasqal_new_row_for_size(rasqal_world* world, int size);
+RASQAL_API
+void rasqal_free_row(rasqal_row* row);
+RASQAL_API
+int rasqal_row_set_value_at(rasqal_row* row, int offset, rasqal_literal* value);
+
+
+/* Triple class */
+RASQAL_API
+rasqal_triple* rasqal_new_triple(rasqal_literal* subject, rasqal_literal* predicate, rasqal_literal* object);
+RASQAL_API
+rasqal_triple* rasqal_new_triple_from_triple(rasqal_triple* t);
+RASQAL_API
+void rasqal_free_triple(rasqal_triple* t);
+RASQAL_API
+int rasqal_triple_print(rasqal_triple* t, FILE* fh);
+RASQAL_API
+void rasqal_triple_set_origin(rasqal_triple* t, rasqal_literal *l);
+RASQAL_API
+rasqal_literal* rasqal_triple_get_origin(rasqal_triple* t);
+
+/* Variable class */
+RASQAL_API
+rasqal_variable* rasqal_new_variable_from_variable(rasqal_variable* v);
+RASQAL_API
+void rasqal_free_variable(rasqal_variable* v);
+RASQAL_API
+int rasqal_variable_print(rasqal_variable* v, FILE* fh);
+RASQAL_API
+void rasqal_variable_set_value(rasqal_variable* v, rasqal_literal* l);
+
+
+/* Variables Table */
+RASQAL_API
+rasqal_variables_table* rasqal_new_variables_table(rasqal_world* world);
+RASQAL_API
+void rasqal_free_variables_table(rasqal_variables_table* vt);
+RASQAL_API RASQAL_DEPRECATED
+rasqal_variable* rasqal_variables_table_add(rasqal_variables_table* vt, rasqal_variable_type type, const unsigned char *name, rasqal_literal *value);
+RASQAL_API
+rasqal_variable* rasqal_variables_table_add2(rasqal_variables_table* vt, rasqal_variable_type type, const unsigned char *name, size_t name_len, rasqal_literal *value);
+RASQAL_API
+int rasqal_variables_table_add_variable(rasqal_variables_table* vt, rasqal_variable* variable);
+RASQAL_API
+rasqal_variable* rasqal_variables_table_get_by_name(rasqal_variables_table* vt, rasqal_variable_type type, const unsigned char *name);
+RASQAL_API
+int rasqal_variables_table_contains(rasqal_variables_table* vt, rasqal_variable_type type, const unsigned char *name);
+
+/* memory functions */
+RASQAL_API
+void rasqal_free_memory(void *ptr);
+RASQAL_API
+void* rasqal_alloc_memory(size_t size);
+RASQAL_API
+void* rasqal_calloc_memory(size_t nmemb, size_t size);
+
+
+/* decimal functions */
+RASQAL_API
+rasqal_xsd_decimal* rasqal_new_xsd_decimal(rasqal_world* world);
+RASQAL_API
+void rasqal_free_xsd_decimal(rasqal_xsd_decimal* dec);
+RASQAL_API
+int rasqal_xsd_decimal_set_string(rasqal_xsd_decimal* dec, const char* string);
+RASQAL_API
+double rasqal_xsd_decimal_get_double(rasqal_xsd_decimal* dec);
+RASQAL_API
+long rasqal_xsd_decimal_get_long(rasqal_xsd_decimal* dec, int* error_p);
+RASQAL_API
+char* rasqal_xsd_decimal_as_string(rasqal_xsd_decimal* dec);
+RASQAL_API
+char* rasqal_xsd_decimal_as_counted_string(rasqal_xsd_decimal* dec, size_t* len_p);
+RASQAL_API
+int rasqal_xsd_decimal_set_long(rasqal_xsd_decimal* dec, long l);
+RASQAL_API
+int rasqal_xsd_decimal_set_double(rasqal_xsd_decimal* dec, double d);
+RASQAL_API
+int rasqal_xsd_decimal_print(rasqal_xsd_decimal* dec, FILE* stream);
+RASQAL_API
+int rasqal_xsd_decimal_add(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a, rasqal_xsd_decimal* b);
+RASQAL_API
+int rasqal_xsd_decimal_subtract(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a, rasqal_xsd_decimal* b);
+RASQAL_API
+int rasqal_xsd_decimal_multiply(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a, rasqal_xsd_decimal* b);
+RASQAL_API
+int rasqal_xsd_decimal_divide(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a, rasqal_xsd_decimal* b);
+RASQAL_API
+int rasqal_xsd_decimal_negate(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a);
+RASQAL_API
+int rasqal_xsd_decimal_compare(rasqal_xsd_decimal* a, rasqal_xsd_decimal* b);
+RASQAL_API
+int rasqal_xsd_decimal_equals(rasqal_xsd_decimal* a, rasqal_xsd_decimal* b);
+RASQAL_API
+int rasqal_xsd_decimal_is_zero(rasqal_xsd_decimal* d);
+RASQAL_API
+int rasqal_xsd_decimal_abs(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a);
+RASQAL_API
+int rasqal_xsd_decimal_round(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a);
+RASQAL_API
+int rasqal_xsd_decimal_ceil(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a);
+RASQAL_API
+int rasqal_xsd_decimal_floor(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a);
+
+
+/* date functions */
+RASQAL_API
+rasqal_xsd_date* rasqal_new_xsd_date(rasqal_world* world, const char *date_string);
+RASQAL_API
+void rasqal_free_xsd_date(rasqal_xsd_date* d);
+RASQAL_API
+char* rasqal_xsd_date_to_counted_string(const rasqal_xsd_date *date, size_t *len_p);
+RASQAL_API
+char* rasqal_xsd_date_to_string(const rasqal_xsd_date *d);
+RASQAL_API
+int rasqal_xsd_date_equals(const rasqal_xsd_date *d1, const rasqal_xsd_date *d2, int *incomparible_p);
+RASQAL_API
+int rasqal_xsd_date_compare(const rasqal_xsd_date *d1, const rasqal_xsd_date *d2, int *incomparible_p);
+
+/* datetime functions */
+RASQAL_API
+rasqal_xsd_datetime* rasqal_new_xsd_datetime(rasqal_world* world, const char *datetime_string);
+RASQAL_API
+rasqal_xsd_datetime* rasqal_new_xsd_datetime_from_unixtime(rasqal_world* world, time_t secs);
+RASQAL_API
+rasqal_xsd_datetime* rasqal_new_xsd_datetime_from_timeval(rasqal_world* world, struct timeval *tv);
+RASQAL_API
+rasqal_xsd_datetime* rasqal_new_xsd_datetime_from_xsd_date(rasqal_world* world, rasqal_xsd_date *date);
+RASQAL_API
+void rasqal_free_xsd_datetime(rasqal_xsd_datetime* dt);
+RASQAL_API
+char* rasqal_xsd_datetime_to_counted_string(const rasqal_xsd_datetime *dt, size_t *len_p);
+RASQAL_API
+char* rasqal_xsd_datetime_to_string(const rasqal_xsd_datetime *dt);
+RASQAL_API
+int rasqal_xsd_datetime_equals2(const rasqal_xsd_datetime *dt1, const rasqal_xsd_datetime *dt2, int *incomparible_p);
+RASQAL_API RASQAL_DEPRECATED
+int rasqal_xsd_datetime_equals(const rasqal_xsd_datetime *dt1, const rasqal_xsd_datetime *dt2);
+RASQAL_API
+int rasqal_xsd_datetime_compare2(const rasqal_xsd_datetime *dt1, const rasqal_xsd_datetime *dt2, int *incomparible_p);
+RASQAL_API RASQAL_DEPRECATED
+int rasqal_xsd_datetime_compare(const rasqal_xsd_datetime *dt1, const rasqal_xsd_datetime *dt2);
+RASQAL_API
+rasqal_xsd_decimal* rasqal_xsd_datetime_get_seconds_as_decimal(rasqal_world* world, rasqal_xsd_datetime* dt);
+RASQAL_API
+int rasqal_xsd_datetime_set_from_timeval(rasqal_xsd_datetime *dt, struct timeval *tv);
+RASQAL_API
+int rasqal_xsd_datetime_set_from_unixtime(rasqal_xsd_datetime* dt, time_t clock);
+RASQAL_API
+time_t rasqal_xsd_datetime_get_as_unixtime(rasqal_xsd_datetime* dt);
+RASQAL_API
+struct timeval* rasqal_xsd_datetime_get_as_timeval(rasqal_xsd_datetime *dt);
+RASQAL_API
+char* rasqal_xsd_datetime_get_timezone_as_counted_string(rasqal_xsd_datetime *dt, size_t *len_p);
+RASQAL_API
+char* rasqal_xsd_datetime_get_tz_as_counted_string(rasqal_xsd_datetime* dt, size_t *len_p);
+
+
+/* regex utilities */
+RASQAL_API
+char* rasqal_regex_replace(rasqal_world* world, raptor_locator* locator, const char* pattern, const char* regex_flags, const char* subject, size_t subject_len, const char* replace, size_t replace_len, size_t* result_len_p);
+
+
+/**
+ * rasqal_service:
+ *
+ * Rasqal SPARQL Protocol Service
+ */
+typedef struct rasqal_service_s rasqal_service;
+
+RASQAL_API
+rasqal_service* rasqal_new_service(rasqal_world* world, raptor_uri* service_uri, const unsigned char* query_string, raptor_sequence* data_graphs);
+RASQAL_API
+void rasqal_free_service(rasqal_service* svc);
+RASQAL_API
+rasqal_query_results* rasqal_service_execute(rasqal_service* svc);
+RASQAL_API
+int rasqal_service_set_www(rasqal_service* svc, raptor_www* www);
+RASQAL_API
+int rasqal_service_set_format(rasqal_service* svc, const char *format);
+
+
+
+/**
+ * rasqal_triple_parts:
+ * @RASQAL_TRIPLE_NONE: no parts
+ * @RASQAL_TRIPLE_SUBJECT: Subject present in a triple.
+ * @RASQAL_TRIPLE_PREDICATE: Predicate present in a triple.
+ * @RASQAL_TRIPLE_OBJECT: Object present in a triple.
+ * @RASQAL_TRIPLE_ORIGIN: Origin/graph present in a triple.
+ * @RASQAL_TRIPLE_GRAPH: Alias for RASQAL_TRIPLE_ORIGIN
+ * @RASQAL_TRIPLE_SPO: Subject, Predicate and Object present in a triple.
+ * @RASQAL_TRIPLE_SPOG: Subject, Predicate, Object, Graph present in a triple.
+ *
+ * Flags for parts of a triple.
+ */
+typedef enum {
+ RASQAL_TRIPLE_NONE = 0,
+ RASQAL_TRIPLE_SUBJECT = 1,
+ RASQAL_TRIPLE_PREDICATE= 2,
+ RASQAL_TRIPLE_OBJECT = 4,
+ RASQAL_TRIPLE_ORIGIN = 8,
+ RASQAL_TRIPLE_GRAPH = RASQAL_TRIPLE_ORIGIN,
+ RASQAL_TRIPLE_SPO = RASQAL_TRIPLE_SUBJECT | RASQAL_TRIPLE_PREDICATE | RASQAL_TRIPLE_OBJECT,
+ RASQAL_TRIPLE_SPOG = RASQAL_TRIPLE_SPO | RASQAL_TRIPLE_GRAPH
+} rasqal_triple_parts;
+
+
+
+/**
+ * rasqal_triples_match:
+ * @world: rasqal_world object
+ * @user_data: User data pointer for factory methods.
+ * @bind_match: The [4]array (s,p,o,origin) bindings against the current triple match only touching triple parts given. Returns parts that were bound or 0 on failure.
+ * @next_match: Move to next match.
+ * @is_end: Check for end of triple match - return non-0 if is end.
+ * @finish: Finish triples match and destroy any allocated memory.
+ * @is_exact: non-0 if triple to match is all literal constants
+ * @finished: >0 if the match has finished
+ *
+ * Triples match structure as initialised by #rasqal_triples_source
+ * method init_triples_match.
+ */
+struct rasqal_triples_match_s {
+ rasqal_world *world;
+
+ void *user_data;
+
+ rasqal_triple_parts (*bind_match)(struct rasqal_triples_match_s* rtm, void *user_data, rasqal_variable *bindings[4], rasqal_triple_parts parts);
+
+ void (*next_match)(struct rasqal_triples_match_s* rtm, void *user_data);
+
+ int (*is_end)(struct rasqal_triples_match_s* rtm, void *user_data);
+
+ void (*finish)(struct rasqal_triples_match_s* rtm, void *user_data);
+
+ int is_exact;
+
+ int finished;
+};
+typedef struct rasqal_triples_match_s rasqal_triples_match;
+
+
+/**
+ * rasqal_triple_meta:
+ * @bindings: Variable bindings for this triple+origin to set.
+ * @triples_match: The matcher that is setting these bindings.
+ * @context: Context data used by the matcher.
+ * @parts: Bitmask of #rasqal_triple_parts flags describing the parts of the triple pattern that will bind to variables. There may also be variables mentioned that are bound in other triple patterns even if @parts is 0.
+ * @is_exact: unused
+ * @executed: unused
+ *
+ * Metadata for triple pattern matching for one triple pattern.
+ */
+typedef struct {
+ /* triple (subject, predicate, object) and origin */
+ rasqal_variable* bindings[4];
+
+ rasqal_triples_match *triples_match;
+
+ void *context;
+
+ rasqal_triple_parts parts;
+
+ int is_exact;
+
+ int executed;
+} rasqal_triple_meta;
+
+
+/**
+ * RASQAL_TRIPLES_SOURCE_MIN_VERSION:
+ *
+ * Lowest accepted @rasqal_triples_source API version
+ */
+#define RASQAL_TRIPLES_SOURCE_MIN_VERSION 1
+
+/**
+ * RASQAL_TRIPLES_SOURCE_MAX_VERSION:
+ *
+ * Highest accepted @rasqal_triples_source API version
+ */
+#define RASQAL_TRIPLES_SOURCE_MAX_VERSION 2
+
+
+/**
+ * rasqal_triples_source_feature:
+ * @RASQAL_TRIPLES_SOURCE_FEATURE_NONE: No feature
+ * @RASQAL_TRIPLES_SOURCE_FEATURE_IOSTREAM_DATA_GRAPH: Support raptor_iostream data graphs
+ *
+ * Optional features that may be supported by a triple source factory
+ */
+typedef enum {
+ RASQAL_TRIPLES_SOURCE_FEATURE_NONE,
+ RASQAL_TRIPLES_SOURCE_FEATURE_IOSTREAM_DATA_GRAPH
+} rasqal_triples_source_feature;
+
+
+/**
+ * rasqal_triples_source:
+ * @version: API version - only V1 is defined for now
+ * @query: Source for this query.
+ * @user_data: Context user data passed into the factory methods.
+ * @init_triples_match: Factory method to initialize a new #rasqal_triples_match.
+ * @triple_present: Factory method to return presence or absence of a complete triple.
+ * @free_triples_source: Factory method to deallocate resources.
+ * @support_feature: Factory method to test support for a feature, returning non-0 if supported
+ *
+ * Triples source as initialised by a #rasqal_triples_source_factory.
+ */
+struct rasqal_triples_source_s {
+ int version;
+
+ rasqal_query* query;
+
+ void *user_data;
+
+ /* API v1 */
+ int (*init_triples_match)(rasqal_triples_match* rtm, struct rasqal_triples_source_s* rts, void *user_data, rasqal_triple_meta *m, rasqal_triple *t);
+
+ int (*triple_present)(struct rasqal_triples_source_s* rts, void *user_data, rasqal_triple *t);
+
+ void (*free_triples_source)(void *user_data);
+
+ /* API v2 onwards */
+ int (*support_feature)(void *user_data, rasqal_triples_source_feature feature);
+};
+typedef struct rasqal_triples_source_s rasqal_triples_source;
+
+
+/**
+ * RASQAL_TRIPLES_SOURCE_FACTORY_MIN_VERSION:
+ *
+ * Lowest accepted @rasqal_triples_source_factory API version
+ */
+#define RASQAL_TRIPLES_SOURCE_FACTORY_MIN_VERSION 1
+
+/**
+ * RASQAL_TRIPLES_SOURCE_FACTORY_MAX_VERSION:
+ *
+ * Highest accepted @rasqal_triples_source_factory API version
+ */
+#define RASQAL_TRIPLES_SOURCE_FACTORY_MAX_VERSION 3
+
+
+/**
+ * rasqal_triples_error_handler:
+ * @query: query object
+ * @locator: error locator (or NULL)
+ * @message: error message
+ *
+ * Triples source factory error handler callback.
+ */
+typedef void (*rasqal_triples_error_handler)(rasqal_query* query, raptor_locator* locator, const char* message);
+
+
+/**
+ * rasqal_triples_error_handler2:
+ * @world: world object
+ * @locator: error locator (or NULL)
+ * @message: error message
+ *
+ * Triples source factory error handler callback.
+ */
+typedef void (*rasqal_triples_error_handler2)(rasqal_world* world, raptor_locator* locator, const char* message);
+
+
+/**
+ * rasqal_triples_source_factory:
+ * @version: API factory version from 1 to 3
+ * @user_data: User data for triples_source_factory.
+ * @user_data_size: Size of @user_data for new_triples_source.
+ * @new_triples_source: Create a new triples source - returns non-zero on failure &lt; 0 is a 'no rdf data error', &gt; 0 is an unspecified error. Error messages are generated by rasqal internally. (V1)
+ * @init_triples_source: Initialise a new triples source V2 for a particular source URI/base URI and syntax. Returns non-zero on failure with errors reported via the handler callback by the implementation. (V2)
+ * @init_triples_source2: Initialise a new triples source V3 for a particular source URI/base URI and syntax and given data graphs. Returns non-zero on failure with errors reported via the handler callback by the implementation. If bit 0 of flags is 1, enforce RAPTOR_FEATURE_NO_NET (V3)
+ *
+ * A factory that initialises #rasqal_triples_source structures to
+ * returning matches to a triple pattern across the dataset formed
+ * from the data graphs recorded in the @query object.
+ */
+typedef struct {
+ int version;
+
+ void *user_data;
+ size_t user_data_size;
+
+ /* API v1 */
+ int (*new_triples_source)(rasqal_query* query, void *factory_user_data, void *user_data, rasqal_triples_source* rts);
+ /* API v2 onwards */
+ int (*init_triples_source)(rasqal_query* query, void *factory_user_data, void *user_data, rasqal_triples_source* rts, rasqal_triples_error_handler handler);
+ /* API v3 onwards */
+ int (*init_triples_source2)(rasqal_world* world, raptor_sequence* data_graphs, void *factory_user_data, void *user_data, rasqal_triples_source *rts, rasqal_triples_error_handler2 handler, unsigned int flags);
+} rasqal_triples_source_factory;
+
+
+/**
+ * rasqal_triples_source_factory_register_fn:
+ * @factory: factory to register
+ *
+ * Register a factory for generating triples sources #rasqal_triples_source
+ *
+ * Return value: non-0 on failure
+ */
+typedef int (*rasqal_triples_source_factory_register_fn)(rasqal_triples_source_factory *factory);
+
+
+/* set the triples_source_factory */
+RASQAL_API
+int rasqal_set_triples_source_factory(rasqal_world* world, rasqal_triples_source_factory_register_fn register_fn, void* user_data);
+
+
+
+/* The info below is solely for gtk-doc - ignore it */
+
+/**
+ * raptor_world:
+ *
+ * Internal
+ */
+
+/**
+ * RASQAL_QUERY_RESULTS_FORMATTER_DECLARED:
+ *
+ * Internal
+ */
+
+/**
+ * RASQAL_WORLD_DECLARED:
+ *
+ * Internal
+ */
+
+
+/**
+ * RASQAL_LITERAL_UDT_DEFINED
+ *
+ * Internal
+ */
+
+/**
+ * rasqal_expression_s:
+ * @world: Internal
+ * @usage: Internal
+ * @op: Internal
+ * @arg1: Internal
+ * @arg2: Internal
+ * @arg3: Internal
+ * @literal: Internal
+ * @value: Internal
+ * @name: Internal
+ * @args: Internal
+ * @params: Internal
+ * @flags: Internal
+ * @arg4: Internal
+ *
+ * Internal - see #rasqal_expression.
+ *
+ */
+
+/**
+ * bind_match:
+ * @rtm: triples match context
+ * @user_data: user data
+ * @bindings: variable binding for parts of triple (s, p, o, g)
+ * @parts: parts of triple to match
+ *
+ * Internal - see #rasqal_triples_match
+ *
+ * Return value: match parts
+*/
+
+/**
+ * next_match:
+ * @rtm: triples match context
+ * @user_data: user data
+ *
+ * Internal - see #rasqal_triples_match
+ */
+
+/**
+ * is_end:
+ * @rtm: triples match context
+ * @user_data: user data
+ *
+ * Internal - see #rasqal_triples_match
+ *
+ * Return value: non-0 if end of match
+ */
+
+/**
+ * finish:
+ * @rtm: triples match context
+ * @user_data: user data
+ *
+ * Internal - see #rasqal_triples_match
+ */
+
+/**
+ * init_triples_match:
+ * @rtm: triples match context
+ * @rts: triples match source
+ * @user_data: user data
+ * @m: triple meta
+ * @t: triple
+ *
+ * Internal - see #rasqal_triples_source
+ *
+ * Return value: non-0 on failure
+ */
+
+/**
+ * triple_present:
+ * @rts: triples match source
+ * @user_data: user data
+ * @t: triple to test for presence
+ *
+ * Internal - see #rasqal_triples_source
+ *
+ * Return value: non-0 on failure
+ */
+
+/**
+ * free_triples_source:
+ * @user_data: user data
+ *
+ * Internal - see #rasqal_triples_source
+ */
+
+/**
+ * support_feature:
+ * @user_data: user data
+ * @feature: feature to test
+ *
+ * Internal - see #rasqal_triples_source
+ *
+ * Return value: non-0 if supported
+ */
+
+/**
+ * rasqal_variables_table:
+ *
+ * Internal - for now
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/external/redland/rasqal/rpath.patch b/external/redland/rasqal/rpath.patch
new file mode 100644
index 000000000..c0eed7725
--- /dev/null
+++ b/external/redland/rasqal/rpath.patch
@@ -0,0 +1,21 @@
+--- configure
++++ configure
+@@ -9843,6 +9843,7 @@
+ else
+ ld_shlibs=no
+ fi
++hardcode_libdir_flag_spec=
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+--- utils/Makefile.in
++++ utils/Makefile.in
+@@ -373,7 +373,7 @@
+ $(man_MANS) \
+ roqet.html
+
+-all: all-am
++all:
+
+ .SUFFIXES:
+ .SUFFIXES: .c .lo .o .obj
diff --git a/external/redland/redland/clang-cl.patch b/external/redland/redland/clang-cl.patch
new file mode 100644
index 000000000..b5a7271fb
--- /dev/null
+++ b/external/redland/redland/clang-cl.patch
@@ -0,0 +1,20 @@
+--- src/librdf.h
++++ src/librdf.h
+@@ -74,7 +74,7 @@
+ /* Use gcc 3.1+ feature to allow marking of deprecated API calls.
+ * This gives a warning during compiling.
+ */
+-#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
++#if (defined __GNUC__ && (( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3)) || defined __clang__
+ #define REDLAND_DEPRECATED __attribute__((deprecated))
+ #define REDLAND_NORETURN __attribute__((__noreturn__))
+ #else
+@@ -83,7 +83,7 @@
+ #endif
+
+
+-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
++#if (defined __GNUC__ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4))) || defined __clang__
+ #define REDLAND_PRINTF_FORMAT(string_index, first_to_check_index) \
+ __attribute__((__format__(__printf__, string_index, first_to_check_index)))
+ #else
diff --git a/external/redland/redland/librdf.h b/external/redland/redland/librdf.h
new file mode 100644
index 000000000..44674c583
--- /dev/null
+++ b/external/redland/redland/librdf.h
@@ -0,0 +1,434 @@
+/* -*- Mode: c; c-basic-offset: 2 -*-
+ *
+ * redland.h - Redland RDF Application Framework public API
+ *
+ * Copyright (C) 2000-2011, David Beckett http://www.dajobe.org/
+ * Copyright (C) 2000-2005, University of Bristol, UK http://www.bristol.ac.uk/
+ *
+ * This package is Free Software and part of Redland http://librdf.org/
+ *
+ * It is licensed under the following three licenses as alternatives:
+ * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
+ * 2. GNU General Public License (GPL) V2 or any newer version
+ * 3. Apache License, V2.0 or any newer version
+ *
+ * You may not use this file except in compliance with at least one of
+ * the above three licenses.
+ *
+ * See LICENSE.html or LICENSE.txt at the top of this package for the
+ * complete terms and further detail along with the license texts for
+ * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
+ *
+ *
+ */
+
+
+#ifndef LIBRDF_H
+#define LIBRDF_H
+
+#ifndef LIBRDF_OBJC_FRAMEWORK
+/* raptor */
+#include <raptor2.h>
+/* rasqal: uses raptor */
+#include <rasqal.h>
+/* librdf: uses rasqal and raptor */
+#else
+#include <Redland/raptor2.h>
+#include <Redland/rasqal.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+#ifndef REDLAND_API
+# ifdef _WIN32
+# ifdef __GNUC__
+# undef _declspec
+# define _declspec(x) __declspec(x)
+# endif
+# ifdef REDLAND_STATIC
+# define REDLAND_API
+# else
+# ifdef LIBRDF_INTERNAL
+# define REDLAND_API _declspec(dllexport)
+# else
+# define REDLAND_API _declspec(dllimport)
+# endif
+# endif
+# else
+# define REDLAND_API
+# endif
+#endif
+
+#ifndef REDLAND_CALLBACK_STDCALL
+# if defined(_WIN32) && defined(USE_STDCALL_CALLBACKS)
+# define REDLAND_CALLBACK_STDCALL _stdcall
+# else
+# define REDLAND_CALLBACK_STDCALL
+# endif
+#endif
+
+/* Use gcc 3.1+ feature to allow marking of deprecated API calls.
+ * This gives a warning during compiling.
+ */
+#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
+#define REDLAND_DEPRECATED __attribute__((deprecated))
+#define REDLAND_NORETURN __attribute__((__noreturn__))
+#else
+#define REDLAND_DEPRECATED
+#define REDLAND_NORETURN
+#endif
+
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#define REDLAND_PRINTF_FORMAT(string_index, first_to_check_index) \
+ __attribute__((__format__(__printf__, string_index, first_to_check_index)))
+#else
+#define REDLAND_PRINTF_FORMAT(string_index, first_to_check_index)
+#endif
+
+
+/* Public defines */
+
+/**
+ * LIBRDF_VERSION:
+ *
+ * Redland librdf library version number
+ *
+ * Format: major * 10000 + minor * 100 + release
+ */
+#define LIBRDF_VERSION 10017
+
+/**
+ * LIBRDF_VERSION_STRING:
+ *
+ * Redland librdf library version string
+ */
+#define LIBRDF_VERSION_STRING "1.0.17"
+
+/**
+ * LIBRDF_VERSION_MAJOR:
+ *
+ * Redland librdf library major version
+ */
+#define LIBRDF_VERSION_MAJOR 1
+
+/**
+ * LIBRDF_VERSION_MINOR:
+ *
+ * Redland librdf library minor version
+ */
+#define LIBRDF_VERSION_MINOR 0
+
+/**
+ * LIBRDF_VERSION_RELEASE:
+ *
+ * Redland librdf library release
+ */
+#define LIBRDF_VERSION_RELEASE 17
+
+
+
+/* Public typedefs (references to private structures) */
+
+/**
+ * librdf_world:
+ *
+ * Redland world class.
+ */
+typedef struct librdf_world_s librdf_world;
+
+/**
+ * librdf_hash:
+ *
+ * Redland hash class.
+ */
+typedef struct librdf_hash_s librdf_hash;
+
+/**
+ * librdf_hash_cursor:
+ *
+ * Redland hash cursor class.
+ */
+typedef struct librdf_hash_cursor_s librdf_hash_cursor;
+
+/**
+ * librdf_digest:
+ *
+ * Redland content digest class.
+ */
+typedef struct librdf_digest_s librdf_digest;
+
+/**
+ * librdf_digest_factory:
+ *
+ * Redland digest factory class.
+ */
+typedef struct librdf_digest_factory_s librdf_digest_factory;
+
+/**
+ * librdf_uri:
+ *
+ * Redland URI class.
+ */
+typedef struct raptor_uri_s librdf_uri;
+
+/**
+ * librdf_list:
+ *
+ * Redland list class.
+ */
+typedef struct librdf_list_s librdf_list;
+
+/**
+ * librdf_iterator:
+ *
+ * Redland iterator class.
+ */
+typedef struct librdf_iterator_s librdf_iterator;
+
+/**
+ * librdf_node:
+ *
+ * Redland node class.
+ */
+typedef raptor_term librdf_node;
+
+/**
+ * librdf_statement:
+ *
+ * Redland statement class.
+ */
+typedef raptor_statement librdf_statement;
+
+/**
+ * librdf_model:
+ *
+ * Redland model class.
+ */
+typedef struct librdf_model_s librdf_model;
+
+/**
+ * librdf_model_factory:
+ *
+ * Redland model factory class.
+ */
+typedef struct librdf_model_factory_s librdf_model_factory;
+
+/**
+ * librdf_storage:
+ *
+ * Redland storage class.
+ */
+typedef struct librdf_storage_s librdf_storage;
+
+/**
+ * librdf_storage_factory:
+ *
+ * Redland storage factory class.
+ */
+typedef struct librdf_storage_factory_s librdf_storage_factory;
+
+/**
+ * librdf_stream:
+ *
+ * Redland stream class.
+ */
+typedef struct librdf_stream_s librdf_stream;
+
+/**
+ * librdf_parser:
+ *
+ * Redland parser class.
+ */
+typedef struct librdf_parser_s librdf_parser;
+
+/**
+ * librdf_parser_factory:
+ *
+ * Redland parser factory class.
+ */
+typedef struct librdf_parser_factory_s librdf_parser_factory;
+
+/**
+ * librdf_query:
+ *
+ * Redland query class.
+ */
+typedef struct librdf_query_s librdf_query;
+
+/**
+ * librdf_query_factory:
+ *
+ * Redland query factory class.
+ */
+typedef struct librdf_query_factory_s librdf_query_factory;
+
+/**
+ * librdf_query_results:
+ *
+ * Redland query results class.
+ */
+typedef struct librdf_query_results_s librdf_query_results;
+
+/**
+ * librdf_query_results_formatter:
+ *
+ * Redland query results formatter class.
+ */
+typedef struct librdf_query_results_formatter_s librdf_query_results_formatter;
+
+/**
+ * librdf_serializer:
+ *
+ * Redland serializer class.
+ */
+typedef struct librdf_serializer_s librdf_serializer;
+
+/**
+ * librdf_serializer_factory:
+ *
+ * Redland serializer factory class.
+ */
+typedef struct librdf_serializer_factory_s librdf_serializer_factory;
+
+
+/* Public statics */
+
+/**
+ * librdf_short_copyright_string:
+ *
+ * Short copyright string (one line).
+ */
+REDLAND_API
+extern const char * const librdf_short_copyright_string;
+
+/**
+ * librdf_copyright_string:
+ *
+ * Copyright string (multiple lines).
+ */
+REDLAND_API
+extern const char * const librdf_copyright_string;
+
+/**
+ * librdf_version_string:
+ *
+ * Redland librdf version as a string.
+ */
+REDLAND_API
+extern const char * const librdf_version_string;
+
+/**
+ * librdf_version_major:
+ *
+ * Redland librdf major version number.
+ */
+REDLAND_API
+extern const unsigned int librdf_version_major;
+
+/**
+ * librdf_version_minor:
+ *
+ * Redland librdf minor version number.
+ */
+REDLAND_API
+extern const unsigned int librdf_version_minor;
+
+/**
+ * librdf_version_release:
+ *
+ * Redland librdf release version number.
+ */
+REDLAND_API
+extern const unsigned int librdf_version_release;
+
+/**
+ * librdf_version_decimal:
+ *
+ * Redland librdf version as a decimal number.
+ *
+ * Format: major * 10000 + minor * 100 + release
+ */
+REDLAND_API
+extern const unsigned int librdf_version_decimal;
+
+/**
+ * librdf_license_string:
+ *
+ * Redland librdf license string.
+ */
+REDLAND_API
+extern const char * const librdf_license_string;
+
+/**
+ * librdf_home_url_string:
+ *
+ * Redland librdf home page URL.
+ */
+REDLAND_API
+extern const char * const librdf_home_url_string;
+
+/* Required for va_list in error handler function registrations
+ * which are in the public API
+ */
+#include <stdarg.h>
+
+
+/* internal interfaces */
+#ifdef LIBRDF_INTERNAL
+#include <rdf_internal.h>
+#endif
+
+/* public interfaces */
+
+/* FIXME: Should be replaced with automatically pulled
+ * definitions from the listed rdf_*.h header files.
+ */
+
+#ifndef LIBRDF_OBJC_FRAMEWORK
+#include <rdf_log.h>
+#include <rdf_digest.h>
+#include <rdf_hash.h>
+#include <rdf_init.h>
+#include <rdf_iterator.h>
+#include <rdf_uri.h>
+#include <rdf_node.h>
+#include <rdf_concepts.h>
+#include <rdf_statement.h>
+#include <rdf_model.h>
+#include <rdf_storage.h>
+#include <rdf_parser.h>
+#include <rdf_raptor.h>
+#include <rdf_serializer.h>
+#include <rdf_stream.h>
+#include <rdf_query.h>
+#include <rdf_utf8.h>
+#else
+#include <Redland/rdf_log.h>
+#include <Redland/rdf_digest.h>
+#include <Redland/rdf_hash.h>
+#include <Redland/rdf_init.h>
+#include <Redland/rdf_iterator.h>
+#include <Redland/rdf_uri.h>
+#include <Redland/rdf_node.h>
+#include <Redland/rdf_concepts.h>
+#include <Redland/rdf_statement.h>
+#include <Redland/rdf_model.h>
+#include <Redland/rdf_storage.h>
+#include <Redland/rdf_parser.h>
+#include <Redland/rdf_raptor.h>
+#include <Redland/rdf_serializer.h>
+#include <Redland/rdf_stream.h>
+#include <Redland/rdf_query.h>
+#include <Redland/rdf_utf8.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/external/redland/redland/libtool.patch b/external/redland/redland/libtool.patch
new file mode 100644
index 000000000..b0baae661
--- /dev/null
+++ b/external/redland/redland/libtool.patch
@@ -0,0 +1,27 @@
+--- build/ltmain.sh
++++ build/ltmain.sh
+@@ -5301,6 +5301,12 @@
+ prev=
+ continue
+ ;;
++ mllvm)
++ # Clang does not use LLVM to link, so we can simply discard any
++ # '-mllvm $arg' options when doing the link step.
++ prev=
++ continue
++ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+@@ -5639,6 +5645,11 @@
+ continue
+ ;;
+
++ -mllvm)
++ prev=mllvm
++ continue
++ ;;
++
+ -module)
+ module=yes
+ continue
diff --git a/external/redland/redland/redland-android.patch.1 b/external/redland/redland/redland-android.patch.1
new file mode 100644
index 000000000..c28fa19ff
--- /dev/null
+++ b/external/redland/redland/redland-android.patch.1
@@ -0,0 +1,14 @@
+No sonames on Android
+
+--- a/configure 2013-03-29 19:46:34.922901756 +0100
++++ b/configure 2013-03-29 19:46:56.051901574 +0100
+@@ -10267,7 +10267,7 @@
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+
diff --git a/external/redland/redland/redland-bundled-soname.patch.1 b/external/redland/redland/redland-bundled-soname.patch.1
new file mode 100644
index 000000000..867cd81e2
--- /dev/null
+++ b/external/redland/redland/redland-bundled-soname.patch.1
@@ -0,0 +1,13 @@
+rhbz#809466 change soname of bundled redland libs
+
+--- a/src/Makefile.in 2013-03-30 17:43:48.127008037 +0100
++++ b/src/Makefile.in 2013-03-30 17:44:19.294007769 +0100
+@@ -625,7 +625,7 @@
+ rdf_parser_raptor.c
+
+ EXTRA_DIST = redland.spec redland.spec.in mysql-v1.ttl mysql-v2.ttl
+-librdf_la_LDFLAGS = -version-info @LIBRDF_LIBTOOL_VERSION@ \
++librdf_la_LDFLAGS = -version-info @LIBRDF_LIBTOOL_VERSION@ -release lo \
+ @LIBRDF_LDFLAGS@ @LIBRDF_EXTERNAL_LIBS@
+
+ pkgdata_DATA = $(am__append_13)
diff --git a/external/redland/redland/redland-format.patch.0 b/external/redland/redland/redland-format.patch.0
new file mode 100644
index 000000000..7bd62a8bb
--- /dev/null
+++ b/external/redland/redland/redland-format.patch.0
@@ -0,0 +1,10 @@
+--- src/rdf_log.c
++++ src/rdf_log.c
+@@ -136,6 +136,7 @@
+ char *buffer = LIBRDF_MALLOC(char*, slocator_len + 2);
+ *buffer=' ';
+ raptor_locator_format(buffer + 1, slocator_len, (raptor_locator*)locator);
++ buffer[slocator_len + 1] = '\0';
+ fputs(buffer, stderr);
+ LIBRDF_FREE(char*, buffer);
+ }
diff --git a/external/redland/redland/redland-freebsd.patch.1 b/external/redland/redland/redland-freebsd.patch.1
new file mode 100644
index 000000000..349f3a197
--- /dev/null
+++ b/external/redland/redland/redland-freebsd.patch.1
@@ -0,0 +1,28 @@
+Usual patch to produce Linux-like .so files on FreeBSD
+
+--- a/build/ltmain.sh 2008-02-02 22:28:24.000000000 +0900
++++ b/build/ltmain.sh 2008-07-08 11:58:42.000000000 +0900
+@@ -7341,9 +7341,9 @@
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+- current="$number_major"
+- revision="$number_minor"
+- age="0"
++ current=`expr $number_major + $number_minor`
++ age="$number_minor"
++ revision="$number_revision"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+@@ -7420,8 +7420,8 @@
+ ;;
+
+ freebsd-elf)
+- major=".$current"
+- versuffix=".$current"
++ major=.`expr $current - $age`
++ versuffix="$major.$age.$revision"
+ ;;
+
+ irix | nonstopux)
diff --git a/external/redland/redland/redland-msvc.patch.1 b/external/redland/redland/redland-msvc.patch.1
new file mode 100644
index 000000000..e1f96b42a
--- /dev/null
+++ b/external/redland/redland/redland-msvc.patch.1
@@ -0,0 +1,123 @@
+--- redland.orig/src/win32_rdf_config.h 2015-09-02 23:12:12.894126138 +0200
++++ redland/src/win32_rdf_config.h 2015-09-02 23:23:54.600173246 +0200
+@@ -43,7 +43,6 @@
+ /* MS names for these functions */
+ // next line breaks build on wntmsci12
+ //#define vsnprintf _vsnprintf
+-#define snprintf _snprintf
+ #define access _access
+ #define stricmp _stricmp
+ #define strnicmp _strnicmp
+@@ -75,40 +78,40 @@
+ */
+
+ /* BDB has close method with 2 args */
+-#define HAVE_BDB_CLOSE_2_ARGS 1
++// #define HAVE_BDB_CLOSE_2_ARGS 1
+
+ /* BDB defines DBC */
+-#define HAVE_BDB_CURSOR 1
++// #define HAVE_BDB_CURSOR 1
+
+ /* BDB cursor method has 4 arguments */
+-#define HAVE_BDB_CURSOR_4_ARGS 1
++// #define HAVE_BDB_CURSOR_4_ARGS 1
+
+ /* BDB defines DB_TXN */
+-#define HAVE_BDB_DB_TXN 1
++// #define HAVE_BDB_DB_TXN 1
+
+ /* BDB has fd method with 2 args */
+-#define HAVE_BDB_FD_2_ARGS 1
++// #define HAVE_BDB_FD_2_ARGS 1
+
+ /* Have BDB hash support */
+-#define HAVE_BDB_HASH 1
++// #define HAVE_BDB_HASH 1
+
+ /* BDB has open method with 6 args */
+ /* #undef HAVE_BDB_OPEN_6_ARGS */
+
+ /* BDB has open method with 7 args */
+-#define HAVE_BDB_OPEN_7_ARGS 1
++// #define HAVE_BDB_OPEN_7_ARGS 1
+
+ /* BDB has set_flags method */
+-#define HAVE_BDB_SET_FLAGS 1
++// #define HAVE_BDB_SET_FLAGS 1
+
+ /* BDB has dbopen method */
+ /* #undef HAVE_DBOPEN */
+
+ /* BDB has db_create method */
+-#define HAVE_DB_CREATE 1
++// #define HAVE_DB_CREATE 1
+
+ /* Define to 1 if you have the <db.h> header file. */
+-#define HAVE_DB_H 1
++// #define HAVE_DB_H 1
+
+ /* Define to 1 if you have the <dlfcn.h> header file. */
+ /* undef HAVE_DLFCN_H */
+@@ -141,13 +144,13 @@
+ /* #undef HAVE_LIBWWW */
+
+ /* Have local MD5 digest */
+-#define HAVE_LOCAL_MD5_DIGEST 1
++// #define HAVE_LOCAL_MD5_DIGEST 1
+
+ /* Have local RIPEMD160 digest */
+ /* #undef HAVE_LOCAL_RIPEMD160_DIGEST */
+
+ /* Have local SHA1 digest */
+-#define HAVE_LOCAL_SHA1_DIGEST 1
++// #define HAVE_LOCAL_SHA1_DIGEST 1
+
+ /* Define to 1 if you have the <memory.h> header file. */
+ #define HAVE_MEMORY_H 1
+@@ -159,7 +162,7 @@
+ #define HAVE_MKTEMP 1
+
+ /* MySQL libraries are present */
+-#define HAVE_MYSQL 1
++// #define HAVE_MYSQL 1
+
+ /* Define to 1 if you have the <openssl/crypto.h> header file. */
+ /* #undef HAVE_OPENSSL_CRYPTO_H */
+@@ -261,7 +267,7 @@
+ /*#undef STORAGE_POSTGRESQL*/
+
+ /* Building SQLite storage */
+-#define STORAGE_SQLITE 1
++// #define STORAGE_SQLITE 1
+
+ /* Building 3store storage */
+ /*#undef STORAGE_TSTORE*/
+@@ -288,11 +288,11 @@
+ #include <io.h>
+ #include <memory.h>
+
+-/* get _isnan() since it is not in math.h */
+-#include <float.h>
+-#ifndef isnan
+-#define isnan(d) (_isnan(d))
+-#endif
++// /* get _isnan() since it is not in math.h */
++// #include <float.h>
++// #ifndef isnan
++// #define isnan(d) (_isnan(d))
++// #endif
+
+ #ifdef __cplusplus
+ }
+--- redland.orig/src/rdf_init.c 2015-09-02 23:12:12.894126138 +0200
++++ redland/src/rdf_init.c 2015-09-02 23:23:54.600173246 +0200
+@@ -42,6 +42,8 @@
+ #endif
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h> /* for getpid() */
++#else
++#include <process.h>
+ #endif
+
+ /* for gettimeofday */
diff --git a/external/redland/redland/redland-xcompile.patch.1 b/external/redland/redland/redland-xcompile.patch.1
new file mode 100644
index 000000000..2635359e7
--- /dev/null
+++ b/external/redland/redland/redland-xcompile.patch.1
@@ -0,0 +1,15 @@
+No point in creating example or util executables when cross-compiling.
+(Especially as doing it anyway wouldn't work without tweaks to have it find
+libxml2 and libm, at least for Android.)
+
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -395,7 +395,7 @@
+ DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
+
+ # Subdirectories to build/install/distribute etc.
+-SUBDIRS = $(subdirs) src examples utils demos docs data scripts
++SUBDIRS = $(subdirs) src docs data scripts
+ EXTRA_DIST = \
+ ChangeLog.1 ChangeLog.2 ChangeLog.3 ChangeLog.4 \
+ ChangeLog.5 ChangeLog.6 ChangeLog.7 ChangeLog.8 ChangeLog.9 ChangeLog.10 \
diff --git a/external/redland/redland/rpath.patch b/external/redland/redland/rpath.patch
new file mode 100644
index 000000000..ec8c765d5
--- /dev/null
+++ b/external/redland/redland/rpath.patch
@@ -0,0 +1,10 @@
+--- configure
++++ configure
+@@ -10308,6 +10308,7 @@
+ else
+ ld_shlibs=no
+ fi
++hardcode_libdir_flag_spec=
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
diff --git a/external/rhino/ExternalPackage_rhino.mk b/external/rhino/ExternalPackage_rhino.mk
new file mode 100644
index 000000000..0ee1d60e3
--- /dev/null
+++ b/external/rhino/ExternalPackage_rhino.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,rhino,rhino))
+
+$(eval $(call gb_ExternalPackage_use_external_project,rhino,rhino))
+
+$(eval $(call gb_ExternalPackage_add_file,rhino,$(LIBO_SHARE_JAVA_FOLDER)/js.jar,build/rhino1_5R5/js.jar))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/rhino/ExternalProject_rhino.mk b/external/rhino/ExternalProject_rhino.mk
new file mode 100644
index 000000000..6ef30ca34
--- /dev/null
+++ b/external/rhino/ExternalProject_rhino.mk
@@ -0,0 +1,32 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,rhino))
+
+$(eval $(call gb_ExternalProject_register_targets,rhino,\
+ build \
+))
+
+$(call gb_ExternalProject_get_state_target,rhino,build) :
+ $(call gb_Trace_StartRange,rhino,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ JAVA_HOME=$(JAVA_HOME_FOR_BUILD) \
+ $(ICECREAM_RUN) "$(ANT)" \
+ $(if $(verbose),-v,-q) \
+ -f build.xml \
+ -Dbuild.label="build-$(LIBO_VERSION_MAJOR).$(LIBO_VERSION_MINOR).$(LIBO_VERSION_MICRO).$(LIBO_VERSION_PATCH)" \
+ -DTARFILE_LOCATION="$(if $(findstring -cygwin,$(BUILD_PLATFORM)),$(shell cygpath -m $(TARFILE_LOCATION)),$(TARFILE_LOCATION))" \
+ -Dant.build.javac.source=$(JAVA_SOURCE_VER) \
+ -Dant.build.javac.target=$(JAVA_TARGET_VER) \
+ $(if $(debug),-Dbuild.debug="on") \
+ jar \
+ )
+ $(call gb_Trace_EndRange,rhino,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/rhino/Makefile b/external/rhino/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/rhino/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/rhino/Module_rhino.mk b/external/rhino/Module_rhino.mk
new file mode 100644
index 000000000..201d3ba9f
--- /dev/null
+++ b/external/rhino/Module_rhino.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,rhino))
+
+ifneq ($(ENABLE_JAVA),)
+ifneq ($(filter RHINO,$(BUILD_TYPE)),)
+$(eval $(call gb_Module_add_targets,rhino,\
+ ExternalPackage_rhino \
+ ExternalProject_rhino \
+ UnpackedTarball_rhino \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/rhino/OfficeScriptInfo.java b/external/rhino/OfficeScriptInfo.java
new file mode 100644
index 000000000..eb1d78641
--- /dev/null
+++ b/external/rhino/OfficeScriptInfo.java
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package org.mozilla.javascript.tools.debugger;
+import java.net.URL;
+import java.util.HashMap;
+import org.mozilla.javascript.Scriptable;
+
+public class OfficeScriptInfo
+{
+ private HashMap<String, SFScriptInfo> loadedSFScripts = new HashMap<String, SFScriptInfo>();
+
+ public void addScript( URL url, Scriptable scope, Runnable closeCallback )
+ {
+ addScript( url.toString(), url, scope, closeCallback );
+ }
+
+ public void addScript( String key, URL url, Scriptable scope, Runnable closeCallback )
+ {
+ SFScriptInfo si = loadedSFScripts.get( key );
+ if ( si == null )
+ {
+ si = new SFScriptInfo();
+ si.url = url;
+ si.scope = scope;
+ si.closeCallback = closeCallback;
+ loadedSFScripts.put( key, si );
+ }
+ }
+
+ public void deleteScript( String key )
+ {
+ SFScriptInfo info = loadedSFScripts.remove( key );
+ if ( info != null )
+ {
+ if ( info.closeCallback != null )
+ {
+ System.out.println("** In removeSFScriptInfo have callback for " + key );
+ info.closeCallback.run(); // really need to do this in separate thread????
+ }
+ }
+ }
+
+ public Scriptable getScriptScope( String key )
+ {
+ Scriptable result = null;
+ SFScriptInfo info = loadedSFScripts.get( key );
+ if ( info != null )
+ {
+ result = info.scope;
+ }
+ return result;
+ }
+
+ public URL getScriptUrl( String key )
+ {
+ URL result = null;
+ SFScriptInfo info = loadedSFScripts.get( key );
+ if ( info != null )
+ {
+ result = info.url;
+ }
+ return result;
+ }
+ public boolean hasScript( String key )
+ {
+ boolean result = true;
+ SFScriptInfo info = loadedSFScripts.get( key );
+ if ( info == null )
+ {
+ result = false;
+ }
+ return result;
+ }
+
+ public void setScriptRunning( String key, boolean running )
+ {
+ SFScriptInfo info = loadedSFScripts.get( key );
+ if ( info != null )
+ {
+ info.isExecuting = running;
+ }
+ }
+
+ public boolean isScriptRunning( String key )
+ {
+ boolean result = false;
+ SFScriptInfo info = loadedSFScripts.get( key );
+ if ( info != null )
+ {
+ result = info.isExecuting;
+ }
+ return result;
+ }
+
+ class SFScriptInfo
+ {
+ Scriptable scope;
+ boolean isExecuting;
+ URL url;
+ Runnable closeCallback;
+ }
+}
diff --git a/external/rhino/README b/external/rhino/README
new file mode 100644
index 000000000..83e4135d0
--- /dev/null
+++ b/external/rhino/README
@@ -0,0 +1,14 @@
+JavaScript engine/interpreter written in Java, used to provide JavaScript extensions.
+
+The Scripting Framework makes use of the Rhino ([http://www.mozilla.org/rhino/])
+JavaScript interpreter, available under the Mozilla Public License
+([http://www.mozilla.org/MPL/MPL-1.1.html]).
+
+In addition, to support the debugging of scripts contained in OpenOffice.org
+documents, we have modified the Java source file Main.java.
+
+The Rhino source tarball is unpacked and patched with the modified code. The
+Rhino Jar file (js.jar) is then built (download/swingExSrc.zip is unpacked and
+built as part of this procesS) and delivered to the solver. The file
+rhino1_5R5.patch contains the changes made in order to build Rhino. The patch
+was generated using the command: diff -wurN
diff --git a/external/rhino/UnpackedTarball_rhino.mk b/external/rhino/UnpackedTarball_rhino.mk
new file mode 100644
index 000000000..15a596eb1
--- /dev/null
+++ b/external/rhino/UnpackedTarball_rhino.mk
@@ -0,0 +1,25 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,rhino))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,rhino,$(RHINO_TARBALL),,rhino))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,rhino,2))
+
+$(eval $(call gb_UnpackedTarball_add_patches,rhino,\
+ external/rhino/rhino1_5R5.patch \
+ external/rhino/rhino1_5R5-find_swing.patch \
+ external/rhino/rhino1_5R5-updateToolTip.patch \
+ external/rhino/rhino-classpath.patch.1 \
+))
+
+$(eval $(call gb_UnpackedTarball_add_file,rhino,toolsrc/org/mozilla/javascript/tools/debugger/OfficeScriptInfo.java,external/rhino/OfficeScriptInfo.java))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/rhino/rhino-classpath.patch.1 b/external/rhino/rhino-classpath.patch.1
new file mode 100644
index 000000000..c751b95b5
--- /dev/null
+++ b/external/rhino/rhino-classpath.patch.1
@@ -0,0 +1,13 @@
+/usr/bin/ant will put dozens of jars on the classpath, including a
+rhino.jar that breaks the build
+
+--- rhino/build.xml.orig 2021-11-11 17:25:07.284267174 +0100
++++ rhino/build.xml 2021-11-11 17:25:38.689242510 +0100
+@@ -33,6 +33,7 @@
+ <property file="apiClasses.properties"/>
+ <property name="docsrc.dir" value="docs"/>
+ <property name="dist.docsrc.dir" value="src/docs"/>
++ <property name="build.sysclasspath" value="ignore"/>
+ </target>
+
+ <target name="init" depends="properties">
diff --git a/external/rhino/rhino1_5R5-find_swing.patch b/external/rhino/rhino1_5R5-find_swing.patch
new file mode 100644
index 000000000..905336eb1
--- /dev/null
+++ b/external/rhino/rhino1_5R5-find_swing.patch
@@ -0,0 +1,16 @@
+--- misc/rhino1_5R5/toolsrc/build.xml 2009-10-29 18:29:46.605524507 +0100
++++ misc/build/rhino1_5R5/toolsrc/build.xml 2009-10-29 18:29:26.536908810 +0100
+@@ -38,11 +38,12 @@
+ property="swing-ex-available"/>
+ </target>
+
++ <property name="swing_zip" value="${TARFILE_LOCATION}/35c94d2df8893241173de1d16b6034c0-swingExSrc.zip"/>
+ <target name="get-swing-ex" unless="swing-ex-available">
+ <!-- Download source from Sun's site, unzip it, remove
+ the files we don't need, and change the package
+ -->
+- <unzip src="../../../../../download/swingExSrc.zip" dest="${src.debugger}"/>
++ <unzip src="${swing_zip}" dest="${src.debugger}"/>
+ <delete file="${src.debugger}/FileSystemModel2.java" />
+ <delete file="${src.debugger}/MergeSort.java" />
+ <delete file="${src.debugger}/TreeTableExample2.java" />
diff --git a/external/rhino/rhino1_5R5-updateToolTip.patch b/external/rhino/rhino1_5R5-updateToolTip.patch
new file mode 100644
index 000000000..be0700daf
--- /dev/null
+++ b/external/rhino/rhino1_5R5-updateToolTip.patch
@@ -0,0 +1,23 @@
+--- misc/rhino1_5R5/toolsrc/org/mozilla/javascript/tools/debugger/Main.java Wed Feb 23 10:25:09 2011
++++ misc/build/rhino1_5R5/toolsrc/org/mozilla/javascript/tools/debugger/Main.java Wed Feb 23 10:25:01 2011
+@@ -1045,9 +1045,18 @@
+ } );
+ }
+
++ // Fix taken from <ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_7R2.zip>
++ // toolsrc/org/mozilla/javascript/tools/debugger/SwingGui.java:
+ private void updateToolTip() {
+- // in case fileName is very long, try to set tool tip on frame
+- Component c = getComponent(1);
++ // Try to set tool tip on frame. On macOS 10.5,
++ // the number of components is different, so try to be safe.
++ int n = getComponentCount() - 1;
++ if (n > 1) {
++ n = 1;
++ } else if (n < 0) {
++ return;
++ }
++ Component c = getComponent(n);
+ // this will work at least for Metal L&F
+ if (c != null && c instanceof JComponent) {
+ ((JComponent)c).setToolTipText(getUrl());
diff --git a/external/rhino/rhino1_5R5.patch b/external/rhino/rhino1_5R5.patch
new file mode 100644
index 000000000..40fc6cc94
--- /dev/null
+++ b/external/rhino/rhino1_5R5.patch
@@ -0,0 +1,1067 @@
+--- misc/rhino1_5R5/src/org/mozilla/javascript/DefiningClassLoader.java Thu Mar 25 21:54:34 2004
++++ misc/build/rhino1_5R5/src/org/mozilla/javascript/DefiningClassLoader.java Fri Mar 28 17:24:23 2008
+@@ -38,6 +38,7 @@
+ package org.mozilla.javascript;
+
+ import java.lang.reflect.Method;
++import java.lang.reflect.InvocationTargetException;
+
+ /**
+ * Load generated classes.
+@@ -48,11 +49,34 @@
+ implements GeneratedClassLoader
+ {
+ public DefiningClassLoader() {
+- this.parentLoader = getClass().getClassLoader();
++ init(getClass().getClassLoader());
+ }
+
+ public DefiningClassLoader(ClassLoader parentLoader) {
++
++ init(parentLoader);
++ }
++
++ private void init(ClassLoader parentLoader) {
++
+ this.parentLoader = parentLoader;
++
++ this.contextLoader = null;
++ if (method_getContextClassLoader != null) {
++ try {
++ this.contextLoader = (ClassLoader)
++ method_getContextClassLoader.invoke(
++ Thread.currentThread(),
++ ScriptRuntime.emptyArgs);
++ } catch (IllegalAccessException ex) {
++ } catch (InvocationTargetException ex) {
++ } catch (SecurityException ex) {
++ }
++ if (this.contextLoader == this.parentLoader) {
++ this.contextLoader = null;
++ }
++ }
++
+ }
+
+ public Class defineClass(String name, byte[] data) {
+@@ -68,10 +92,20 @@
+ {
+ Class cl = findLoadedClass(name);
+ if (cl == null) {
+- if (parentLoader != null) {
+- cl = parentLoader.loadClass(name);
++ // First try parent class loader and if that does not work, try
++ // contextLoader, but that will be null if
++ // Thread.getContextClassLoader() == parentLoader
++ // or on JDK 1.1 due to lack Thread.getContextClassLoader().
++ // To avoid catching and rethrowing ClassNotFoundException
++ // in this cases, use try/catch check only if contextLoader != null.
++ if (contextLoader == null) {
++ cl = loadFromParent(name);
+ } else {
+- cl = findSystemClass(name);
++ try {
++ cl = loadFromParent(name);
++ } catch (ClassNotFoundException ex) {
++ cl = contextLoader.loadClass(name);
++ }
+ }
+ }
+ if (resolve) {
+@@ -80,5 +114,37 @@
+ return cl;
+ }
+
++ private Class loadFromParent(String name)
++ throws ClassNotFoundException
++ {
++ if (parentLoader != null) {
++ return parentLoader.loadClass(name);
++ } else {
++ return findSystemClass(name);
++ }
++
++ }
++
+ private ClassLoader parentLoader;
++
++ private ClassLoader contextLoader;
++
++ // We'd like to use "Thread.getContextClassLoader", but
++ // that's only available on Java2.
++ private static Method method_getContextClassLoader;
++
++ static {
++ try {
++ // Don't use "Thread.class": that performs the lookup
++ // in the class initializer, which doesn't allow us to
++ // catch possible security exceptions.
++ Class threadClass = Class.forName("java.lang.Thread");
++ method_getContextClassLoader =
++ threadClass.getDeclaredMethod("getContextClassLoader",
++ new Class[0]);
++ } catch (ClassNotFoundException e) {
++ } catch (NoSuchMethodException e) {
++ } catch (SecurityException e) {
++ }
++ }
+ }
+--- misc/rhino1_5R5/toolsrc/build.xml 2004-03-25 21:54:34.000000000 +0100
++++ misc/build/rhino1_5R5/toolsrc/build.xml 2009-01-17 20:46:44.000000000 +0100
+@@ -6,6 +6,28 @@
+ -->
+ <project name="toolsrc" default="compile" basedir=".">
+
++ <condition property="boot_refID" value="macPath" else="nonMacPath">
++ <and>
++ <os family="mac"/>
++ <os family="unix"/>
++ <or>
++ <equals arg1="${ant.java.version}" arg2="1.5"/>
++ <equals arg1="${ant.java.version}" arg2="1.6"/>
++ </or>
++ </and>
++ </condition>
++ <path id="macPath" location="${java.home}/../Classes/classes.jar"/>
++ <!-- rhino.jar from OpenJDK breaks build -->
++ <path id="nonMacPath">
++ <fileset dir="${java.home}/">
++ <include name="jre/lib/*.jar"/>
++ <include name="lib/*.jar"/>
++ <exclude name="jre/lib/rhino.jar"/>
++ <exclude name="lib/rhino.jar"/>
++ </fileset>
++ </path>
++ <path id="my.bootstrap.classpath" refID="${boot_refID}"/>
++
+ <target name="properties">
+ <property name="nest" value=".."/>
+ <property name="build.dir" value="./build"/>
+@@ -20,46 +42,10 @@
+ <!-- Download source from Sun's site, unzip it, remove
+ the files we don't need, and change the package
+ -->
+- <get src="http://java.sun.com/products/jfc/tsc/articles/treetable2/downloads/src.zip" dest="${nest}/${build.dir}/swingExSrc.zip"/>
+- <unzip src="${nest}/${build.dir}/swingExSrc.zip" dest="${src.debugger}"/>
++ <unzip src="../../../../../download/swingExSrc.zip" dest="${src.debugger}"/>
+ <delete file="${src.debugger}/FileSystemModel2.java" />
+ <delete file="${src.debugger}/MergeSort.java" />
+ <delete file="${src.debugger}/TreeTableExample2.java" />
+- <replace file="${src.debugger}/AbstractCellEditor.java">
+- <replacetoken>import java.awt.Component;</replacetoken>
+- <replacevalue>
+- package org.mozilla.javascript.tools.debugger;
+- import java.awt.Component;
+- </replacevalue>
+- </replace>
+- <replace file="${src.debugger}/AbstractTreeTableModel.java">
+- <replacetoken>import javax.swing.tree.*;</replacetoken>
+- <replacevalue>
+- package org.mozilla.javascript.tools.debugger;
+- import javax.swing.tree.*;
+- </replacevalue>
+- </replace>
+- <replace file="${src.debugger}/JTreeTable.java">
+- <replacetoken>import javax.swing.*;</replacetoken>
+- <replacevalue>
+- package org.mozilla.javascript.tools.debugger;
+- import javax.swing.*;
+- </replacevalue>
+- </replace>
+- <replace file="${src.debugger}/TreeTableModel.java">
+- <replacetoken>import javax.swing.tree.TreeModel;</replacetoken>
+- <replacevalue>
+- package org.mozilla.javascript.tools.debugger;
+- import javax.swing.tree.TreeModel;
+- </replacevalue>
+- </replace>
+- <replace file="${src.debugger}/TreeTableModelAdapter.java">
+- <replacetoken>import javax.swing.JTree;</replacetoken>
+- <replacevalue>
+- package org.mozilla.javascript.tools.debugger;
+- import javax.swing.JTree;
+- </replacevalue>
+- </replace>
+ </target>
+
+ <target name="compile" depends="properties,get-swing-ex">
+--- misc/rhino1_5R5/toolsrc/org/mozilla/javascript/tools/debugger/Main.java 2004-03-25 21:54:34.000000000 +0100
++++ misc/build/rhino1_5R5/toolsrc/org/mozilla/javascript/tools/debugger/Main.java 2009-01-17 20:44:22.000000000 +0100
+@@ -470,15 +470,21 @@
+ case KeyEvent.VK_BACK_SPACE:
+ case KeyEvent.VK_ENTER:
+ case KeyEvent.VK_DELETE:
++ if (w.isEditable() == false) {
+ e.consume();
++ }
+ break;
+ }
+ }
+ public void keyTyped(KeyEvent e) {
++ if (w.isEditable() == false) {
+ e.consume();
++ }
+ }
+ public void keyReleased(KeyEvent e) {
++ if (w.isEditable() == false) {
+ e.consume();
++ }
+ }
+ }
+
+@@ -879,7 +885,7 @@
+ }
+ };
+
+-class FileWindow extends JInternalFrame implements ActionListener {
++class FileWindow extends JInternalFrame implements ActionListener, DocumentListener {
+
+ Main db;
+ SourceInfo sourceInfo;
+@@ -888,15 +894,16 @@
+ JScrollPane p;
+ int currentPos;
+ JLabel statusBar;
++ boolean isModified = false;
+
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ if (cmd.equals("Cut")) {
+- // textArea.cut();
++ textArea.cut();
+ } else if (cmd.equals("Copy")) {
+ textArea.copy();
+ } else if (cmd.equals("Paste")) {
+- // textArea.paste();
++ textArea.paste();
+ }
+ }
+
+@@ -910,17 +917,73 @@
+ }
+
+ void load() {
+- Scriptable scope = db.getScope();
++ //Scriptable scope = db.getScope();
++ Scriptable scope = db.officeScripts.getScriptScope( getUrl() );
++ if ( scope == null )
++ {
++ scope = db.getScope();
++ }
+ if (scope == null) {
+ MessageDialogWrapper.showMessageDialog(db, "Can't load scripts: no scope available", "Run", JOptionPane.ERROR_MESSAGE);
+ } else {
+ String url = getUrl();
+ if (url != null) {
+- new Thread(new LoadFile(db,scope,url)).start();
++ new Thread(new LoadFile(db,scope, url, new StringReader(textArea.getText()))).start();
+ }
+ }
+ }
+
++ void save() {
++ if (getUrl() != null) {
++ OutputStream os = null;
++ try {
++ if ( getUrl().startsWith("vnd.sun.star") )
++ {
++ URL scriptUrl = db.officeScripts.getScriptUrl( getUrl() );
++ if ( scriptUrl == null )
++ {
++ throw new IOException("Can't optain stream for " + getUrl() );
++ }
++ os = scriptUrl.openConnection().getOutputStream();
++ }
++ else
++ {
++ os = new FileOutputStream( getUrl() );
++ }
++ String s = textArea.getText();
++ os.write(s.getBytes(), 0, s.length());
++
++ this.isModified = false;
++ }
++ catch (IOException ioe) {
++ JOptionPane.showMessageDialog(this,
++ "Error saving file: " + ioe.getMessage(),
++ "Error", JOptionPane.ERROR_MESSAGE);
++ }
++ finally
++ {
++ if ( os != null )
++ {
++ try
++ {
++ os.close();
++ os = null;
++ }
++ catch( IOException ioe )
++ {
++ System.err.println("Error closing stream: " + ioe.getMessage() );
++ ioe.printStackTrace();
++ }
++ }
++ }
++ }
++ }
++
++ public boolean isEditable() {
++ return db.isSourceEditingEnabled();
++ }
++
++
+ public int getPosition(int line) {
+ int result = -1;
+ try {
+@@ -953,7 +1016,7 @@
+ fileHeader.repaint();
+ }
+ }
+-
++ public Main getDB() { return db; }
+ FileWindow(Main db, SourceInfo sourceInfo) {
+ super(SourceInfo.getShortName(sourceInfo.getUrl()),
+ true, true, true, true);
+@@ -972,6 +1035,14 @@
+ pack();
+ updateText();
+ textArea.select(0);
++ addInternalFrameListener( new InternalFrameAdapter() {
++ public void internalFrameClosed(InternalFrameEvent e) {
++ // clean up scriptItems and sourceNames hashes
++ getDB().removeScript( getUrl() );
++ // remove scripts for officeScripts
++ getDB().officeScripts.deleteScript( getUrl() );
++ }
++ } );
+ }
+
+ private void updateToolTip() {
+@@ -990,7 +1061,10 @@
+ void updateText() {
+ String newText = sourceInfo.getSource();
+ if (!textArea.getText().equals(newText)) {
++ textArea.getDocument().removeDocumentListener(this);
+ textArea.setText(newText);
++ this.isModified = false;
++ textArea.getDocument().addDocumentListener(this);
+ int pos = 0;
+ if (currentPos != -1) {
+ pos = currentPos;
+@@ -1001,6 +1075,31 @@
+ fileHeader.repaint();
+ }
+
++ /* Implementation of DocumentListener interface */
++ public void insertUpdate(DocumentEvent e) {
++ doChanged(e);
++ }
++
++ public void removeUpdate(DocumentEvent e) {
++ doChanged(e);
++ }
++
++ public void changedUpdate(DocumentEvent e) {
++ doChanged(e);
++ }
++
++ public void doChanged(DocumentEvent e) {
++ this.isModified = true;
++ }
++
++ public boolean isModified() {
++ return this.isModified;
++ }
++
++ public String getText() {
++ return textArea.getText();
++ }
++
+ void setPosition(int pos) {
+ textArea.select(pos);
+ currentPos = pos;
+@@ -1618,7 +1717,7 @@
+ if (line != -1) {
+ db.currentWindow = w;
+ }
+- db.menubar.addFile(url);
++ // db.menubar.addFile(url);
+ w.setVisible(true);
+ if (activate) {
+ try {
+@@ -1752,8 +1851,10 @@
+ Menubar(Main db) {
+ super();
+ this.db = db;
+- String[] fileItems = {"Open...", "Run...", "", "Exit"};
+- String[] fileCmds = {"Open", "Load", "", "Exit"};
++ // String[] fileItems = {"Open...", "Run...", "", "Exit"};
++ // String[] fileCmds = {"Open", "Load", "", "Exit"};
++ String[] fileItems = {"Run", "Save", "", "Exit"};
++ String[] fileCmds = {"Run", "Save", "", "Exit"};
+ char[] fileShortCuts = {'0', 'N', '\0', 'X'};
+ int[] fileAccelerators = {KeyEvent.VK_O,
+ KeyEvent.VK_N,
+@@ -1795,6 +1896,9 @@
+ KeyStroke k = KeyStroke.getKeyStroke(fileAccelerators[i], Event.CTRL_MASK);
+ item.setAccelerator(k);
+ }
++ if (fileItems[i].equals("Save")) {
++ saveItem = item;
++ }
+ }
+ }
+ for (int i = 0; i < editItems.length; ++i) {
+@@ -1849,9 +1953,9 @@
+ item.addActionListener(this);
+ windowMenu.add(item = new JMenuItem("Tile", 'T'));
+ item.addActionListener(this);
+- windowMenu.addSeparator();
+- windowMenu.add(item = new JMenuItem("Console", 'C'));
+- item.addActionListener(this);
++// windowMenu.addSeparator();
++// windowMenu.add(item = new JMenuItem("Console", 'C'));
++// item.addActionListener(this);
+ add(windowMenu);
+
+ }
+@@ -1925,11 +2029,16 @@
+ item.addActionListener(this);
+ }
+
++ public void setSaveEnabled(boolean state) {
++ saveItem.setEnabled(state);
++ }
++
+ Main db;
+ JMenu windowMenu;
+ JCheckBoxMenuItem breakOnExceptions;
+ JCheckBoxMenuItem breakOnEnter;
+ JCheckBoxMenuItem breakOnReturn;
++ JMenuItem saveItem;
+ };
+
+ class EnterInterrupt implements Runnable {
+@@ -1942,6 +2051,13 @@
+ public void run() {
+ JMenu menu = db.getJMenuBar().getMenu(0);
+ //menu.getItem(0).setEnabled(false); // File->Load
++
++ // disable Edit menu Cut, Copy, Paste items
++ menu = db.getJMenuBar().getMenu(1);
++ for (int i = 0; i < 3; i++) {
++ menu.getItem(i).setEnabled(false);
++ }
++
+ menu = db.getJMenuBar().getMenu(2);
+ menu.getItem(0).setEnabled(false); // Debug->Break
+ int count = menu.getItemCount();
+@@ -1954,6 +2070,10 @@
+ b = true;
+ }
+ db.toolBar.setEnabled(true);
++
++ // set flag to disable source editing
++ db.setSourceEditingEnabled(false);
++
+ // raise the debugger window
+ db.toFront();
+ }
+@@ -1967,6 +2087,13 @@
+ public void run() {
+ JMenu menu = db.getJMenuBar().getMenu(0);
+ menu.getItem(0).setEnabled(true); // File->Load
++
++ // enable Edit menu items
++ menu = db.getJMenuBar().getMenu(1);
++ for (int i = 0; i < 3; i++) {
++ menu.getItem(i).setEnabled(true);
++ }
++
+ menu = db.getJMenuBar().getMenu(2);
+ menu.getItem(0).setEnabled(true); // Debug->Break
+ int count = menu.getItemCount() - 1;
+@@ -1980,6 +2107,10 @@
+ db.toolBar.getComponent(ci).setEnabled(b);
+ b = false;
+ }
++
++ // set flag to enable source editing
++ db.setSourceEditingEnabled(true);
++
+ //db.console.consoleTextArea.requestFocus();
+ }
+ };
+@@ -1988,17 +2119,24 @@
+ {
+ String fileName;
+ Main db;
++ Reader reader = null;
+ OpenFile(Main db, String fileName)
+ {
+ this.fileName = fileName;
+ this.db = db;
+ }
++ OpenFile(Main db, String fileName, Reader reader) {
++ this(db, fileName);
++ this.reader = reader;
++ }
+ public void run() {
+ Context cx = Context.enter();
+ ContextData contextData = ContextData.get(cx);
+ contextData.breakNextLine = true;
+ try {
+- cx.compileReader(new FileReader(fileName), fileName, 1, null);
++ cx.compileReader(
++ reader == null ? new FileReader(fileName) : reader,
++ fileName, 1, null);
+ } catch (Exception exc) {
+ String msg = exc.getMessage();
+ if (exc instanceof EcmaError) {
+@@ -2019,29 +2157,79 @@
+ Scriptable scope;
+ String fileName;
+ Main db;
++ Reader reader = null;
++ Object result = null;
++ Exception exception = null;
++ int lineNum = -1;
++ boolean sfExecute = false;
++
+ LoadFile(Main db, Scriptable scope, String fileName) {
+ this.scope = scope;
+ this.fileName = fileName;
+ this.db = db;
+ }
++
++ LoadFile(Main db, Scriptable scope, String fileName, Reader reader) {
++ this(db, scope, fileName);
++ this.reader = reader;
++ }
++ LoadFile(Main db, Scriptable scope, String fileName, Reader reader, boolean sfExecute ) {
++ this(db, scope, fileName);
++ this.reader = reader;
++ this.sfExecute = sfExecute;
++ }
++
+ public void run() {
++ if ( db.officeScripts.isScriptRunning( fileName ) )
++ {
++ exception = new Exception("The script is already executing");
++ if ( !sfExecute ) {
++ MessageDialogWrapper.showMessageDialog(db,
++ "Script already executing",
++ "Run",
++ JOptionPane.ERROR_MESSAGE);
++ }
++ return;
++ }
++ db.officeScripts.setScriptRunning( fileName, true );
+ Context cx = Context.enter();
+ ContextData contextData = ContextData.get(cx);
++ if ( sfExecute )
++ {
++ contextData.breakNextLine = false;
++ }
++ else
++ {
+ contextData.breakNextLine = true;
++ }
++ /*
++ FileWindow w = (FileWindow)db.getSelectedFrame();
++ if ( sfExecute )
++ {
++ db.swingInvoke(new SetFilePosition(db, w, -1 ) );
++ }*/
+ try {
+- cx.evaluateReader(scope, new FileReader(fileName),
++ result = cx.evaluateReader(scope,
++ reader == null ? new FileReader(fileName) : reader,
+ fileName, 1, null);
+ } catch (Exception exc) {
++ exception = exc;
+ String msg = exc.getMessage();
+ if (exc instanceof EcmaError) {
+ EcmaError err = (EcmaError)exc;
+ msg = err.getSourceName() + ", line " + err.getLineNumber() + ": " + msg;
+- }
++
++ int lineNum = err.getLineNumber() ;
++ //db.swingInvoke(new SetFilePosition(db, w, lineNum ) );
++ if ( !sfExecute ) {
+ MessageDialogWrapper.showMessageDialog(db,
+ msg,
+ "Run",
+ JOptionPane.ERROR_MESSAGE);
++ }
++ }
+ } finally {
++ db.officeScripts.setScriptRunning( fileName, false );
+ cx.exit();
+ }
+ }
+@@ -2416,13 +2604,13 @@
+ super.setVisible(b);
+ if (b) {
+ // this needs to be done after the window is visible
+- console.consoleTextArea.requestFocus();
++ // console.consoleTextArea.requestFocus();
+ context.split.setDividerLocation(0.5);
+ try {
+- console.setMaximum(true);
+- console.setSelected(true);
+- console.show();
+- console.consoleTextArea.requestFocus();
++ // console.setMaximum(true);
++ // console.setSelected(true);
++ // console.show();
++ // console.consoleTextArea.requestFocus();
+ } catch (Exception exc) {
+ }
+ }
+@@ -2449,35 +2637,6 @@
+
+ Hashtable functionNames = new Hashtable();
+
+- ScriptItem getScriptItem(DebuggableScript fnOrScript) {
+- ScriptItem item = (ScriptItem)scriptItems.get(fnOrScript);
+- if (item == null) {
+- String url = getNormilizedUrl(fnOrScript);
+- SourceInfo si = (SourceInfo)sourceNames.get(url);
+- if (si == null) {
+- if (!fnOrScript.isGeneratedScript()) {
+- // Not eval or Function, try to load it from URL
+- String source = null;
+- try {
+- InputStream is = openSource(url);
+- try { source = readSource(is); }
+- finally { is.close(); }
+- } catch (IOException ex) {
+- System.err.println
+- ("Failed to load source from "+url+": "+ ex);
+- }
+- if (source != null) {
+- si = registerSource(url, source);
+- }
+- }
+- }
+- if (si != null) {
+- item = registerScript(si, fnOrScript);
+- }
+- }
+- return item;
+- }
+-
+ /* Debugger Interface */
+
+ public void handleCompilationDone(Context cx, DebuggableScript fnOrScript,
+@@ -2490,7 +2649,7 @@
+
+ String getNormilizedUrl(DebuggableScript fnOrScript) {
+ String url = fnOrScript.getSourceName();
+- if (url == null) { url = "<stdin>"; }
++ if (url == null) { url = "document"; }
+ else {
+ // Not to produce window for eval from different lines,
+ // strip line numbers, i.e. replace all #[0-9]+\(eval\) by (eval)
+@@ -2601,7 +2760,7 @@
+ if (si == null) {
+ si = new SourceInfo(sourceUrl, source);
+ sourceNames.put(sourceUrl, si);
+- } else {
++ } else if (!source.equals(si.getSource())) {
+ si.setSource(source);
+ }
+ }
+@@ -2762,7 +2921,7 @@
+ desk = new JDesktopPane();
+ desk.setPreferredSize(new Dimension(600, 300));
+ desk.setMinimumSize(new Dimension(150, 50));
+- desk.add(console = new JSInternalConsole("JavaScript Console"));
++ // desk.add(console = new JSInternalConsole("JavaScript Console"));
+ context = new ContextWindow(this);
+ context.setPreferredSize(new Dimension(600, 120));
+ context.setMinimumSize(new Dimension(50, 50));
+@@ -2871,7 +3030,7 @@
+ FrameHelper frame = contextData.getFrame(frameIndex);
+ String sourceName = frame.getUrl();
+ if (sourceName == null || sourceName.equals("<stdin>")) {
+- console.show();
++ // console.show();
+ helper.reset();
+ return;
+ }
+@@ -2895,6 +3054,19 @@
+ int dispatcherIsWaiting = 0;
+ Context currentContext = null;
+
++ // Flag used to establish whether source code editing is allowed in
++ // the debugger, switched on and off depending on whether a debug session
++ // is active
++ boolean sourceEditingEnabled = true;
++
++ public boolean isSourceEditingEnabled() {
++ return sourceEditingEnabled;
++ }
++
++ void setSourceEditingEnabled(boolean b) {
++ sourceEditingEnabled = b;
++ }
++
+ Context getCurrentContext() {
+ return currentContext;
+ }
+@@ -3028,14 +3200,14 @@
+ swingInvoke(CreateFileWindow.action(this, si, line));
+ }
+ } else {
+- if (console.isVisible()) {
++ /* if (console.isVisible()) {
+ final JSInternalConsole finalConsole = console;
+ swingInvoke(new Runnable() {
+ public void run() {
+ finalConsole.show();
+ }
+ });
+- }
++ } */
+ }
+ swingInvoke(new EnterInterrupt(this, cx));
+ swingInvoke(new UpdateContext(this, cx));
+@@ -3217,6 +3389,14 @@
+ fileName)).start();
+ }
+ }
++ } else if (cmd.equals("Run")) {
++ FileWindow w = (FileWindow)getSelectedFrame();
++ if (w != null)
++ w.load();
++ } else if (cmd.equals("Save")) {
++ FileWindow w = (FileWindow)getSelectedFrame();
++ if (w != null)
++ w.save();
+ } else if (cmd.equals("More Windows...")) {
+ MoreWindows dlg = new MoreWindows(this, fileWindows,
+ "Window", "Files");
+@@ -3509,6 +3689,60 @@
+ }
+ }
+
++ JInternalFrame getFrameForUrl( URL url )
++ {
++ JInternalFrame[] frames = desk.getAllFrames();
++ for (int i = 0; i < frames.length; i++) {
++ FileWindow w = (FileWindow)frames[i];
++ if ( url.toString().equals( w.getUrl() ) ) {
++ return w;
++ }
++ }
++ return null;
++ }
++ public void highlighLineInSelectedWindow(URL url, int lineNum ){
++ //FileWindow w = (FileWindow)getFrameForUrl( url );
++ FileWindow w = (FileWindow)getSelectedFrame();
++ if (w != null)
++ {
++ if ( lineNum > -1 )
++ swingInvoke(new SetFilePosition(this, w, lineNum ) );
++ }
++ }
++ public Object runSelectedWindow( URL scriptUrl ) throws Exception
++ {
++ Object result = null;
++ FileWindow w = (FileWindow)getSelectedFrame();
++ //FileWindow w = (FileWindow)getFrameForUrl( scriptUrl );
++ w.toFront();
++ if (w != null)
++ {
++ Scriptable scope = w.db.getScope();
++ if (scope == null)
++ {
++ MessageDialogWrapper.showMessageDialog(w.db, "Can't load scripts: no scope available", "Run", JOptionPane.ERROR_MESSAGE);
++ result = null;
++ }
++ else
++ {
++ String url = w.getUrl();
++ Thread executorThread = null;
++ if (url != null)
++ {
++ LoadFile executor = new LoadFile(w.db,scope, url, new StringReader(w.textArea.getText()), true );
++ executor.run();
++ result = executor.result;
++ if ( executor.exception != null )
++ {
++ throw executor.exception;
++ }
++ }
++ }
++ }
++ return result;
++
++ }
++
+ //
+ // public interface
+ //
+@@ -3604,6 +3838,69 @@
+ return console.getErr();
+ }
+
++ public void openFile(URL scriptUrl, Scriptable scope, Runnable closeCallback ) {
++ if (scope == null) {
++ MessageDialogWrapper.showMessageDialog(this,
++ "Can't compile scripts: no scope available",
++ "Open", JOptionPane.ERROR_MESSAGE);
++ } else {
++ if (scriptUrl != null) {
++ try
++ {
++ InputStreamReader reader = new InputStreamReader(scriptUrl.openStream());
++ String fileName = null;
++ if ( scriptUrl.getProtocol().startsWith("vnd.sun.star.") )
++ {
++ fileName = scriptUrl.toString();
++ }
++ else
++ {
++ fileName = scriptUrl.getPath();
++ }
++ officeScripts.addScript( fileName, scriptUrl, scope, closeCallback );
++ //new Thread(new OpenFile(this, scope, fileName, reader )).start();
++ swingInvoke( new OpenFile(this, fileName, reader ));
++ }
++ catch ( IOException e )
++ {
++ MessageDialogWrapper.showMessageDialog(this,
++ "Can't open stream for script: " + e.toString(),
++ "Open", JOptionPane.ERROR_MESSAGE);
++ }
++ }
++ }
++ split1.setDividerLocation(1.0);
++ }
++
++ public void openFile(String fileName) {
++ Scriptable scope = getScope();
++ if (scope == null) {
++ MessageDialogWrapper.showMessageDialog(this,
++ "Can't compile scripts: no scope available",
++ "Open", JOptionPane.ERROR_MESSAGE);
++ } else {
++ if (fileName != null) {
++ new Thread(new OpenFile(this, fileName)).start();
++ }
++ }
++ split1.setDividerLocation(1.0);
++ }
++
++ public void openStream(InputStream in) {
++ Scriptable scope = getScope();
++ if (scope == null) {
++ MessageDialogWrapper.showMessageDialog(this,
++ "Can't compile scripts: no scope available",
++ "Open", JOptionPane.ERROR_MESSAGE);
++ } else {
++ if (in != null) {
++ new Thread(new OpenFile(this, null, new InputStreamReader(in))).start();
++ }
++ }
++ split1.setDividerLocation(1.0);
++ menubar.setSaveEnabled(false);
++ }
++
+ public static void main(String[] args) {
+ try {
+ mainThread = Thread.currentThread();
+@@ -3635,5 +3932,162 @@
+ }
+ }
+
++ // patched Office specific interface
++
++ OfficeScriptInfo officeScripts = new OfficeScriptInfo();
++
++ void removeScript( String url )
++ {
++ // Remove the FileWindow from list of open sources
++ fileWindows.remove( url );
++
++ // Remove sourceInfo from sourceNames, ensures that
++ // breakpoints etc are deleted
++ synchronized (sourceNames) {
++ sourceNames.remove( url );
++ }
++ // Removes scriptItems for the script, ensures that a new open ( from openFile )
++ // will succeed, openFile should open file but fails due to fact that
++ synchronized ( scriptItems )
++ {
++ Iterator iter = scriptItems.entrySet().iterator();
++ while ( iter.hasNext() )
++ {
++ Map.Entry me = ( Map.Entry )iter.next();
++ ScriptItem item = (ScriptItem)me.getValue();
++ SourceInfo si = item.getSourceInfo();
++ if ( si.getUrl().equals( url ) )
++ {
++ //match
++ scriptItems.remove( me.getKey() );
++ break;
++ }
++ }
++ }
++ officeScripts.deleteScript( url );
++ }
++
++
++ ScriptItem getScriptItem(DebuggableScript fnOrScript) {
++ ScriptItem item = (ScriptItem)scriptItems.get(fnOrScript);
++ if (item == null) {
++ String url = getNormilizedUrl(fnOrScript);
++ SourceInfo si = (SourceInfo)sourceNames.get(url);
++ if (si == null) {
++ if (!fnOrScript.isGeneratedScript()) {
++ // Not eval or Function, try to load it from URL
++ String source = null;
++ try {
++ InputStream is = openSource(url);
++ try { source = readSource(is); }
++ finally { is.close(); }
++ } catch (IOException ex) {
++ System.err.println
++ ("Failed to load source from "+url+": "+ ex);
++ }
++ if (source != null) {
++ si = registerSource(url, source);
++ }
++ }
++ }
++ if (si != null) {
++ item = registerScript(si, fnOrScript);
++ }
++ }
++
++ return item;
++ }
++
++ public void showScriptWindow(URL url ){
++ String key = url.getPath();
++ if ( url.getProtocol().startsWith("vnd.sun.star") )
++ {
++ key = url.toString();
++ }
++ FileWindow w = (FileWindow)getFileWindow( key );
++ if ( w != null )
++ {
++ //w.maximize();
++ desk.getDesktopManager().deiconifyFrame(w);
++ desk.getDesktopManager().activateFrame(w);
++ w.show();
++ w.toFront();
++ }
++ }
++
++ public void highlighLineInScriptWindow(URL url, int lineNum ){
++ String key = url.getPath();
++ if ( url.getProtocol().startsWith("vnd.sun.star") )
++ {
++ key = url.getPath();
++ }
++ FileWindow w = (FileWindow)getFileWindow( key );
++ if (w != null)
++ {
++ if ( lineNum > -1 )
++ swingInvoke(new SetFilePosition(this, w, lineNum ) );
++ }
++ }
++ public Object runScriptWindow( URL scriptUrl ) throws Exception
++ {
++ String key = scriptUrl.getPath();
++ if ( scriptUrl.getProtocol().startsWith("vnd.sun.star") )
++ {
++ key = scriptUrl.toString();
++ }
++ FileWindow w = (FileWindow)getFileWindow( key );
++ Object result = null;
++ w.toFront();
++ if (w != null)
++ {
++ //Scriptable scope = w.db.getScope();
++ Scriptable scope = w.db.officeScripts.getScriptScope( key );
++ if (scope == null)
++ {
++ MessageDialogWrapper.showMessageDialog(w.db, "Can't load scripts: no scope available", "Run", JOptionPane.ERROR_MESSAGE);
++ result = null;
++ }
++ else
++ {
++ String url = w.getUrl();
++ Thread executorThread = null;
++ if (url != null)
++ {
++ LoadFile executor = new LoadFile(w.db,scope, url, new StringReader(w.textArea.getText()), true );
++ executor.run();
++ result = executor.result;
++ if ( executor.exception != null )
++ {
++ throw executor.exception;
++ }
++ }
++ }
++ }
++ return result;
++
++ }
++
++ public boolean isModified( URL url )
++ {
++ String key = url.getPath();
++ if ( url.getProtocol().startsWith("vnd.sun.star") )
++ {
++ key = url.toString();
++ }
++ FileWindow w = (FileWindow)getFileWindow( key );
++ return w.isModified();
++ }
++
++ public String getText( URL url )
++ {
++ String key = url.toString();
++ if ( url.getProtocol().startsWith("vnd.sun.star") )
++ {
++ key = url.toString();
++ }
++ FileWindow w = (FileWindow)getFileWindow( key );
++ return w.getText();
++ }
++
+ }
+
+--- misc/rhino1_5R5/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java Thu Mar 25 21:54:34 2004
++++ misc/build/rhino1_5R5/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java Fri Mar 28 17:24:23 2008
+@@ -36,6 +36,7 @@
+ package org.mozilla.javascript.tools.shell;
+
+ import java.security.*;
++import java.security.cert.Certificate;
+ import java.net.MalformedURLException;
+ import java.net.URL;
+ import java.util.Hashtable;
+@@ -124,7 +125,7 @@
+
+ public JavaPolicySecurity() {
+ // To trigger error on jdk-1.1 with lazy load
+- new CodeSource(null, null);
++ new CodeSource(null, (Certificate [])null);
+ }
+
+ protected void callProcessFileSecure(final Context cx,
+@@ -167,7 +168,7 @@
+ }
+
+ private ProtectionDomain getUrlDomain(URL url) {
+- CodeSource cs = new CodeSource(url, null);
++ CodeSource cs = new CodeSource(url, (Certificate [])null);
+ PermissionCollection pc = Policy.getPolicy().getPermissions(cs);
+ return new ProtectionDomain(cs, pc);
+ }
diff --git a/external/sane/README b/external/sane/README
new file mode 100644
index 000000000..eda976da1
--- /dev/null
+++ b/external/sane/README
@@ -0,0 +1 @@
+Scanner library from [http://www.sane-project.org/]
diff --git a/external/sane/inc/sane/sane.h b/external/sane/inc/sane/sane.h
new file mode 100644
index 000000000..eb18eef1a
--- /dev/null
+++ b/external/sane/inc/sane/sane.h
@@ -0,0 +1,213 @@
+/* sane - Scanner Access Now Easy.
+ Copyright (C) 1997 David Mosberger-Tang and Andreas Beck
+ This file is part of the SANE package.
+
+ This file is in the public domain. You may use and modify it as
+ you see fit, as long as this copyright message is included and
+ that there is an indication as to what modifications have been
+ made (if any).
+
+ SANE 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.
+
+ This file declares SANE application interface. See the SANE
+ standard for a detailed explanation of the interface. */
+#ifndef sane_h
+#define sane_h
+
+#define SANE_CURRENT_MAJOR 0
+
+#define SANE_VERSION_CODE(major, minor, build) \
+ ( (((SANE_Word) (major) & 0xff) << 24) \
+ | (((SANE_Word) (minor) & 0xff) << 16) \
+ | (((SANE_Word) (build) & 0xffff) << 0))
+
+#define SANE_VERSION_MAJOR(code) ((((SANE_Word)(code)) >> 24) & 0xff)
+#define SANE_VERSION_MINOR(code) ((((SANE_Word)(code)) >> 16) & 0xff)
+#define SANE_VERSION_BUILD(code) ((((SANE_Word)(code)) >> 0) & 0xffff)
+
+#define SANE_FALSE 0
+#define SANE_TRUE 1
+
+typedef unsigned char SANE_Byte;
+typedef int SANE_Word;
+typedef SANE_Word SANE_Bool;
+typedef SANE_Word SANE_Int;
+typedef char SANE_Char;
+typedef SANE_Char *SANE_String;
+typedef const SANE_Char *SANE_String_Const;
+typedef void *SANE_Handle;
+typedef SANE_Word SANE_Fixed;
+
+#define SANE_FIXED_SCALE_SHIFT 16
+#define SANE_FIX(v) ((SANE_Word) ((v) * (1 << SANE_FIXED_SCALE_SHIFT)))
+#define SANE_UNFIX(v) ((double)(v) / (1 << SANE_FIXED_SCALE_SHIFT))
+
+typedef enum
+ {
+ SANE_STATUS_GOOD = 0, /* everything A-OK */
+ SANE_STATUS_UNSUPPORTED, /* operation is not supported */
+ SANE_STATUS_CANCELLED, /* operation was cancelled */
+ SANE_STATUS_DEVICE_BUSY, /* device is busy; try again later */
+ SANE_STATUS_INVAL, /* data is invalid (includes no dev at open) */
+ SANE_STATUS_EOF, /* no more data available (end-of-file) */
+ SANE_STATUS_JAMMED, /* document feeder jammed */
+ SANE_STATUS_NO_DOCS, /* document feeder out of documents */
+ SANE_STATUS_COVER_OPEN, /* scanner cover is open */
+ SANE_STATUS_IO_ERROR, /* error during device I/O */
+ SANE_STATUS_NO_MEM, /* out of memory */
+ SANE_STATUS_ACCESS_DENIED /* access to resource has been denied */
+ }
+SANE_Status;
+
+typedef enum
+ {
+ SANE_TYPE_BOOL = 0,
+ SANE_TYPE_INT,
+ SANE_TYPE_FIXED,
+ SANE_TYPE_STRING,
+ SANE_TYPE_BUTTON,
+ SANE_TYPE_GROUP
+ }
+SANE_Value_Type;
+
+typedef enum
+ {
+ SANE_UNIT_NONE = 0, /* the value is unit-less (e.g., # of scans) */
+ SANE_UNIT_PIXEL, /* value is number of pixels */
+ SANE_UNIT_BIT, /* value is number of bits */
+ SANE_UNIT_MM, /* value is millimeters */
+ SANE_UNIT_DPI, /* value is resolution in dots/inch */
+ SANE_UNIT_PERCENT, /* value is a percentage */
+ SANE_UNIT_MICROSECOND /* value is micro seconds */
+ }
+SANE_Unit;
+
+typedef struct
+ {
+ SANE_String_Const name; /* unique device name */
+ SANE_String_Const vendor; /* device vendor string */
+ SANE_String_Const model; /* device model name */
+ SANE_String_Const type; /* device type (e.g., "flatbed scanner") */
+ }
+SANE_Device;
+
+#define SANE_CAP_SOFT_SELECT (1 << 0)
+#define SANE_CAP_HARD_SELECT (1 << 1)
+#define SANE_CAP_SOFT_DETECT (1 << 2)
+#define SANE_CAP_EMULATED (1 << 3)
+#define SANE_CAP_AUTOMATIC (1 << 4)
+#define SANE_CAP_INACTIVE (1 << 5)
+#define SANE_CAP_ADVANCED (1 << 6)
+#define SANE_CAP_ALWAYS_SETTABLE (1 << 7)
+
+#define SANE_OPTION_IS_ACTIVE(cap) (((cap) & SANE_CAP_INACTIVE) == 0)
+#define SANE_OPTION_IS_SETTABLE(cap) (((cap) & SANE_CAP_SOFT_SELECT) != 0)
+
+#define SANE_INFO_INEXACT (1 << 0)
+#define SANE_INFO_RELOAD_OPTIONS (1 << 1)
+#define SANE_INFO_RELOAD_PARAMS (1 << 2)
+
+typedef enum
+ {
+ SANE_CONSTRAINT_NONE = 0,
+ SANE_CONSTRAINT_RANGE,
+ SANE_CONSTRAINT_WORD_LIST,
+ SANE_CONSTRAINT_STRING_LIST
+ }
+SANE_Constraint_Type;
+
+typedef struct
+ {
+ SANE_Word min; /* minimum (element) value */
+ SANE_Word max; /* maximum (element) value */
+ SANE_Word quant; /* quantization value (0 if none) */
+ }
+SANE_Range;
+
+typedef struct
+ {
+ SANE_String_Const name; /* name of this option (command-line name) */
+ SANE_String_Const title; /* title of this option (single-line) */
+ SANE_String_Const desc; /* description of this option (multi-line) */
+ SANE_Value_Type type; /* how are values interpreted? */
+ SANE_Unit unit; /* what is the (physical) unit? */
+ SANE_Int size;
+ SANE_Int cap; /* capabilities */
+
+ SANE_Constraint_Type constraint_type;
+ union
+ {
+ const SANE_String_Const *string_list; /* NULL-terminated list */
+ const SANE_Word *word_list; /* first element is list-length */
+ const SANE_Range *range;
+ }
+ constraint;
+ }
+SANE_Option_Descriptor;
+
+typedef enum
+ {
+ SANE_ACTION_GET_VALUE = 0,
+ SANE_ACTION_SET_VALUE,
+ SANE_ACTION_SET_AUTO
+ }
+SANE_Action;
+
+typedef enum
+ {
+ SANE_FRAME_GRAY, /* band covering human visual range */
+ SANE_FRAME_RGB, /* pixel-interleaved red/green/blue bands */
+ SANE_FRAME_RED, /* red band only */
+ SANE_FRAME_GREEN, /* green band only */
+ SANE_FRAME_BLUE /* blue band only */
+ }
+SANE_Frame;
+
+typedef struct
+ {
+ SANE_Frame format;
+ SANE_Bool last_frame;
+ SANE_Int bytes_per_line;
+ SANE_Int pixels_per_line;
+ SANE_Int lines;
+ SANE_Int depth;
+ }
+SANE_Parameters;
+
+struct SANE_Auth_Data;
+
+#define SANE_MAX_USERNAME_LEN 256
+#define SANE_MAX_PASSWORD_LEN 256
+
+typedef void (*SANE_Auth_Callback) (SANE_String_Const resource,
+ SANE_Char username[SANE_MAX_USERNAME_LEN],
+ SANE_Char password[SANE_MAX_PASSWORD_LEN]);
+
+extern SANE_Status sane_init (SANE_Int * version_code,
+ SANE_Auth_Callback authorize);
+extern void sane_exit (void);
+extern SANE_Status sane_get_devices (const SANE_Device *** device_list,
+ SANE_Bool local_only);
+extern SANE_Status sane_open (SANE_String_Const devicename,
+ SANE_Handle * handle);
+extern void sane_close (SANE_Handle handle);
+extern const SANE_Option_Descriptor *
+ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option);
+extern SANE_Status sane_control_option (SANE_Handle handle, SANE_Int option,
+ SANE_Action action, void *value,
+ SANE_Int * info);
+extern SANE_Status sane_get_parameters (SANE_Handle handle,
+ SANE_Parameters * params);
+extern SANE_Status sane_start (SANE_Handle handle);
+extern SANE_Status sane_read (SANE_Handle handle, SANE_Byte * data,
+ SANE_Int max_length, SANE_Int * length);
+extern void sane_cancel (SANE_Handle handle);
+extern SANE_Status sane_set_io_mode (SANE_Handle handle,
+ SANE_Bool non_blocking);
+extern SANE_Status sane_get_select_fd (SANE_Handle handle,
+ SANE_Int * fd);
+extern SANE_String_Const sane_strstatus (SANE_Status status);
+
+#endif /* sane_h */
diff --git a/external/skia/Library_skia.mk b/external/skia/Library_skia.mk
new file mode 100644
index 000000000..14c59c99c
--- /dev/null
+++ b/external/skia/Library_skia.mk
@@ -0,0 +1,1017 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,skia))
+
+$(eval $(call gb_Library_set_warnings_disabled,skia))
+
+$(eval $(call gb_Library_use_unpacked,skia,skia))
+
+$(eval $(call gb_Library_use_clang,skia))
+$(eval $(call gb_Library_set_clang_precompiled_header,skia,external/skia/inc/pch/precompiled_skia))
+
+$(eval $(call gb_Library_add_defs,skia,\
+ -DSKIA_IMPLEMENTATION=1 \
+ -DSKIA_DLL \
+ -DSK_USER_CONFIG_HEADER="<$(BUILDDIR)/config_host/config_skia.h>" \
+))
+
+# SK_DEBUG controls runtime checks and is controlled by config_skia.h and depends on DBG_UTIL.
+# This controls whether to build with compiler optimizations, normally yes, --enable-skia=debug
+# allows to build non-optimized. We normally wouldn't debug a 3rd-party library, and Skia
+# performance is relatively important (it may be the drawing engine used in software mode).
+# Some code may be always built with optimizations, even with Skia debug enabled (see
+# $(gb_COMPILEROPTFLAGS) usage).
+ifeq ($(ENABLE_SKIA_DEBUG),)
+$(eval $(call gb_Library_add_cxxflags,skia, \
+ $(gb_COMPILEROPTFLAGS) \
+ $(PCH_NO_CODEGEN) \
+))
+endif
+
+ifeq ($(OS),WNT)
+# Skia can be built with or without UNICODE set, in LO sources we explicitly use the *W unicode
+# variants, so build Skia with UNICODE to make it also use the *W variants.
+$(eval $(call gb_Library_add_defs,skia,\
+ -DUNICODE -D_UNICODE \
+))
+ifneq ($(gb_ENABLE_PCH),)
+$(eval $(call gb_Library_add_cxxflags,skia, \
+ -FIsrc/utils/win/SkDWriteNTDDI_VERSION.h \
+))
+endif
+
+$(eval $(call gb_Library_use_system_win32_libs,skia,\
+ fontsub \
+ ole32 \
+ oleaut32 \
+ user32 \
+ usp10 \
+ gdi32 \
+))
+
+# cl.exe (and thus clang-cl) likes to emit copies of inline functions even when not needed,
+# which means that for e.g. AVX-compiled sources the .o may contain a copy of an inline
+# function built using AVX, and the linker may select that copy as the one to keep, thus
+# introducing AVX code into generic code. Avoid generating such inlines. The flag currently
+# cannot be used for the whole Skia, because code built without the flag cannot use
+# libraries built with the flag, so cl.exe-built VCL would have undefined references.
+ifeq ($(HAVE_LO_CLANG_DLLEXPORTINLINES),TRUE)
+LO_SKIA_AVOID_INLINE_COPIES := -Zc:dllexportInlines-
+endif
+
+else ifeq ($(OS),MACOSX)
+
+$(eval $(call gb_Library_use_system_darwin_frameworks,skia,\
+ Cocoa \
+ Metal \
+ QuartzCore \
+))
+
+ifneq ($(SKIA_DISABLE_VMA_USE_STL_SHARED_MUTEX),)
+# Disable std::shared_mutex usage on MacOSX < 10.12.
+$(eval $(call gb_Library_add_defs,skia,\
+ -DVMA_USE_STL_SHARED_MUTEX=0 \
+))
+endif
+
+else
+$(eval $(call gb_Library_use_externals,skia,\
+ freetype \
+ fontconfig \
+))
+endif
+
+# we don't enable jpeg for skia, but it has incorrect #ifdef's in places
+$(eval $(call gb_Library_use_externals,skia,\
+ zlib \
+ libjpeg \
+ libpng \
+))
+
+ifeq ($(OS),LINUX)
+$(eval $(call gb_Library_add_libs,skia,\
+ -lm \
+ -ldl \
+ -lX11-xcb \
+ -lX11 \
+))
+endif
+
+$(eval $(call gb_Library_use_libraries,skia,\
+ sal \
+))
+
+$(eval $(call gb_Library_set_include,skia,\
+ $$(INCLUDE) \
+ -I$(call gb_UnpackedTarball_get_dir,skia) \
+ -I$(call gb_UnpackedTarball_get_dir,skia)/include/third_party/skcms/ \
+ -I$(call gb_UnpackedTarball_get_dir,skia)/third_party/vulkanmemoryallocator/ \
+ -I$(call gb_UnpackedTarball_get_dir,skia)/include/third_party/vulkan/ \
+ -I$(SRCDIR)/external/skia/inc/ \
+))
+
+$(eval $(call gb_Library_add_exception_objects,skia,\
+ external/skia/source/SkMemory_malloc \
+ external/skia/source/skia_compiler \
+ external/skia/source/skia_opts \
+))
+
+$(eval $(call gb_Library_set_generated_cxx_suffix,skia,cpp))
+
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/codec/SkAndroidCodecAdapter \
+ UnpackedTarball/skia/src/codec/SkAndroidCodec \
+ UnpackedTarball/skia/src/codec/SkBmpBaseCodec \
+ UnpackedTarball/skia/src/codec/SkBmpCodec \
+ UnpackedTarball/skia/src/codec/SkBmpMaskCodec \
+ UnpackedTarball/skia/src/codec/SkBmpRLECodec \
+ UnpackedTarball/skia/src/codec/SkBmpStandardCodec \
+ UnpackedTarball/skia/src/codec/SkCodec \
+ UnpackedTarball/skia/src/codec/SkCodecImageGenerator \
+ UnpackedTarball/skia/src/codec/SkColorTable \
+ UnpackedTarball/skia/src/codec/SkEncodedInfo \
+ UnpackedTarball/skia/src/codec/SkIcoCodec \
+ UnpackedTarball/skia/src/codec/SkMasks \
+ UnpackedTarball/skia/src/codec/SkMaskSwizzler \
+ UnpackedTarball/skia/src/codec/SkParseEncodedOrigin \
+ UnpackedTarball/skia/src/codec/SkPngCodec \
+ UnpackedTarball/skia/src/codec/SkSampledCodec \
+ UnpackedTarball/skia/src/codec/SkSampler \
+ UnpackedTarball/skia/src/codec/SkStreamBuffer \
+ UnpackedTarball/skia/src/codec/SkSwizzler \
+ UnpackedTarball/skia/src/codec/SkWbmpCodec \
+ UnpackedTarball/skia/src/core/SkAAClip \
+ UnpackedTarball/skia/src/core/SkAlphaRuns \
+ UnpackedTarball/skia/src/core/SkAnalyticEdge \
+ UnpackedTarball/skia/src/core/SkAnnotation \
+ UnpackedTarball/skia/src/core/SkArenaAlloc \
+ UnpackedTarball/skia/src/core/SkATrace \
+ UnpackedTarball/skia/src/core/SkAutoPixmapStorage \
+ UnpackedTarball/skia/src/core/SkBBHFactory \
+ UnpackedTarball/skia/src/core/SkBigPicture \
+ UnpackedTarball/skia/src/core/SkBitmapCache \
+ UnpackedTarball/skia/src/core/SkBitmap \
+ UnpackedTarball/skia/src/core/SkBitmapDevice \
+ UnpackedTarball/skia/src/core/SkBitmapProcState \
+ UnpackedTarball/skia/src/core/SkBitmapProcState_matrixProcs \
+ UnpackedTarball/skia/src/core/SkBlendMode \
+ UnpackedTarball/skia/src/core/SkBlendModeBlender \
+ UnpackedTarball/skia/src/core/SkBlitRow_D32 \
+ UnpackedTarball/skia/src/core/SkBlitter_ARGB32 \
+ UnpackedTarball/skia/src/core/SkBlitter_A8 \
+ UnpackedTarball/skia/src/core/SkBlitter \
+ UnpackedTarball/skia/src/core/SkBlitter_RGB565 \
+ UnpackedTarball/skia/src/core/SkBlitter_Sprite \
+ UnpackedTarball/skia/src/core/SkBlockAllocator \
+ UnpackedTarball/skia/src/core/SkBlurMask \
+ UnpackedTarball/skia/src/core/SkBlurMF \
+ UnpackedTarball/skia/src/core/SkBuffer \
+ UnpackedTarball/skia/src/core/SkCachedData \
+ UnpackedTarball/skia/src/core/SkCanvas \
+ UnpackedTarball/skia/src/core/SkCanvasPriv \
+ UnpackedTarball/skia/src/core/SkChromeRemoteGlyphCache \
+ UnpackedTarball/skia/src/core/SkClipStack \
+ UnpackedTarball/skia/src/core/SkClipStackDevice \
+ UnpackedTarball/skia/src/core/SkColor \
+ UnpackedTarball/skia/src/core/SkColorFilter \
+ UnpackedTarball/skia/src/core/SkColorFilter_Matrix \
+ UnpackedTarball/skia/src/core/SkColorSpace \
+ UnpackedTarball/skia/src/core/SkColorSpaceXformSteps \
+ UnpackedTarball/skia/src/core/SkCompressedDataUtils \
+ UnpackedTarball/skia/src/core/SkContourMeasure \
+ UnpackedTarball/skia/src/core/SkConvertPixels \
+ UnpackedTarball/skia/src/core/SkCpu \
+ UnpackedTarball/skia/src/core/SkCubicClipper \
+ UnpackedTarball/skia/src/core/SkCubicMap \
+ UnpackedTarball/skia/src/core/SkData \
+ UnpackedTarball/skia/src/core/SkDataTable \
+ UnpackedTarball/skia/src/core/SkDebug \
+ UnpackedTarball/skia/src/core/SkDeferredDisplayList \
+ UnpackedTarball/skia/src/core/SkDeferredDisplayListRecorder \
+ UnpackedTarball/skia/src/core/SkDeque \
+ UnpackedTarball/skia/src/core/SkDescriptor \
+ UnpackedTarball/skia/src/core/SkDevice \
+ UnpackedTarball/skia/src/core/SkDistanceFieldGen \
+ UnpackedTarball/skia/src/core/SkDocument \
+ UnpackedTarball/skia/src/core/SkDrawable \
+ UnpackedTarball/skia/src/core/SkDraw \
+ UnpackedTarball/skia/src/core/SkDrawLooper \
+ UnpackedTarball/skia/src/core/SkDrawShadowInfo \
+ UnpackedTarball/skia/src/core/SkDraw_atlas \
+ UnpackedTarball/skia/src/core/SkDraw_text \
+ UnpackedTarball/skia/src/core/SkDraw_vertices \
+ UnpackedTarball/skia/src/core/SkEdgeBuilder \
+ UnpackedTarball/skia/src/core/SkEdgeClipper \
+ UnpackedTarball/skia/src/core/SkEdge \
+ UnpackedTarball/skia/src/core/SkExecutor \
+ UnpackedTarball/skia/src/core/SkFlattenable \
+ UnpackedTarball/skia/src/core/SkFont \
+ UnpackedTarball/skia/src/core/SkFont_serial \
+ UnpackedTarball/skia/src/core/SkFontDescriptor \
+ UnpackedTarball/skia/src/core/SkFontMgr \
+ UnpackedTarball/skia/src/core/SkFontStream \
+ UnpackedTarball/skia/src/core/SkGaussFilter \
+ UnpackedTarball/skia/src/core/SkGeometry \
+ UnpackedTarball/skia/src/core/SkIDChangeListener \
+ UnpackedTarball/skia/src/core/SkGlobalInitialization_core \
+ UnpackedTarball/skia/src/core/SkGlyph \
+ UnpackedTarball/skia/src/core/SkGlyphBuffer \
+ UnpackedTarball/skia/src/core/SkGlyphRun \
+ UnpackedTarball/skia/src/core/SkGlyphRunPainter \
+ UnpackedTarball/skia/src/core/SkGraphics \
+ UnpackedTarball/skia/src/core/SkHalf \
+ UnpackedTarball/skia/src/core/SkICC \
+ UnpackedTarball/skia/src/core/SkImageFilterCache \
+ UnpackedTarball/skia/src/core/SkImageFilterTypes \
+ UnpackedTarball/skia/src/core/SkImageFilter \
+ UnpackedTarball/skia/src/core/SkImageGenerator \
+ UnpackedTarball/skia/src/core/SkImageInfo \
+ UnpackedTarball/skia/src/core/SkKeyContext \
+ UnpackedTarball/skia/src/core/SkKeyHelpers \
+ UnpackedTarball/skia/src/core/SkLatticeIter \
+ UnpackedTarball/skia/src/core/SkLineClipper \
+ UnpackedTarball/skia/src/core/SkLocalMatrixImageFilter \
+ UnpackedTarball/skia/src/core/SkMalloc \
+ UnpackedTarball/skia/src/core/SkMallocPixelRef \
+ UnpackedTarball/skia/src/core/SkMaskBlurFilter \
+ UnpackedTarball/skia/src/core/SkMaskCache \
+ UnpackedTarball/skia/src/core/SkMask \
+ UnpackedTarball/skia/src/core/SkMaskFilter \
+ UnpackedTarball/skia/src/core/SkMaskGamma \
+ UnpackedTarball/skia/src/core/SkMath \
+ UnpackedTarball/skia/src/core/SkMatrix \
+ UnpackedTarball/skia/src/core/SkMatrixImageFilter \
+ UnpackedTarball/skia/src/core/SkMatrixInvert \
+ UnpackedTarball/skia/src/core/SkM44 \
+ UnpackedTarball/skia/src/core/SkMD5 \
+ UnpackedTarball/skia/src/core/SkMesh \
+ UnpackedTarball/skia/src/core/SkMiniRecorder \
+ UnpackedTarball/skia/src/core/SkMipmap \
+ UnpackedTarball/skia/src/core/SkMipmapAccessor \
+ UnpackedTarball/skia/src/core/SkModeColorFilter \
+ UnpackedTarball/skia/src/core/SkOpts \
+ UnpackedTarball/skia/src/core/SkOpts_erms \
+ UnpackedTarball/skia/src/core/SkOverdrawCanvas \
+ UnpackedTarball/skia/src/core/SkPaint \
+ UnpackedTarball/skia/src/core/SkPaintParamsKey \
+ UnpackedTarball/skia/src/core/SkPaintPriv \
+ UnpackedTarball/skia/src/core/SkPath \
+ UnpackedTarball/skia/src/core/SkPathBuilder \
+ UnpackedTarball/skia/src/core/SkPathEffect \
+ UnpackedTarball/skia/src/core/SkPathMeasure \
+ UnpackedTarball/skia/src/core/SkPathRef \
+ UnpackedTarball/skia/src/core/SkPath_serial \
+ UnpackedTarball/skia/src/core/SkPipelineData \
+ UnpackedTarball/skia/src/core/SkPicture \
+ UnpackedTarball/skia/src/core/SkPictureData \
+ UnpackedTarball/skia/src/core/SkPictureFlat \
+ UnpackedTarball/skia/src/core/SkPictureImageGenerator \
+ UnpackedTarball/skia/src/core/SkPicturePlayback \
+ UnpackedTarball/skia/src/core/SkPictureRecord \
+ UnpackedTarball/skia/src/core/SkPictureRecorder \
+ UnpackedTarball/skia/src/core/SkPixelRef \
+ UnpackedTarball/skia/src/core/SkPixmap \
+ UnpackedTarball/skia/src/core/SkPoint \
+ UnpackedTarball/skia/src/core/SkPoint3 \
+ UnpackedTarball/skia/src/core/SkPromiseImageTexture \
+ UnpackedTarball/skia/src/core/SkPtrRecorder \
+ UnpackedTarball/skia/src/core/SkQuadClipper \
+ UnpackedTarball/skia/src/core/SkRasterClip \
+ UnpackedTarball/skia/src/core/SkRasterPipelineBlitter \
+ UnpackedTarball/skia/src/core/SkRasterPipeline \
+ UnpackedTarball/skia/src/core/SkReadBuffer \
+ UnpackedTarball/skia/src/core/SkRecord \
+ UnpackedTarball/skia/src/core/SkRecordDraw \
+ UnpackedTarball/skia/src/core/SkRecordedDrawable \
+ UnpackedTarball/skia/src/core/SkRecorder \
+ UnpackedTarball/skia/src/core/SkRecordOpts \
+ UnpackedTarball/skia/src/core/SkRecords \
+ UnpackedTarball/skia/src/core/SkRect \
+ UnpackedTarball/skia/src/core/SkRegion \
+ UnpackedTarball/skia/src/core/SkRegion_path \
+ UnpackedTarball/skia/src/core/SkResourceCache \
+ UnpackedTarball/skia/src/core/SkRRect \
+ UnpackedTarball/skia/src/core/SkRTree \
+ UnpackedTarball/skia/src/core/SkRuntimeEffect \
+ UnpackedTarball/skia/src/core/SkScalar \
+ UnpackedTarball/skia/src/core/SkScalerCache \
+ UnpackedTarball/skia/src/core/SkScalerContext \
+ UnpackedTarball/skia/src/core/SkScan_AAAPath \
+ UnpackedTarball/skia/src/core/SkScan_Antihair \
+ UnpackedTarball/skia/src/core/SkScan_AntiPath \
+ UnpackedTarball/skia/src/core/SkScan \
+ UnpackedTarball/skia/src/core/SkScan_Hairline \
+ UnpackedTarball/skia/src/core/SkScan_Path \
+ UnpackedTarball/skia/src/core/SkSemaphore \
+ UnpackedTarball/skia/src/core/SkShaderCodeDictionary \
+ UnpackedTarball/skia/src/core/SkSharedMutex \
+ UnpackedTarball/skia/src/core/SkSpecialImage \
+ UnpackedTarball/skia/src/core/SkSpecialSurface \
+ UnpackedTarball/skia/src/core/SkSpinlock \
+ UnpackedTarball/skia/src/core/SkSpriteBlitter_ARGB32 \
+ UnpackedTarball/skia/src/core/SkSpriteBlitter_RGB565 \
+ UnpackedTarball/skia/src/core/SkStream \
+ UnpackedTarball/skia/src/core/SkStrikeCache \
+ UnpackedTarball/skia/src/core/SkStrikeForGPU \
+ UnpackedTarball/skia/src/core/SkStrikeSpec \
+ UnpackedTarball/skia/src/core/SkString \
+ UnpackedTarball/skia/src/core/SkStringUtils \
+ UnpackedTarball/skia/src/core/SkStroke \
+ UnpackedTarball/skia/src/core/SkStrokeRec \
+ UnpackedTarball/skia/src/core/SkStrokerPriv \
+ UnpackedTarball/skia/src/core/SkSurfaceCharacterization \
+ UnpackedTarball/skia/src/core/SkSwizzle \
+ UnpackedTarball/skia/src/core/SkTaskGroup \
+ UnpackedTarball/skia/src/core/SkTextBlob \
+ UnpackedTarball/skia/src/core/SkTextBlobTrace \
+ UnpackedTarball/skia/src/core/SkThreadID \
+ UnpackedTarball/skia/src/core/SkTime \
+ UnpackedTarball/skia/src/core/SkTSearch \
+ UnpackedTarball/skia/src/core/SkTypefaceCache \
+ UnpackedTarball/skia/src/core/SkTypeface \
+ UnpackedTarball/skia/src/core/SkTypeface_remote \
+ UnpackedTarball/skia/src/core/SkUnPreMultiply \
+ UnpackedTarball/skia/src/core/SkUtilsArm \
+ UnpackedTarball/skia/src/core/SkUtils \
+ UnpackedTarball/skia/src/core/SkVertices \
+ UnpackedTarball/skia/src/core/SkVertState \
+ UnpackedTarball/skia/src/core/SkVM \
+ UnpackedTarball/skia/src/core/SkVMBlitter \
+ UnpackedTarball/skia/src/core/SkWriteBuffer \
+ UnpackedTarball/skia/src/core/SkWriter32 \
+ UnpackedTarball/skia/src/core/SkXfermode \
+ UnpackedTarball/skia/src/core/SkXfermodeInterpretation \
+ UnpackedTarball/skia/src/core/SkYUVAInfo \
+ UnpackedTarball/skia/src/core/SkYUVAPixmaps \
+ UnpackedTarball/skia/src/core/SkYUVMath \
+ UnpackedTarball/skia/src/core/SkYUVPlanesCache \
+ UnpackedTarball/skia/src/c/sk_effects \
+ UnpackedTarball/skia/src/c/sk_imageinfo \
+ UnpackedTarball/skia/src/c/sk_paint \
+ UnpackedTarball/skia/src/c/sk_surface \
+ UnpackedTarball/skia/src/effects/imagefilters/SkAlphaThresholdImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkArithmeticImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkBlendImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkBlurImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkColorFilterImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkComposeImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkCropImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkDisplacementMapImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkDropShadowImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkImageImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkLightingImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkMagnifierImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkMatrixConvolutionImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkMergeImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkMorphologyImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkOffsetImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkPictureImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkShaderImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkRuntimeImageFilter \
+ UnpackedTarball/skia/src/effects/imagefilters/SkTileImageFilter \
+ UnpackedTarball/skia/src/effects/SkBlenders \
+ UnpackedTarball/skia/src/effects/SkColorMatrix \
+ UnpackedTarball/skia/src/effects/SkColorMatrixFilter \
+ UnpackedTarball/skia/src/effects/SkCornerPathEffect \
+ UnpackedTarball/skia/src/effects/SkDashPathEffect \
+ UnpackedTarball/skia/src/effects/SkDiscretePathEffect \
+ UnpackedTarball/skia/src/effects/SkEmbossMask \
+ UnpackedTarball/skia/src/effects/SkEmbossMaskFilter \
+ UnpackedTarball/skia/src/effects/SkHighContrastFilter \
+ UnpackedTarball/skia/src/effects/SkLayerDrawLooper \
+ UnpackedTarball/skia/src/effects/SkLumaColorFilter \
+ UnpackedTarball/skia/src/effects/SkOpPathEffect \
+ UnpackedTarball/skia/src/effects/SkOverdrawColorFilter \
+ UnpackedTarball/skia/src/effects/SkShaderMaskFilter \
+ UnpackedTarball/skia/src/effects/SkTableColorFilter \
+ UnpackedTarball/skia/src/effects/SkTableMaskFilter \
+ UnpackedTarball/skia/src/effects/SkTrimPathEffect \
+ UnpackedTarball/skia/src/effects/Sk1DPathEffect \
+ UnpackedTarball/skia/src/effects/Sk2DPathEffect \
+ UnpackedTarball/skia/src/fonts/SkRemotableFontMgr \
+ UnpackedTarball/skia/src/image/SkImage \
+ UnpackedTarball/skia/src/image/SkImage_Lazy \
+ UnpackedTarball/skia/src/image/SkImage_Raster \
+ UnpackedTarball/skia/src/image/SkRescaleAndReadPixels \
+ UnpackedTarball/skia/src/image/SkSurface \
+ UnpackedTarball/skia/src/image/SkSurface_Raster \
+ UnpackedTarball/skia/src/images/SkImageEncoder \
+ UnpackedTarball/skia/src/images/SkPngEncoder \
+ UnpackedTarball/skia/src/images/SkWebpEncoder \
+ UnpackedTarball/skia/src/lazy/SkDiscardableMemoryPool \
+ UnpackedTarball/skia/src/pathops/SkAddIntersections \
+ UnpackedTarball/skia/src/pathops/SkDConicLineIntersection \
+ UnpackedTarball/skia/src/pathops/SkDCubicLineIntersection \
+ UnpackedTarball/skia/src/pathops/SkDCubicToQuads \
+ UnpackedTarball/skia/src/pathops/SkDLineIntersection \
+ UnpackedTarball/skia/src/pathops/SkDQuadLineIntersection \
+ UnpackedTarball/skia/src/pathops/SkIntersections \
+ UnpackedTarball/skia/src/pathops/SkOpAngle \
+ UnpackedTarball/skia/src/pathops/SkOpBuilder \
+ UnpackedTarball/skia/src/pathops/SkOpCoincidence \
+ UnpackedTarball/skia/src/pathops/SkOpContour \
+ UnpackedTarball/skia/src/pathops/SkOpCubicHull \
+ UnpackedTarball/skia/src/pathops/SkOpEdgeBuilder \
+ UnpackedTarball/skia/src/pathops/SkOpSegment \
+ UnpackedTarball/skia/src/pathops/SkOpSpan \
+ UnpackedTarball/skia/src/pathops/SkPathOpsAsWinding \
+ UnpackedTarball/skia/src/pathops/SkPathOpsCommon \
+ UnpackedTarball/skia/src/pathops/SkPathOpsConic \
+ UnpackedTarball/skia/src/pathops/SkPathOpsCubic \
+ UnpackedTarball/skia/src/pathops/SkPathOpsCurve \
+ UnpackedTarball/skia/src/pathops/SkPathOpsDebug \
+ UnpackedTarball/skia/src/pathops/SkPathOpsLine \
+ UnpackedTarball/skia/src/pathops/SkPathOpsOp \
+ UnpackedTarball/skia/src/pathops/SkPathOpsQuad \
+ UnpackedTarball/skia/src/pathops/SkPathOpsRect \
+ UnpackedTarball/skia/src/pathops/SkPathOpsSimplify \
+ UnpackedTarball/skia/src/pathops/SkPathOpsTightBounds \
+ UnpackedTarball/skia/src/pathops/SkPathOpsTSect \
+ UnpackedTarball/skia/src/pathops/SkPathOpsTypes \
+ UnpackedTarball/skia/src/pathops/SkPathOpsWinding \
+ UnpackedTarball/skia/src/pathops/SkPathWriter \
+ UnpackedTarball/skia/src/pathops/SkReduceOrder \
+ UnpackedTarball/skia/src/sfnt/SkOTTable_name \
+ UnpackedTarball/skia/src/sfnt/SkOTUtils \
+ UnpackedTarball/skia/src/shaders/gradients/SkGradientShader \
+ UnpackedTarball/skia/src/shaders/gradients/SkLinearGradient \
+ UnpackedTarball/skia/src/shaders/gradients/SkRadialGradient \
+ UnpackedTarball/skia/src/shaders/gradients/SkSweepGradient \
+ UnpackedTarball/skia/src/shaders/gradients/SkTwoPointConicalGradient \
+ UnpackedTarball/skia/src/shaders/gradients/Sk4fGradientBase \
+ UnpackedTarball/skia/src/shaders/gradients/Sk4fLinearGradient \
+ UnpackedTarball/skia/src/shaders/SkBitmapProcShader \
+ UnpackedTarball/skia/src/shaders/SkColorFilterShader \
+ UnpackedTarball/skia/src/shaders/SkColorShader \
+ UnpackedTarball/skia/src/shaders/SkComposeShader \
+ UnpackedTarball/skia/src/shaders/SkImageShader \
+ UnpackedTarball/skia/src/shaders/SkLocalMatrixShader \
+ UnpackedTarball/skia/src/shaders/SkPerlinNoiseShader \
+ UnpackedTarball/skia/src/shaders/SkPictureShader \
+ UnpackedTarball/skia/src/shaders/SkShader \
+ UnpackedTarball/skia/src/shaders/SkTransformShader \
+ UnpackedTarball/skia/src/sksl/dsl/DSLBlock \
+ UnpackedTarball/skia/src/sksl/dsl/DSLCase \
+ UnpackedTarball/skia/src/sksl/dsl/DSLCore \
+ UnpackedTarball/skia/src/sksl/dsl/DSLExpression \
+ UnpackedTarball/skia/src/sksl/dsl/DSLFunction \
+ UnpackedTarball/skia/src/sksl/dsl/DSLLayout \
+ UnpackedTarball/skia/src/sksl/dsl/DSLRuntimeEffects \
+ UnpackedTarball/skia/src/sksl/dsl/DSLStatement \
+ UnpackedTarball/skia/src/sksl/dsl/DSLSymbols \
+ UnpackedTarball/skia/src/sksl/dsl/DSLType \
+ UnpackedTarball/skia/src/sksl/dsl/DSLVar \
+ UnpackedTarball/skia/src/sksl/dsl/priv/DSLFPs \
+ UnpackedTarball/skia/src/sksl/dsl/priv/DSLWriter \
+ UnpackedTarball/skia/src/sksl/ir/SkSLBinaryExpression \
+ UnpackedTarball/skia/src/sksl/ir/SkSLBlock \
+ UnpackedTarball/skia/src/sksl/ir/SkSLChildCall \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructor \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructorArray \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructorArrayCast \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructorCompound \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructorCompoundCast \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructorDiagonalMatrix \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructorMatrixResize \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructorScalarCast \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructorSplat \
+ UnpackedTarball/skia/src/sksl/ir/SkSLConstructorStruct \
+ UnpackedTarball/skia/src/sksl/ir/SkSLDoStatement \
+ UnpackedTarball/skia/src/sksl/ir/SkSLExpression \
+ UnpackedTarball/skia/src/sksl/ir/SkSLExpressionStatement \
+ UnpackedTarball/skia/src/sksl/ir/SkSLFieldAccess \
+ UnpackedTarball/skia/src/sksl/ir/SkSLForStatement \
+ UnpackedTarball/skia/src/sksl/ir/SkSLFunctionCall \
+ UnpackedTarball/skia/src/sksl/ir/SkSLFunctionDeclaration \
+ UnpackedTarball/skia/src/sksl/ir/SkSLFunctionDefinition \
+ UnpackedTarball/skia/src/sksl/ir/SkSLIfStatement \
+ UnpackedTarball/skia/src/sksl/ir/SkSLIndexExpression \
+ UnpackedTarball/skia/src/sksl/ir/SkSLModifiers \
+ UnpackedTarball/skia/src/sksl/ir/SkSLPrefixExpression \
+ UnpackedTarball/skia/src/sksl/ir/SkSLPostfixExpression \
+ UnpackedTarball/skia/src/sksl/ir/SkSLSetting \
+ UnpackedTarball/skia/src/sksl/ir/SkSLSwitchStatement \
+ UnpackedTarball/skia/src/sksl/ir/SkSLSwizzle \
+ UnpackedTarball/skia/src/sksl/ir/SkSLSymbolTable \
+ UnpackedTarball/skia/src/sksl/ir/SkSLTernaryExpression \
+ UnpackedTarball/skia/src/sksl/ir/SkSLType \
+ UnpackedTarball/skia/src/sksl/ir/SkSLTypeReference \
+ UnpackedTarball/skia/src/sksl/ir/SkSLVarDeclarations \
+ UnpackedTarball/skia/src/sksl/ir/SkSLVariable \
+ UnpackedTarball/skia/src/sksl/ir/SkSLVariableReference \
+ UnpackedTarball/skia/src/sksl/SkSLAnalysis \
+ UnpackedTarball/skia/src/sksl/SkSLBuiltinMap \
+ UnpackedTarball/skia/src/sksl/SkSLBuiltinTypes \
+ UnpackedTarball/skia/src/sksl/SkSLCompiler \
+ UnpackedTarball/skia/src/sksl/SkSLConstantFolder \
+ UnpackedTarball/skia/src/sksl/SkSLContext \
+ UnpackedTarball/skia/src/sksl/SkSLDSLParser \
+ UnpackedTarball/skia/src/sksl/SkSLDehydrator \
+ UnpackedTarball/skia/src/sksl/SkSLErrorReporter \
+ UnpackedTarball/skia/src/sksl/SkSLInliner \
+ UnpackedTarball/skia/src/sksl/SkSLLexer \
+ UnpackedTarball/skia/src/sksl/SkSLMangler \
+ UnpackedTarball/skia/src/sksl/SkSLOperator \
+ UnpackedTarball/skia/src/sksl/SkSLOutputStream \
+ UnpackedTarball/skia/src/sksl/SkSLPool \
+ UnpackedTarball/skia/src/sksl/SkSLPosition \
+ UnpackedTarball/skia/src/sksl/SkSLRehydrator \
+ UnpackedTarball/skia/src/sksl/SkSLSampleUsage \
+ UnpackedTarball/skia/src/sksl/SkSLSharedCompiler \
+ UnpackedTarball/skia/src/sksl/SkSLString \
+ UnpackedTarball/skia/src/sksl/SkSLThreadContext \
+ UnpackedTarball/skia/src/sksl/SkSLUtil \
+ UnpackedTarball/skia/src/sksl/analysis/SkSLCanExitWithoutReturningValue \
+ UnpackedTarball/skia/src/sksl/analysis/SkSLCheckProgramStructure \
+ UnpackedTarball/skia/src/sksl/analysis/SkSLFinalizationChecks \
+ UnpackedTarball/skia/src/sksl/analysis/SkSLGetLoopUnrollInfo \
+ UnpackedTarball/skia/src/sksl/analysis/SkSLIsConstantExpression \
+ UnpackedTarball/skia/src/sksl/analysis/SkSLIsSameExpressionTree \
+ UnpackedTarball/skia/src/sksl/analysis/SkSLProgramUsage \
+ UnpackedTarball/skia/src/sksl/analysis/SkSLSwitchCaseContainsExit \
+ UnpackedTarball/skia/src/sksl/codegen/SkSLGLSLCodeGenerator \
+ UnpackedTarball/skia/src/sksl/codegen/SkSLMetalCodeGenerator \
+ UnpackedTarball/skia/src/sksl/codegen/SkSLPipelineStageCodeGenerator \
+ UnpackedTarball/skia/src/sksl/codegen/SkSLSPIRVCodeGenerator \
+ UnpackedTarball/skia/src/sksl/codegen/SkSLSPIRVtoHLSL \
+ UnpackedTarball/skia/src/sksl/codegen/SkSLVMCodeGenerator \
+ UnpackedTarball/skia/src/sksl/codegen/SkSLWGSLCodeGenerator \
+ UnpackedTarball/skia/src/sksl/tracing/SkVMDebugTrace \
+ UnpackedTarball/skia/src/sksl/transform/SkSLBuiltinVariableScanner \
+ UnpackedTarball/skia/src/sksl/transform/SkSLEliminateDeadFunctions \
+ UnpackedTarball/skia/src/sksl/transform/SkSLEliminateDeadGlobalVariables \
+ UnpackedTarball/skia/src/sksl/transform/SkSLEliminateDeadLocalVariables \
+ UnpackedTarball/skia/src/sksl/transform/SkSLEliminateUnreachableCode \
+ UnpackedTarball/skia/src/utils/SkBase64 \
+ UnpackedTarball/skia/src/utils/SkCamera \
+ UnpackedTarball/skia/src/utils/SkCanvasStack \
+ UnpackedTarball/skia/src/utils/SkCanvasStateUtils \
+ UnpackedTarball/skia/src/utils/SkDashPath \
+ UnpackedTarball/skia/src/utils/SkEventTracer \
+ UnpackedTarball/skia/src/utils/SkFloatToDecimal \
+ UnpackedTarball/skia/src/utils/SkCharToGlyphCache \
+ UnpackedTarball/skia/src/utils/SkClipStackUtils \
+ UnpackedTarball/skia/src/utils/SkCustomTypeface \
+ UnpackedTarball/skia/src/utils/SkJSON \
+ UnpackedTarball/skia/src/utils/SkJSONWriter \
+ UnpackedTarball/skia/src/utils/SkMatrix22 \
+ UnpackedTarball/skia/src/utils/SkMultiPictureDocument \
+ UnpackedTarball/skia/src/utils/SkNullCanvas \
+ UnpackedTarball/skia/src/utils/SkNWayCanvas \
+ UnpackedTarball/skia/src/utils/SkOSPath \
+ UnpackedTarball/skia/src/utils/SkOrderedFontMgr \
+ UnpackedTarball/skia/src/utils/SkPaintFilterCanvas \
+ UnpackedTarball/skia/src/utils/SkParseColor \
+ UnpackedTarball/skia/src/utils/SkParse \
+ UnpackedTarball/skia/src/utils/SkParsePath \
+ UnpackedTarball/skia/src/utils/SkPatchUtils \
+ UnpackedTarball/skia/src/utils/SkPolyUtils \
+ UnpackedTarball/skia/src/utils/SkShaderUtils \
+ UnpackedTarball/skia/src/utils/SkShadowTessellator \
+ UnpackedTarball/skia/src/utils/SkShadowUtils \
+ UnpackedTarball/skia/src/utils/SkShaperJSONWriter \
+ UnpackedTarball/skia/src/utils/SkTextUtils \
+ UnpackedTarball/skia/src/utils/SkThreadUtils_pthread \
+ UnpackedTarball/skia/src/utils/SkThreadUtils_win \
+ UnpackedTarball/skia/src/utils/SkUTF \
+ UnpackedTarball/skia/src/utils/SkVMVisualizer \
+ UnpackedTarball/skia/src/xps/SkXPSDevice \
+ UnpackedTarball/skia/src/xps/SkXPSDocument \
+))
+
+ifneq ($(SKIA_GPU),)
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/core/SkGpuBlurUtils \
+ UnpackedTarball/skia/src/gpu/AtlasTypes \
+ UnpackedTarball/skia/src/gpu/Blend \
+ UnpackedTarball/skia/src/gpu/RectanizerPow2 \
+ UnpackedTarball/skia/src/gpu/RectanizerSkyline \
+ UnpackedTarball/skia/src/gpu/ResourceKey \
+ UnpackedTarball/skia/src/gpu/ShaderErrorHandler \
+ UnpackedTarball/skia/src/gpu/Swizzle \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrBezierEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrBicubicEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrBitmapTextGeoProc \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrBlendFragmentProcessor \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrConvexPolyEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrCoverageSetOpXP \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrCustomXfermode \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrDisableColorXP \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrDistanceFieldGeoProc \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrGaussianConvolutionFragmentProcessor \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrMatrixConvolutionEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrMatrixEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrModulateAtlasCoverageEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrOvalEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrPorterDuffXferProcessor \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrRRectEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrShadowGeoProc \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrSkSLFP \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrTextureEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/effects/GrYUVtoRGBEffect \
+ UnpackedTarball/skia/src/gpu/ganesh/geometry/GrPathUtils \
+ UnpackedTarball/skia/src/gpu/ganesh/geometry/GrQuad \
+ UnpackedTarball/skia/src/gpu/ganesh/geometry/GrQuadUtils \
+ UnpackedTarball/skia/src/gpu/ganesh/geometry/GrShape \
+ UnpackedTarball/skia/src/gpu/ganesh/geometry/GrStyledShape \
+ UnpackedTarball/skia/src/gpu/ganesh/glsl/GrGLSLBlend \
+ UnpackedTarball/skia/src/gpu/ganesh/glsl/GrGLSL \
+ UnpackedTarball/skia/src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder \
+ UnpackedTarball/skia/src/gpu/ganesh/glsl/GrGLSLProgramBuilder \
+ UnpackedTarball/skia/src/gpu/ganesh/glsl/GrGLSLProgramDataManager \
+ UnpackedTarball/skia/src/gpu/ganesh/glsl/GrGLSLShaderBuilder \
+ UnpackedTarball/skia/src/gpu/ganesh/glsl/GrGLSLUniformHandler \
+ UnpackedTarball/skia/src/gpu/ganesh/glsl/GrGLSLVarying \
+ UnpackedTarball/skia/src/gpu/ganesh/glsl/GrGLSLVertexGeoBuilder \
+ UnpackedTarball/skia/src/gpu/ganesh/gradients/GrGradientBitmapCache \
+ UnpackedTarball/skia/src/gpu/ganesh/gradients/GrGradientShader \
+ UnpackedTarball/skia/src/gpu/ganesh/GrAHardwareBufferImageGenerator \
+ UnpackedTarball/skia/src/gpu/ganesh/GrAHardwareBufferUtils \
+ UnpackedTarball/skia/src/gpu/ganesh/GrAttachment \
+ UnpackedTarball/skia/src/gpu/ganesh/GrBackendSemaphore \
+ UnpackedTarball/skia/src/gpu/ganesh/GrBackendSurfaceMutableState \
+ UnpackedTarball/skia/src/gpu/ganesh/GrBackendSurface \
+ UnpackedTarball/skia/src/gpu/ganesh/GrBackendTextureImageGenerator \
+ UnpackedTarball/skia/src/gpu/ganesh/GrBackendUtils \
+ UnpackedTarball/skia/src/gpu/ganesh/GrBufferAllocPool \
+ UnpackedTarball/skia/src/gpu/ganesh/GrCaps \
+ UnpackedTarball/skia/src/gpu/ganesh/GrClientMappedBufferManager \
+ UnpackedTarball/skia/src/gpu/ganesh/GrColorInfo \
+ UnpackedTarball/skia/src/gpu/ganesh/GrColorSpaceXform \
+ UnpackedTarball/skia/src/gpu/ganesh/GrContext_Base \
+ UnpackedTarball/skia/src/gpu/ganesh/GrContextThreadSafeProxy \
+ UnpackedTarball/skia/src/gpu/ganesh/GrCopyRenderTask \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDataUtils \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDDLContext \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDDLTask \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDefaultGeoProcFactory \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDirectContext \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDirectContextPriv \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDistanceFieldGenFromVector \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDrawingManager \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDrawOpAtlas \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDriverBugWorkarounds \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDynamicAtlas \
+ UnpackedTarball/skia/src/gpu/ganesh/GrEagerVertexAllocator \
+ UnpackedTarball/skia/src/gpu/ganesh/GrFinishCallbacks \
+ UnpackedTarball/skia/src/gpu/ganesh/GrFixedClip \
+ UnpackedTarball/skia/src/gpu/ganesh/GrFragmentProcessor \
+ UnpackedTarball/skia/src/gpu/ganesh/GrGeometryProcessor \
+ UnpackedTarball/skia/src/gpu/ganesh/GrGpu \
+ UnpackedTarball/skia/src/gpu/ganesh/GrGpuBuffer \
+ UnpackedTarball/skia/src/gpu/ganesh/GrGpuResource \
+ UnpackedTarball/skia/src/gpu/ganesh/GrImageContext \
+ UnpackedTarball/skia/src/gpu/ganesh/GrImageInfo \
+ UnpackedTarball/skia/src/gpu/ganesh/GrManagedResource \
+ UnpackedTarball/skia/src/gpu/ganesh/GrMemoryPool \
+ UnpackedTarball/skia/src/gpu/ganesh/GrMeshDrawTarget \
+ UnpackedTarball/skia/src/gpu/ganesh/GrOnFlushResourceProvider \
+ UnpackedTarball/skia/src/gpu/ganesh/GrOpFlushState \
+ UnpackedTarball/skia/src/gpu/ganesh/GrOpsRenderPass \
+ UnpackedTarball/skia/src/gpu/ganesh/GrPaint \
+ UnpackedTarball/skia/src/gpu/ganesh/GrPersistentCacheUtils \
+ UnpackedTarball/skia/src/gpu/ganesh/GrPipeline \
+ UnpackedTarball/skia/src/gpu/ganesh/GrProcessorAnalysis \
+ UnpackedTarball/skia/src/gpu/ganesh/GrProcessor \
+ UnpackedTarball/skia/src/gpu/ganesh/GrProcessorSet \
+ UnpackedTarball/skia/src/gpu/ganesh/GrProcessorUnitTest \
+ UnpackedTarball/skia/src/gpu/ganesh/GrProgramDesc \
+ UnpackedTarball/skia/src/gpu/ganesh/GrProgramInfo \
+ UnpackedTarball/skia/src/gpu/ganesh/GrProxyProvider \
+ UnpackedTarball/skia/src/gpu/ganesh/GrRecordingContext \
+ UnpackedTarball/skia/src/gpu/ganesh/GrRecordingContextPriv \
+ UnpackedTarball/skia/src/gpu/ganesh/GrRenderTask \
+ UnpackedTarball/skia/src/gpu/ganesh/GrRenderTaskCluster \
+ UnpackedTarball/skia/src/gpu/ganesh/GrRenderTarget \
+ UnpackedTarball/skia/src/gpu/ganesh/GrRenderTargetProxy \
+ UnpackedTarball/skia/src/gpu/ganesh/GrResourceAllocator \
+ UnpackedTarball/skia/src/gpu/ganesh/GrResourceCache \
+ UnpackedTarball/skia/src/gpu/ganesh/GrResourceProvider \
+ UnpackedTarball/skia/src/gpu/ganesh/GrRingBuffer \
+ UnpackedTarball/skia/src/gpu/ganesh/GrShaderCaps \
+ UnpackedTarball/skia/src/gpu/ganesh/GrShaderVar \
+ UnpackedTarball/skia/src/gpu/ganesh/GrSPIRVUniformHandler \
+ UnpackedTarball/skia/src/gpu/ganesh/GrSPIRVVaryingHandler \
+ UnpackedTarball/skia/src/gpu/ganesh/GrStagingBufferManager \
+ UnpackedTarball/skia/src/gpu/ganesh/GrStencilSettings \
+ UnpackedTarball/skia/src/gpu/ganesh/GrStyle \
+ UnpackedTarball/skia/src/gpu/ganesh/GrSurface \
+ UnpackedTarball/skia/src/gpu/ganesh/GrSurfaceInfo \
+ UnpackedTarball/skia/src/gpu/ganesh/GrSurfaceProxy \
+ UnpackedTarball/skia/src/gpu/ganesh/GrSWMaskHelper \
+ UnpackedTarball/skia/src/gpu/ganesh/GrTestUtils \
+ UnpackedTarball/skia/src/gpu/ganesh/GrUniformDataManager \
+ UnpackedTarball/skia/src/gpu/ganesh/GrTexture \
+ UnpackedTarball/skia/src/gpu/ganesh/GrTextureProxy \
+ UnpackedTarball/skia/src/gpu/ganesh/GrTextureRenderTargetProxy \
+ UnpackedTarball/skia/src/gpu/ganesh/GrTextureResolveRenderTask \
+ UnpackedTarball/skia/src/gpu/ganesh/GrThreadSafeCache \
+ UnpackedTarball/skia/src/gpu/ganesh/GrThreadSafePipelineBuilder \
+ UnpackedTarball/skia/src/gpu/ganesh/GrTransferFromRenderTask \
+ UnpackedTarball/skia/src/gpu/ganesh/GrUtil \
+ UnpackedTarball/skia/src/gpu/ganesh/GrVertexChunkArray \
+ UnpackedTarball/skia/src/gpu/ganesh/GrWaitRenderTask \
+ UnpackedTarball/skia/src/gpu/ganesh/GrWritePixelsRenderTask \
+ UnpackedTarball/skia/src/gpu/ganesh/GrXferProcessor \
+ UnpackedTarball/skia/src/gpu/ganesh/GrYUVABackendTextures \
+ UnpackedTarball/skia/src/gpu/ganesh/GrYUVATextureProxies \
+ UnpackedTarball/skia/src/gpu/ganesh/geometry/GrAAConvexTessellator \
+ UnpackedTarball/skia/src/gpu/ganesh/geometry/GrAATriangulator \
+ UnpackedTarball/skia/src/gpu/ganesh/geometry/GrTriangulator \
+ UnpackedTarball/skia/src/gpu/ganesh/mock/GrMockCaps \
+ UnpackedTarball/skia/src/gpu/ganesh/mock/GrMockGpu \
+ UnpackedTarball/skia/src/gpu/ganesh/mock/GrMockTypes \
+ UnpackedTarball/skia/src/gpu/ganesh/BaseDevice \
+ UnpackedTarball/skia/src/gpu/ganesh/SkGr \
+ UnpackedTarball/skia/src/gpu/ganesh/SurfaceContext \
+ UnpackedTarball/skia/src/gpu/ganesh/SurfaceFillContext \
+ UnpackedTarball/skia/src/gpu/ganesh/tessellate/GrPathTessellationShader \
+ UnpackedTarball/skia/src/gpu/ganesh/tessellate/GrStrokeTessellationShader \
+ UnpackedTarball/skia/src/gpu/ganesh/tessellate/GrTessellationShader \
+ UnpackedTarball/skia/src/gpu/ganesh/tessellate/PathTessellator \
+ UnpackedTarball/skia/src/gpu/ganesh/tessellate/StrokeTessellator \
+ UnpackedTarball/skia/src/gpu/ganesh/text/GrAtlasManager \
+ UnpackedTarball/skia/src/gpu/ganesh/text/GrDistanceFieldAdjustTable \
+ UnpackedTarball/skia/src/gpu/ganesh/text/GrSDFMaskFilter \
+ UnpackedTarball/skia/src/gpu/ganesh/text/GrSDFTControl \
+ UnpackedTarball/skia/src/gpu/ganesh/text/GrSlug \
+ UnpackedTarball/skia/src/gpu/ganesh/text/GrTextBlob \
+ UnpackedTarball/skia/src/gpu/ganesh/text/GrTextBlobRedrawCoordinator \
+ UnpackedTarball/skia/src/gpu/tessellate/FixedCountBufferUtils \
+ UnpackedTarball/skia/src/gpu/tessellate/Tessellation \
+ UnpackedTarball/skia/src/image/SkImage_GpuBase \
+ UnpackedTarball/skia/src/image/SkImage_Gpu \
+ UnpackedTarball/skia/src/image/SkImage_GpuYUVA \
+ UnpackedTarball/skia/src/image/SkSurface_Gpu \
+ UnpackedTarball/skia/src/text/gpu/GlyphVector \
+ UnpackedTarball/skia/src/text/gpu/StrikeCache \
+ UnpackedTarball/skia/src/text/gpu/SubRunAllocator \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/gpu/ganesh/GrAuditTrail \
+ UnpackedTarball/skia/src/gpu/ganesh/GrBlurUtils \
+ UnpackedTarball/skia/src/gpu/ganesh/GrDrawOpTest \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/AAConvexPathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/AAHairLinePathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/AALinearizingConvexPathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/AtlasInstancedHelper \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/AtlasPathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/AtlasRenderTask \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/AtlasTextOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/ClearOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/DashLinePathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/DashOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/DefaultPathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/DrawAtlasOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/DrawAtlasPathOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/DrawMeshOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/DrawableOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/FillRRectOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/FillRectOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/GrMeshDrawOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/GrOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/GrOvalOpFactory \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelperWithStencil \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/LatticeOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/OpsTask \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/PathInnerTriangulateOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/PathStencilCoverOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/PathTessellateOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/QuadPerEdgeAA \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/RegionOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/ShadowRRectOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/SmallPathAtlasMgr \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/SmallPathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/SmallPathShapeData \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/SoftwarePathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/StrokeRectOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/StrokeTessellateOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/TessellationPathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/TextureOp \
+ UnpackedTarball/skia/src/gpu/ganesh/ops/TriangulatingPathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/v1/ClipStack \
+ UnpackedTarball/skia/src/gpu/ganesh/v1/Device \
+ UnpackedTarball/skia/src/gpu/ganesh/v1/Device_drawTexture \
+ UnpackedTarball/skia/src/gpu/ganesh/v1/PathRenderer \
+ UnpackedTarball/skia/src/gpu/ganesh/v1/PathRendererChain \
+ UnpackedTarball/skia/src/gpu/ganesh/v1/StencilMaskHelper \
+ UnpackedTarball/skia/src/gpu/ganesh/v1/SurfaceDrawContext \
+ UnpackedTarball/skia/src/gpu/ganesh/v1/SurfaceFillContext_v1 \
+))
+
+ifeq ($(SKIA_GPU),VULKAN)
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkAMDMemoryAllocator \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkBuffer \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkCaps \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkCommandBuffer \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkCommandPool \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkDescriptorPool \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkDescriptorSet \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkDescriptorSetManager \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkExtensions \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkFramebuffer \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkGpu \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkImage \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkImageView \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkInterface \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkMSAALoadManager \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkMemory \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkOpsRenderPass \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkPipeline \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkPipelineStateBuilder \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkPipelineStateCache \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkPipelineState \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkPipelineStateDataManager \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkRenderPass \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkRenderTarget \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkResourceProvider \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkSampler \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkSamplerYcbcrConversion \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkSecondaryCBDrawContext \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkSemaphore \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkTexture \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkTextureRenderTarget \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkTypesPriv \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkUniformHandler \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkUtil \
+ UnpackedTarball/skia/src/gpu/ganesh/vk/GrVkVaryingHandler \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/tools/gpu/vk/VkTestUtils \
+ UnpackedTarball/skia/tools/sk_app/VulkanWindowContext \
+ UnpackedTarball/skia/third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator \
+))
+
+endif
+endif
+
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/ports/SkGlobalInitialization_default \
+ UnpackedTarball/skia/src/ports/SkImageGenerator_none \
+ UnpackedTarball/skia/src/ports/SkOSFile_stdio \
+))
+
+$(eval $(call gb_Library_add_exception_objects,skia,\
+ external/skia/source/skia_opts_ssse3, $(CXXFLAGS_INTRINSICS_SSSE3) $(LO_CLANG_CXXFLAGS_INTRINSICS_SSSE3) \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/opts/SkOpts_avx, $(CXXFLAGS_INTRINSICS_AVX) $(LO_CLANG_CXXFLAGS_INTRINSICS_AVX) \
+ $(LO_SKIA_AVOID_INLINE_COPIES) \
+))
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/opts/SkOpts_hsw, \
+ $(CXXFLAGS_INTRINSICS_AVX2) $(CXXFLAGS_INTRINSICS_F16C) $(CXXFLAGS_INTRINSICS_FMA) \
+ $(LO_CLANG_CXXFLAGS_INTRINSICS_AVX2) $(LO_CLANG_CXXFLAGS_INTRINSICS_F16C) $(LO_CLANG_CXXFLAGS_INTRINSICS_FMA) \
+ $(LO_SKIA_AVOID_INLINE_COPIES) \
+))
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/opts/SkOpts_sse41, $(CXXFLAGS_INTRINSICS_SSE41) $(LO_CLANG_CXXFLAGS_INTRINSICS_SSE41) \
+ $(LO_SKIA_AVOID_INLINE_COPIES) \
+))
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/opts/SkOpts_sse42, $(CXXFLAGS_INTRINSICS_SSE42) $(LO_CLANG_CXXFLAGS_INTRINSICS_SSE42) \
+ $(LO_SKIA_AVOID_INLINE_COPIES) \
+))
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/opts/SkOpts_ssse3, $(CXXFLAGS_INTRINSICS_SSSE3) $(LO_CLANG_CXXFLAGS_INTRINSICS_SSSE3) \
+ $(LO_SKIA_AVOID_INLINE_COPIES) \
+))
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/opts/SkOpts_crc32 \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/opts/SkOpts_skx, $(CXXFLAGS_INTRINSICS_AVX512) $(LO_CLANG_CXXFLAGS_INTRINSICS_AVX512)\
+ $(LO_SKIA_AVOID_INLINE_COPIES) \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/tools/sk_app/WindowContext \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/ports/SkDebug_win \
+ UnpackedTarball/skia/src/ports/SkFontHost_win \
+ UnpackedTarball/skia/src/fonts/SkFontMgr_indirect \
+ UnpackedTarball/skia/src/ports/SkFontMgr_win_dw \
+ UnpackedTarball/skia/src/ports/SkFontMgr_win_dw_factory \
+ UnpackedTarball/skia/src/ports/SkOSFile_win \
+ UnpackedTarball/skia/src/ports/SkOSLibrary_win \
+ UnpackedTarball/skia/src/ports/SkScalerContext_win_dw \
+ UnpackedTarball/skia/src/ports/SkTypeface_win_dw \
+ UnpackedTarball/skia/src/utils/win/SkAutoCoInitialize \
+ UnpackedTarball/skia/src/utils/win/SkDWrite \
+ UnpackedTarball/skia/src/utils/win/SkDWriteFontFileStream \
+ UnpackedTarball/skia/src/utils/win/SkDWriteGeometrySink \
+ UnpackedTarball/skia/src/utils/win/SkHRESULT \
+ UnpackedTarball/skia/src/utils/win/SkIStream \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/tools/sk_app/win/RasterWindowContext_win \
+))
+
+ifeq ($(SKIA_GPU),VULKAN)
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/tools/sk_app/win/VulkanWindowContext_win \
+))
+endif
+
+else ifeq ($(OS),MACOSX)
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/ports/SkDebug_stdio \
+ UnpackedTarball/skia/src/ports/SkImageEncoder_CG \
+ UnpackedTarball/skia/src/ports/SkImageGeneratorCG \
+ UnpackedTarball/skia/src/ports/SkFontMgr_mac_ct \
+ UnpackedTarball/skia/src/ports/SkFontMgr_mac_ct_factory \
+ UnpackedTarball/skia/src/ports/SkScalerContext_mac_ct \
+ UnpackedTarball/skia/src/ports/SkTypeface_mac_ct \
+ UnpackedTarball/skia/src/ports/SkOSFile_posix \
+ UnpackedTarball/skia/src/ports/SkOSLibrary_posix \
+ UnpackedTarball/skia/src/utils/mac/SkCTFont \
+ UnpackedTarball/skia/src/utils/mac/SkCreateCGImageRef \
+))
+
+ifeq ($(SKIA_GPU),METAL)
+$(eval $(call gb_Library_add_generated_objcxxobjects,skia,\
+ UnpackedTarball/skia/tools/sk_app/MetalWindowContext \
+ UnpackedTarball/skia/tools/sk_app/mac/MetalWindowContext_mac \
+))
+
+# Not used, uses OpenGL - UnpackedTarball/skia/tools/sk_app/mac/RasterWindowContext_mac
+
+$(eval $(call gb_Library_add_generated_objcxxobjects,skia,\
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlAttachment \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlBuffer \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlCaps \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlCommandBuffer \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlDepthStencil \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlFramebuffer \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlGpu \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlOpsRenderPass \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlPipelineState \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlPipelineStateBuilder \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlPipelineStateDataManager \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlRenderTarget \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlResourceProvider \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlSampler \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlSemaphore \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlTexture \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlTextureRenderTarget \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlTrampoline \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlTypesPriv \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlUniformHandler \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlUtil \
+ UnpackedTarball/skia/src/gpu/ganesh/mtl/GrMtlVaryingHandler \
+ UnpackedTarball/skia/src/image/SkSurface_GpuMtl \
+ , -fobjc-arc \
+))
+endif
+
+else
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/src/ports/SkDebug_stdio \
+ UnpackedTarball/skia/src/ports/SkFontConfigInterface \
+ UnpackedTarball/skia/src/ports/SkFontConfigInterface_direct \
+ UnpackedTarball/skia/src/ports/SkFontConfigInterface_direct_factory \
+ UnpackedTarball/skia/src/ports/SkFontHost_FreeType_common \
+ UnpackedTarball/skia/src/ports/SkFontHost_FreeType \
+ UnpackedTarball/skia/src/ports/SkFontMgr_FontConfigInterface \
+ UnpackedTarball/skia/src/ports/SkFontMgr_fontconfig \
+ UnpackedTarball/skia/src/ports/SkFontMgr_fontconfig_factory \
+ UnpackedTarball/skia/src/ports/SkOSFile_posix \
+ UnpackedTarball/skia/src/ports/SkOSLibrary_posix \
+))
+
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/tools/sk_app/unix/RasterWindowContext_unix \
+))
+ifeq ($(SKIA_GPU),VULKAN)
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/tools/sk_app/unix/VulkanWindowContext_unix \
+))
+endif
+
+endif
+
+# Skcms code is used by png writer, which is used by SkiaHelper::dump(). Building
+# this without optimizations would mean having each pixel of saved images be
+# processed by unoptimized code.
+$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/third_party/skcms/skcms, $(gb_COMPILEROPTFLAGS) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/skia/Makefile b/external/skia/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/skia/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/skia/Module_skia.mk b/external/skia/Module_skia.mk
new file mode 100644
index 000000000..4cb8b5157
--- /dev/null
+++ b/external/skia/Module_skia.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,skia))
+
+$(eval $(call gb_Module_add_targets,skia,\
+ UnpackedTarball_skia \
+ Library_skia \
+))
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/skia/README b/external/skia/README
new file mode 100644
index 000000000..bf59a2384
--- /dev/null
+++ b/external/skia/README
@@ -0,0 +1,33 @@
+External package containing skia.
+
+https://skia.org/
+
+
+How to update the tarball:
+==========================
+
+git clone https://skia.googlesource.com/skia.git
+cd skia
+git checkout chrome/mXX
+id=$(git rev-parse chrome/mXX)
+git clean -idx
+rm -rf .git gitignore infra modules/canvaskit resources site
+cd ..
+tar cvJf skia-mXX-$id.tar.xz skia
+
+(where XX refers to the branch version)
+
+And review differences for BUILD.gn and relevant files in gn/ :
+git diff chrome/mYY..chrome/mXX ./BUILD.gn ./gn
+
+
+Debugging Skia:
+===============
+
+Note that Skia is always built optimized, unless you use --enable-skia=debug.
+
+
+GrContext sharing:
+==================
+
+For details about the share-grcontext patch, see vcl/skia/README.
diff --git a/external/skia/UnpackedTarball_skia.mk b/external/skia/UnpackedTarball_skia.mk
new file mode 100644
index 000000000..f88cb371d
--- /dev/null
+++ b/external/skia/UnpackedTarball_skia.mk
@@ -0,0 +1,53 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,skia))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,skia,$(SKIA_TARBALL)))
+
+skia_patches := \
+ fix-pch.patch.1 \
+ fix-ddi.patch \
+ make-api-visible.patch.1 \
+ no-trace-resources-on-exit.patch.1 \
+ fix-alpha-difference-copy.patch.1 \
+ share-grcontext.patch.1 \
+ clang11-flax-vector-conversion.patch.0 \
+ clang-attributes-warning.patch.1 \
+ fontconfig-get-typeface.patch.0 \
+ windows-do-not-modify-logfont.patch.0 \
+ windows-text-gamma.patch.0 \
+ windows-force-unicode-api.patch.0 \
+ fix-without-gl.patch.1 \
+ windows-typeface-directwrite.patch.0 \
+ windows-raster-surface-no-copies.patch.1 \
+ fix-windows-dwrite.patch.1 \
+ swap-buffers-rect.patch.1 \
+ ubsan.patch.1 \
+ fast-png-write.patch.1 \
+ skia_sk_cpu_sse_level_0_by_default.patch.1 \
+ fix-warnings.patch.1 \
+ windows-libraries-system32.patch.1 \
+ fix-graphite-ifdef.patch.1 \
+ allow-no-es2restrictions.patch.1 \
+ vk_mem_alloc.patch.1 \
+ tdf148624.patch.1 \
+ missing-include.patch.0 \
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,skia,1))
+
+$(eval $(call gb_UnpackedTarball_add_patches,skia,\
+ $(foreach patch,$(skia_patches),external/skia/$(patch)) \
+))
+
+$(eval $(call gb_UnpackedTarball_set_post_action,skia,\
+ mv third_party/skcms/skcms.cc third_party/skcms/skcms.cpp \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/skia/allow-no-es2restrictions.patch.1 b/external/skia/allow-no-es2restrictions.patch.1
new file mode 100644
index 000000000..ea2dd0219
--- /dev/null
+++ b/external/skia/allow-no-es2restrictions.patch.1
@@ -0,0 +1,13 @@
+diff --git a/include/effects/SkRuntimeEffect.h b/include/effects/SkRuntimeEffect.h
+index e424910b34..cee7794d3a 100644
+--- a/include/effects/SkRuntimeEffect.h
++++ b/include/effects/SkRuntimeEffect.h
+@@ -108,7 +108,7 @@ public:
+ // painted.)
+ bool forceUnoptimized = false;
+
+- private:
++// private:
+ friend class SkRuntimeEffect;
+ friend class SkRuntimeEffectPriv;
+
diff --git a/external/skia/clang-attributes-warning.patch.1 b/external/skia/clang-attributes-warning.patch.1
new file mode 100644
index 000000000..6384735e9
--- /dev/null
+++ b/external/skia/clang-attributes-warning.patch.1
@@ -0,0 +1,31 @@
+diff --git a/include/private/SkFloatingPoint.h b/include/private/SkFloatingPoint.h
+index 3c6d22c310..60500b2d2c 100644
+--- a/include/private/SkFloatingPoint.h
++++ b/include/private/SkFloatingPoint.h
+@@ -159,7 +159,9 @@ static inline int64_t sk_float_saturate2int64(float x) {
+ // Cast double to float, ignoring any warning about too-large finite values being cast to float.
+ // Clang thinks this is undefined, but it's actually implementation defined to return either
+ // the largest float or infinity (one of the two bracketing representable floats). Good enough!
++#if defined(__clang__)
+ SK_ATTRIBUTE(no_sanitize("float-cast-overflow"))
++#endif
+ static inline float sk_double_to_float(double x) {
+ return static_cast<float>(x);
+ }
+@@ -242,12 +244,16 @@ static inline int sk_float_nextlog2(float x) {
+ // IEEE defines how float divide behaves for non-finite values and zero-denoms, but C does not
+ // so we have a helper that suppresses the possible undefined-behavior warnings.
+
++#if defined(__clang__)
+ SK_ATTRIBUTE(no_sanitize("float-divide-by-zero"))
++#endif
+ static inline float sk_ieee_float_divide(float numer, float denom) {
+ return numer / denom;
+ }
+
++#if defined(__clang__)
+ SK_ATTRIBUTE(no_sanitize("float-divide-by-zero"))
++#endif
+ static inline double sk_ieee_double_divide(double numer, double denom) {
+ return numer / denom;
+ }
diff --git a/external/skia/clang11-flax-vector-conversion.patch.0 b/external/skia/clang11-flax-vector-conversion.patch.0
new file mode 100644
index 000000000..40cf4e0a4
--- /dev/null
+++ b/external/skia/clang11-flax-vector-conversion.patch.0
@@ -0,0 +1,11 @@
+--- src/opts/SkRasterPipeline_opts.h
++++ src/opts/SkRasterPipeline_opts.h
+@@ -68,7 +68,7 @@
+ };
+
+
+-#if !defined(__clang__)
++#if !defined(__clang__) || __clang_major__ >= 11
+ #define JUMPER_IS_SCALAR
+ #elif defined(SK_ARM_HAS_NEON)
+ #define JUMPER_IS_NEON
diff --git a/external/skia/fast-png-write.patch.1 b/external/skia/fast-png-write.patch.1
new file mode 100644
index 000000000..f47a2af70
--- /dev/null
+++ b/external/skia/fast-png-write.patch.1
@@ -0,0 +1,15 @@
+diff --git a/src/images/SkImageEncoder.cpp b/src/images/SkImageEncoder.cpp
+index a96a93e0fc..1c110afa58 100644
+--- a/src/images/SkImageEncoder.cpp
++++ b/src/images/SkImageEncoder.cpp
+@@ -46,6 +46,10 @@ bool SkEncodeImage(SkWStream* dst, const SkPixmap& src,
+ }
+ case SkEncodedImageFormat::kPNG: {
+ SkPngEncoder::Options opts;
++ if (quality == 1) {
++ opts.fFilterFlags = SkPngEncoder::FilterFlag::kNone;
++ opts.fZLibLevel = 1;
++ }
+ return SkPngEncoder::Encode(dst, src, opts);
+ }
+ case SkEncodedImageFormat::kWEBP: {
diff --git a/external/skia/fix-alpha-difference-copy.patch.1 b/external/skia/fix-alpha-difference-copy.patch.1
new file mode 100644
index 000000000..61a61e621
--- /dev/null
+++ b/external/skia/fix-alpha-difference-copy.patch.1
@@ -0,0 +1,13 @@
+diff --git a/src/core/SkBlitter_Sprite.cpp b/src/core/SkBlitter_Sprite.cpp
+index df7d9a7025..7f94c2a660 100644
+--- a/src/core/SkBlitter_Sprite.cpp
++++ b/src/core/SkBlitter_Sprite.cpp
+@@ -191,7 +191,7 @@ SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint,
+ }
+
+ // TODO: in principle SkRasterPipelineSpriteBlitter could be made to handle this.
+- if (source.alphaType() == kUnpremul_SkAlphaType) {
++ if (source.alphaType() != dst.alphaType()) {
+ return nullptr;
+ }
+
diff --git a/external/skia/fix-ddi.patch b/external/skia/fix-ddi.patch
new file mode 100644
index 000000000..f827c1d69
--- /dev/null
+++ b/external/skia/fix-ddi.patch
@@ -0,0 +1,9 @@
+--- skia/src/utils/win/SkDWriteNTDDI_VERSION.h.sav 2019-08-15 21:59:46.000000000 +0200
++++ skia/src/utils/win/SkDWriteNTDDI_VERSION.h 2019-09-26 15:30:36.395622200 +0200
+@@ -28,4 +28,6 @@
+ # endif
+ #endif
+
++#define NTDDI_VERSION 0x0A000002 // NTDDI_WIN10_RS1
++
+ #endif
diff --git a/external/skia/fix-graphite-ifdef.patch.1 b/external/skia/fix-graphite-ifdef.patch.1
new file mode 100644
index 000000000..4ed2ff252
--- /dev/null
+++ b/external/skia/fix-graphite-ifdef.patch.1
@@ -0,0 +1,48 @@
+diff --git a/include/core/SkImage.h b/include/core/SkImage.h
+index 9ca9317408..fee18fe58c 100644
+--- a/include/core/SkImage.h
++++ b/include/core/SkImage.h
+@@ -17,7 +17,7 @@
+ #if SK_SUPPORT_GPU
+ #include "include/gpu/GrTypes.h"
+ #endif
+-#if SK_GRAPHITE_ENABLED
++#ifdef SK_GRAPHITE_ENABLED
+ #include "include/gpu/graphite/GraphiteTypes.h"
+ #endif
+ #include <functional> // std::function
+@@ -49,7 +49,7 @@ class SkYUVAPixmaps;
+
+ enum class SkEncodedImageFormat;
+
+-#if SK_GRAPHITE_ENABLED
++#ifdef SK_GRAPHITE_ENABLED
+ namespace skgpu::graphite {
+ class Recorder;
+ };
+diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
+index 5301361a2b..8adaf3ac09 100644
+--- a/include/core/SkTypes.h
++++ b/include/core/SkTypes.h
+@@ -236,7 +236,7 @@
+ # define SK_SUPPORT_GPU 1
+ #endif
+
+-#if SK_SUPPORT_GPU || SK_GRAPHITE_ENABLED
++#if SK_SUPPORT_GPU || defined(SK_GRAPHITE_ENABLED)
+ # if !defined(SK_ENABLE_SKSL)
+ # define SK_ENABLE_SKSL
+ # endif
+diff --git a/tools/sk_app/WindowContext.h b/tools/sk_app/WindowContext.h
+index 65ab8b9aa4..c1bc7fb03a 100644
+--- a/tools/sk_app/WindowContext.h
++++ b/tools/sk_app/WindowContext.h
+@@ -58,7 +58,7 @@ protected:
+ virtual bool isGpuContext() { return true; }
+
+ sk_sp<GrDirectContext> fContext;
+-#if SK_GRAPHITE_ENABLED
++#ifdef SK_GRAPHITE_ENABLED
+ std::unique_ptr<skgpu::graphite::Context> fGraphiteContext;
+ std::unique_ptr<skgpu::graphite::Recorder> fGraphiteRecorder;
+ #endif
diff --git a/external/skia/fix-pch.patch.1 b/external/skia/fix-pch.patch.1
new file mode 100644
index 000000000..a2fe81562
--- /dev/null
+++ b/external/skia/fix-pch.patch.1
@@ -0,0 +1,106 @@
+diff --git a/include/core/SkColor.h b/include/core/SkColor.h
+index a6e63def23..1c0655c3d7 100644
+--- a/include/core/SkColor.h
++++ b/include/core/SkColor.h
+@@ -420,6 +420,7 @@ using SkColor4f = SkRGBA4f<kUnpremul_SkAlphaType>;
+
+ template <> SK_API SkColor4f SkColor4f::FromColor(SkColor);
+ template <> SK_API SkColor SkColor4f::toSkColor() const;
++template <> uint32_t SkColor4f::toBytes_RGBA() const;
+
+ namespace SkColors {
+ constexpr SkColor4f kTransparent = {0, 0, 0, 0};
+diff --git a/include/private/SkColorData.h b/include/private/SkColorData.h
+index a59e7b0446..960b4c0313 100644
+--- a/include/private/SkColorData.h
++++ b/include/private/SkColorData.h
+@@ -438,4 +438,6 @@ constexpr SkPMColor4f SK_PMColor4fILLEGAL = { SK_FloatNegativeInfinity,
+ SK_FloatNegativeInfinity,
+ SK_FloatNegativeInfinity };
+
++template <> uint32_t SkPMColor4f::toBytes_RGBA() const;
++
+ #endif
+diff --git a/src/core/SkM44.cpp b/src/core/SkM44.cpp
+index 02b1741763..4cece999d2 100644
+--- a/src/core/SkM44.cpp
++++ b/src/core/SkM44.cpp
+@@ -341,6 +341,8 @@ SkM44 SkM44::LookAt(const SkV3& eye, const SkV3& center, const SkV3& up) {
+ return m;
+ }
+
++#undef near
++#undef far
+ SkM44 SkM44::Perspective(float near, float far, float angle) {
+ SkASSERT(far > near);
+
+diff --git a/src/gpu/ganesh/vk/GrVkSemaphore.cpp b/src/gpu/ganesh/vk/GrVkSemaphore.cpp
+index 70c7f0ea80..ab8319a447 100644
+--- a/src/gpu/ganesh/vk/GrVkSemaphore.cpp
++++ b/src/gpu/ganesh/vk/GrVkSemaphore.cpp
+@@ -10,6 +10,7 @@
+ #include "include/gpu/GrBackendSemaphore.h"
+ #include "src/gpu/ganesh/vk/GrVkGpu.h"
+ #include "src/gpu/ganesh/vk/GrVkUtil.h"
++#include "tools/gpu/vk/GrVulkanDefines.h"
+
+ #ifdef VK_USE_PLATFORM_WIN32_KHR
+ // windows wants to define this as CreateSemaphoreA or CreateSemaphoreW
+diff --git a/src/sksl/ir/SkSLPoison.h b/src/sksl/ir/SkSLPoison.h
+index 035f94e1f6..3cf12db902 100644
+--- a/src/sksl/ir/SkSLPoison.h
++++ b/src/sksl/ir/SkSLPoison.h
+@@ -5,6 +5,9 @@
+ * found in the LICENSE file.
+ */
+
++#ifndef SKSL_POISON
++#define SKSL_POISON
++
+ #include "src/sksl/SkSLCompiler.h"
+ #include "src/sksl/SkSLContext.h"
+
+@@ -38,3 +41,5 @@ private:
+ };
+
+ } // namespace SkSL
++
++#endif
+diff --git a/src/utils/win/SkDWriteGeometrySink.h b/src/utils/win/SkDWriteGeometrySink.h
+index af4909aaaf..825ec35c83 100644
+--- a/src/utils/win/SkDWriteGeometrySink.h
++++ b/src/utils/win/SkDWriteGeometrySink.h
+@@ -13,6 +13,8 @@
+
+ class SkPath;
+
++#define CONST const
++
+ #include <dwrite.h>
+ #include <d2d1.h>
+
+diff --git a/third_party/skcms/skcms.cc b/third_party/skcms/skcms.cc
+index 1b643f45cf..c1981110da 100644
+--- a/third_party/skcms/skcms.cc
++++ b/third_party/skcms/skcms.cc
+@@ -130,7 +130,8 @@ static float minus_1_ulp(float x) {
+ // Most transfer functions we work with are sRGBish.
+ // For exotic HDR transfer functions, we encode them using a tf.g that makes no sense,
+ // and repurpose the other fields to hold the parameters of the HDR functions.
+-enum TFKind { Bad, sRGBish, PQish, HLGish, HLGinvish };
++enum TFKind_skcms { Bad, sRGBish, PQish, HLGish, HLGinvish };
++#define TFKind TFKind_skcms
+ struct TF_PQish { float A,B,C,D,E,F; };
+ struct TF_HLGish { float R,G,a,b,c,K_minus_1; };
+ // We didn't originally support a scale factor K for HLG, and instead just stored 0 in
+@@ -2318,7 +2319,9 @@ typedef enum {
+ Op_store_hhhh,
+ Op_store_fff,
+ Op_store_ffff,
+-} Op;
++} Op_skcms;
++
++#define Op Op_skcms
+
+ #if defined(__clang__)
+ template <int N, typename T> using Vec = T __attribute__((ext_vector_type(N)));
diff --git a/external/skia/fix-warnings.patch.1 b/external/skia/fix-warnings.patch.1
new file mode 100644
index 000000000..2aefd91c5
--- /dev/null
+++ b/external/skia/fix-warnings.patch.1
@@ -0,0 +1,39 @@
+diff --git a/include/core/SkFontParameters.h b/include/core/SkFontParameters.h
+index ae4f1d68b6..71263da7c5 100644
+--- a/include/core/SkFontParameters.h
++++ b/include/core/SkFontParameters.h
+@@ -16,8 +16,8 @@ struct SkFontParameters {
+ // Parameters in a variation font axis.
+ struct Axis {
+ constexpr Axis() : tag(0), min(0), def(0), max(0), flags(0) {}
+- constexpr Axis(SkFourByteTag tag, float min, float def, float max, bool hidden) :
+- tag(tag), min(min), def(def), max(max), flags(hidden ? HIDDEN : 0) {}
++ constexpr Axis(SkFourByteTag _tag, float _min, float _def, float _max, bool hidden) :
++ tag(_tag), min(_min), def(_def), max(_max), flags(hidden ? HIDDEN : 0) {}
+
+ // Four character identifier of the font axis (weight, width, slant, italic...).
+ SkFourByteTag tag;
+diff --git a/tools/sk_app/WindowContext.h b/tools/sk_app/WindowContext.h
+index f143dab013..be3cde0f4f 100644
+--- a/tools/sk_app/WindowContext.h
++++ b/tools/sk_app/WindowContext.h
+@@ -31,7 +31,7 @@ public:
+
+ virtual void resize(int w, int h) = 0;
+
+- virtual void activate(bool isActive) {}
++ virtual void activate(bool /*isActive*/) {}
+
+ const DisplayParams& getDisplayParams() { return fDisplayParams; }
+ virtual void setDisplayParams(const DisplayParams& params) = 0;
+--- skia/include/core/SkSamplingOptions.h.orig 2022-05-22 12:25:06.112544528 +0200
++++ skia/include/core/SkSamplingOptions.h 2022-05-22 12:25:09.207636134 +0200
+@@ -97,7 +97,7 @@
+ bool isAniso() const { return maxAniso != 0; }
+
+ private:
+- SkSamplingOptions(int maxAniso) : maxAniso(maxAniso) {}
++ SkSamplingOptions(int maxAniso_) : maxAniso(maxAniso_) {}
+ };
+
+ #endif
diff --git a/external/skia/fix-windows-dwrite.patch.1 b/external/skia/fix-windows-dwrite.patch.1
new file mode 100644
index 000000000..b5f216a52
--- /dev/null
+++ b/external/skia/fix-windows-dwrite.patch.1
@@ -0,0 +1,40 @@
+diff --git a/src/ports/SkFontMgr_win_dw.cpp b/src/ports/SkFontMgr_win_dw.cpp
+index 6a4748f91c..50086a7780 100644
+--- a/src/ports/SkFontMgr_win_dw.cpp
++++ b/src/ports/SkFontMgr_win_dw.cpp
+@@ -361,6 +361,7 @@ static bool FindByDWriteFont(SkTypeface* cached, void* ctx) {
+ DWriteFontTypeface* cshFace = reinterpret_cast<DWriteFontTypeface*>(cached);
+ ProtoDWriteTypeface* ctxFace = reinterpret_cast<ProtoDWriteTypeface*>(ctx);
+
++#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3
+ // IDWriteFontFace5 introduced both Equals and HasVariations
+ SkTScopedComPtr<IDWriteFontFace5> cshFontFace5;
+ SkTScopedComPtr<IDWriteFontFace5> ctxFontFace5;
+@@ -369,6 +370,7 @@ static bool FindByDWriteFont(SkTypeface* cached, void* ctx) {
+ if (cshFontFace5 && ctxFontFace5) {
+ return cshFontFace5->Equals(ctxFontFace5.get());
+ }
++#endif
+
+ bool same;
+
+diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp
+index b2df467b22..385094e506 100644
+--- a/src/ports/SkScalerContext_win_dw.cpp
++++ b/src/ports/SkScalerContext_win_dw.cpp
+@@ -778,6 +778,7 @@ void SkScalerContext_DW::generateFontMetrics(SkFontMetrics* metrics) {
+ metrics->fFlags |= SkFontMetrics::kStrikeoutThicknessIsValid_Flag;
+ metrics->fFlags |= SkFontMetrics::kStrikeoutPositionIsValid_Flag;
+
++#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3
+ SkTScopedComPtr<IDWriteFontFace5> fontFace5;
+ if (SUCCEEDED(this->getDWriteTypeface()->fDWriteFontFace->QueryInterface(&fontFace5))) {
+ if (fontFace5->HasVariations()) {
+@@ -785,6 +786,7 @@ void SkScalerContext_DW::generateFontMetrics(SkFontMetrics* metrics) {
+ metrics->fFlags |= SkFontMetrics::kBoundsInvalid_Flag;
+ }
+ }
++#endif
+
+ if (this->getDWriteTypeface()->fDWriteFontFace1.get()) {
+ DWRITE_FONT_METRICS1 dwfm1;
diff --git a/external/skia/fix-without-gl.patch.1 b/external/skia/fix-without-gl.patch.1
new file mode 100644
index 000000000..8735dc81d
--- /dev/null
+++ b/external/skia/fix-without-gl.patch.1
@@ -0,0 +1,50 @@
+diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h
+index e10242b3b7..a1c0058caa 100644
+--- a/include/gpu/gl/GrGLInterface.h
++++ b/include/gpu/gl/GrGLInterface.h
+@@ -83,7 +83,9 @@ public:
+
+ GrGLExtensions fExtensions;
+
++#ifdef SK_GL
+ bool hasExtension(const char ext[]) const { return fExtensions.has(ext); }
++#endif
+
+ /**
+ * The function pointers are in a struct so that we can have a compiler generated assignment
+diff --git a/src/gpu/ganesh/gl/GrGLContext.h b/src/gpu/ganesh/gl/GrGLContext.h
+index d5424ca6cf..5b730fe176 100644
+--- a/src/gpu/ganesh/gl/GrGLContext.h
++++ b/src/gpu/ganesh/gl/GrGLContext.h
+@@ -64,9 +64,11 @@ public:
+ const GrGLCaps* caps() const { return fGLCaps.get(); }
+ GrGLCaps* caps() { return fGLCaps.get(); }
+
++#ifdef SK_GL
+ bool hasExtension(const char* ext) const {
+ return fInterface->hasExtension(ext);
+ }
++#endif
+
+ const GrGLExtensions& extensions() const { return fInterface->fExtensions; }
+
+diff --git a/src/gpu/ganesh/gl/GrGLGpu.h b/src/gpu/ganesh/gl/GrGLGpu.h
+index a3ac1ad25d..ffc18093e6 100644
+--- a/src/gpu/ganesh/gl/GrGLGpu.h
++++ b/src/gpu/ganesh/gl/GrGLGpu.h
+@@ -279,6 +279,7 @@ private:
+ // compatible stencil format, or negative if there is no compatible stencil format.
+ int getCompatibleStencilIndex(GrGLFormat format);
+
++#ifdef SK_GL
+ GrBackendFormat getPreferredStencilFormat(const GrBackendFormat& format) override {
+ int idx = this->getCompatibleStencilIndex(format.asGLFormat());
+ if (idx < 0) {
+@@ -287,6 +288,7 @@ private:
+ return GrBackendFormat::MakeGL(GrGLFormatToEnum(this->glCaps().stencilFormats()[idx]),
+ GR_GL_TEXTURE_NONE);
+ }
++#endif
+
+ void onFBOChanged();
+
diff --git a/external/skia/fontconfig-get-typeface.patch.0 b/external/skia/fontconfig-get-typeface.patch.0
new file mode 100644
index 000000000..20c3f5b9c
--- /dev/null
+++ b/external/skia/fontconfig-get-typeface.patch.0
@@ -0,0 +1,40 @@
+diff --git a/include/ports/SkFontMgr_fontconfig.h b/include/ports/SkFontMgr_fontconfig.h
+index 4b2bb2d297..2b82cbfedd 100644
+--- include/ports/SkFontMgr_fontconfig.h
++++ include/ports/SkFontMgr_fontconfig.h
+@@ -19,4 +19,9 @@ class SkFontMgr;
+ */
+ SK_API sk_sp<SkFontMgr> SkFontMgr_New_FontConfig(FcConfig* fc);
+
++struct _FcPattern;
++typedef struct _FcPattern FcPattern;
++class SkTypeface;
++SK_API sk_sp<SkTypeface> SkFontMgr_createTypefaceFromFcPattern(const sk_sp<SkFontMgr>& mgr, FcPattern* pattern);
++
+ #endif // #ifndef SkFontMgr_fontconfig_DEFINED
+diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp
+index c2da39b28f..28483faf02 100644
+--- src/ports/SkFontMgr_fontconfig.cpp
++++ src/ports/SkFontMgr_fontconfig.cpp
+@@ -690,6 +690,7 @@ class SkFontMgr_fontconfig : public SkFontMgr {
+ /** Creates a typeface using a typeface cache.
+ * @param pattern a complete pattern from FcFontRenderPrepare.
+ */
++public:
+ sk_sp<SkTypeface> createTypefaceFromFcPattern(SkAutoFcPattern pattern) const {
+ if (!pattern) {
+ return nullptr;
+@@ -1043,3 +1044,13 @@ protected:
+ SK_API sk_sp<SkFontMgr> SkFontMgr_New_FontConfig(FcConfig* fc) {
+ return sk_make_sp<SkFontMgr_fontconfig>(fc);
+ }
++
++SK_API sk_sp<SkTypeface> SkFontMgr_createTypefaceFromFcPattern(const sk_sp<SkFontMgr>& mgr, FcPattern* pattern)
++{
++ SkAutoFcPattern p([pattern]() {
++ FCLocker lock;
++ FcPatternReference(pattern);
++ return pattern;
++ }());
++ return static_cast<SkFontMgr_fontconfig*>(mgr.get())->createTypefaceFromFcPattern(std::move(p));
++}
diff --git a/external/skia/inc/pch/precompiled_skia.cxx b/external/skia/inc/pch/precompiled_skia.cxx
new file mode 100644
index 000000000..8892e30fd
--- /dev/null
+++ b/external/skia/inc/pch/precompiled_skia.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_skia.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/skia/inc/pch/precompiled_skia.hxx b/external/skia/inc/pch/precompiled_skia.hxx
new file mode 100644
index 000000000..e9631b68d
--- /dev/null
+++ b/external/skia/inc/pch/precompiled_skia.hxx
@@ -0,0 +1,618 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2022-05-20 16:24:18 using:
+ ./bin/update_pch external/skia skia --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/skia/inc/pch/precompiled_skia.hxx "make external/skia.build" --find-conflicts
+*/
+
+#include <sal/config.h>
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <array>
+#include <atomic>
+#include <bitset>
+#include <cctype>
+#include <cfloat>
+#include <chrono>
+#include <cinttypes>
+#include <climits>
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstring>
+#include <ctype.h>
+#include <deque>
+#include <errno.h>
+#include <forward_list>
+#include <functional>
+#include <initializer_list>
+#include <inttypes.h>
+#include <iterator>
+#include <limits.h>
+#include <limits>
+#include <locale>
+#include <map>
+#include <math.h>
+#include <memory>
+#include <new>
+#include <numeric>
+#include <optional>
+#include <png.h>
+#include <queue>
+#include <set>
+#include <sstream>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+#include <string_view>
+#include <thread>
+#include <tuple>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#include <rtl/alloc.h>
+#include <sal/log.hxx>
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <include/c/sk_canvas.h>
+#include <include/c/sk_colorspace.h>
+#include <include/c/sk_data.h>
+#include <include/c/sk_image.h>
+#include <include/c/sk_imageinfo.h>
+#include <include/c/sk_maskfilter.h>
+#include <include/c/sk_paint.h>
+#include <include/c/sk_path.h>
+#include <include/c/sk_picture.h>
+#include <include/c/sk_shader.h>
+#include <include/c/sk_surface.h>
+#include <include/codec/SkAndroidCodec.h>
+#include <include/codec/SkCodec.h>
+#include <include/core/SkAlphaType.h>
+#include <include/core/SkAnnotation.h>
+#include <include/core/SkBBHFactory.h>
+#include <include/core/SkBitmap.h>
+#include <include/core/SkBlendMode.h>
+#include <include/core/SkBlender.h>
+#include <include/core/SkBlurTypes.h>
+#include <include/core/SkCanvas.h>
+#include <include/core/SkClipOp.h>
+#include <include/core/SkColor.h>
+#include <include/core/SkColorFilter.h>
+#include <include/core/SkColorPriv.h>
+#include <include/core/SkColorSpace.h>
+#include <include/core/SkColorType.h>
+#include <include/core/SkContourMeasure.h>
+#include <include/core/SkCubicMap.h>
+#include <include/core/SkData.h>
+#include <include/core/SkDataTable.h>
+#include <include/core/SkDeferredDisplayList.h>
+#include <include/core/SkDeferredDisplayListRecorder.h>
+#include <include/core/SkDocument.h>
+#include <include/core/SkDrawable.h>
+#include <include/core/SkExecutor.h>
+#include <include/core/SkFlattenable.h>
+#include <include/core/SkFont.h>
+#include <include/core/SkFontArguments.h>
+#include <include/core/SkFontMetrics.h>
+#include <include/core/SkFontMgr.h>
+#include <include/core/SkFontParameters.h>
+#include <include/core/SkFontStyle.h>
+#include <include/core/SkFontTypes.h>
+#include <include/core/SkGraphics.h>
+#include <include/core/SkICC.h>
+#include <include/core/SkImage.h>
+#include <include/core/SkImageEncoder.h>
+#include <include/core/SkImageFilter.h>
+#include <include/core/SkImageGenerator.h>
+#include <include/core/SkImageInfo.h>
+#include <include/core/SkM44.h>
+#include <include/core/SkMallocPixelRef.h>
+#include <include/core/SkMaskFilter.h>
+#include <include/core/SkMath.h>
+#include <include/core/SkMatrix.h>
+#include <include/core/SkMesh.h>
+#include <include/core/SkOpenTypeSVGDecoder.h>
+#include <include/core/SkOverdrawCanvas.h>
+#include <include/core/SkPaint.h>
+#include <include/core/SkPath.h>
+#include <include/core/SkPathBuilder.h>
+#include <include/core/SkPathEffect.h>
+#include <include/core/SkPathMeasure.h>
+#include <include/core/SkPathTypes.h>
+#include <include/core/SkPicture.h>
+#include <include/core/SkPictureRecorder.h>
+#include <include/core/SkPixelRef.h>
+#include <include/core/SkPixmap.h>
+#include <include/core/SkPoint.h>
+#include <include/core/SkPoint3.h>
+#include <include/core/SkPromiseImageTexture.h>
+#include <include/core/SkRRect.h>
+#include <include/core/SkRSXform.h>
+#include <include/core/SkRasterHandleAllocator.h>
+#include <include/core/SkRect.h>
+#include <include/core/SkRefCnt.h>
+#include <include/core/SkRegion.h>
+#include <include/core/SkSamplingOptions.h>
+#include <include/core/SkScalar.h>
+#include <include/core/SkSerialProcs.h>
+#include <include/core/SkShader.h>
+#include <include/core/SkSize.h>
+#include <include/core/SkSpan.h>
+#include <include/core/SkStream.h>
+#include <include/core/SkString.h>
+#include <include/core/SkStrokeRec.h>
+#include <include/core/SkSurface.h>
+#include <include/core/SkSurfaceCharacterization.h>
+#include <include/core/SkSwizzle.h>
+#include <include/core/SkTextBlob.h>
+#include <include/core/SkTileMode.h>
+#include <include/core/SkTime.h>
+#include <include/core/SkTraceMemoryDump.h>
+#include <include/core/SkTypeface.h>
+#include <include/core/SkTypes.h>
+#include <include/core/SkUnPreMultiply.h>
+#include <include/core/SkVertices.h>
+#include <include/core/SkYUVAInfo.h>
+#include <include/core/SkYUVAPixmaps.h>
+#include <include/effects/Sk1DPathEffect.h>
+#include <include/effects/Sk2DPathEffect.h>
+#include <include/effects/SkBlenders.h>
+#include <include/effects/SkBlurMaskFilter.h>
+#include <include/effects/SkColorMatrix.h>
+#include <include/effects/SkColorMatrixFilter.h>
+#include <include/effects/SkCornerPathEffect.h>
+#include <include/effects/SkDashPathEffect.h>
+#include <include/effects/SkDiscretePathEffect.h>
+#include <include/effects/SkGradientShader.h>
+#include <include/effects/SkHighContrastFilter.h>
+#include <include/effects/SkImageFilters.h>
+#include <include/effects/SkLumaColorFilter.h>
+#include <include/effects/SkOpPathEffect.h>
+#include <include/effects/SkOverdrawColorFilter.h>
+#include <include/effects/SkPerlinNoiseShader.h>
+#include <include/effects/SkRuntimeEffect.h>
+#include <include/effects/SkShaderMaskFilter.h>
+#include <include/effects/SkStrokeAndFillPathEffect.h>
+#include <include/effects/SkTableColorFilter.h>
+#include <include/effects/SkTableMaskFilter.h>
+#include <include/effects/SkTrimPathEffect.h>
+#include <include/encode/SkJpegEncoder.h>
+#include <include/encode/SkPngEncoder.h>
+#include <include/encode/SkWebpEncoder.h>
+#include <include/gpu/GrBackendSurface.h>
+#include <include/gpu/GrContextOptions.h>
+#include <include/gpu/GrContextThreadSafeProxy.h>
+#include <include/gpu/GrDirectContext.h>
+#include <include/gpu/GrRecordingContext.h>
+#include <include/pathops/SkPathOps.h>
+#include <include/ports/SkRemotableFontMgr.h>
+#include <include/private/SkBitmaskEnum.h>
+#include <include/private/SkChecksum.h>
+#include <include/private/SkColorData.h>
+#include <include/private/SkDeque.h>
+#include <include/private/SkEncodedInfo.h>
+#include <include/private/SkFixed.h>
+#include <include/private/SkFloatBits.h>
+#include <include/private/SkFloatingPoint.h>
+#include <include/private/SkHalf.h>
+#include <include/private/SkIDChangeListener.h>
+#include <include/private/SkImageInfoPriv.h>
+#include <include/private/SkMacros.h>
+#include <include/private/SkMalloc.h>
+#include <include/private/SkMutex.h>
+#include <include/private/SkNx.h>
+#include <include/private/SkOnce.h>
+#include <include/private/SkOpts_spi.h>
+#include <include/private/SkPathRef.h>
+#include <include/private/SkSLDefines.h>
+#include <include/private/SkSLLayout.h>
+#include <include/private/SkSLModifiers.h>
+#include <include/private/SkSLProgramElement.h>
+#include <include/private/SkSLProgramKind.h>
+#include <include/private/SkSLSampleUsage.h>
+#include <include/private/SkSLStatement.h>
+#include <include/private/SkSLString.h>
+#include <include/private/SkSLSymbol.h>
+#include <include/private/SkSafe32.h>
+#include <include/private/SkSemaphore.h>
+#include <include/private/SkShadowFlags.h>
+#include <include/private/SkSpinlock.h>
+#include <include/private/SkStringView.h>
+#include <include/private/SkTArray.h>
+#include <include/private/SkTDArray.h>
+#include <include/private/SkTFitsIn.h>
+#include <include/private/SkTHash.h>
+#include <include/private/SkTPin.h>
+#include <include/private/SkTemplates.h>
+#include <include/private/SkThreadAnnotations.h>
+#include <include/private/SkThreadID.h>
+#include <include/private/SkTo.h>
+#include <include/private/SkVx.h>
+#include <include/private/chromium/GrSlug.h>
+#include <include/private/chromium/SkChromeRemoteGlyphCache.h>
+#include <include/private/gpu/ganesh/GrImageContext.h>
+#include <include/private/gpu/ganesh/GrTypesPriv.h>
+#include <include/third_party/skcms/skcms.h>
+#include <include/utils/SkBase64.h>
+#include <include/utils/SkCamera.h>
+#include <include/utils/SkCanvasStateUtils.h>
+#include <include/utils/SkCustomTypeface.h>
+#include <include/utils/SkEventTracer.h>
+#include <include/utils/SkNWayCanvas.h>
+#include <include/utils/SkNoDrawCanvas.h>
+#include <include/utils/SkNullCanvas.h>
+#include <include/utils/SkOrderedFontMgr.h>
+#include <include/utils/SkPaintFilterCanvas.h>
+#include <include/utils/SkParse.h>
+#include <include/utils/SkParsePath.h>
+#include <include/utils/SkRandom.h>
+#include <include/utils/SkShadowUtils.h>
+#include <include/utils/SkTextUtils.h>
+#include <src/codec/SkAndroidCodecAdapter.h>
+#include <src/codec/SkBmpBaseCodec.h>
+#include <src/codec/SkBmpCodec.h>
+#include <src/codec/SkBmpMaskCodec.h>
+#include <src/codec/SkBmpRLECodec.h>
+#include <src/codec/SkBmpStandardCodec.h>
+#include <src/codec/SkCodecImageGenerator.h>
+#include <src/codec/SkCodecPriv.h>
+#include <src/codec/SkColorTable.h>
+#include <src/codec/SkFrameHolder.h>
+#include <src/codec/SkIcoCodec.h>
+#include <src/codec/SkMaskSwizzler.h>
+#include <src/codec/SkMasks.h>
+#include <src/codec/SkPngCodec.h>
+#include <src/codec/SkPngPriv.h>
+#include <src/codec/SkSampledCodec.h>
+#include <src/codec/SkSampler.h>
+#include <src/codec/SkStreamBuffer.h>
+#include <src/codec/SkSwizzler.h>
+#include <src/codec/SkWbmpCodec.h>
+#include <src/core/SkAAClip.h>
+#include <src/core/SkATrace.h>
+#include <src/core/SkAdvancedTypefaceMetrics.h>
+#include <src/core/SkAnalyticEdge.h>
+#include <src/core/SkAnnotationKeys.h>
+#include <src/core/SkAntiRun.h>
+#include <src/core/SkArenaAlloc.h>
+#include <src/core/SkAutoBlitterChoose.h>
+#include <src/core/SkAutoMalloc.h>
+#include <src/core/SkAutoPixmapStorage.h>
+#include <src/core/SkBigPicture.h>
+#include <src/core/SkBitmapCache.h>
+#include <src/core/SkBitmapDevice.h>
+#include <src/core/SkBitmapProcState.h>
+#include <src/core/SkBlendModeBlender.h>
+#include <src/core/SkBlendModePriv.h>
+#include <src/core/SkBlenderBase.h>
+#include <src/core/SkBlitRow.h>
+#include <src/core/SkBlitter.h>
+#include <src/core/SkBlockAllocator.h>
+#include <src/core/SkBlurMask.h>
+#include <src/core/SkBuffer.h>
+#include <src/core/SkCachedData.h>
+#include <src/core/SkCanvasPriv.h>
+#include <src/core/SkClipStack.h>
+#include <src/core/SkClipStackDevice.h>
+#include <src/core/SkColorFilterBase.h>
+#include <src/core/SkColorFilterPriv.h>
+#include <src/core/SkColorFilter_Matrix.h>
+#include <src/core/SkColorSpacePriv.h>
+#include <src/core/SkColorSpaceXformSteps.h>
+#include <src/core/SkCompressedDataUtils.h>
+#include <src/core/SkConvertPixels.h>
+#include <src/core/SkCoreBlitters.h>
+#include <src/core/SkCpu.h>
+#include <src/core/SkCubicClipper.h>
+#include <src/core/SkDebugUtils.h>
+#include <src/core/SkDescriptor.h>
+#include <src/core/SkDevice.h>
+#include <src/core/SkDiscardableMemory.h>
+#include <src/core/SkDistanceFieldGen.h>
+#include <src/core/SkDraw.h>
+#include <src/core/SkDrawProcs.h>
+#include <src/core/SkDrawShadowInfo.h>
+#include <src/core/SkEdge.h>
+#include <src/core/SkEdgeBuilder.h>
+#include <src/core/SkEdgeClipper.h>
+#include <src/core/SkEffectPriv.h>
+#include <src/core/SkEndian.h>
+#include <src/core/SkEnumerate.h>
+#include <src/core/SkFDot6.h>
+#include <src/core/SkFontDescriptor.h>
+#include <src/core/SkFontPriv.h>
+#include <src/core/SkFontStream.h>
+#include <src/core/SkFuzzLogging.h>
+#include <src/core/SkGaussFilter.h>
+#include <src/core/SkGeometry.h>
+#include <src/core/SkGlyph.h>
+#include <src/core/SkGlyphBuffer.h>
+#include <src/core/SkGlyphRun.h>
+#include <src/core/SkGlyphRunPainter.h>
+#include <src/core/SkGpuBlurUtils.h>
+#include <src/core/SkICCPriv.h>
+#include <src/core/SkImageFilterCache.h>
+#include <src/core/SkImageFilterTypes.h>
+#include <src/core/SkImageFilter_Base.h>
+#include <src/core/SkImagePriv.h>
+#include <src/core/SkKeyContext.h>
+#include <src/core/SkKeyHelpers.h>
+#include <src/core/SkLRUCache.h>
+#include <src/core/SkLatticeIter.h>
+#include <src/core/SkLeanWindows.h>
+#include <src/core/SkLineClipper.h>
+#include <src/core/SkLocalMatrixImageFilter.h>
+#include <src/core/SkMD5.h>
+#include <src/core/SkMSAN.h>
+#include <src/core/SkMask.h>
+#include <src/core/SkMaskBlurFilter.h>
+#include <src/core/SkMaskCache.h>
+#include <src/core/SkMaskFilterBase.h>
+#include <src/core/SkMaskGamma.h>
+#include <src/core/SkMathPriv.h>
+#include <src/core/SkMatrixImageFilter.h>
+#include <src/core/SkMatrixInvert.h>
+#include <src/core/SkMatrixPriv.h>
+#include <src/core/SkMatrixProvider.h>
+#include <src/core/SkMatrixUtils.h>
+#include <src/core/SkMeshPriv.h>
+#include <src/core/SkMessageBus.h>
+#include <src/core/SkMiniRecorder.h>
+#include <src/core/SkMipmap.h>
+#include <src/core/SkMipmapAccessor.h>
+#include <src/core/SkMipmapBuilder.h>
+#include <src/core/SkModeColorFilter.h>
+#include <src/core/SkNextID.h>
+#include <src/core/SkOSFile.h>
+#include <src/core/SkOpts.h>
+#include <src/core/SkPaintDefaults.h>
+#include <src/core/SkPaintParamsKey.h>
+#include <src/core/SkPaintPriv.h>
+#include <src/core/SkPathEffectBase.h>
+#include <src/core/SkPathMakers.h>
+#include <src/core/SkPathMeasurePriv.h>
+#include <src/core/SkPathPriv.h>
+#include <src/core/SkPictureCommon.h>
+#include <src/core/SkPictureData.h>
+#include <src/core/SkPictureFlat.h>
+#include <src/core/SkPicturePlayback.h>
+#include <src/core/SkPicturePriv.h>
+#include <src/core/SkPictureRecord.h>
+#include <src/core/SkPipelineData.h>
+#include <src/core/SkPixelRefPriv.h>
+#include <src/core/SkPixmapPriv.h>
+#include <src/core/SkPointPriv.h>
+#include <src/core/SkPtrRecorder.h>
+#include <src/core/SkQuadClipper.h>
+#include <src/core/SkRRectPriv.h>
+#include <src/core/SkRTree.h>
+#include <src/core/SkRasterClip.h>
+#include <src/core/SkRasterPipeline.h>
+#include <src/core/SkReadBuffer.h>
+#include <src/core/SkRecord.h>
+#include <src/core/SkRecordDraw.h>
+#include <src/core/SkRecordOpts.h>
+#include <src/core/SkRecordPattern.h>
+#include <src/core/SkRecordedDrawable.h>
+#include <src/core/SkRecorder.h>
+#include <src/core/SkRecords.h>
+#include <src/core/SkRectPriv.h>
+#include <src/core/SkRegionPriv.h>
+#include <src/core/SkResourceCache.h>
+#include <src/core/SkRuntimeEffectPriv.h>
+#include <src/core/SkSLTypeShared.h>
+#include <src/core/SkSafeMath.h>
+#include <src/core/SkSafeRange.h>
+#include <src/core/SkSamplingPriv.h>
+#include <src/core/SkScaleToSides.h>
+#include <src/core/SkScalerCache.h>
+#include <src/core/SkScalerContext.h>
+#include <src/core/SkScan.h>
+#include <src/core/SkScanPriv.h>
+#include <src/core/SkScopeExit.h>
+#include <src/core/SkShaderCodeDictionary.h>
+#include <src/core/SkSharedMutex.h>
+#include <src/core/SkSpecialImage.h>
+#include <src/core/SkSpecialSurface.h>
+#include <src/core/SkSpriteBlitter.h>
+#include <src/core/SkStreamPriv.h>
+#include <src/core/SkStrikeCache.h>
+#include <src/core/SkStrikeForGPU.h>
+#include <src/core/SkStrikeSpec.h>
+#include <src/core/SkStringUtils.h>
+#include <src/core/SkStroke.h>
+#include <src/core/SkStrokerPriv.h>
+#include <src/core/SkSurfacePriv.h>
+#include <src/core/SkTDPQueue.h>
+#include <src/core/SkTDynamicHash.h>
+#include <src/core/SkTInternalLList.h>
+#include <src/core/SkTLazy.h>
+#include <src/core/SkTSearch.h>
+#include <src/core/SkTSort.h>
+#include <src/core/SkTaskGroup.h>
+#include <src/core/SkTextBlobPriv.h>
+#include <src/core/SkTextBlobTrace.h>
+#include <src/core/SkTextFormatParams.h>
+#include <src/core/SkTraceEvent.h>
+#include <src/core/SkTraceEventCommon.h>
+#include <src/core/SkTypefaceCache.h>
+#include <src/core/SkTypeface_remote.h>
+#include <src/core/SkUniform.h>
+#include <src/core/SkUtils.h>
+#include <src/core/SkVM.h>
+#include <src/core/SkVMBlitter.h>
+#include <src/core/SkValidationUtils.h>
+#include <src/core/SkVertState.h>
+#include <src/core/SkVerticesPriv.h>
+#include <src/core/SkWriteBuffer.h>
+#include <src/core/SkWritePixelsRec.h>
+#include <src/core/SkWriter32.h>
+#include <src/core/SkXfermodeInterpretation.h>
+#include <src/core/SkXfermodePriv.h>
+#include <src/core/SkYUVAInfoLocation.h>
+#include <src/core/SkYUVMath.h>
+#include <src/core/SkYUVPlanesCache.h>
+#include <src/effects/SkDashImpl.h>
+#include <src/effects/SkEmbossMask.h>
+#include <src/effects/SkEmbossMaskFilter.h>
+#include <src/effects/SkOpPE.h>
+#include <src/effects/SkTrimPE.h>
+#include <src/effects/imagefilters/SkCropImageFilter.h>
+#include <src/effects/imagefilters/SkRuntimeImageFilter.h>
+#include <src/gpu/Blend.h>
+#include <src/gpu/KeyBuilder.h>
+#include <src/gpu/ResourceKey.h>
+#include <src/gpu/ganesh/BaseDevice.h>
+#include <src/gpu/ganesh/GrCaps.h>
+#include <src/gpu/ganesh/GrColorInfo.h>
+#include <src/gpu/ganesh/GrColorSpaceXform.h>
+#include <src/gpu/ganesh/GrContextThreadSafeProxyPriv.h>
+#include <src/gpu/ganesh/GrDirectContextPriv.h>
+#include <src/gpu/ganesh/GrDrawOpAtlas.h>
+#include <src/gpu/ganesh/GrFPArgs.h>
+#include <src/gpu/ganesh/GrFragmentProcessor.h>
+#include <src/gpu/ganesh/GrGpuResourcePriv.h>
+#include <src/gpu/ganesh/GrImageContextPriv.h>
+#include <src/gpu/ganesh/GrImageInfo.h>
+#include <src/gpu/ganesh/GrMemoryPool.h>
+#include <src/gpu/ganesh/GrPaint.h>
+#include <src/gpu/ganesh/GrProxyProvider.h>
+#include <src/gpu/ganesh/GrRecordingContextPriv.h>
+#include <src/gpu/ganesh/GrRenderTask.h>
+#include <src/gpu/ganesh/GrResourceProvider.h>
+#include <src/gpu/ganesh/GrSamplerState.h>
+#include <src/gpu/ganesh/GrShaderCaps.h>
+#include <src/gpu/ganesh/GrStyle.h>
+#include <src/gpu/ganesh/GrSurfaceProxyView.h>
+#include <src/gpu/ganesh/GrTexture.h>
+#include <src/gpu/ganesh/GrTextureProxy.h>
+#include <src/gpu/ganesh/GrThreadSafeCache.h>
+#include <src/gpu/ganesh/GrYUVATextureProxies.h>
+#include <src/gpu/ganesh/SkGr.h>
+#include <src/gpu/ganesh/SurfaceFillContext.h>
+#include <src/gpu/ganesh/effects/GrBicubicEffect.h>
+#include <src/gpu/ganesh/effects/GrBlendFragmentProcessor.h>
+#include <src/gpu/ganesh/effects/GrCustomXfermode.h>
+#include <src/gpu/ganesh/effects/GrMatrixConvolutionEffect.h>
+#include <src/gpu/ganesh/effects/GrMatrixEffect.h>
+#include <src/gpu/ganesh/effects/GrPorterDuffXferProcessor.h>
+#include <src/gpu/ganesh/effects/GrSkSLFP.h>
+#include <src/gpu/ganesh/effects/GrTextureEffect.h>
+#include <src/gpu/ganesh/effects/GrYUVtoRGBEffect.h>
+#include <src/gpu/ganesh/geometry/GrPathUtils.h>
+#include <src/gpu/ganesh/geometry/GrStyledShape.h>
+#include <src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h>
+#include <src/gpu/ganesh/glsl/GrGLSLProgramDataManager.h>
+#include <src/gpu/ganesh/glsl/GrGLSLUniformHandler.h>
+#include <src/gpu/ganesh/gradients/GrGradientShader.h>
+#include <src/gpu/ganesh/text/GrSDFMaskFilter.h>
+#include <src/gpu/ganesh/text/GrSDFTControl.h>
+#include <src/gpu/ganesh/text/GrTextBlob.h>
+#include <src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.h>
+#include <src/gpu/ganesh/v1/SurfaceDrawContext_v1.h>
+#include <src/image/SkImage_Base.h>
+#include <src/image/SkImage_Gpu.h>
+#include <src/image/SkImage_Lazy.h>
+#include <src/image/SkReadPixelsRec.h>
+#include <src/image/SkRescaleAndReadPixels.h>
+#include <src/image/SkSurface_Base.h>
+#include <src/images/SkImageEncoderPriv.h>
+#include <src/lazy/SkDiscardableMemoryPool.h>
+#include <src/pathops/SkAddIntersections.h>
+#include <src/pathops/SkIntersectionHelper.h>
+#include <src/pathops/SkIntersections.h>
+#include <src/pathops/SkLineParameters.h>
+#include <src/pathops/SkOpAngle.h>
+#include <src/pathops/SkOpCoincidence.h>
+#include <src/pathops/SkOpContour.h>
+#include <src/pathops/SkOpEdgeBuilder.h>
+#include <src/pathops/SkOpSegment.h>
+#include <src/pathops/SkOpSpan.h>
+#include <src/pathops/SkPathOpsBounds.h>
+#include <src/pathops/SkPathOpsCommon.h>
+#include <src/pathops/SkPathOpsConic.h>
+#include <src/pathops/SkPathOpsCubic.h>
+#include <src/pathops/SkPathOpsCurve.h>
+#include <src/pathops/SkPathOpsDebug.h>
+#include <src/pathops/SkPathOpsLine.h>
+#include <src/pathops/SkPathOpsPoint.h>
+#include <src/pathops/SkPathOpsQuad.h>
+#include <src/pathops/SkPathOpsRect.h>
+#include <src/pathops/SkPathOpsTSect.h>
+#include <src/pathops/SkPathOpsTypes.h>
+#include <src/pathops/SkPathWriter.h>
+#include <src/pathops/SkReduceOrder.h>
+#include <src/sfnt/SkOTTableTypes.h>
+#include <src/sfnt/SkOTTable_OS_2.h>
+#include <src/sfnt/SkOTTable_head.h>
+#include <src/sfnt/SkOTTable_name.h>
+#include <src/sfnt/SkOTUtils.h>
+#include <src/shaders/SkBitmapProcShader.h>
+#include <src/shaders/SkColorFilterShader.h>
+#include <src/shaders/SkColorShader.h>
+#include <src/shaders/SkComposeShader.h>
+#include <src/shaders/SkEmptyShader.h>
+#include <src/shaders/SkImageShader.h>
+#include <src/shaders/SkLocalMatrixShader.h>
+#include <src/shaders/SkPictureShader.h>
+#include <src/shaders/SkShaderBase.h>
+#include <src/shaders/SkTransformShader.h>
+#include <src/shaders/gradients/Sk4fGradientBase.h>
+#include <src/shaders/gradients/Sk4fLinearGradient.h>
+#include <src/shaders/gradients/SkGradientShaderPriv.h>
+#include <src/shaders/gradients/SkLinearGradient.h>
+#include <src/shaders/gradients/SkRadialGradient.h>
+#include <src/shaders/gradients/SkSweepGradient.h>
+#include <src/shaders/gradients/SkTwoPointConicalGradient.h>
+#include <src/text/gpu/StrikeCache.h>
+#include <src/utils/SkBlitterTrace.h>
+#include <src/utils/SkCanvasStack.h>
+#include <src/utils/SkCharToGlyphCache.h>
+#include <src/utils/SkClipStackUtils.h>
+#include <src/utils/SkDashPathPriv.h>
+#include <src/utils/SkFloatToDecimal.h>
+#include <src/utils/SkJSON.h>
+#include <src/utils/SkJSONWriter.h>
+#include <src/utils/SkMatrix22.h>
+#include <src/utils/SkMultiPictureDocument.h>
+#include <src/utils/SkMultiPictureDocumentPriv.h>
+#include <src/utils/SkOSPath.h>
+#include <src/utils/SkPatchUtils.h>
+#include <src/utils/SkPolyUtils.h>
+#include <src/utils/SkShaderUtils.h>
+#include <src/utils/SkShadowTessellator.h>
+#include <src/utils/SkShaperJSONWriter.h>
+#include <src/utils/SkTestCanvas.h>
+#include <src/utils/SkUTF.h>
+#include <src/utils/SkVMVisualizer.h>
+#include <tools/sk_app/WindowContext.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#include <skia_compiler.hxx>
+#include <skia_opts.hxx>
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/skia/inc/skia_compiler.hxx b/external/skia/inc/skia_compiler.hxx
new file mode 100644
index 000000000..a26ec29bd
--- /dev/null
+++ b/external/skia/inc/skia_compiler.hxx
@@ -0,0 +1,13 @@
+/*
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SKIA_COMPILER_H
+#define SKIA_COMPILER_H
+
+#include <include/core/SkTypes.h>
+
+SK_API const char* skia_compiler_name();
+
+#endif
diff --git a/external/skia/inc/skia_opts.hxx b/external/skia/inc/skia_opts.hxx
new file mode 100644
index 000000000..33f82f9d2
--- /dev/null
+++ b/external/skia/inc/skia_opts.hxx
@@ -0,0 +1,28 @@
+/*
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SKIA_OPTS_H
+#define SKIA_OPTS_H
+
+#include <include/core/SkTypes.h>
+
+SK_API void SkConvertRGBToRGBA(uint32_t* dest, const uint8_t* src, int count);
+
+SK_API void SkConvertGrayToRGBA(uint32_t* dest, const uint8_t* src, int count);
+
+SK_API void SkConvertRGBAToRGB(uint8_t* dest, const uint32_t* src, int count);
+
+SK_API void SkConvertRGBAToR(uint8_t* dest, const uint32_t* src, int count);
+
+namespace SkLoOpts
+{
+SK_API void Init();
+
+typedef void (*Swizzle_u8_8888)(uint8_t*, const uint32_t*, int);
+extern Swizzle_u8_8888 RGB1_to_RGB, // i.e. remove an (opaque) alpha
+ RGB1_to_R; // i.e. copy one channel to the result
+}
+
+#endif
diff --git a/external/skia/make-api-visible.patch.1 b/external/skia/make-api-visible.patch.1
new file mode 100644
index 000000000..a90bd9943
--- /dev/null
+++ b/external/skia/make-api-visible.patch.1
@@ -0,0 +1,82 @@
+diff --git a/tools/sk_app/WindowContext.h b/tools/sk_app/WindowContext.h
+index 79f6d72f35..428d198159 100644
+--- a/tools/sk_app/WindowContext.h
++++ b/tools/sk_app/WindowContext.h
+@@ -22,7 +22,7 @@ class Context;
+
+ namespace sk_app {
+
+-class WindowContext {
++class SK_API WindowContext {
+ public:
+ WindowContext(const DisplayParams&);
+
+diff --git a/tools/sk_app/mac/WindowContextFactory_mac.h b/tools/sk_app/mac/WindowContextFactory_mac.h
+index 3e136a8f57..affb89e43e 100644
+--- a/tools/sk_app/mac/WindowContextFactory_mac.h
++++ b/tools/sk_app/mac/WindowContextFactory_mac.h
+@@ -52,7 +52,7 @@ std::unique_ptr<WindowContext> MakeDawnMTLForMac(const MacWindowInfo&, const Dis
+ #endif
+
+ #ifdef SK_METAL
+-std::unique_ptr<WindowContext> MakeMetalForMac(const MacWindowInfo&, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeMetalForMac(const MacWindowInfo&, const DisplayParams&);
+ #ifdef SK_GRAPHITE_ENABLED
+ std::unique_ptr<WindowContext> MakeGraphiteMetalForMac(const MacWindowInfo&, const DisplayParams&);
+ #endif
+diff --git a/tools/sk_app/unix/WindowContextFactory_unix.h b/tools/sk_app/unix/WindowContextFactory_unix.h
+index 11bd2d2ac2..09c92dc417 100644
+--- a/tools/sk_app/unix/WindowContextFactory_unix.h
++++ b/tools/sk_app/unix/WindowContextFactory_unix.h
+@@ -36,15 +36,15 @@ struct XlibWindowInfo {
+ int fHeight;
+ };
+
+-std::unique_ptr<WindowContext> MakeVulkanForXlib(const XlibWindowInfo&, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeVulkanForXlib(const XlibWindowInfo&, const DisplayParams&);
+
+-std::unique_ptr<WindowContext> MakeGLForXlib(const XlibWindowInfo&, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeGLForXlib(const XlibWindowInfo&, const DisplayParams&);
+
+ #ifdef SK_DAWN
+-std::unique_ptr<WindowContext> MakeDawnVulkanForXlib(const XlibWindowInfo&, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeDawnVulkanForXlib(const XlibWindowInfo&, const DisplayParams&);
+ #endif
+
+-std::unique_ptr<WindowContext> MakeRasterForXlib(const XlibWindowInfo&, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeRasterForXlib(const XlibWindowInfo&, const DisplayParams&);
+
+ } // namespace window_context_factory
+
+diff --git a/tools/sk_app/win/WindowContextFactory_win.h b/tools/sk_app/win/WindowContextFactory_win.h
+index c05a4f0acf..fc27cd2afb 100644
+--- a/tools/sk_app/win/WindowContextFactory_win.h
++++ b/tools/sk_app/win/WindowContextFactory_win.h
+@@ -20,21 +20,21 @@ struct DisplayParams;
+
+ namespace window_context_factory {
+
+-std::unique_ptr<WindowContext> MakeVulkanForWin(HWND, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeVulkanForWin(HWND, const DisplayParams&);
+
+-std::unique_ptr<WindowContext> MakeGLForWin(HWND, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeGLForWin(HWND, const DisplayParams&);
+
+-std::unique_ptr<WindowContext> MakeANGLEForWin(HWND, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeANGLEForWin(HWND, const DisplayParams&);
+
+ #ifdef SK_DIRECT3D
+-std::unique_ptr<WindowContext> MakeD3D12ForWin(HWND, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeD3D12ForWin(HWND, const DisplayParams&);
+ #endif
+
+ #ifdef SK_DAWN
+-std::unique_ptr<WindowContext> MakeDawnD3D12ForWin(HWND, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeDawnD3D12ForWin(HWND, const DisplayParams&);
+ #endif
+
+-std::unique_ptr<WindowContext> MakeRasterForWin(HWND, const DisplayParams&);
++SK_API std::unique_ptr<WindowContext> MakeRasterForWin(HWND, const DisplayParams&);
+
+ } // namespace window_context_factory
+
diff --git a/external/skia/missing-include.patch.0 b/external/skia/missing-include.patch.0
new file mode 100644
index 000000000..5d1d0609b
--- /dev/null
+++ b/external/skia/missing-include.patch.0
@@ -0,0 +1,20 @@
+--- src/core/SkShaderCodeDictionary.h
++++ src/core/SkShaderCodeDictionary.h
+@@ -9,6 +9,7 @@
+ #define SkShaderCodeDictionary_DEFINED
+
+ #include <array>
++#include <string>
+ #include <unordered_map>
+ #include <vector>
+ #include "include/core/SkSpan.h"
+--- third_party/vulkanmemoryallocator/include/vk_mem_alloc.h
++++ third_party/vulkanmemoryallocator/include/vk_mem_alloc.h
+@@ -2570,6 +2570,7 @@
+ #include <cstring>
+ #include <utility>
+ #include <type_traits>
++#include <stdio.h>
+
+ #ifdef _MSC_VER
+ #include <intrin.h> // For functions like __popcnt, _BitScanForward etc.
diff --git a/external/skia/no-trace-resources-on-exit.patch.1 b/external/skia/no-trace-resources-on-exit.patch.1
new file mode 100644
index 000000000..4d52a37dc
--- /dev/null
+++ b/external/skia/no-trace-resources-on-exit.patch.1
@@ -0,0 +1,13 @@
+diff --git a/src/gpu/vk/GrVkResource.h b/src/gpu/vk/GrVkResource.h
+index 7b9949ba1b..4e8fb48c7c 100644
+--- a/src/gpu/ganesh/GrManagedResource.h
++++ b/src/gpu/ganesh/GrManagedResource.h
+@@ -17,7 +17,7 @@ class GrVkGpu;
+
+ // uncomment to enable tracing of resource refs
+ #ifdef SK_DEBUG
+-#define SK_TRACE_MANAGED_RESOURCES
++//#define SK_TRACE_MANAGED_RESOURCES
+ #endif
+
+ /** \class GrManagedResource
diff --git a/external/skia/share-grcontext.patch.1 b/external/skia/share-grcontext.patch.1
new file mode 100644
index 000000000..2a957c284
--- /dev/null
+++ b/external/skia/share-grcontext.patch.1
@@ -0,0 +1,872 @@
+diff --git a/tools/sk_app/MetalWindowContext.h b/tools/sk_app/MetalWindowContext.h
+index 106d366415..08dc19b5c8 100644
+--- a/tools/sk_app/MetalWindowContext.h
++++ b/tools/sk_app/MetalWindowContext.h
+@@ -14,13 +14,18 @@
+
+ #include "tools/sk_app/WindowContext.h"
+
++#ifdef __OBJC__
+ #import <Metal/Metal.h>
+ #import <QuartzCore/CAMetalLayer.h>
++#endif
+
+ namespace sk_app {
+
++#ifdef __OBJC__
+ class MetalWindowContext : public WindowContext {
+ public:
++ static GrDirectContext* getSharedGrDirectContext() { return fGlobalShared ? fGlobalShared->fContext.get() : nullptr; }
++
+ sk_sp<SkSurface> getBackbufferSurface() override;
+
+ bool isValid() override { return fValid; }
+@@ -46,16 +51,34 @@ protected:
+ void destroyContext();
+ virtual void onDestroyContext() = 0;
+
++ static void checkDestroyShared();
++
+ bool fValid;
++
++ // We need to use just one GrDirectContext, so share all the relevant data.
++ struct Shared : public SkRefCnt
++ {
+ sk_cfp<id<MTLDevice>> fDevice;
+ sk_cfp<id<MTLCommandQueue>> fQueue;
+- CAMetalLayer* fMetalLayer;
+- GrMTLHandle fDrawableHandle;
+ #if GR_METAL_SDK_VERSION >= 230
+ // wrapping this in sk_cfp throws up an availability warning, so we'll track lifetime manually
+ id<MTLBinaryArchive> fPipelineArchive SK_API_AVAILABLE(macos(11.0), ios(14.0));
+ #endif
++
++ sk_sp<GrDirectContext> fContext;
++ };
++
++ sk_sp<Shared> fShared;
++
++ static sk_sp<Shared> fGlobalShared;
++
++ CAMetalLayer* fMetalLayer;
++ GrMTLHandle fDrawableHandle;
+ };
++#endif // __OBJC__
++
++// Access function when header is used from C++ code that wouldn't handle ObjC++ headers.
++extern "C" SK_API GrDirectContext* getMetalSharedGrDirectContext();
+
+ } // namespace sk_app
+
+diff --git a/tools/sk_app/MetalWindowContext.mm b/tools/sk_app/MetalWindowContext.mm
+index d972e321a6..9f576944b7 100644
+--- a/tools/sk_app/MetalWindowContext.mm
++++ b/tools/sk_app/MetalWindowContext.mm
+@@ -37,24 +37,30 @@ NSURL* MetalWindowContext::CacheURL() {
+ }
+
+ void MetalWindowContext::initializeContext() {
++ fShared = fGlobalShared;
++ if( !fShared )
++ {
++ // TODO do we need a mutex?
++
++ fGlobalShared = sk_make_sp<Shared>();
++ Shared* d = fGlobalShared.get(); // shorter variable name
++
+ SkASSERT(!fContext);
+
+- fDevice.reset(MTLCreateSystemDefaultDevice());
+- fQueue.reset([*fDevice newCommandQueue]);
++ d->fDevice.reset(MTLCreateSystemDefaultDevice());
++ d->fQueue.reset([*d->fDevice newCommandQueue]);
+
+ if (fDisplayParams.fMSAASampleCount > 1) {
+ if (@available(macOS 10.11, iOS 9.0, *)) {
+- if (![*fDevice supportsTextureSampleCount:fDisplayParams.fMSAASampleCount]) {
++ if (![*d->fDevice supportsTextureSampleCount:fDisplayParams.fMSAASampleCount]) {
++ fGlobalShared.reset();
+ return;
+ }
+ } else {
++ fGlobalShared.reset();
+ return;
+ }
+ }
+- fSampleCount = fDisplayParams.fMSAASampleCount;
+- fStencilBits = 8;
+-
+- fValid = this->onInitializeContext();
+
+ #if GR_METAL_SDK_VERSION >= 230
+ if (fDisplayParams.fEnableBinaryArchive) {
+@@ -62,11 +68,11 @@ void MetalWindowContext::initializeContext() {
+ sk_cfp<MTLBinaryArchiveDescriptor*> desc([MTLBinaryArchiveDescriptor new]);
+ (*desc).url = CacheURL(); // try to load
+ NSError* error;
+- fPipelineArchive = [*fDevice newBinaryArchiveWithDescriptor:*desc error:&error];
+- if (!fPipelineArchive) {
++ d->fPipelineArchive = [*d->fDevice newBinaryArchiveWithDescriptor:*desc error:&error];
++ if (!d->fPipelineArchive) {
+ (*desc).url = nil; // create new
+- fPipelineArchive = [*fDevice newBinaryArchiveWithDescriptor:*desc error:&error];
+- if (!fPipelineArchive) {
++ d->fPipelineArchive = [*d->fDevice newBinaryArchiveWithDescriptor:*desc error:&error];
++ if (!d->fPipelineArchive) {
+ SkDebugf("Error creating MTLBinaryArchive:\n%s\n",
+ error.debugDescription.UTF8String);
+ }
+@@ -74,46 +80,75 @@ void MetalWindowContext::initializeContext() {
+ }
+ } else {
+ if (@available(macOS 11.0, iOS 14.0, *)) {
+- fPipelineArchive = nil;
++ d->fPipelineArchive = nil;
+ }
+ }
+ #endif
+
+ GrMtlBackendContext backendContext = {};
+- backendContext.fDevice.retain((GrMTLHandle)fDevice.get());
+- backendContext.fQueue.retain((GrMTLHandle)fQueue.get());
++ backendContext.fDevice.retain((GrMTLHandle)d->fDevice.get());
++ backendContext.fQueue.retain((GrMTLHandle)d->fQueue.get());
+ #if GR_METAL_SDK_VERSION >= 230
+ if (@available(macOS 11.0, iOS 14.0, *)) {
+- backendContext.fBinaryArchive.retain((__bridge GrMTLHandle)fPipelineArchive);
++ backendContext.fBinaryArchive.retain((__bridge GrMTLHandle)d->fPipelineArchive);
+ }
+ #endif
+- fContext = GrDirectContext::MakeMetal(backendContext, fDisplayParams.fGrContextOptions);
+- if (!fContext && fDisplayParams.fMSAASampleCount > 1) {
++ d->fContext = GrDirectContext::MakeMetal(backendContext, fDisplayParams.fGrContextOptions);
++ if (!d->fContext && fDisplayParams.fMSAASampleCount > 1) {
+ fDisplayParams.fMSAASampleCount /= 2;
++ fGlobalShared.reset();
+ this->initializeContext();
+ return;
+ }
++
++ fShared = fGlobalShared;
++ } // if( !fShared )
++
++ fContext = fShared->fContext;
++
++ fSampleCount = fDisplayParams.fMSAASampleCount;
++ fStencilBits = 8;
++
++ fValid = this->onInitializeContext();
+ }
+
+ void MetalWindowContext::destroyContext() {
+- if (fContext) {
+- // in case we have outstanding refs to this (lua?)
+- fContext->abandonContext();
+- fContext.reset();
+- }
+-
+ this->onDestroyContext();
+
+ fMetalLayer = nil;
+ fValid = false;
+
++ fContext.reset();
++ fShared.reset();
++
++ checkDestroyShared();
++}
++
++void MetalWindowContext::checkDestroyShared()
++{
++ if(!fGlobalShared || !fGlobalShared->unique()) // TODO mutex?
++ return;
++#ifndef SK_TRACE_VK_RESOURCES
++ if(!fGlobalShared->fContext->unique())
++ return;
++#endif
++ SkASSERT(fGlobalShared->fContext->unique());
++
++ if (fGlobalShared->fContext) {
++ // in case we have outstanding refs to this (lua?)
++ fGlobalShared->fContext->abandonContext();
++ fGlobalShared->fContext.reset();
++ }
++
+ #if GR_METAL_SDK_VERSION >= 230
+ if (@available(macOS 11.0, iOS 14.0, *)) {
+- [fPipelineArchive release];
++ [fGlobalShared->fPipelineArchive release];
+ }
+ #endif
+- fQueue.reset();
+- fDevice.reset();
++ fGlobalShared->fQueue.reset();
++ fGlobalShared->fDevice.reset();
++
++ fGlobalShared.reset();
+ }
+
+ sk_sp<SkSurface> MetalWindowContext::getBackbufferSurface() {
+@@ -154,7 +189,7 @@ sk_sp<SkSurface> MetalWindowContext::getBackbufferSurface() {
+ void MetalWindowContext::swapBuffers() {
+ id<CAMetalDrawable> currentDrawable = (id<CAMetalDrawable>)fDrawableHandle;
+
+- id<MTLCommandBuffer> commandBuffer([*fQueue commandBuffer]);
++ id<MTLCommandBuffer> commandBuffer([*fShared->fQueue commandBuffer]);
+ commandBuffer.label = @"Present";
+
+ [commandBuffer presentDrawable:currentDrawable];
+@@ -175,9 +210,9 @@ void MetalWindowContext::activate(bool isActive) {
+ if (!isActive) {
+ #if GR_METAL_SDK_VERSION >= 230
+ if (@available(macOS 11.0, iOS 14.0, *)) {
+- if (fPipelineArchive) {
++ if (fShared->fPipelineArchive) {
+ NSError* error;
+- [fPipelineArchive serializeToURL:CacheURL() error:&error];
++ [fShared->fPipelineArchive serializeToURL:CacheURL() error:&error];
+ if (error) {
+ SkDebugf("Error storing MTLBinaryArchive:\n%s\n",
+ error.debugDescription.UTF8String);
+@@ -188,4 +223,11 @@ void MetalWindowContext::activate(bool isActive) {
+ }
+ }
+
++SK_API sk_sp<MetalWindowContext::Shared> MetalWindowContext::fGlobalShared;
++
++GrDirectContext* getMetalSharedGrDirectContext()
++{
++ return MetalWindowContext::getSharedGrDirectContext();
++}
++
+ } //namespace sk_app
+diff --git a/tools/sk_app/VulkanWindowContext.cpp b/tools/sk_app/VulkanWindowContext.cpp
+index c9db528ca4..634034da5a 100644
+--- a/tools/sk_app/VulkanWindowContext.cpp
++++ b/tools/sk_app/VulkanWindowContext.cpp
+@@ -25,9 +25,13 @@
+ #endif
+
+ #define GET_PROC(F) f ## F = \
+- (PFN_vk ## F) backendContext.fGetProc("vk" #F, fInstance, VK_NULL_HANDLE)
++ (PFN_vk ## F) fGlobalShared->backendContext.fGetProc("vk" #F, fShared->fInstance, VK_NULL_HANDLE)
+ #define GET_DEV_PROC(F) f ## F = \
+- (PFN_vk ## F) backendContext.fGetProc("vk" #F, VK_NULL_HANDLE, fDevice)
++ (PFN_vk ## F) fGlobalShared->backendContext.fGetProc("vk" #F, VK_NULL_HANDLE, fShared->fDevice)
++#define GET_PROC_GLOBAL(F) fGlobalShared->f ## F = \
++ (PFN_vk ## F) fGlobalShared->backendContext.fGetProc("vk" #F, fGlobalShared->fInstance, VK_NULL_HANDLE)
++#define GET_DEV_PROC_GLOBAL(F) fGlobalShared->f ## F = \
++ (PFN_vk ## F) fGlobalShared->backendContext.fGetProc("vk" #F, VK_NULL_HANDLE, fGlobalShared->fDevice)
+
+ namespace sk_app {
+
+@@ -49,31 +53,39 @@ VulkanWindowContext::VulkanWindowContext(const DisplayParams& params,
+ }
+
+ void VulkanWindowContext::initializeContext() {
++ fShared = fGlobalShared;
++ if( !fShared )
++ {
++ // TODO do we need a mutex?
++
++ fGlobalShared = sk_make_sp<Shared>();
++ Shared* d = fGlobalShared.get(); // shorter variable name
++
+ SkASSERT(!fContext);
+ // any config code here (particularly for msaa)?
+
+ PFN_vkGetInstanceProcAddr getInstanceProc = fGetInstanceProcAddr;
+- GrVkBackendContext backendContext;
++ GrVkBackendContext& backendContext = fGlobalShared->backendContext;
+ GrVkExtensions extensions;
+- VkPhysicalDeviceFeatures2 features;
+- if (!sk_gpu_test::CreateVkBackendContext(getInstanceProc, &backendContext, &extensions,
+- &features, &fDebugCallback, &fPresentQueueIndex,
+- fCanPresentFn)) {
+- sk_gpu_test::FreeVulkanFeaturesStructs(&features);
++ if (!sk_gpu_test::CreateVkBackendContext(getInstanceProc, &backendContext, &extensions, &d->features,
++ &d->fDebugCallback, &d->fPresentQueueIndex, fCanPresentFn)) {
++ sk_gpu_test::FreeVulkanFeaturesStructs(&d->features);
++ fGlobalShared.reset();
+ return;
+ }
+
+ if (!extensions.hasExtension(VK_KHR_SURFACE_EXTENSION_NAME, 25) ||
+ !extensions.hasExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME, 68)) {
+- sk_gpu_test::FreeVulkanFeaturesStructs(&features);
++ sk_gpu_test::FreeVulkanFeaturesStructs(&d->features);
++ fGlobalShared.reset();
+ return;
+ }
+
+- fInstance = backendContext.fInstance;
+- fPhysicalDevice = backendContext.fPhysicalDevice;
+- fDevice = backendContext.fDevice;
+- fGraphicsQueueIndex = backendContext.fGraphicsQueueIndex;
+- fGraphicsQueue = backendContext.fQueue;
++ d->fInstance = backendContext.fInstance;
++ d->fPhysicalDevice = backendContext.fPhysicalDevice;
++ d->fDevice = backendContext.fDevice;
++ d->fGraphicsQueueIndex = backendContext.fGraphicsQueueIndex;
++ d->fGraphicsQueue = backendContext.fQueue;
+
+ PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties =
+ reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
+@@ -81,21 +93,30 @@ void VulkanWindowContext::initializeContext() {
+ backendContext.fInstance,
+ VK_NULL_HANDLE));
+ if (!localGetPhysicalDeviceProperties) {
+- sk_gpu_test::FreeVulkanFeaturesStructs(&features);
++ sk_gpu_test::FreeVulkanFeaturesStructs(&d->features);
++ fGlobalShared.reset();
+ return;
+ }
+- VkPhysicalDeviceProperties physDeviceProperties;
+- localGetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &physDeviceProperties);
+- uint32_t physDevVersion = physDeviceProperties.apiVersion;
++ localGetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &d->physDeviceProperties);
++ uint32_t physDevVersion = d->physDeviceProperties.apiVersion;
+
+- fInterface.reset(new GrVkInterface(backendContext.fGetProc, fInstance, fDevice,
++ d->fInterface.reset(new GrVkInterface(backendContext.fGetProc, d->fInstance, d->fDevice,
+ backendContext.fInstanceVersion, physDevVersion,
+ &extensions));
+
+- GET_PROC(DestroyInstance);
+- if (fDebugCallback != VK_NULL_HANDLE) {
+- GET_PROC(DestroyDebugReportCallbackEXT);
++ d->fContext = GrDirectContext::MakeVulkan(backendContext, fDisplayParams.fGrContextOptions);
++
++ GET_PROC_GLOBAL(DestroyInstance);
++ GET_DEV_PROC_GLOBAL(DestroyDevice);
++ if (fGlobalShared->fDebugCallback != VK_NULL_HANDLE) {
++ GET_PROC_GLOBAL(DestroyDebugReportCallbackEXT);
+ }
++
++ fShared = fGlobalShared;
++ } // if( !fShared )
++
++ fContext = fShared->fContext;
++
+ GET_PROC(DestroySurfaceKHR);
+ GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
+ GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
+@@ -103,7 +124,6 @@ void VulkanWindowContext::initializeContext() {
+ GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
+ GET_DEV_PROC(DeviceWaitIdle);
+ GET_DEV_PROC(QueueWaitIdle);
+- GET_DEV_PROC(DestroyDevice);
+ GET_DEV_PROC(CreateSwapchainKHR);
+ GET_DEV_PROC(DestroySwapchainKHR);
+ GET_DEV_PROC(GetSwapchainImagesKHR);
+@@ -111,46 +131,44 @@ void VulkanWindowContext::initializeContext() {
+ GET_DEV_PROC(QueuePresentKHR);
+ GET_DEV_PROC(GetDeviceQueue);
+
+- fContext = GrDirectContext::MakeVulkan(backendContext, fDisplayParams.fGrContextOptions);
++ // No actual window, used just to create the shared GrContext.
++ if(fCreateVkSurfaceFn == nullptr)
++ return;
+
+- fSurface = fCreateVkSurfaceFn(fInstance);
++ fSurface = fCreateVkSurfaceFn(fShared->fInstance);
+ if (VK_NULL_HANDLE == fSurface) {
+ this->destroyContext();
+- sk_gpu_test::FreeVulkanFeaturesStructs(&features);
+ return;
+ }
+
++ // create presentQueue
++ fGetDeviceQueue(fShared->fDevice, fShared->fPresentQueueIndex, 0, &fPresentQueue);
++
+ VkBool32 supported;
+- VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fPhysicalDevice, fPresentQueueIndex,
++ VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fShared->fPhysicalDevice, fShared->fPresentQueueIndex,
+ fSurface, &supported);
+ if (VK_SUCCESS != res) {
+ this->destroyContext();
+- sk_gpu_test::FreeVulkanFeaturesStructs(&features);
+ return;
+ }
+
+ if (!this->createSwapchain(-1, -1, fDisplayParams)) {
+ this->destroyContext();
+- sk_gpu_test::FreeVulkanFeaturesStructs(&features);
+ return;
+ }
+-
+- // create presentQueue
+- fGetDeviceQueue(fDevice, fPresentQueueIndex, 0, &fPresentQueue);
+- sk_gpu_test::FreeVulkanFeaturesStructs(&features);
+ }
+
+ bool VulkanWindowContext::createSwapchain(int width, int height,
+ const DisplayParams& params) {
+ // check for capabilities
+ VkSurfaceCapabilitiesKHR caps;
+- VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fPhysicalDevice, fSurface, &caps);
++ VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fShared->fPhysicalDevice, fSurface, &caps);
+ if (VK_SUCCESS != res) {
+ return false;
+ }
+
+ uint32_t surfaceFormatCount;
+- res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
++ res = fGetPhysicalDeviceSurfaceFormatsKHR(fShared->fPhysicalDevice, fSurface, &surfaceFormatCount,
+ nullptr);
+ if (VK_SUCCESS != res) {
+ return false;
+@@ -158,14 +176,14 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+
+ SkAutoMalloc surfaceFormatAlloc(surfaceFormatCount * sizeof(VkSurfaceFormatKHR));
+ VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)surfaceFormatAlloc.get();
+- res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
++ res = fGetPhysicalDeviceSurfaceFormatsKHR(fShared->fPhysicalDevice, fSurface, &surfaceFormatCount,
+ surfaceFormats);
+ if (VK_SUCCESS != res) {
+ return false;
+ }
+
+ uint32_t presentModeCount;
+- res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
++ res = fGetPhysicalDeviceSurfacePresentModesKHR(fShared->fPhysicalDevice, fSurface, &presentModeCount,
+ nullptr);
+ if (VK_SUCCESS != res) {
+ return false;
+@@ -173,7 +191,7 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+
+ SkAutoMalloc presentModeAlloc(presentModeCount * sizeof(VkPresentModeKHR));
+ VkPresentModeKHR* presentModes = (VkPresentModeKHR*)presentModeAlloc.get();
+- res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
++ res = fGetPhysicalDeviceSurfacePresentModesKHR(fShared->fPhysicalDevice, fSurface, &presentModeCount,
+ presentModes);
+ if (VK_SUCCESS != res) {
+ return false;
+@@ -286,8 +304,8 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+ swapchainCreateInfo.imageArrayLayers = 1;
+ swapchainCreateInfo.imageUsage = usageFlags;
+
+- uint32_t queueFamilies[] = { fGraphicsQueueIndex, fPresentQueueIndex };
+- if (fGraphicsQueueIndex != fPresentQueueIndex) {
++ uint32_t queueFamilies[] = { fShared->fGraphicsQueueIndex, fShared->fPresentQueueIndex };
++ if (fShared->fGraphicsQueueIndex != fShared->fPresentQueueIndex) {
+ swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
+ swapchainCreateInfo.queueFamilyIndexCount = 2;
+ swapchainCreateInfo.pQueueFamilyIndices = queueFamilies;
+@@ -303,27 +321,27 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+ swapchainCreateInfo.clipped = true;
+ swapchainCreateInfo.oldSwapchain = fSwapchain;
+
+- res = fCreateSwapchainKHR(fDevice, &swapchainCreateInfo, nullptr, &fSwapchain);
++ res = fCreateSwapchainKHR(fShared->fDevice, &swapchainCreateInfo, nullptr, &fSwapchain);
+ if (VK_SUCCESS != res) {
+ return false;
+ }
+
+ // destroy the old swapchain
+ if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
+- fDeviceWaitIdle(fDevice);
++ fDeviceWaitIdle(fShared->fDevice);
+
+ this->destroyBuffers();
+
+- fDestroySwapchainKHR(fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
++ fDestroySwapchainKHR(fShared->fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
+ }
+
+ if (!this->createBuffers(swapchainCreateInfo.imageFormat, usageFlags, colorType,
+ swapchainCreateInfo.imageSharingMode)) {
+- fDeviceWaitIdle(fDevice);
++ fDeviceWaitIdle(fShared->fDevice);
+
+ this->destroyBuffers();
+
+- fDestroySwapchainKHR(fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
++ fDestroySwapchainKHR(fShared->fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
+ }
+
+ return true;
+@@ -332,10 +350,10 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+ bool VulkanWindowContext::createBuffers(VkFormat format, VkImageUsageFlags usageFlags,
+ SkColorType colorType,
+ VkSharingMode sharingMode) {
+- fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, nullptr);
++ fGetSwapchainImagesKHR(fShared->fDevice, fSwapchain, &fImageCount, nullptr);
+ SkASSERT(fImageCount);
+ fImages = new VkImage[fImageCount];
+- fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, fImages);
++ fGetSwapchainImagesKHR(fShared->fDevice, fSwapchain, &fImageCount, fImages);
+
+ // set up initial image layouts and create surfaces
+ fImageLayouts = new VkImageLayout[fImageCount];
+@@ -351,7 +369,7 @@ bool VulkanWindowContext::createBuffers(VkFormat format, VkImageUsageFlags usage
+ info.fFormat = format;
+ info.fImageUsageFlags = usageFlags;
+ info.fLevelCount = 1;
+- info.fCurrentQueueFamily = fPresentQueueIndex;
++ info.fCurrentQueueFamily = fShared->fPresentQueueIndex;
+ info.fSharingMode = sharingMode;
+
+ if (usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) {
+@@ -387,8 +405,8 @@ bool VulkanWindowContext::createBuffers(VkFormat format, VkImageUsageFlags usage
+ fBackbuffers = new BackbufferInfo[fImageCount + 1];
+ for (uint32_t i = 0; i < fImageCount + 1; ++i) {
+ fBackbuffers[i].fImageIndex = -1;
+- SkDEBUGCODE(VkResult result = )GR_VK_CALL(fInterface,
+- CreateSemaphore(fDevice, &semaphoreInfo, nullptr,
++ SkDEBUGCODE(VkResult result = )GR_VK_CALL(fShared->fInterface,
++ CreateSemaphore(fShared->fDevice, &semaphoreInfo, nullptr,
+ &fBackbuffers[i].fRenderSemaphore));
+ SkASSERT(result == VK_SUCCESS);
+ }
+@@ -401,8 +419,8 @@ void VulkanWindowContext::destroyBuffers() {
+ if (fBackbuffers) {
+ for (uint32_t i = 0; i < fImageCount + 1; ++i) {
+ fBackbuffers[i].fImageIndex = -1;
+- GR_VK_CALL(fInterface,
+- DestroySemaphore(fDevice,
++ GR_VK_CALL(fShared->fInterface,
++ DestroySemaphore(fShared->fDevice,
+ fBackbuffers[i].fRenderSemaphore,
+ nullptr));
+ }
+@@ -427,42 +445,59 @@ VulkanWindowContext::~VulkanWindowContext() {
+ void VulkanWindowContext::destroyContext() {
+ if (this->isValid()) {
+ fQueueWaitIdle(fPresentQueue);
+- fDeviceWaitIdle(fDevice);
++ fDeviceWaitIdle(fShared->fDevice);
+
+ this->destroyBuffers();
+
+ if (VK_NULL_HANDLE != fSwapchain) {
+- fDestroySwapchainKHR(fDevice, fSwapchain, nullptr);
++ fDestroySwapchainKHR(fShared->fDevice, fSwapchain, nullptr);
+ fSwapchain = VK_NULL_HANDLE;
+ }
+
+ if (VK_NULL_HANDLE != fSurface) {
+- fDestroySurfaceKHR(fInstance, fSurface, nullptr);
++ fDestroySurfaceKHR(fShared->fInstance, fSurface, nullptr);
+ fSurface = VK_NULL_HANDLE;
+ }
+ }
+
+- SkASSERT(fContext->unique());
+ fContext.reset();
+- fInterface.reset();
++ fShared.reset();
++
++ checkDestroyShared();
++}
++
++void VulkanWindowContext::checkDestroyShared()
++{
++ if(!fGlobalShared || !fGlobalShared->unique()) // TODO mutex?
++ return;
++#ifndef SK_TRACE_VK_RESOURCES
++ if(!fGlobalShared->fContext->unique())
++ return;
++#endif
++ SkASSERT(fGlobalShared->fContext->unique());
++ fGlobalShared->fContext.reset();
++ fGlobalShared->fInterface.reset();
+
+- if (VK_NULL_HANDLE != fDevice) {
+- fDestroyDevice(fDevice, nullptr);
+- fDevice = VK_NULL_HANDLE;
++ if (VK_NULL_HANDLE != fGlobalShared->fDevice) {
++ fGlobalShared->fDestroyDevice(fGlobalShared->fDevice, nullptr);
++ fGlobalShared->fDevice = VK_NULL_HANDLE;
+ }
+
+ #ifdef SK_ENABLE_VK_LAYERS
+- if (fDebugCallback != VK_NULL_HANDLE) {
+- fDestroyDebugReportCallbackEXT(fInstance, fDebugCallback, nullptr);
++ if (fGlobalShared->fDebugCallback != VK_NULL_HANDLE) {
++ fGlobalShared->fDestroyDebugReportCallbackEXT(fGlobalShared->fInstance, fDebugCallback, nullptr);
+ }
+ #endif
+
+- fPhysicalDevice = VK_NULL_HANDLE;
++ fGlobalShared->fPhysicalDevice = VK_NULL_HANDLE;
+
+- if (VK_NULL_HANDLE != fInstance) {
+- fDestroyInstance(fInstance, nullptr);
+- fInstance = VK_NULL_HANDLE;
++ if (VK_NULL_HANDLE != fGlobalShared->fInstance) {
++ fGlobalShared->fDestroyInstance(fGlobalShared->fInstance, nullptr);
++ fGlobalShared->fInstance = VK_NULL_HANDLE;
+ }
++
++ sk_gpu_test::FreeVulkanFeaturesStructs(&fGlobalShared->features);
++ fGlobalShared.reset();
+ }
+
+ VulkanWindowContext::BackbufferInfo* VulkanWindowContext::getAvailableBackbuffer() {
+@@ -488,35 +523,35 @@ sk_sp<SkSurface> VulkanWindowContext::getBackbufferSurface() {
+ semaphoreInfo.pNext = nullptr;
+ semaphoreInfo.flags = 0;
+ VkSemaphore semaphore;
+- SkDEBUGCODE(VkResult result = )GR_VK_CALL(fInterface, CreateSemaphore(fDevice, &semaphoreInfo,
++ SkDEBUGCODE(VkResult result = )GR_VK_CALL(fShared->fInterface, CreateSemaphore(fShared->fDevice, &semaphoreInfo,
+ nullptr, &semaphore));
+ SkASSERT(result == VK_SUCCESS);
+
+ // acquire the image
+- VkResult res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
++ VkResult res = fAcquireNextImageKHR(fShared->fDevice, fSwapchain, UINT64_MAX,
+ semaphore, VK_NULL_HANDLE,
+ &backbuffer->fImageIndex);
+ if (VK_ERROR_SURFACE_LOST_KHR == res) {
+ // need to figure out how to create a new vkSurface without the platformData*
+ // maybe use attach somehow? but need a Window
+- GR_VK_CALL(fInterface, DestroySemaphore(fDevice, semaphore, nullptr));
++ GR_VK_CALL(fShared->fInterface, DestroySemaphore(fShared->fDevice, semaphore, nullptr));
+ return nullptr;
+ }
+ if (VK_ERROR_OUT_OF_DATE_KHR == res) {
+ // tear swapchain down and try again
+ if (!this->createSwapchain(-1, -1, fDisplayParams)) {
+- GR_VK_CALL(fInterface, DestroySemaphore(fDevice, semaphore, nullptr));
++ GR_VK_CALL(fShared->fInterface, DestroySemaphore(fShared->fDevice, semaphore, nullptr));
+ return nullptr;
+ }
+ backbuffer = this->getAvailableBackbuffer();
+
+ // acquire the image
+- res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
++ res = fAcquireNextImageKHR(fShared->fDevice, fSwapchain, UINT64_MAX,
+ semaphore, VK_NULL_HANDLE,
+ &backbuffer->fImageIndex);
+
+ if (VK_SUCCESS != res) {
+- GR_VK_CALL(fInterface, DestroySemaphore(fDevice, semaphore, nullptr));
++ GR_VK_CALL(fShared->fInterface, DestroySemaphore(fShared->fDevice, semaphore, nullptr));
+ return nullptr;
+ }
+ }
+@@ -542,7 +577,7 @@ void VulkanWindowContext::swapBuffers() {
+ GrFlushInfo info;
+ info.fNumSemaphores = 1;
+ info.fSignalSemaphores = &beSemaphore;
+- GrBackendSurfaceMutableState presentState(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, fPresentQueueIndex);
++ GrBackendSurfaceMutableState presentState(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, fShared->fPresentQueueIndex);
+ surface->flush(info, &presentState);
+ surface->recordingContext()->asDirectContext()->submit();
+
+@@ -562,4 +597,6 @@ void VulkanWindowContext::swapBuffers() {
+ fQueuePresentKHR(fPresentQueue, &presentInfo);
+ }
+
++SK_API sk_sp<VulkanWindowContext::Shared> VulkanWindowContext::fGlobalShared;
++
+ } //namespace sk_app
+diff --git a/tools/sk_app/VulkanWindowContext.h b/tools/sk_app/VulkanWindowContext.h
+index 7e1fdd9af5..946bca7522 100644
+--- a/tools/sk_app/VulkanWindowContext.h
++++ b/tools/sk_app/VulkanWindowContext.h
+@@ -19,18 +19,22 @@
+ #include "tools/gpu/vk/VkTestUtils.h"
+ #include "tools/sk_app/WindowContext.h"
+
++#include <cassert>
++
+ class GrRenderTarget;
+
+ namespace sk_app {
+
+-class VulkanWindowContext : public WindowContext {
++class SK_API VulkanWindowContext : public WindowContext {
+ public:
+ ~VulkanWindowContext() override;
+
++ static GrDirectContext* getSharedGrDirectContext() { return fGlobalShared ? fGlobalShared->fContext.get() : nullptr; }
++
+ sk_sp<SkSurface> getBackbufferSurface() override;
+ void swapBuffers() override;
+
+- bool isValid() override { return fDevice != VK_NULL_HANDLE; }
++ bool isValid() override { return fSurface != VK_NULL_HANDLE; }
+
+ void resize(int w, int h) override {
+ this->createSwapchain(w, h, fDisplayParams);
+@@ -50,9 +54,15 @@ public:
+ VulkanWindowContext(const DisplayParams&, CreateVkSurfaceFn, CanPresentFn,
+ PFN_vkGetInstanceProcAddr);
+
++ static const VkPhysicalDeviceProperties& getPhysDeviceProperties() {
++ assert( fGlobalShared != nullptr );
++ return fGlobalShared->physDeviceProperties;
++ }
++
+ private:
+ void initializeContext();
+ void destroyContext();
++ static void checkDestroyShared();
+
+ struct BackbufferInfo {
+ uint32_t fImageIndex; // image this is associated with
+@@ -64,11 +74,6 @@ private:
+ bool createBuffers(VkFormat format, VkImageUsageFlags, SkColorType colorType, VkSharingMode);
+ void destroyBuffers();
+
+- VkInstance fInstance = VK_NULL_HANDLE;
+- VkPhysicalDevice fPhysicalDevice = VK_NULL_HANDLE;
+- VkDevice fDevice = VK_NULL_HANDLE;
+- VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
+-
+ // Create functions
+ CreateVkSurfaceFn fCreateVkSurfaceFn;
+ CanPresentFn fCanPresentFn;
+@@ -88,20 +93,46 @@ private:
+ PFN_vkAcquireNextImageKHR fAcquireNextImageKHR = nullptr;
+ PFN_vkQueuePresentKHR fQueuePresentKHR = nullptr;
+
+- PFN_vkDestroyInstance fDestroyInstance = nullptr;
+ PFN_vkDeviceWaitIdle fDeviceWaitIdle = nullptr;
+- PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugReportCallbackEXT = nullptr;
+ PFN_vkQueueWaitIdle fQueueWaitIdle = nullptr;
+- PFN_vkDestroyDevice fDestroyDevice = nullptr;
+ PFN_vkGetDeviceQueue fGetDeviceQueue = nullptr;
+
++ // We need to use just one GrDirectContext, so share all the relevant data.
++ struct Shared : public SkRefCnt
++ {
++ PFN_vkDestroyInstance fDestroyInstance = nullptr;
++ PFN_vkDestroyDevice fDestroyDevice = nullptr;
++ PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugReportCallbackEXT = nullptr;
++
++ VkInstance fInstance = VK_NULL_HANDLE;
++ VkPhysicalDevice fPhysicalDevice = VK_NULL_HANDLE;
++ VkDevice fDevice = VK_NULL_HANDLE;
++ VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
++
+ sk_sp<const GrVkInterface> fInterface;
+
+- VkSurfaceKHR fSurface;
+- VkSwapchainKHR fSwapchain;
++ // Original code had this as a function-local variable, but that seems wrong.
++ // It should exist as long as the context exists.
++ VkPhysicalDeviceFeatures2 features;
++
++ // Store this to make it accessible.
++ VkPhysicalDeviceProperties physDeviceProperties;
++
++ GrVkBackendContext backendContext;
++
+ uint32_t fGraphicsQueueIndex;
+ VkQueue fGraphicsQueue;
+ uint32_t fPresentQueueIndex;
++
++ sk_sp<GrDirectContext> fContext;
++ };
++
++ sk_sp<Shared> fShared;
++
++ static sk_sp<Shared> fGlobalShared;
++
++ VkSurfaceKHR fSurface;
++ VkSwapchainKHR fSwapchain;
+ VkQueue fPresentQueue;
+
+ uint32_t fImageCount;
+diff --git a/tools/sk_app/WindowContext.h b/tools/sk_app/WindowContext.h
+index 65ab8b9aa4..2d222385a3 100644
+--- a/tools/sk_app/WindowContext.h
++++ b/tools/sk_app/WindowContext.h
+@@ -10,9 +10,9 @@
+ #include "include/core/SkRefCnt.h"
+ #include "include/core/SkSurfaceProps.h"
+ #include "include/gpu/GrTypes.h"
++#include "include/gpu/GrDirectContext.h"
+ #include "tools/sk_app/DisplayParams.h"
+
+-class GrDirectContext;
+ class SkSurface;
+ #ifdef SK_GRAPHITE_ENABLED
+ namespace skgpu::graphite {
+diff --git a/tools/sk_app/mac/MetalWindowContext_mac.mm b/tools/sk_app/mac/MetalWindowContext_mac.mm
+index 5bea8578fa..f7df061af0 100644
+--- a/tools/sk_app/mac/MetalWindowContext_mac.mm
++++ b/tools/sk_app/mac/MetalWindowContext_mac.mm
+@@ -49,10 +49,14 @@ MetalWindowContext_mac::~MetalWindowContext_mac() {
+ }
+
+ bool MetalWindowContext_mac::onInitializeContext() {
++ // Allow creating just the shared context, without an associated window.
++ if(fMainView == nil)
++ return true;
++
+ SkASSERT(nil != fMainView);
+
+ fMetalLayer = [CAMetalLayer layer];
+- fMetalLayer.device = fDevice.get();
++ fMetalLayer.device = fShared->fDevice.get();
+ fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
+
+ // resize ignores the passed values and uses the fMainView directly.
+diff --git a/tools/sk_app/unix/VulkanWindowContext_unix.cpp b/tools/sk_app/unix/VulkanWindowContext_unix.cpp
+index 2b31fedc19..0c05fbfc92 100644
+--- a/tools/sk_app/unix/VulkanWindowContext_unix.cpp
++++ b/tools/sk_app/unix/VulkanWindowContext_unix.cpp
+@@ -30,7 +30,7 @@ std::unique_ptr<WindowContext> MakeVulkanForXlib(const XlibWindowInfo& info,
+ return nullptr;
+ }
+
+- auto createVkSurface = [&info, instProc](VkInstance instance) -> VkSurfaceKHR {
++ VulkanWindowContext::CreateVkSurfaceFn createVkSurface = [&info, instProc](VkInstance instance) -> VkSurfaceKHR {
+ static PFN_vkCreateXcbSurfaceKHR createXcbSurfaceKHR = nullptr;
+ if (!createXcbSurfaceKHR) {
+ createXcbSurfaceKHR =
+@@ -54,6 +54,9 @@ std::unique_ptr<WindowContext> MakeVulkanForXlib(const XlibWindowInfo& info,
+
+ return surface;
+ };
++ // Allow creating just the shared context, without an associated window.
++ if(info.fWindow == None)
++ createVkSurface = nullptr;
+
+ auto canPresent = [&info, instProc](VkInstance instance, VkPhysicalDevice physDev,
+ uint32_t queueFamilyIndex) {
+@@ -76,7 +79,7 @@ std::unique_ptr<WindowContext> MakeVulkanForXlib(const XlibWindowInfo& info,
+ };
+ std::unique_ptr<WindowContext> ctx(
+ new VulkanWindowContext(displayParams, createVkSurface, canPresent, instProc));
+- if (!ctx->isValid()) {
++ if (!ctx->isValid() && createVkSurface != nullptr) {
+ return nullptr;
+ }
+ return ctx;
+diff --git a/tools/sk_app/win/VulkanWindowContext_win.cpp b/tools/sk_app/win/VulkanWindowContext_win.cpp
+index 976c42556e..c8f6b162bf 100644
+--- a/tools/sk_app/win/VulkanWindowContext_win.cpp
++++ b/tools/sk_app/win/VulkanWindowContext_win.cpp
+@@ -29,7 +29,7 @@ std::unique_ptr<WindowContext> MakeVulkanForWin(HWND hwnd, const DisplayParams&
+ return nullptr;
+ }
+
+- auto createVkSurface = [hwnd, instProc] (VkInstance instance) -> VkSurfaceKHR {
++ VulkanWindowContext::CreateVkSurfaceFn createVkSurface = [hwnd, instProc] (VkInstance instance) -> VkSurfaceKHR {
+ static PFN_vkCreateWin32SurfaceKHR createWin32SurfaceKHR = nullptr;
+ if (!createWin32SurfaceKHR) {
+ createWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
+@@ -53,6 +53,9 @@ std::unique_ptr<WindowContext> MakeVulkanForWin(HWND hwnd, const DisplayParams&
+
+ return surface;
+ };
++ // Allow creating just the shared context, without an associated window.
++ if(hwnd == nullptr)
++ createVkSurface = nullptr;
+
+ auto canPresent = [instProc] (VkInstance instance, VkPhysicalDevice physDev,
+ uint32_t queueFamilyIndex) {
+@@ -70,7 +73,7 @@ std::unique_ptr<WindowContext> MakeVulkanForWin(HWND hwnd, const DisplayParams&
+
+ std::unique_ptr<WindowContext> ctx(
+ new VulkanWindowContext(params, createVkSurface, canPresent, instProc));
+- if (!ctx->isValid()) {
++ if (!ctx->isValid() && createVkSurface != nullptr) {
+ return nullptr;
+ }
+ return ctx;
diff --git a/external/skia/skia_sk_cpu_sse_level_0_by_default.patch.1 b/external/skia/skia_sk_cpu_sse_level_0_by_default.patch.1
new file mode 100644
index 000000000..f2259a318
--- /dev/null
+++ b/external/skia/skia_sk_cpu_sse_level_0_by_default.patch.1
@@ -0,0 +1,15 @@
+diff -ur skia.org/include/core/SkTypes.h skia/include/core/SkTypes.h
+--- skia.org/include/core/SkTypes.h 2021-01-10 12:37:19.016176437 +0100
++++ skia/include/core/SkTypes.h 2021-01-10 12:43:29.155312067 +0100
+@@ -153,6 +153,11 @@
+ #endif
+ #endif
+
++// So let's initialize SK_CPU_SSE_LEVEL to 0 by default
++#ifndef SK_CPU_SSE_LEVEL
++ #define SK_CPU_SSE_LEVEL 0
++#endif
++
+ // ARM defines
+ #if defined(__arm__) && (!defined(__APPLE__) || !TARGET_IPHONE_SIMULATOR)
+ #define SK_CPU_ARM32
diff --git a/external/skia/source/SkMemory_malloc.cxx b/external/skia/source/SkMemory_malloc.cxx
new file mode 100644
index 000000000..9e2da3c20
--- /dev/null
+++ b/external/skia/source/SkMemory_malloc.cxx
@@ -0,0 +1,68 @@
+/*
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/core/SkTypes.h"
+#include "include/private/SkMalloc.h"
+
+#include <sal/log.hxx>
+#include <rtl/alloc.h>
+
+// Based on SkMemory_malloc.cpp :
+
+static inline void sk_out_of_memory(size_t size)
+{
+ SAL_WARN("skia", "sk_out_of_memory (asked for " << size << " bytes)");
+ abort();
+}
+
+static inline void* throw_on_failure(size_t size, void* p)
+{
+ if (size > 0 && p == nullptr)
+ {
+ // If we've got a nullptr here, the only reason we should have failed is running out of RAM.
+ sk_out_of_memory(size);
+ }
+ return p;
+}
+
+void sk_abort_no_print()
+{
+ SAL_WARN("skia", "sk_abort_no_print");
+ abort();
+}
+
+void sk_out_of_memory(void)
+{
+ SAL_WARN("skia", "sk_out_of_memory");
+ abort();
+}
+
+void* sk_realloc_throw(void* addr, size_t size)
+{
+ return throw_on_failure(size, rtl_reallocateMemory(addr, size));
+}
+
+void sk_free(void* p) { rtl_freeMemory(p); }
+
+void* sk_malloc_flags(size_t size, unsigned flags)
+{
+ void* p;
+ if (flags & SK_MALLOC_ZERO_INITIALIZE)
+ {
+ p = rtl_allocateZeroMemory(size);
+ }
+ else
+ {
+ p = rtl_allocateMemory(size);
+ }
+ if (flags & SK_MALLOC_THROW)
+ {
+ return throw_on_failure(size, p);
+ }
+ else
+ {
+ return p;
+ }
+}
diff --git a/external/skia/source/skia_compiler.cxx b/external/skia/source/skia_compiler.cxx
new file mode 100644
index 000000000..6339a4a4f
--- /dev/null
+++ b/external/skia/source/skia_compiler.cxx
@@ -0,0 +1,20 @@
+/*
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <skia_compiler.hxx>
+
+// Get the type of compiler that Skia is compiled with.
+const char* skia_compiler_name()
+{
+#if defined __clang__
+ return "Clang";
+#elif defined __GNUC__
+ return "GCC";
+#elif defined _MSC_VER
+ return "MSVC";
+#else
+ return "?";
+#endif
+}
diff --git a/external/skia/source/skia_opts.cxx b/external/skia/source/skia_opts.cxx
new file mode 100644
index 000000000..be728d600
--- /dev/null
+++ b/external/skia/source/skia_opts.cxx
@@ -0,0 +1,77 @@
+/*
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <skia_opts.hxx>
+
+#include "include/private/SkOnce.h"
+
+#if defined __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#endif
+#include "src/core/SkCpu.h"
+#include "src/core/SkOpts.h"
+#if defined __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+void SkConvertRGBToRGBA(uint32_t* dest, const uint8_t* src, int count)
+{
+ SkOpts::RGB_to_RGB1(dest, src, count);
+}
+
+void SkConvertGrayToRGBA(uint32_t* dest, const uint8_t* src, int count)
+{
+ SkOpts::gray_to_RGB1(dest, src, count);
+}
+
+void SkConvertRGBAToRGB(uint8_t* dest, const uint32_t* src, int count)
+{
+ SkLoOpts::RGB1_to_RGB(dest, src, count);
+}
+
+void SkConvertRGBAToR(uint8_t* dest, const uint32_t* src, int count)
+{
+ SkLoOpts::RGB1_to_R(dest, src, count);
+}
+
+// The rest is mostly based on Skia's SkOpts.cpp, reduced to only SSSE3 so far.
+
+#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
+ #define SK_OPTS_NS ssse3
+#else
+ #define SK_OPTS_NS portable
+#endif
+
+#include "skia_opts_internal.hxx"
+
+namespace SkLoOpts {
+ // Define default function pointer values here...
+ // If our global compile options are set high enough, these defaults might even be
+ // CPU-specialized, e.g. a typical x86-64 machine might start with SSE2 defaults.
+ // They'll still get a chance to be replaced with even better ones, e.g. using SSE4.1.
+#define DEFINE_DEFAULT(name) decltype(name) name = SK_OPTS_NS::name
+ DEFINE_DEFAULT(RGB1_to_RGB);
+ DEFINE_DEFAULT(RGB1_to_R);
+#undef DEFINE_DEFAULT
+
+ // Each Init_foo() is defined in its own file.
+ void Init_ssse3();
+
+ static void init() {
+#if !defined(SK_BUILD_NO_OPTS)
+ #if defined(SK_CPU_X86)
+ #if SK_CPU_SSE_LEVEL < SK_CPU_SSE_LEVEL_SSSE3
+ if (SkCpu::Supports(SkCpu::SSSE3)) { Init_ssse3(); }
+ #endif
+ #endif
+#endif
+ }
+
+ void Init() {
+ static SkOnce once;
+ once(init);
+ }
+} // namespace SkLoOpts
diff --git a/external/skia/source/skia_opts_internal.hxx b/external/skia/source/skia_opts_internal.hxx
new file mode 100644
index 000000000..0ca6a0435
--- /dev/null
+++ b/external/skia/source/skia_opts_internal.hxx
@@ -0,0 +1,81 @@
+/*
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SKIA_OPTS_INTERNAL_H
+#define SKIA_OPTS_INTERNAL_H
+
+#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
+ #include <immintrin.h>
+#endif
+
+namespace SK_OPTS_NS {
+
+static void RGB1_to_RGB_portable(uint8_t dst[], const uint32_t* src, int count) {
+ for (int i = 0; i < count; i++) {
+ dst[0] = src[i] >> 0;
+ dst[1] = src[i] >> 8;
+ dst[2] = src[i] >> 16;
+ dst += 3;
+ }
+}
+static void RGB1_to_R_portable(uint8_t dst[], const uint32_t* src, int count) {
+ for (int i = 0; i < count; i++) {
+ dst[i] = src[i] & 0xFF;
+ }
+}
+
+#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
+inline void RGB1_to_RGB(uint8_t dst[], const uint32_t* src, int count) {
+ const uint8_t X = 0xFF; // Used a placeholder. The value of X is irrelevant.
+ __m128i pack = _mm_setr_epi8(0,1,2, 4,5,6, 8,9,10, 12,13,14, X,X,X,X);
+
+// Storing 4 pixels should store 12 bytes, but here it stores 16, so test count >= 6
+// in order to not overrun the output buffer.
+ while (count >= 6) {
+ __m128i rgba = _mm_loadu_si128((const __m128i*) src);
+
+ __m128i rgb = _mm_shuffle_epi8(rgba, pack);
+
+ // Store 4 pixels.
+ _mm_storeu_si128((__m128i*) dst, rgb);
+
+ src += 4;
+ dst += 4*3;
+ count -= 4;
+ }
+ RGB1_to_RGB_portable(dst, src, count);
+}
+
+inline void RGB1_to_R(uint8_t dst[], const uint32_t* src, int count) {
+ const uint8_t X = 0xFF; // Used a placeholder. The value of X is irrelevant.
+ __m128i pack = _mm_setr_epi8(0,4,8,12, X,X,X,X,X,X,X,X,X,X,X,X);
+
+ while (count >= 4) {
+ __m128i rgba = _mm_loadu_si128((const __m128i*) src);
+
+ __m128i rgb = _mm_shuffle_epi8(rgba, pack);
+
+ // Store 4 pixels.
+ *((uint32_t*)dst) = _mm_cvtsi128_si32(rgb);
+
+ src += 4;
+ dst += 4;
+ count -= 4;
+ }
+ RGB1_to_R_portable(dst, src, count);
+}
+
+#else
+inline void RGB1_to_RGB(uint8_t dst[], const uint32_t* src, int count) {
+ RGB1_to_RGB_portable(dst, src, count);
+}
+inline void RGB1_to_R(uint8_t dst[], const uint32_t* src, int count) {
+ RGB1_to_R_portable(dst, src, count);
+}
+#endif
+
+} // namespace
+
+#endif
diff --git a/external/skia/source/skia_opts_ssse3.cxx b/external/skia/source/skia_opts_ssse3.cxx
new file mode 100644
index 000000000..31a446c99
--- /dev/null
+++ b/external/skia/source/skia_opts_ssse3.cxx
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <skia_opts.hxx>
+#define SK_OPTS_NS ssse3
+#include "skia_opts_internal.hxx"
+
+namespace SkLoOpts {
+ void Init_ssse3() {
+ RGB1_to_RGB = ssse3::RGB1_to_RGB;
+ RGB1_to_R = ssse3::RGB1_to_R;
+ }
+}
diff --git a/external/skia/swap-buffers-rect.patch.1 b/external/skia/swap-buffers-rect.patch.1
new file mode 100644
index 000000000..628a7e26c
--- /dev/null
+++ b/external/skia/swap-buffers-rect.patch.1
@@ -0,0 +1,153 @@
+diff --git a/tools/sk_app/GLWindowContext.h b/tools/sk_app/GLWindowContext.h
+index c519903006..5dc5bcd180 100644
+--- a/tools/sk_app/GLWindowContext.h
++++ b/tools/sk_app/GLWindowContext.h
+@@ -25,7 +25,7 @@ public:
+ bool isValid() override { return SkToBool(fBackendContext.get()); }
+
+ void resize(int w, int h) override;
+- void swapBuffers() override;
++ void swapBuffers(const SkIRect* rect = nullptr) override;
+
+ void setDisplayParams(const DisplayParams& params) override;
+
+diff --git a/tools/sk_app/MetalWindowContext.h b/tools/sk_app/MetalWindowContext.h
+index fbf35c3c2b..2194277922 100644
+--- a/tools/sk_app/MetalWindowContext.h
++++ b/tools/sk_app/MetalWindowContext.h
+@@ -29,7 +29,7 @@ public:
+
+ bool isValid() override { return fValid; }
+
+- void swapBuffers() override;
++ void swapBuffers(const SkIRect* rect = nullptr) override;
+
+ void setDisplayParams(const DisplayParams& params) override;
+
+diff --git a/tools/sk_app/MetalWindowContext.mm b/tools/sk_app/MetalWindowContext.mm
+index 49dc77b74d..ca1d74dc6c 100644
+--- a/tools/sk_app/MetalWindowContext.mm
++++ b/tools/sk_app/MetalWindowContext.mm
+@@ -187,7 +187,7 @@ GrBackendRenderTarget backendRT(fWidth,
+ return surface;
+ }
+
+-void MetalWindowContext::swapBuffers() {
++void MetalWindowContext::swapBuffers(const SkIRect*) {
+ id<CAMetalDrawable> currentDrawable = (id<CAMetalDrawable>)fDrawableHandle;
+
+ id<MTLCommandBuffer> commandBuffer([*fShared->fQueue commandBuffer]);
+diff --git a/tools/sk_app/VulkanWindowContext.cpp b/tools/sk_app/VulkanWindowContext.cpp
+index 2b36d60076..d73978c9e4 100644
+--- a/tools/sk_app/VulkanWindowContext.cpp
++++ b/tools/sk_app/VulkanWindowContext.cpp
+@@ -572,7 +572,7 @@ sk_sp<SkSurface> VulkanWindowContext::getBackbufferSurface() {
+ return sk_ref_sp(surface);
+ }
+
+-void VulkanWindowContext::swapBuffers() {
++void VulkanWindowContext::swapBuffers(const SkIRect*) {
+
+ BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
+ SkSurface* surface = fSurfaces[backbuffer->fImageIndex].get();
+diff --git a/tools/sk_app/VulkanWindowContext.h b/tools/sk_app/VulkanWindowContext.h
+index 92bfba6dff..46f7fd97bd 100644
+--- a/tools/sk_app/VulkanWindowContext.h
++++ b/tools/sk_app/VulkanWindowContext.h
+@@ -32,7 +32,7 @@ public:
+ static GrDirectContext* getSharedGrDirectContext() { return fGlobalShared ? fGlobalShared->fContext.get() : nullptr; }
+
+ sk_sp<SkSurface> getBackbufferSurface() override;
+- void swapBuffers() override;
++ void swapBuffers(const SkIRect* rect = nullptr) override;
+
+ bool isValid() override { return fSurface != VK_NULL_HANDLE; }
+
+diff --git a/tools/sk_app/WindowContext.h b/tools/sk_app/WindowContext.h
+index 68bb84b988..e15c1a3cf3 100644
+--- a/tools/sk_app/WindowContext.h
++++ b/tools/sk_app/WindowContext.h
+@@ -8,6 +8,7 @@
+ #define WindowContext_DEFINED
+
+ #include "include/core/SkRefCnt.h"
++#include "include/core/SkRect.h"
+ #include "include/core/SkSurfaceProps.h"
+ #include "include/gpu/GrTypes.h"
+ #include "include/gpu/GrDirectContext.h"
+@@ -25,7 +26,7 @@ public:
+
+ virtual sk_sp<SkSurface> getBackbufferSurface() = 0;
+
+- virtual void swapBuffers() = 0;
++ virtual void swapBuffers(const SkIRect* rect = nullptr) = 0;
+
+ virtual bool isValid() = 0;
+
+diff --git a/tools/sk_app/unix/RasterWindowContext_unix.cpp b/tools/sk_app/unix/RasterWindowContext_unix.cpp
+index 6ac20962b7..2ea9e07588 100644
+--- a/tools/sk_app/unix/RasterWindowContext_unix.cpp
++++ b/tools/sk_app/unix/RasterWindowContext_unix.cpp
+@@ -19,7 +19,7 @@ public:
+ RasterWindowContext_xlib(Display*, XWindow, int width, int height, const DisplayParams&);
+
+ sk_sp<SkSurface> getBackbufferSurface() override;
+- void swapBuffers() override;
++ void swapBuffers(const SkIRect* rect) override;
+ bool isValid() override { return SkToBool(fWindow); }
+ void resize(int w, int h) override;
+ void setDisplayParams(const DisplayParams& params) override;
+@@ -60,7 +60,7 @@ void RasterWindowContext_xlib::resize(int w, int h) {
+
+ sk_sp<SkSurface> RasterWindowContext_xlib::getBackbufferSurface() { return fBackbufferSurface; }
+
+-void RasterWindowContext_xlib::swapBuffers() {
++void RasterWindowContext_xlib::swapBuffers(const SkIRect* rect) {
+ SkPixmap pm;
+ if (!fBackbufferSurface->peekPixels(&pm)) {
+ return;
+@@ -82,7 +82,9 @@ void RasterWindowContext_xlib::swapBuffers() {
+ if (!XInitImage(&image)) {
+ return;
+ }
+- XPutImage(fDisplay, fWindow, fGC, &image, 0, 0, 0, 0, pm.width(), pm.height());
++ SkIRect update = rect ? *rect : SkIRect::MakeWH( pm.width(), pm.height());
++ XPutImage(fDisplay, fWindow, fGC, &image, update.x(), update.y(),
++ update.x(), update.y(), update.width(), update.height());
+ }
+
+ } // anonymous namespace
+diff --git a/tools/sk_app/win/RasterWindowContext_win.cpp b/tools/sk_app/win/RasterWindowContext_win.cpp
+index d80c6fbeec..72df8d5170 100644
+--- a/tools/sk_app/win/RasterWindowContext_win.cpp
++++ b/tools/sk_app/win/RasterWindowContext_win.cpp
+@@ -22,7 +22,7 @@ public:
+ RasterWindowContext_win(HWND, const DisplayParams&);
+
+ sk_sp<SkSurface> getBackbufferSurface() override;
+- void swapBuffers() override;
++ void swapBuffers(const SkIRect* rect) override;
+ bool isValid() override { return SkToBool(fWnd); }
+ void resize(int w, int h) override;
+ void setDisplayParams(const DisplayParams& params) override;
+@@ -75,13 +75,17 @@ void RasterWindowContext_win::resize(int w, int h) {
+
+ sk_sp<SkSurface> RasterWindowContext_win::getBackbufferSurface() { return fBackbufferSurface; }
+
+-void RasterWindowContext_win::swapBuffers() {
++void RasterWindowContext_win::swapBuffers(const SkIRect* rect) {
+ BITMAPINFO* bmpInfo = reinterpret_cast<BITMAPINFO*>(fSurfaceMemory.get());
+ HDC dc = GetDC(fWnd);
+ SkPixmap pixmap;
+ fBackbufferSurface->peekPixels(&pixmap);
+- StretchDIBits(dc, 0, 0, fWidth, fHeight, 0, 0, fWidth, fHeight, pixmap.addr(), bmpInfo,
+- DIB_RGB_COLORS, SRCCOPY);
++ SkIRect update = rect ? *rect : SkIRect::MakeWH( fWidth, fHeight );
++ // It appears that y-axis handling is broken if it doesn't match the window size.
++ update = SkIRect::MakeXYWH( update.x(), 0, update.width(), fHeight );
++ StretchDIBits(dc, update.x(), update.y(), update.width(), update.height(),
++ update.x(), update.y(), update.width(), update.height(),
++ pixmap.addr(), bmpInfo, DIB_RGB_COLORS, SRCCOPY);
+ ReleaseDC(fWnd, dc);
+ }
+
diff --git a/external/skia/tdf148624.patch.1 b/external/skia/tdf148624.patch.1
new file mode 100644
index 000000000..c42beca22
--- /dev/null
+++ b/external/skia/tdf148624.patch.1
@@ -0,0 +1,60 @@
+commit b2cecde549c76cbd1c8b7d0cee2c6799936c1e7a
+Author: Greg Daniel <egdaniel@google.com>
+Date: Thu Jun 16 11:29:08 2022 -0400
+
+ Fix not using texture barrier on StrokeTessOp.
+
+ Previously we were overwriting the renderpassXferBarriers flag on
+ ProgramInfo to set it to kNone. This flag is meant to say whether or not
+ the entire render pass uses barriers or not. This is needed in Vulkan
+ because all pipelines in a render pass that has an input attachment
+ must bind the input attachment regardless if it is used or not. So the
+ pipeline must be created with a layout for an input attachment
+ descriptor set.
+
+ This change just removes to performance optimization to only use the
+ barrier on the stencil and not fill draw. This use case shouldn't
+ come up too often and also shouldn't be a big perf hit regardless.
+ The way GrAppliedClip is created/used it is hard for us to create
+ multiple different Pipeline objects: one for stencil and one for the
+ fill.
+
+ Bug: skia:13402
+ Change-Id: I15ce74b4d41b90d3dd4169a1f4fb77ed87c8b26d
+ Reviewed-on: https://skia-review.googlesource.com/c/skia/+/549898
+ Reviewed-by: Michael Ludwig <michaelludwig@google.com>
+ Commit-Queue: Greg Daniel <egdaniel@google.com>
+
+diff --git a/src/gpu/ganesh/ops/StrokeTessellateOp.cpp b/src/gpu/ganesh/ops/StrokeTessellateOp.cpp
+index 8f47441eb9..de8153cd0f 100644
+--- a/src/gpu/ganesh/ops/StrokeTessellateOp.cpp
++++ b/src/gpu/ganesh/ops/StrokeTessellateOp.cpp
+@@ -179,7 +179,12 @@ void StrokeTessellateOp::prePrepareTessellator(GrTessellationShader::ProgramArgs
+ fStencilProgram = GrTessellationShader::MakeProgram(args, fTessellationShader, pipeline,
+ &kMarkStencil);
+ fillStencil = &kTestAndResetStencil;
+- args.fXferBarrierFlags = GrXferBarrierFlags::kNone;
++ // TODO: Currently if we have a texture barrier for a dst read it will get put in before
++ // both the stencil draw and the fill draw. In reality we only really need the barrier
++ // once to guard the reads of the color buffer in the fill from the previous writes. Maybe
++ // we can investigate how to remove one of these barriers but it is probably not something
++ // that is required a lot and thus the extra barrier shouldn't be too much of a perf hit to
++ // general Skia use.
+ }
+
+ fFillProgram = GrTessellationShader::MakeProgram(args, fTessellationShader, pipeline,
+diff --git a/src/gpu/ganesh/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/ganesh/vk/GrVkPipelineStateBuilder.cpp
+index 54bc7f857a..0d61b8c4cb 100644
+--- a/src/gpu/ganesh/vk/GrVkPipelineStateBuilder.cpp
++++ b/src/gpu/ganesh/vk/GrVkPipelineStateBuilder.cpp
+@@ -279,6 +279,10 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrProgramDesc& desc,
+ }
+ }
+
++ // The vulkan spec says that if a subpass has an input attachment, then the input attachment
++ // descriptor set must be bound to all pipelines in that subpass. This includes pipelines that
++ // don't actually use the input attachment. Thus we look at the renderPassBarriers and not just
++ // the DstProxyView barrier flags to determine if we use the input attachment.
+ bool usesInput = SkToBool(fProgramInfo.renderPassBarriers() & GrXferBarrierFlags::kTexture);
+ uint32_t layoutCount =
+ usesInput ? GrVkUniformHandler::kDescSetCount : (GrVkUniformHandler::kDescSetCount - 1);
diff --git a/external/skia/ubsan.patch.1 b/external/skia/ubsan.patch.1
new file mode 100644
index 000000000..005fdfebf
--- /dev/null
+++ b/external/skia/ubsan.patch.1
@@ -0,0 +1,42 @@
+diff --git a/include/private/gpu/ganesh/GrContext_Base.h b/include/private/gpu/ganesh/GrContext_Base.h
+index 847e76f232..e27d9454f8 100644
+--- a/include/private/gpu/ganesh/GrContext_Base.h
++++ b/include/private/gpu/ganesh/GrContext_Base.h
+@@ -20,7 +20,7 @@ class GrDirectContext;
+ class GrImageContext;
+ class GrRecordingContext;
+
+-class GrContext_Base : public SkRefCnt {
++class SK_API GrContext_Base : public SkRefCnt {
+ public:
+ ~GrContext_Base() override;
+
+@@ -32,7 +32,7 @@ public:
+ /*
+ * The 3D API backing this context
+ */
+- SK_API GrBackendApi backend() const;
++ GrBackendApi backend() const;
+
+ /*
+ * Retrieve the default GrBackendFormat for a given SkColorType and renderability.
+@@ -41,16 +41,16 @@ public:
+ *
+ * The caller should check that the returned format is valid.
+ */
+- SK_API GrBackendFormat defaultBackendFormat(SkColorType, GrRenderable) const;
++ GrBackendFormat defaultBackendFormat(SkColorType, GrRenderable) const;
+
+- SK_API GrBackendFormat compressedBackendFormat(SkImage::CompressionType) const;
++ GrBackendFormat compressedBackendFormat(SkImage::CompressionType) const;
+
+ /**
+ * Gets the maximum supported sample count for a color type. 1 is returned if only non-MSAA
+ * rendering is supported for the color type. 0 is returned if rendering to this color type
+ * is not supported at all.
+ */
+- SK_API int maxSurfaceSampleCountForColorType(SkColorType colorType) const;
++ int maxSurfaceSampleCountForColorType(SkColorType colorType) const;
+
+ // TODO: When the public version is gone, rename to refThreadSafeProxy and add raw ptr ver.
+ sk_sp<GrContextThreadSafeProxy> threadSafeProxy();
diff --git a/external/skia/vk_mem_alloc.patch.1 b/external/skia/vk_mem_alloc.patch.1
new file mode 100644
index 000000000..94f2504cb
--- /dev/null
+++ b/external/skia/vk_mem_alloc.patch.1
@@ -0,0 +1,19639 @@
+diff --git a/third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator.h b/third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator.h
+index 1c6212bd47..756175b4e7 100644
+--- a/third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator.h
++++ b/third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator.h
+@@ -32,7 +32,7 @@
+ #define VULKAN_H_
+ #define GR_NEEDED_TO_DEFINE_VULKAN_H
+ #endif
+-#include "vk_mem_alloc.h"
++#include "include/vk_mem_alloc.h"
+ #ifdef GR_NEEDED_TO_DEFINE_VULKAN_H
+ #undef VULKAN_H_
+ #endif
+diff --git a/third_party/vulkanmemoryallocator/include/LICENSE.txt b/third_party/vulkanmemoryallocator/include/LICENSE.txt
+new file mode 100644
+index 0000000000..dbfe253391
+--- /dev/null
++++ b/third_party/vulkanmemoryallocator/include/LICENSE.txt
+@@ -0,0 +1,19 @@
++Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved.
++
++Permission is hereby granted, free of charge, to any person obtaining a copy
++of this software and associated documentation files (the "Software"), to deal
++in the Software without restriction, including without limitation the rights
++to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++copies of the Software, and to permit persons to whom the Software is
++furnished to do so, subject to the following conditions:
++
++The above copyright notice and this permission notice shall be included in
++all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++THE SOFTWARE.
+diff --git a/third_party/vulkanmemoryallocator/include/vk_mem_alloc.h b/third_party/vulkanmemoryallocator/include/vk_mem_alloc.h
+new file mode 100644
+index 0000000000..90410b56af
+--- /dev/null
++++ b/third_party/vulkanmemoryallocator/include/vk_mem_alloc.h
+@@ -0,0 +1,19595 @@
++//
++// Copyright (c) 2017-2022 Advanced Micro Devices, Inc. All rights reserved.
++//
++// Permission is hereby granted, free of charge, to any person obtaining a copy
++// of this software and associated documentation files (the "Software"), to deal
++// in the Software without restriction, including without limitation the rights
++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++// copies of the Software, and to permit persons to whom the Software is
++// furnished to do so, subject to the following conditions:
++//
++// The above copyright notice and this permission notice shall be included in
++// all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++// THE SOFTWARE.
++//
++
++#ifndef AMD_VULKAN_MEMORY_ALLOCATOR_H
++#define AMD_VULKAN_MEMORY_ALLOCATOR_H
++
++/** \mainpage Vulkan Memory Allocator
++
++<b>Version 3.0.1-development (2022-03-28)</b>
++
++Copyright (c) 2017-2022 Advanced Micro Devices, Inc. All rights reserved. \n
++License: MIT
++
++<b>API documentation divided into groups:</b> [Modules](modules.html)
++
++\section main_table_of_contents Table of contents
++
++- <b>User guide</b>
++ - \subpage quick_start
++ - [Project setup](@ref quick_start_project_setup)
++ - [Initialization](@ref quick_start_initialization)
++ - [Resource allocation](@ref quick_start_resource_allocation)
++ - \subpage choosing_memory_type
++ - [Usage](@ref choosing_memory_type_usage)
++ - [Required and preferred flags](@ref choosing_memory_type_required_preferred_flags)
++ - [Explicit memory types](@ref choosing_memory_type_explicit_memory_types)
++ - [Custom memory pools](@ref choosing_memory_type_custom_memory_pools)
++ - [Dedicated allocations](@ref choosing_memory_type_dedicated_allocations)
++ - \subpage memory_mapping
++ - [Mapping functions](@ref memory_mapping_mapping_functions)
++ - [Persistently mapped memory](@ref memory_mapping_persistently_mapped_memory)
++ - [Cache flush and invalidate](@ref memory_mapping_cache_control)
++ - \subpage staying_within_budget
++ - [Querying for budget](@ref staying_within_budget_querying_for_budget)
++ - [Controlling memory usage](@ref staying_within_budget_controlling_memory_usage)
++ - \subpage resource_aliasing
++ - \subpage custom_memory_pools
++ - [Choosing memory type index](@ref custom_memory_pools_MemTypeIndex)
++ - [Linear allocation algorithm](@ref linear_algorithm)
++ - [Free-at-once](@ref linear_algorithm_free_at_once)
++ - [Stack](@ref linear_algorithm_stack)
++ - [Double stack](@ref linear_algorithm_double_stack)
++ - [Ring buffer](@ref linear_algorithm_ring_buffer)
++ - \subpage defragmentation
++ - \subpage statistics
++ - [Numeric statistics](@ref statistics_numeric_statistics)
++ - [JSON dump](@ref statistics_json_dump)
++ - \subpage allocation_annotation
++ - [Allocation user data](@ref allocation_user_data)
++ - [Allocation names](@ref allocation_names)
++ - \subpage virtual_allocator
++ - \subpage debugging_memory_usage
++ - [Memory initialization](@ref debugging_memory_usage_initialization)
++ - [Margins](@ref debugging_memory_usage_margins)
++ - [Corruption detection](@ref debugging_memory_usage_corruption_detection)
++ - \subpage opengl_interop
++- \subpage usage_patterns
++ - [GPU-only resource](@ref usage_patterns_gpu_only)
++ - [Staging copy for upload](@ref usage_patterns_staging_copy_upload)
++ - [Readback](@ref usage_patterns_readback)
++ - [Advanced data uploading](@ref usage_patterns_advanced_data_uploading)
++ - [Other use cases](@ref usage_patterns_other_use_cases)
++- \subpage configuration
++ - [Pointers to Vulkan functions](@ref config_Vulkan_functions)
++ - [Custom host memory allocator](@ref custom_memory_allocator)
++ - [Device memory allocation callbacks](@ref allocation_callbacks)
++ - [Device heap memory limit](@ref heap_memory_limit)
++- <b>Extension support</b>
++ - \subpage vk_khr_dedicated_allocation
++ - \subpage enabling_buffer_device_address
++ - \subpage vk_ext_memory_priority
++ - \subpage vk_amd_device_coherent_memory
++- \subpage general_considerations
++ - [Thread safety](@ref general_considerations_thread_safety)
++ - [Versioning and compatibility](@ref general_considerations_versioning_and_compatibility)
++ - [Validation layer warnings](@ref general_considerations_validation_layer_warnings)
++ - [Allocation algorithm](@ref general_considerations_allocation_algorithm)
++ - [Features not supported](@ref general_considerations_features_not_supported)
++
++\section main_see_also See also
++
++- [**Product page on GPUOpen**](https://gpuopen.com/gaming-product/vulkan-memory-allocator/)
++- [**Source repository on GitHub**](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator)
++
++\defgroup group_init Library initialization
++
++\brief API elements related to the initialization and management of the entire library, especially #VmaAllocator object.
++
++\defgroup group_alloc Memory allocation
++
++\brief API elements related to the allocation, deallocation, and management of Vulkan memory, buffers, images.
++Most basic ones being: vmaCreateBuffer(), vmaCreateImage().
++
++\defgroup group_virtual Virtual allocator
++
++\brief API elements related to the mechanism of \ref virtual_allocator - using the core allocation algorithm
++for user-defined purpose without allocating any real GPU memory.
++
++\defgroup group_stats Statistics
++
++\brief API elements that query current status of the allocator, from memory usage, budget, to full dump of the internal state in JSON format.
++See documentation chapter: \ref statistics.
++*/
++
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#ifndef VULKAN_H_
++ #include <vulkan/vulkan.h>
++#endif
++
++// Define this macro to declare maximum supported Vulkan version in format AAABBBCCC,
++// where AAA = major, BBB = minor, CCC = patch.
++// If you want to use version > 1.0, it still needs to be enabled via VmaAllocatorCreateInfo::vulkanApiVersion.
++#if !defined(VMA_VULKAN_VERSION)
++ #if defined(VK_VERSION_1_3)
++ #define VMA_VULKAN_VERSION 1003000
++ #elif defined(VK_VERSION_1_2)
++ #define VMA_VULKAN_VERSION 1002000
++ #elif defined(VK_VERSION_1_1)
++ #define VMA_VULKAN_VERSION 1001000
++ #else
++ #define VMA_VULKAN_VERSION 1000000
++ #endif
++#endif
++
++#if defined(__ANDROID__) && defined(VK_NO_PROTOTYPES) && VMA_STATIC_VULKAN_FUNCTIONS
++ extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
++ extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
++ extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
++ extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
++ extern PFN_vkAllocateMemory vkAllocateMemory;
++ extern PFN_vkFreeMemory vkFreeMemory;
++ extern PFN_vkMapMemory vkMapMemory;
++ extern PFN_vkUnmapMemory vkUnmapMemory;
++ extern PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
++ extern PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
++ extern PFN_vkBindBufferMemory vkBindBufferMemory;
++ extern PFN_vkBindImageMemory vkBindImageMemory;
++ extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
++ extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
++ extern PFN_vkCreateBuffer vkCreateBuffer;
++ extern PFN_vkDestroyBuffer vkDestroyBuffer;
++ extern PFN_vkCreateImage vkCreateImage;
++ extern PFN_vkDestroyImage vkDestroyImage;
++ extern PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
++ #if VMA_VULKAN_VERSION >= 1001000
++ extern PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2;
++ extern PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2;
++ extern PFN_vkBindBufferMemory2 vkBindBufferMemory2;
++ extern PFN_vkBindImageMemory2 vkBindImageMemory2;
++ extern PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2;
++ #endif // #if VMA_VULKAN_VERSION >= 1001000
++#endif // #if defined(__ANDROID__) && VMA_STATIC_VULKAN_FUNCTIONS && VK_NO_PROTOTYPES
++
++#if !defined(VMA_DEDICATED_ALLOCATION)
++ #if VK_KHR_get_memory_requirements2 && VK_KHR_dedicated_allocation
++ #define VMA_DEDICATED_ALLOCATION 1
++ #else
++ #define VMA_DEDICATED_ALLOCATION 0
++ #endif
++#endif
++
++#if !defined(VMA_BIND_MEMORY2)
++ #if VK_KHR_bind_memory2
++ #define VMA_BIND_MEMORY2 1
++ #else
++ #define VMA_BIND_MEMORY2 0
++ #endif
++#endif
++
++#if !defined(VMA_MEMORY_BUDGET)
++ #if VK_EXT_memory_budget && (VK_KHR_get_physical_device_properties2 || VMA_VULKAN_VERSION >= 1001000)
++ #define VMA_MEMORY_BUDGET 1
++ #else
++ #define VMA_MEMORY_BUDGET 0
++ #endif
++#endif
++
++// Defined to 1 when VK_KHR_buffer_device_address device extension or equivalent core Vulkan 1.2 feature is defined in its headers.
++#if !defined(VMA_BUFFER_DEVICE_ADDRESS)
++ #if VK_KHR_buffer_device_address || VMA_VULKAN_VERSION >= 1002000
++ #define VMA_BUFFER_DEVICE_ADDRESS 1
++ #else
++ #define VMA_BUFFER_DEVICE_ADDRESS 0
++ #endif
++#endif
++
++// Defined to 1 when VK_EXT_memory_priority device extension is defined in Vulkan headers.
++#if !defined(VMA_MEMORY_PRIORITY)
++ #if VK_EXT_memory_priority
++ #define VMA_MEMORY_PRIORITY 1
++ #else
++ #define VMA_MEMORY_PRIORITY 0
++ #endif
++#endif
++
++// Defined to 1 when VK_KHR_external_memory device extension is defined in Vulkan headers.
++#if !defined(VMA_EXTERNAL_MEMORY)
++ #if VK_KHR_external_memory
++ #define VMA_EXTERNAL_MEMORY 1
++ #else
++ #define VMA_EXTERNAL_MEMORY 0
++ #endif
++#endif
++
++// Define these macros to decorate all public functions with additional code,
++// before and after returned type, appropriately. This may be useful for
++// exporting the functions when compiling VMA as a separate library. Example:
++// #define VMA_CALL_PRE __declspec(dllexport)
++// #define VMA_CALL_POST __cdecl
++#ifndef VMA_CALL_PRE
++ #define VMA_CALL_PRE
++#endif
++#ifndef VMA_CALL_POST
++ #define VMA_CALL_POST
++#endif
++
++// Define this macro to decorate pointers with an attribute specifying the
++// length of the array they point to if they are not null.
++//
++// The length may be one of
++// - The name of another parameter in the argument list where the pointer is declared
++// - The name of another member in the struct where the pointer is declared
++// - The name of a member of a struct type, meaning the value of that member in
++// the context of the call. For example
++// VMA_LEN_IF_NOT_NULL("VkPhysicalDeviceMemoryProperties::memoryHeapCount"),
++// this means the number of memory heaps available in the device associated
++// with the VmaAllocator being dealt with.
++#ifndef VMA_LEN_IF_NOT_NULL
++ #define VMA_LEN_IF_NOT_NULL(len)
++#endif
++
++// The VMA_NULLABLE macro is defined to be _Nullable when compiling with Clang.
++// see: https://clang.llvm.org/docs/AttributeReference.html#nullable
++#ifndef VMA_NULLABLE
++ #ifdef __clang__
++ #define VMA_NULLABLE _Nullable
++ #else
++ #define VMA_NULLABLE
++ #endif
++#endif
++
++// The VMA_NOT_NULL macro is defined to be _Nonnull when compiling with Clang.
++// see: https://clang.llvm.org/docs/AttributeReference.html#nonnull
++#ifndef VMA_NOT_NULL
++ #ifdef __clang__
++ #define VMA_NOT_NULL _Nonnull
++ #else
++ #define VMA_NOT_NULL
++ #endif
++#endif
++
++// If non-dispatchable handles are represented as pointers then we can give
++// then nullability annotations
++#ifndef VMA_NOT_NULL_NON_DISPATCHABLE
++ #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
++ #define VMA_NOT_NULL_NON_DISPATCHABLE VMA_NOT_NULL
++ #else
++ #define VMA_NOT_NULL_NON_DISPATCHABLE
++ #endif
++#endif
++
++#ifndef VMA_NULLABLE_NON_DISPATCHABLE
++ #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
++ #define VMA_NULLABLE_NON_DISPATCHABLE VMA_NULLABLE
++ #else
++ #define VMA_NULLABLE_NON_DISPATCHABLE
++ #endif
++#endif
++
++#ifndef VMA_STATS_STRING_ENABLED
++ #define VMA_STATS_STRING_ENABLED 1
++#endif
++
++////////////////////////////////////////////////////////////////////////////////
++////////////////////////////////////////////////////////////////////////////////
++//
++// INTERFACE
++//
++////////////////////////////////////////////////////////////////////////////////
++////////////////////////////////////////////////////////////////////////////////
++
++// Sections for managing code placement in file, only for development purposes e.g. for convenient folding inside an IDE.
++#ifndef _VMA_ENUM_DECLARATIONS
++
++/**
++\addtogroup group_init
++@{
++*/
++
++/// Flags for created #VmaAllocator.
++typedef enum VmaAllocatorCreateFlagBits
++{
++ /** \brief Allocator and all objects created from it will not be synchronized internally, so you must guarantee they are used from only one thread at a time or synchronized externally by you.
++
++ Using this flag may increase performance because internal mutexes are not used.
++ */
++ VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001,
++ /** \brief Enables usage of VK_KHR_dedicated_allocation extension.
++
++ The flag works only if VmaAllocatorCreateInfo::vulkanApiVersion `== VK_API_VERSION_1_0`.
++ When it is `VK_API_VERSION_1_1`, the flag is ignored because the extension has been promoted to Vulkan 1.1.
++
++ Using this extension will automatically allocate dedicated blocks of memory for
++ some buffers and images instead of suballocating place for them out of bigger
++ memory blocks (as if you explicitly used #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
++ flag) when it is recommended by the driver. It may improve performance on some
++ GPUs.
++
++ You may set this flag only if you found out that following device extensions are
++ supported, you enabled them while creating Vulkan device passed as
++ VmaAllocatorCreateInfo::device, and you want them to be used internally by this
++ library:
++
++ - VK_KHR_get_memory_requirements2 (device extension)
++ - VK_KHR_dedicated_allocation (device extension)
++
++ When this flag is set, you can experience following warnings reported by Vulkan
++ validation layer. You can ignore them.
++
++ > vkBindBufferMemory(): Binding memory to buffer 0x2d but vkGetBufferMemoryRequirements() has not been called on that buffer.
++ */
++ VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT = 0x00000002,
++ /**
++ Enables usage of VK_KHR_bind_memory2 extension.
++
++ The flag works only if VmaAllocatorCreateInfo::vulkanApiVersion `== VK_API_VERSION_1_0`.
++ When it is `VK_API_VERSION_1_1`, the flag is ignored because the extension has been promoted to Vulkan 1.1.
++
++ You may set this flag only if you found out that this device extension is supported,
++ you enabled it while creating Vulkan device passed as VmaAllocatorCreateInfo::device,
++ and you want it to be used internally by this library.
++
++ The extension provides functions `vkBindBufferMemory2KHR` and `vkBindImageMemory2KHR`,
++ which allow to pass a chain of `pNext` structures while binding.
++ This flag is required if you use `pNext` parameter in vmaBindBufferMemory2() or vmaBindImageMemory2().
++ */
++ VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT = 0x00000004,
++ /**
++ Enables usage of VK_EXT_memory_budget extension.
++
++ You may set this flag only if you found out that this device extension is supported,
++ you enabled it while creating Vulkan device passed as VmaAllocatorCreateInfo::device,
++ and you want it to be used internally by this library, along with another instance extension
++ VK_KHR_get_physical_device_properties2, which is required by it (or Vulkan 1.1, where this extension is promoted).
++
++ The extension provides query for current memory usage and budget, which will probably
++ be more accurate than an estimation used by the library otherwise.
++ */
++ VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT = 0x00000008,
++ /**
++ Enables usage of VK_AMD_device_coherent_memory extension.
++
++ You may set this flag only if you:
++
++ - found out that this device extension is supported and enabled it while creating Vulkan device passed as VmaAllocatorCreateInfo::device,
++ - checked that `VkPhysicalDeviceCoherentMemoryFeaturesAMD::deviceCoherentMemory` is true and set it while creating the Vulkan device,
++ - want it to be used internally by this library.
++
++ The extension and accompanying device feature provide access to memory types with
++ `VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD` and `VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD` flags.
++ They are useful mostly for writing breadcrumb markers - a common method for debugging GPU crash/hang/TDR.
++
++ When the extension is not enabled, such memory types are still enumerated, but their usage is illegal.
++ To protect from this error, if you don't create the allocator with this flag, it will refuse to allocate any memory or create a custom pool in such memory type,
++ returning `VK_ERROR_FEATURE_NOT_PRESENT`.
++ */
++ VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT = 0x00000010,
++ /**
++ Enables usage of "buffer device address" feature, which allows you to use function
++ `vkGetBufferDeviceAddress*` to get raw GPU pointer to a buffer and pass it for usage inside a shader.
++
++ You may set this flag only if you:
++
++ 1. (For Vulkan version < 1.2) Found as available and enabled device extension
++ VK_KHR_buffer_device_address.
++ This extension is promoted to core Vulkan 1.2.
++ 2. Found as available and enabled device feature `VkPhysicalDeviceBufferDeviceAddressFeatures::bufferDeviceAddress`.
++
++ When this flag is set, you can create buffers with `VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT` using VMA.
++ The library automatically adds `VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT` to
++ allocated memory blocks wherever it might be needed.
++
++ For more information, see documentation chapter \ref enabling_buffer_device_address.
++ */
++ VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT = 0x00000020,
++ /**
++ Enables usage of VK_EXT_memory_priority extension in the library.
++
++ You may set this flag only if you found available and enabled this device extension,
++ along with `VkPhysicalDeviceMemoryPriorityFeaturesEXT::memoryPriority == VK_TRUE`,
++ while creating Vulkan device passed as VmaAllocatorCreateInfo::device.
++
++ When this flag is used, VmaAllocationCreateInfo::priority and VmaPoolCreateInfo::priority
++ are used to set priorities of allocated Vulkan memory. Without it, these variables are ignored.
++
++ A priority must be a floating-point value between 0 and 1, indicating the priority of the allocation relative to other memory allocations.
++ Larger values are higher priority. The granularity of the priorities is implementation-dependent.
++ It is automatically passed to every call to `vkAllocateMemory` done by the library using structure `VkMemoryPriorityAllocateInfoEXT`.
++ The value to be used for default priority is 0.5.
++ For more details, see the documentation of the VK_EXT_memory_priority extension.
++ */
++ VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT = 0x00000040,
++
++ VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
++} VmaAllocatorCreateFlagBits;
++/// See #VmaAllocatorCreateFlagBits.
++typedef VkFlags VmaAllocatorCreateFlags;
++
++/** @} */
++
++/**
++\addtogroup group_alloc
++@{
++*/
++
++/// \brief Intended usage of the allocated memory.
++typedef enum VmaMemoryUsage
++{
++ /** No intended memory usage specified.
++ Use other members of VmaAllocationCreateInfo to specify your requirements.
++ */
++ VMA_MEMORY_USAGE_UNKNOWN = 0,
++ /**
++ \deprecated Obsolete, preserved for backward compatibility.
++ Prefers `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`.
++ */
++ VMA_MEMORY_USAGE_GPU_ONLY = 1,
++ /**
++ \deprecated Obsolete, preserved for backward compatibility.
++ Guarantees `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` and `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT`.
++ */
++ VMA_MEMORY_USAGE_CPU_ONLY = 2,
++ /**
++ \deprecated Obsolete, preserved for backward compatibility.
++ Guarantees `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`, prefers `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`.
++ */
++ VMA_MEMORY_USAGE_CPU_TO_GPU = 3,
++ /**
++ \deprecated Obsolete, preserved for backward compatibility.
++ Guarantees `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`, prefers `VK_MEMORY_PROPERTY_HOST_CACHED_BIT`.
++ */
++ VMA_MEMORY_USAGE_GPU_TO_CPU = 4,
++ /**
++ \deprecated Obsolete, preserved for backward compatibility.
++ Prefers not `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`.
++ */
++ VMA_MEMORY_USAGE_CPU_COPY = 5,
++ /**
++ Lazily allocated GPU memory having `VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT`.
++ Exists mostly on mobile platforms. Using it on desktop PC or other GPUs with no such memory type present will fail the allocation.
++
++ Usage: Memory for transient attachment images (color attachments, depth attachments etc.), created with `VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT`.
++
++ Allocations with this usage are always created as dedicated - it implies #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
++ */
++ VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED = 6,
++ /**
++ Selects best memory type automatically.
++ This flag is recommended for most common use cases.
++
++ When using this flag, if you want to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT),
++ you must pass one of the flags: #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
++ in VmaAllocationCreateInfo::flags.
++
++ It can be used only with functions that let the library know `VkBufferCreateInfo` or `VkImageCreateInfo`, e.g.
++ vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo()
++ and not with generic memory allocation functions.
++ */
++ VMA_MEMORY_USAGE_AUTO = 7,
++ /**
++ Selects best memory type automatically with preference for GPU (device) memory.
++
++ When using this flag, if you want to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT),
++ you must pass one of the flags: #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
++ in VmaAllocationCreateInfo::flags.
++
++ It can be used only with functions that let the library know `VkBufferCreateInfo` or `VkImageCreateInfo`, e.g.
++ vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo()
++ and not with generic memory allocation functions.
++ */
++ VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE = 8,
++ /**
++ Selects best memory type automatically with preference for CPU (host) memory.
++
++ When using this flag, if you want to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT),
++ you must pass one of the flags: #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
++ in VmaAllocationCreateInfo::flags.
++
++ It can be used only with functions that let the library know `VkBufferCreateInfo` or `VkImageCreateInfo`, e.g.
++ vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo()
++ and not with generic memory allocation functions.
++ */
++ VMA_MEMORY_USAGE_AUTO_PREFER_HOST = 9,
++
++ VMA_MEMORY_USAGE_MAX_ENUM = 0x7FFFFFFF
++} VmaMemoryUsage;
++
++/// Flags to be passed as VmaAllocationCreateInfo::flags.
++typedef enum VmaAllocationCreateFlagBits
++{
++ /** \brief Set this flag if the allocation should have its own memory block.
++
++ Use it for special, big resources, like fullscreen images used as attachments.
++ */
++ VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT = 0x00000001,
++
++ /** \brief Set this flag to only try to allocate from existing `VkDeviceMemory` blocks and never create new such block.
++
++ If new allocation cannot be placed in any of the existing blocks, allocation
++ fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY` error.
++
++ You should not use #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT and
++ #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT at the same time. It makes no sense.
++ */
++ VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT = 0x00000002,
++ /** \brief Set this flag to use a memory that will be persistently mapped and retrieve pointer to it.
++
++ Pointer to mapped memory will be returned through VmaAllocationInfo::pMappedData.
++
++ It is valid to use this flag for allocation made from memory type that is not
++ `HOST_VISIBLE`. This flag is then ignored and memory is not mapped. This is
++ useful if you need an allocation that is efficient to use on GPU
++ (`DEVICE_LOCAL`) and still want to map it directly if possible on platforms that
++ support it (e.g. Intel GPU).
++ */
++ VMA_ALLOCATION_CREATE_MAPPED_BIT = 0x00000004,
++ /** \deprecated Preserved for backward compatibility. Consider using vmaSetAllocationName() instead.
++
++ Set this flag to treat VmaAllocationCreateInfo::pUserData as pointer to a
++ null-terminated string. Instead of copying pointer value, a local copy of the
++ string is made and stored in allocation's `pName`. The string is automatically
++ freed together with the allocation. It is also used in vmaBuildStatsString().
++ */
++ VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT = 0x00000020,
++ /** Allocation will be created from upper stack in a double stack pool.
++
++ This flag is only allowed for custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT flag.
++ */
++ VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = 0x00000040,
++ /** Create both buffer/image and allocation, but don't bind them together.
++ It is useful when you want to bind yourself to do some more advanced binding, e.g. using some extensions.
++ The flag is meaningful only with functions that bind by default: vmaCreateBuffer(), vmaCreateImage().
++ Otherwise it is ignored.
++
++ If you want to make sure the new buffer/image is not tied to the new memory allocation
++ through `VkMemoryDedicatedAllocateInfoKHR` structure in case the allocation ends up in its own memory block,
++ use also flag #VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT.
++ */
++ VMA_ALLOCATION_CREATE_DONT_BIND_BIT = 0x00000080,
++ /** Create allocation only if additional device memory required for it, if any, won't exceed
++ memory budget. Otherwise return `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
++ */
++ VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT = 0x00000100,
++ /** \brief Set this flag if the allocated memory will have aliasing resources.
++
++ Usage of this flag prevents supplying `VkMemoryDedicatedAllocateInfoKHR` when #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT is specified.
++ Otherwise created dedicated memory will not be suitable for aliasing resources, resulting in Vulkan Validation Layer errors.
++ */
++ VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT = 0x00000200,
++ /**
++ Requests possibility to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT).
++
++ - If you use #VMA_MEMORY_USAGE_AUTO or other `VMA_MEMORY_USAGE_AUTO*` value,
++ you must use this flag to be able to map the allocation. Otherwise, mapping is incorrect.
++ - If you use other value of #VmaMemoryUsage, this flag is ignored and mapping is always possible in memory types that are `HOST_VISIBLE`.
++ This includes allocations created in \ref custom_memory_pools.
++
++ Declares that mapped memory will only be written sequentially, e.g. using `memcpy()` or a loop writing number-by-number,
++ never read or accessed randomly, so a memory type can be selected that is uncached and write-combined.
++
++ \warning Violating this declaration may work correctly, but will likely be very slow.
++ Watch out for implicit reads introduced by doing e.g. `pMappedData[i] += x;`
++ Better prepare your data in a local variable and `memcpy()` it to the mapped pointer all at once.
++ */
++ VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT = 0x00000400,
++ /**
++ Requests possibility to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT).
++
++ - If you use #VMA_MEMORY_USAGE_AUTO or other `VMA_MEMORY_USAGE_AUTO*` value,
++ you must use this flag to be able to map the allocation. Otherwise, mapping is incorrect.
++ - If you use other value of #VmaMemoryUsage, this flag is ignored and mapping is always possible in memory types that are `HOST_VISIBLE`.
++ This includes allocations created in \ref custom_memory_pools.
++
++ Declares that mapped memory can be read, written, and accessed in random order,
++ so a `HOST_CACHED` memory type is required.
++ */
++ VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT = 0x00000800,
++ /**
++ Together with #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT,
++ it says that despite request for host access, a not-`HOST_VISIBLE` memory type can be selected
++ if it may improve performance.
++
++ By using this flag, you declare that you will check if the allocation ended up in a `HOST_VISIBLE` memory type
++ (e.g. using vmaGetAllocationMemoryProperties()) and if not, you will create some "staging" buffer and
++ issue an explicit transfer to write/read your data.
++ To prepare for this possibility, don't forget to add appropriate flags like
++ `VK_BUFFER_USAGE_TRANSFER_DST_BIT`, `VK_BUFFER_USAGE_TRANSFER_SRC_BIT` to the parameters of created buffer or image.
++ */
++ VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT = 0x00001000,
++ /** Allocation strategy that chooses smallest possible free range for the allocation
++ to minimize memory usage and fragmentation, possibly at the expense of allocation time.
++ */
++ VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = 0x00010000,
++ /** Allocation strategy that chooses first suitable free range for the allocation -
++ not necessarily in terms of the smallest offset but the one that is easiest and fastest to find
++ to minimize allocation time, possibly at the expense of allocation quality.
++ */
++ VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = 0x00020000,
++ /** Allocation strategy that chooses always the lowest offset in available space.
++ This is not the most efficient strategy but achieves highly packed data.
++ Used internally by defragmentation, not recomended in typical usage.
++ */
++ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = 0x00040000,
++ /** Alias to #VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT.
++ */
++ VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT,
++ /** Alias to #VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT.
++ */
++ VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT,
++ /** A bit mask to extract only `STRATEGY` bits from entire set of flags.
++ */
++ VMA_ALLOCATION_CREATE_STRATEGY_MASK =
++ VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT |
++ VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT |
++ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
++
++ VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
++} VmaAllocationCreateFlagBits;
++/// See #VmaAllocationCreateFlagBits.
++typedef VkFlags VmaAllocationCreateFlags;
++
++/// Flags to be passed as VmaPoolCreateInfo::flags.
++typedef enum VmaPoolCreateFlagBits
++{
++ /** \brief Use this flag if you always allocate only buffers and linear images or only optimal images out of this pool and so Buffer-Image Granularity can be ignored.
++
++ This is an optional optimization flag.
++
++ If you always allocate using vmaCreateBuffer(), vmaCreateImage(),
++ vmaAllocateMemoryForBuffer(), then you don't need to use it because allocator
++ knows exact type of your allocations so it can handle Buffer-Image Granularity
++ in the optimal way.
++
++ If you also allocate using vmaAllocateMemoryForImage() or vmaAllocateMemory(),
++ exact type of such allocations is not known, so allocator must be conservative
++ in handling Buffer-Image Granularity, which can lead to suboptimal allocation
++ (wasted memory). In that case, if you can make sure you always allocate only
++ buffers and linear images or only optimal images out of this pool, use this flag
++ to make allocator disregard Buffer-Image Granularity and so make allocations
++ faster and more optimal.
++ */
++ VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = 0x00000002,
++
++ /** \brief Enables alternative, linear allocation algorithm in this pool.
++
++ Specify this flag to enable linear allocation algorithm, which always creates
++ new allocations after last one and doesn't reuse space from allocations freed in
++ between. It trades memory consumption for simplified algorithm and data
++ structure, which has better performance and uses less memory for metadata.
++
++ By using this flag, you can achieve behavior of free-at-once, stack,
++ ring buffer, and double stack.
++ For details, see documentation chapter \ref linear_algorithm.
++ */
++ VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT = 0x00000004,
++
++ /** Bit mask to extract only `ALGORITHM` bits from entire set of flags.
++ */
++ VMA_POOL_CREATE_ALGORITHM_MASK =
++ VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT,
++
++ VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
++} VmaPoolCreateFlagBits;
++/// Flags to be passed as VmaPoolCreateInfo::flags. See #VmaPoolCreateFlagBits.
++typedef VkFlags VmaPoolCreateFlags;
++
++/// Flags to be passed as VmaDefragmentationInfo::flags.
++typedef enum VmaDefragmentationFlagBits
++{
++ /* \brief Use simple but fast algorithm for defragmentation.
++ May not achieve best results but will require least time to compute and least allocations to copy.
++ */
++ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT = 0x1,
++ /* \brief Default defragmentation algorithm, applied also when no `ALGORITHM` flag is specified.
++ Offers a balance between defragmentation quality and the amount of allocations and bytes that need to be moved.
++ */
++ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT = 0x2,
++ /* \brief Perform full defragmentation of memory.
++ Can result in notably more time to compute and allocations to copy, but will achieve best memory packing.
++ */
++ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT = 0x4,
++ /** \brief Use the most roboust algorithm at the cost of time to compute and number of copies to make.
++ Only available when bufferImageGranularity is greater than 1, since it aims to reduce
++ alignment issues between different types of resources.
++ Otherwise falls back to same behavior as #VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT.
++ */
++ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT = 0x8,
++
++ /// A bit mask to extract only `ALGORITHM` bits from entire set of flags.
++ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK =
++ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT |
++ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT |
++ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT |
++ VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT,
++
++ VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
++} VmaDefragmentationFlagBits;
++/// See #VmaDefragmentationFlagBits.
++typedef VkFlags VmaDefragmentationFlags;
++
++/// Operation performed on single defragmentation move. See structure #VmaDefragmentationMove.
++typedef enum VmaDefragmentationMoveOperation
++{
++ /// Buffer/image has been recreated at `dstTmpAllocation`, data has been copied, old buffer/image has been destroyed. `srcAllocation` should be changed to point to the new place. This is the default value set by vmaBeginDefragmentationPass().
++ VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY = 0,
++ /// Set this value if you cannot move the allocation. New place reserved at `dstTmpAllocation` will be freed. `srcAllocation` will remain unchanged.
++ VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE = 1,
++ /// Set this value if you decide to abandon the allocation and you destroyed the buffer/image. New place reserved at `dstTmpAllocation` will be freed, along with `srcAllocation`, which will be destroyed.
++ VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY = 2,
++} VmaDefragmentationMoveOperation;
++
++/** @} */
++
++/**
++\addtogroup group_virtual
++@{
++*/
++
++/// Flags to be passed as VmaVirtualBlockCreateInfo::flags.
++typedef enum VmaVirtualBlockCreateFlagBits
++{
++ /** \brief Enables alternative, linear allocation algorithm in this virtual block.
++
++ Specify this flag to enable linear allocation algorithm, which always creates
++ new allocations after last one and doesn't reuse space from allocations freed in
++ between. It trades memory consumption for simplified algorithm and data
++ structure, which has better performance and uses less memory for metadata.
++
++ By using this flag, you can achieve behavior of free-at-once, stack,
++ ring buffer, and double stack.
++ For details, see documentation chapter \ref linear_algorithm.
++ */
++ VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT = 0x00000001,
++
++ /** \brief Bit mask to extract only `ALGORITHM` bits from entire set of flags.
++ */
++ VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK =
++ VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT,
++
++ VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
++} VmaVirtualBlockCreateFlagBits;
++/// Flags to be passed as VmaVirtualBlockCreateInfo::flags. See #VmaVirtualBlockCreateFlagBits.
++typedef VkFlags VmaVirtualBlockCreateFlags;
++
++/// Flags to be passed as VmaVirtualAllocationCreateInfo::flags.
++typedef enum VmaVirtualAllocationCreateFlagBits
++{
++ /** \brief Allocation will be created from upper stack in a double stack pool.
++
++ This flag is only allowed for virtual blocks created with #VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT flag.
++ */
++ VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT,
++ /** \brief Allocation strategy that tries to minimize memory usage.
++ */
++ VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT,
++ /** \brief Allocation strategy that tries to minimize allocation time.
++ */
++ VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT,
++ /** Allocation strategy that chooses always the lowest offset in available space.
++ This is not the most efficient strategy but achieves highly packed data.
++ */
++ VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
++ /** \brief A bit mask to extract only `STRATEGY` bits from entire set of flags.
++
++ These strategy flags are binary compatible with equivalent flags in #VmaAllocationCreateFlagBits.
++ */
++ VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK = VMA_ALLOCATION_CREATE_STRATEGY_MASK,
++
++ VMA_VIRTUAL_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
++} VmaVirtualAllocationCreateFlagBits;
++/// Flags to be passed as VmaVirtualAllocationCreateInfo::flags. See #VmaVirtualAllocationCreateFlagBits.
++typedef VkFlags VmaVirtualAllocationCreateFlags;
++
++/** @} */
++
++#endif // _VMA_ENUM_DECLARATIONS
++
++#ifndef _VMA_DATA_TYPES_DECLARATIONS
++
++/**
++\addtogroup group_init
++@{ */
++
++/** \struct VmaAllocator
++\brief Represents main object of this library initialized.
++
++Fill structure #VmaAllocatorCreateInfo and call function vmaCreateAllocator() to create it.
++Call function vmaDestroyAllocator() to destroy it.
++
++It is recommended to create just one object of this type per `VkDevice` object,
++right after Vulkan is initialized and keep it alive until before Vulkan device is destroyed.
++*/
++VK_DEFINE_HANDLE(VmaAllocator)
++
++/** @} */
++
++/**
++\addtogroup group_alloc
++@{
++*/
++
++/** \struct VmaPool
++\brief Represents custom memory pool
++
++Fill structure VmaPoolCreateInfo and call function vmaCreatePool() to create it.
++Call function vmaDestroyPool() to destroy it.
++
++For more information see [Custom memory pools](@ref choosing_memory_type_custom_memory_pools).
++*/
++VK_DEFINE_HANDLE(VmaPool)
++
++/** \struct VmaAllocation
++\brief Represents single memory allocation.
++
++It may be either dedicated block of `VkDeviceMemory` or a specific region of a bigger block of this type
++plus unique offset.
++
++There are multiple ways to create such object.
++You need to fill structure VmaAllocationCreateInfo.
++For more information see [Choosing memory type](@ref choosing_memory_type).
++
++Although the library provides convenience functions that create Vulkan buffer or image,
++allocate memory for it and bind them together,
++binding of the allocation to a buffer or an image is out of scope of the allocation itself.
++Allocation object can exist without buffer/image bound,
++binding can be done manually by the user, and destruction of it can be done
++independently of destruction of the allocation.
++
++The object also remembers its size and some other information.
++To retrieve this information, use function vmaGetAllocationInfo() and inspect
++returned structure VmaAllocationInfo.
++*/
++VK_DEFINE_HANDLE(VmaAllocation)
++
++/** \struct VmaDefragmentationContext
++\brief An opaque object that represents started defragmentation process.
++
++Fill structure #VmaDefragmentationInfo and call function vmaBeginDefragmentation() to create it.
++Call function vmaEndDefragmentation() to destroy it.
++*/
++VK_DEFINE_HANDLE(VmaDefragmentationContext)
++
++/** @} */
++
++/**
++\addtogroup group_virtual
++@{
++*/
++
++/** \struct VmaVirtualAllocation
++\brief Represents single memory allocation done inside VmaVirtualBlock.
++
++Use it as a unique identifier to virtual allocation within the single block.
++
++Use value `VK_NULL_HANDLE` to represent a null/invalid allocation.
++*/
++VK_DEFINE_NON_DISPATCHABLE_HANDLE(VmaVirtualAllocation);
++
++/** @} */
++
++/**
++\addtogroup group_virtual
++@{
++*/
++
++/** \struct VmaVirtualBlock
++\brief Handle to a virtual block object that allows to use core allocation algorithm without allocating any real GPU memory.
++
++Fill in #VmaVirtualBlockCreateInfo structure and use vmaCreateVirtualBlock() to create it. Use vmaDestroyVirtualBlock() to destroy it.
++For more information, see documentation chapter \ref virtual_allocator.
++
++This object is not thread-safe - should not be used from multiple threads simultaneously, must be synchronized externally.
++*/
++VK_DEFINE_HANDLE(VmaVirtualBlock)
++
++/** @} */
++
++/**
++\addtogroup group_init
++@{
++*/
++
++/// Callback function called after successful vkAllocateMemory.
++typedef void (VKAPI_PTR* PFN_vmaAllocateDeviceMemoryFunction)(
++ VmaAllocator VMA_NOT_NULL allocator,
++ uint32_t memoryType,
++ VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory,
++ VkDeviceSize size,
++ void* VMA_NULLABLE pUserData);
++
++/// Callback function called before vkFreeMemory.
++typedef void (VKAPI_PTR* PFN_vmaFreeDeviceMemoryFunction)(
++ VmaAllocator VMA_NOT_NULL allocator,
++ uint32_t memoryType,
++ VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory,
++ VkDeviceSize size,
++ void* VMA_NULLABLE pUserData);
++
++/** \brief Set of callbacks that the library will call for `vkAllocateMemory` and `vkFreeMemory`.
++
++Provided for informative purpose, e.g. to gather statistics about number of
++allocations or total amount of memory allocated in Vulkan.
++
++Used in VmaAllocatorCreateInfo::pDeviceMemoryCallbacks.
++*/
++typedef struct VmaDeviceMemoryCallbacks
++{
++ /// Optional, can be null.
++ PFN_vmaAllocateDeviceMemoryFunction VMA_NULLABLE pfnAllocate;
++ /// Optional, can be null.
++ PFN_vmaFreeDeviceMemoryFunction VMA_NULLABLE pfnFree;
++ /// Optional, can be null.
++ void* VMA_NULLABLE pUserData;
++} VmaDeviceMemoryCallbacks;
++
++/** \brief Pointers to some Vulkan functions - a subset used by the library.
++
++Used in VmaAllocatorCreateInfo::pVulkanFunctions.
++*/
++typedef struct VmaVulkanFunctions
++{
++ /// Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
++ PFN_vkGetInstanceProcAddr VMA_NULLABLE vkGetInstanceProcAddr;
++ /// Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS.
++ PFN_vkGetDeviceProcAddr VMA_NULLABLE vkGetDeviceProcAddr;
++ PFN_vkGetPhysicalDeviceProperties VMA_NULLABLE vkGetPhysicalDeviceProperties;
++ PFN_vkGetPhysicalDeviceMemoryProperties VMA_NULLABLE vkGetPhysicalDeviceMemoryProperties;
++ PFN_vkAllocateMemory VMA_NULLABLE vkAllocateMemory;
++ PFN_vkFreeMemory VMA_NULLABLE vkFreeMemory;
++ PFN_vkMapMemory VMA_NULLABLE vkMapMemory;
++ PFN_vkUnmapMemory VMA_NULLABLE vkUnmapMemory;
++ PFN_vkFlushMappedMemoryRanges VMA_NULLABLE vkFlushMappedMemoryRanges;
++ PFN_vkInvalidateMappedMemoryRanges VMA_NULLABLE vkInvalidateMappedMemoryRanges;
++ PFN_vkBindBufferMemory VMA_NULLABLE vkBindBufferMemory;
++ PFN_vkBindImageMemory VMA_NULLABLE vkBindImageMemory;
++ PFN_vkGetBufferMemoryRequirements VMA_NULLABLE vkGetBufferMemoryRequirements;
++ PFN_vkGetImageMemoryRequirements VMA_NULLABLE vkGetImageMemoryRequirements;
++ PFN_vkCreateBuffer VMA_NULLABLE vkCreateBuffer;
++ PFN_vkDestroyBuffer VMA_NULLABLE vkDestroyBuffer;
++ PFN_vkCreateImage VMA_NULLABLE vkCreateImage;
++ PFN_vkDestroyImage VMA_NULLABLE vkDestroyImage;
++ PFN_vkCmdCopyBuffer VMA_NULLABLE vkCmdCopyBuffer;
++#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
++ /// Fetch "vkGetBufferMemoryRequirements2" on Vulkan >= 1.1, fetch "vkGetBufferMemoryRequirements2KHR" when using VK_KHR_dedicated_allocation extension.
++ PFN_vkGetBufferMemoryRequirements2KHR VMA_NULLABLE vkGetBufferMemoryRequirements2KHR;
++ /// Fetch "vkGetImageMemoryRequirements 2" on Vulkan >= 1.1, fetch "vkGetImageMemoryRequirements2KHR" when using VK_KHR_dedicated_allocation extension.
++ PFN_vkGetImageMemoryRequirements2KHR VMA_NULLABLE vkGetImageMemoryRequirements2KHR;
++#endif
++#if VMA_BIND_MEMORY2 || VMA_VULKAN_VERSION >= 1001000
++ /// Fetch "vkBindBufferMemory2" on Vulkan >= 1.1, fetch "vkBindBufferMemory2KHR" when using VK_KHR_bind_memory2 extension.
++ PFN_vkBindBufferMemory2KHR VMA_NULLABLE vkBindBufferMemory2KHR;
++ /// Fetch "vkBindImageMemory2" on Vulkan >= 1.1, fetch "vkBindImageMemory2KHR" when using VK_KHR_bind_memory2 extension.
++ PFN_vkBindImageMemory2KHR VMA_NULLABLE vkBindImageMemory2KHR;
++#endif
++#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000
++ PFN_vkGetPhysicalDeviceMemoryProperties2KHR VMA_NULLABLE vkGetPhysicalDeviceMemoryProperties2KHR;
++#endif
++#if VMA_VULKAN_VERSION >= 1003000
++ /// Fetch from "vkGetDeviceBufferMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceBufferMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4.
++ PFN_vkGetDeviceBufferMemoryRequirements VMA_NULLABLE vkGetDeviceBufferMemoryRequirements;
++ /// Fetch from "vkGetDeviceImageMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceImageMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4.
++ PFN_vkGetDeviceImageMemoryRequirements VMA_NULLABLE vkGetDeviceImageMemoryRequirements;
++#endif
++} VmaVulkanFunctions;
++
++/// Description of a Allocator to be created.
++typedef struct VmaAllocatorCreateInfo
++{
++ /// Flags for created allocator. Use #VmaAllocatorCreateFlagBits enum.
++ VmaAllocatorCreateFlags flags;
++ /// Vulkan physical device.
++ /** It must be valid throughout whole lifetime of created allocator. */
++ VkPhysicalDevice VMA_NOT_NULL physicalDevice;
++ /// Vulkan device.
++ /** It must be valid throughout whole lifetime of created allocator. */
++ VkDevice VMA_NOT_NULL device;
++ /// Preferred size of a single `VkDeviceMemory` block to be allocated from large heaps > 1 GiB. Optional.
++ /** Set to 0 to use default, which is currently 256 MiB. */
++ VkDeviceSize preferredLargeHeapBlockSize;
++ /// Custom CPU memory allocation callbacks. Optional.
++ /** Optional, can be null. When specified, will also be used for all CPU-side memory allocations. */
++ const VkAllocationCallbacks* VMA_NULLABLE pAllocationCallbacks;
++ /// Informative callbacks for `vkAllocateMemory`, `vkFreeMemory`. Optional.
++ /** Optional, can be null. */
++ const VmaDeviceMemoryCallbacks* VMA_NULLABLE pDeviceMemoryCallbacks;
++ /** \brief Either null or a pointer to an array of limits on maximum number of bytes that can be allocated out of particular Vulkan memory heap.
++
++ If not NULL, it must be a pointer to an array of
++ `VkPhysicalDeviceMemoryProperties::memoryHeapCount` elements, defining limit on
++ maximum number of bytes that can be allocated out of particular Vulkan memory
++ heap.
++
++ Any of the elements may be equal to `VK_WHOLE_SIZE`, which means no limit on that
++ heap. This is also the default in case of `pHeapSizeLimit` = NULL.
++
++ If there is a limit defined for a heap:
++
++ - If user tries to allocate more memory from that heap using this allocator,
++ the allocation fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
++ - If the limit is smaller than heap size reported in `VkMemoryHeap::size`, the
++ value of this limit will be reported instead when using vmaGetMemoryProperties().
++
++ Warning! Using this feature may not be equivalent to installing a GPU with
++ smaller amount of memory, because graphics driver doesn't necessary fail new
++ allocations with `VK_ERROR_OUT_OF_DEVICE_MEMORY` result when memory capacity is
++ exceeded. It may return success and just silently migrate some device memory
++ blocks to system RAM. This driver behavior can also be controlled using
++ VK_AMD_memory_overallocation_behavior extension.
++ */
++ const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL("VkPhysicalDeviceMemoryProperties::memoryHeapCount") pHeapSizeLimit;
++
++ /** \brief Pointers to Vulkan functions. Can be null.
++
++ For details see [Pointers to Vulkan functions](@ref config_Vulkan_functions).
++ */
++ const VmaVulkanFunctions* VMA_NULLABLE pVulkanFunctions;
++ /** \brief Handle to Vulkan instance object.
++
++ Starting from version 3.0.0 this member is no longer optional, it must be set!
++ */
++ VkInstance VMA_NOT_NULL instance;
++ /** \brief Optional. The highest version of Vulkan that the application is designed to use.
++
++ It must be a value in the format as created by macro `VK_MAKE_VERSION` or a constant like: `VK_API_VERSION_1_1`, `VK_API_VERSION_1_0`.
++ The patch version number specified is ignored. Only the major and minor versions are considered.
++ It must be less or equal (preferably equal) to value as passed to `vkCreateInstance` as `VkApplicationInfo::apiVersion`.
++ Only versions 1.0, 1.1, 1.2, 1.3 are supported by the current implementation.
++ Leaving it initialized to zero is equivalent to `VK_API_VERSION_1_0`.
++ */
++ uint32_t vulkanApiVersion;
++#if VMA_EXTERNAL_MEMORY
++ /** \brief Either null or a pointer to an array of external memory handle types for each Vulkan memory type.
++
++ If not NULL, it must be a pointer to an array of `VkPhysicalDeviceMemoryProperties::memoryTypeCount`
++ elements, defining external memory handle types of particular Vulkan memory type,
++ to be passed using `VkExportMemoryAllocateInfoKHR`.
++
++ Any of the elements may be equal to 0, which means not to use `VkExportMemoryAllocateInfoKHR` on this memory type.
++ This is also the default in case of `pTypeExternalMemoryHandleTypes` = NULL.
++ */
++ const VkExternalMemoryHandleTypeFlagsKHR* VMA_NULLABLE VMA_LEN_IF_NOT_NULL("VkPhysicalDeviceMemoryProperties::memoryTypeCount") pTypeExternalMemoryHandleTypes;
++#endif // #if VMA_EXTERNAL_MEMORY
++} VmaAllocatorCreateInfo;
++
++/// Information about existing #VmaAllocator object.
++typedef struct VmaAllocatorInfo
++{
++ /** \brief Handle to Vulkan instance object.
++
++ This is the same value as has been passed through VmaAllocatorCreateInfo::instance.
++ */
++ VkInstance VMA_NOT_NULL instance;
++ /** \brief Handle to Vulkan physical device object.
++
++ This is the same value as has been passed through VmaAllocatorCreateInfo::physicalDevice.
++ */
++ VkPhysicalDevice VMA_NOT_NULL physicalDevice;
++ /** \brief Handle to Vulkan device object.
++
++ This is the same value as has been passed through VmaAllocatorCreateInfo::device.
++ */
++ VkDevice VMA_NOT_NULL device;
++} VmaAllocatorInfo;
++
++/** @} */
++
++/**
++\addtogroup group_stats
++@{
++*/
++
++/** \brief Calculated statistics of memory usage e.g. in a specific memory type, heap, custom pool, or total.
++
++These are fast to calculate.
++See functions: vmaGetHeapBudgets(), vmaGetPoolStatistics().
++*/
++typedef struct VmaStatistics
++{
++ /** \brief Number of `VkDeviceMemory` objects - Vulkan memory blocks allocated.
++ */
++ uint32_t blockCount;
++ /** \brief Number of #VmaAllocation objects allocated.
++
++ Dedicated allocations have their own blocks, so each one adds 1 to `allocationCount` as well as `blockCount`.
++ */
++ uint32_t allocationCount;
++ /** \brief Number of bytes allocated in `VkDeviceMemory` blocks.
++
++ \note To avoid confusion, please be aware that what Vulkan calls an "allocation" - a whole `VkDeviceMemory` object
++ (e.g. as in `VkPhysicalDeviceLimits::maxMemoryAllocationCount`) is called a "block" in VMA, while VMA calls
++ "allocation" a #VmaAllocation object that represents a memory region sub-allocated from such block, usually for a single buffer or image.
++ */
++ VkDeviceSize blockBytes;
++ /** \brief Total number of bytes occupied by all #VmaAllocation objects.
++
++ Always less or equal than `blockBytes`.
++ Difference `(blockBytes - allocationBytes)` is the amount of memory allocated from Vulkan
++ but unused by any #VmaAllocation.
++ */
++ VkDeviceSize allocationBytes;
++} VmaStatistics;
++
++/** \brief More detailed statistics than #VmaStatistics.
++
++These are slower to calculate. Use for debugging purposes.
++See functions: vmaCalculateStatistics(), vmaCalculatePoolStatistics().
++
++Previous version of the statistics API provided averages, but they have been removed
++because they can be easily calculated as:
++
++\code
++VkDeviceSize allocationSizeAvg = detailedStats.statistics.allocationBytes / detailedStats.statistics.allocationCount;
++VkDeviceSize unusedBytes = detailedStats.statistics.blockBytes - detailedStats.statistics.allocationBytes;
++VkDeviceSize unusedRangeSizeAvg = unusedBytes / detailedStats.unusedRangeCount;
++\endcode
++*/
++typedef struct VmaDetailedStatistics
++{
++ /// Basic statistics.
++ VmaStatistics statistics;
++ /// Number of free ranges of memory between allocations.
++ uint32_t unusedRangeCount;
++ /// Smallest allocation size. `VK_WHOLE_SIZE` if there are 0 allocations.
++ VkDeviceSize allocationSizeMin;
++ /// Largest allocation size. 0 if there are 0 allocations.
++ VkDeviceSize allocationSizeMax;
++ /// Smallest empty range size. `VK_WHOLE_SIZE` if there are 0 empty ranges.
++ VkDeviceSize unusedRangeSizeMin;
++ /// Largest empty range size. 0 if there are 0 empty ranges.
++ VkDeviceSize unusedRangeSizeMax;
++} VmaDetailedStatistics;
++
++/** \brief General statistics from current state of the Allocator -
++total memory usage across all memory heaps and types.
++
++These are slower to calculate. Use for debugging purposes.
++See function vmaCalculateStatistics().
++*/
++typedef struct VmaTotalStatistics
++{
++ VmaDetailedStatistics memoryType[VK_MAX_MEMORY_TYPES];
++ VmaDetailedStatistics memoryHeap[VK_MAX_MEMORY_HEAPS];
++ VmaDetailedStatistics total;
++} VmaTotalStatistics;
++
++/** \brief Statistics of current memory usage and available budget for a specific memory heap.
++
++These are fast to calculate.
++See function vmaGetHeapBudgets().
++*/
++typedef struct VmaBudget
++{
++ /** \brief Statistics fetched from the library.
++ */
++ VmaStatistics statistics;
++ /** \brief Estimated current memory usage of the program, in bytes.
++
++ Fetched from system using VK_EXT_memory_budget extension if enabled.
++
++ It might be different than `statistics.blockBytes` (usually higher) due to additional implicit objects
++ also occupying the memory, like swapchain, pipelines, descriptor heaps, command buffers, or
++ `VkDeviceMemory` blocks allocated outside of this library, if any.
++ */
++ VkDeviceSize usage;
++ /** \brief Estimated amount of memory available to the program, in bytes.
++
++ Fetched from system using VK_EXT_memory_budget extension if enabled.
++
++ It might be different (most probably smaller) than `VkMemoryHeap::size[heapIndex]` due to factors
++ external to the program, decided by the operating system.
++ Difference `budget - usage` is the amount of additional memory that can probably
++ be allocated without problems. Exceeding the budget may result in various problems.
++ */
++ VkDeviceSize budget;
++} VmaBudget;
++
++/** @} */
++
++/**
++\addtogroup group_alloc
++@{
++*/
++
++/** \brief Parameters of new #VmaAllocation.
++
++To be used with functions like vmaCreateBuffer(), vmaCreateImage(), and many others.
++*/
++typedef struct VmaAllocationCreateInfo
++{
++ /// Use #VmaAllocationCreateFlagBits enum.
++ VmaAllocationCreateFlags flags;
++ /** \brief Intended usage of memory.
++
++ You can leave #VMA_MEMORY_USAGE_UNKNOWN if you specify memory requirements in other way. \n
++ If `pool` is not null, this member is ignored.
++ */
++ VmaMemoryUsage usage;
++ /** \brief Flags that must be set in a Memory Type chosen for an allocation.
++
++ Leave 0 if you specify memory requirements in other way. \n
++ If `pool` is not null, this member is ignored.*/
++ VkMemoryPropertyFlags requiredFlags;
++ /** \brief Flags that preferably should be set in a memory type chosen for an allocation.
++
++ Set to 0 if no additional flags are preferred. \n
++ If `pool` is not null, this member is ignored. */
++ VkMemoryPropertyFlags preferredFlags;
++ /** \brief Bitmask containing one bit set for every memory type acceptable for this allocation.
++
++ Value 0 is equivalent to `UINT32_MAX` - it means any memory type is accepted if
++ it meets other requirements specified by this structure, with no further
++ restrictions on memory type index. \n
++ If `pool` is not null, this member is ignored.
++ */
++ uint32_t memoryTypeBits;
++ /** \brief Pool that this allocation should be created in.
++
++ Leave `VK_NULL_HANDLE` to allocate from default pool. If not null, members:
++ `usage`, `requiredFlags`, `preferredFlags`, `memoryTypeBits` are ignored.
++ */
++ VmaPool VMA_NULLABLE pool;
++ /** \brief Custom general-purpose pointer that will be stored in #VmaAllocation, can be read as VmaAllocationInfo::pUserData and changed using vmaSetAllocationUserData().
++
++ If #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT is used, it must be either
++ null or pointer to a null-terminated string. The string will be then copied to
++ internal buffer, so it doesn't need to be valid after allocation call.
++ */
++ void* VMA_NULLABLE pUserData;
++ /** \brief A floating-point value between 0 and 1, indicating the priority of the allocation relative to other memory allocations.
++
++ It is used only when #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT flag was used during creation of the #VmaAllocator object
++ and this allocation ends up as dedicated or is explicitly forced as dedicated using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
++ Otherwise, it has the priority of a memory block where it is placed and this variable is ignored.
++ */
++ float priority;
++} VmaAllocationCreateInfo;
++
++/// Describes parameter of created #VmaPool.
++typedef struct VmaPoolCreateInfo
++{
++ /** \brief Vulkan memory type index to allocate this pool from.
++ */
++ uint32_t memoryTypeIndex;
++ /** \brief Use combination of #VmaPoolCreateFlagBits.
++ */
++ VmaPoolCreateFlags flags;
++ /** \brief Size of a single `VkDeviceMemory` block to be allocated as part of this pool, in bytes. Optional.
++
++ Specify nonzero to set explicit, constant size of memory blocks used by this
++ pool.
++
++ Leave 0 to use default and let the library manage block sizes automatically.
++ Sizes of particular blocks may vary.
++ In this case, the pool will also support dedicated allocations.
++ */
++ VkDeviceSize blockSize;
++ /** \brief Minimum number of blocks to be always allocated in this pool, even if they stay empty.
++
++ Set to 0 to have no preallocated blocks and allow the pool be completely empty.
++ */
++ size_t minBlockCount;
++ /** \brief Maximum number of blocks that can be allocated in this pool. Optional.
++
++ Set to 0 to use default, which is `SIZE_MAX`, which means no limit.
++
++ Set to same value as VmaPoolCreateInfo::minBlockCount to have fixed amount of memory allocated
++ throughout whole lifetime of this pool.
++ */
++ size_t maxBlockCount;
++ /** \brief A floating-point value between 0 and 1, indicating the priority of the allocations in this pool relative to other memory allocations.
++
++ It is used only when #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT flag was used during creation of the #VmaAllocator object.
++ Otherwise, this variable is ignored.
++ */
++ float priority;
++ /** \brief Additional minimum alignment to be used for all allocations created from this pool. Can be 0.
++
++ Leave 0 (default) not to impose any additional alignment. If not 0, it must be a power of two.
++ It can be useful in cases where alignment returned by Vulkan by functions like `vkGetBufferMemoryRequirements` is not enough,
++ e.g. when doing interop with OpenGL.
++ */
++ VkDeviceSize minAllocationAlignment;
++ /** \brief Additional `pNext` chain to be attached to `VkMemoryAllocateInfo` used for every allocation made by this pool. Optional.
++
++ Optional, can be null. If not null, it must point to a `pNext` chain of structures that can be attached to `VkMemoryAllocateInfo`.
++ It can be useful for special needs such as adding `VkExportMemoryAllocateInfoKHR`.
++ Structures pointed by this member must remain alive and unchanged for the whole lifetime of the custom pool.
++
++ Please note that some structures, e.g. `VkMemoryPriorityAllocateInfoEXT`, `VkMemoryDedicatedAllocateInfoKHR`,
++ can be attached automatically by this library when using other, more convenient of its features.
++ */
++ void* VMA_NULLABLE pMemoryAllocateNext;
++} VmaPoolCreateInfo;
++
++/** @} */
++
++/**
++\addtogroup group_alloc
++@{
++*/
++
++/// Parameters of #VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo().
++typedef struct VmaAllocationInfo
++{
++ /** \brief Memory type index that this allocation was allocated from.
++
++ It never changes.
++ */
++ uint32_t memoryType;
++ /** \brief Handle to Vulkan memory object.
++
++ Same memory object can be shared by multiple allocations.
++
++ It can change after the allocation is moved during \ref defragmentation.
++ */
++ VkDeviceMemory VMA_NULLABLE_NON_DISPATCHABLE deviceMemory;
++ /** \brief Offset in `VkDeviceMemory` object to the beginning of this allocation, in bytes. `(deviceMemory, offset)` pair is unique to this allocation.
++
++ You usually don't need to use this offset. If you create a buffer or an image together with the allocation using e.g. function
++ vmaCreateBuffer(), vmaCreateImage(), functions that operate on these resources refer to the beginning of the buffer or image,
++ not entire device memory block. Functions like vmaMapMemory(), vmaBindBufferMemory() also refer to the beginning of the allocation
++ and apply this offset automatically.
++
++ It can change after the allocation is moved during \ref defragmentation.
++ */
++ VkDeviceSize offset;
++ /** \brief Size of this allocation, in bytes.
++
++ It never changes.
++
++ \note Allocation size returned in this variable may be greater than the size
++ requested for the resource e.g. as `VkBufferCreateInfo::size`. Whole size of the
++ allocation is accessible for operations on memory e.g. using a pointer after
++ mapping with vmaMapMemory(), but operations on the resource e.g. using
++ `vkCmdCopyBuffer` must be limited to the size of the resource.
++ */
++ VkDeviceSize size;
++ /** \brief Pointer to the beginning of this allocation as mapped data.
++
++ If the allocation hasn't been mapped using vmaMapMemory() and hasn't been
++ created with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag, this value is null.
++
++ It can change after call to vmaMapMemory(), vmaUnmapMemory().
++ It can also change after the allocation is moved during \ref defragmentation.
++ */
++ void* VMA_NULLABLE pMappedData;
++ /** \brief Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vmaSetAllocationUserData().
++
++ It can change after call to vmaSetAllocationUserData() for this allocation.
++ */
++ void* VMA_NULLABLE pUserData;
++ /** \brief Custom allocation name that was set with vmaSetAllocationName().
++
++ It can change after call to vmaSetAllocationName() for this allocation.
++
++ Another way to set custom name is to pass it in VmaAllocationCreateInfo::pUserData with
++ additional flag #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT set [DEPRECATED].
++ */
++ const char* VMA_NULLABLE pName;
++} VmaAllocationInfo;
++
++/** \brief Parameters for defragmentation.
++
++To be used with function vmaBeginDefragmentation().
++*/
++typedef struct VmaDefragmentationInfo
++{
++ /// \brief Use combination of #VmaDefragmentationFlagBits.
++ VmaDefragmentationFlags flags;
++ /** \brief Custom pool to be defragmented.
++
++ If null then default pools will undergo defragmentation process.
++ */
++ VmaPool VMA_NULLABLE pool;
++ /** \brief Maximum numbers of bytes that can be copied during single pass, while moving allocations to different places.
++
++ `0` means no limit.
++ */
++ VkDeviceSize maxBytesPerPass;
++ /** \brief Maximum number of allocations that can be moved during single pass to a different place.
++
++ `0` means no limit.
++ */
++ uint32_t maxAllocationsPerPass;
++} VmaDefragmentationInfo;
++
++/// Single move of an allocation to be done for defragmentation.
++typedef struct VmaDefragmentationMove
++{
++ /// Operation to be performed on the allocation by vmaEndDefragmentationPass(). Default value is #VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY. You can modify it.
++ VmaDefragmentationMoveOperation operation;
++ /// Allocation that should be moved.
++ VmaAllocation VMA_NOT_NULL srcAllocation;
++ /** \brief Temporary allocation pointing to destination memory that will replace `srcAllocation`.
++
++ \warning Do not store this allocation in your data structures! It exists only temporarily, for the duration of the defragmentation pass,
++ to be used for binding new buffer/image to the destination memory using e.g. vmaBindBufferMemory().
++ vmaEndDefragmentationPass() will destroy it and make `srcAllocation` point to this memory.
++ */
++ VmaAllocation VMA_NOT_NULL dstTmpAllocation;
++} VmaDefragmentationMove;
++
++/** \brief Parameters for incremental defragmentation steps.
++
++To be used with function vmaBeginDefragmentationPass().
++*/
++typedef struct VmaDefragmentationPassMoveInfo
++{
++ /// Number of elements in the `pMoves` array.
++ uint32_t moveCount;
++ /** \brief Array of moves to be performed by the user in the current defragmentation pass.
++
++ Pointer to an array of `moveCount` elements, owned by VMA, created in vmaBeginDefragmentationPass(), destroyed in vmaEndDefragmentationPass().
++
++ For each element, you should:
++
++ 1. Create a new buffer/image in the place pointed by VmaDefragmentationMove::dstMemory + VmaDefragmentationMove::dstOffset.
++ 2. Copy data from the VmaDefragmentationMove::srcAllocation e.g. using `vkCmdCopyBuffer`, `vkCmdCopyImage`.
++ 3. Make sure these commands finished executing on the GPU.
++ 4. Destroy the old buffer/image.
++
++ Only then you can finish defragmentation pass by calling vmaEndDefragmentationPass().
++ After this call, the allocation will point to the new place in memory.
++
++ Alternatively, if you cannot move specific allocation, you can set VmaDefragmentationMove::operation to #VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE.
++
++ Alternatively, if you decide you want to completely remove the allocation:
++
++ 1. Destroy its buffer/image.
++ 2. Set VmaDefragmentationMove::operation to #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY.
++
++ Then, after vmaEndDefragmentationPass() the allocation will be freed.
++ */
++ VmaDefragmentationMove* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(moveCount) pMoves;
++} VmaDefragmentationPassMoveInfo;
++
++/// Statistics returned for defragmentation process in function vmaEndDefragmentation().
++typedef struct VmaDefragmentationStats
++{
++ /// Total number of bytes that have been copied while moving allocations to different places.
++ VkDeviceSize bytesMoved;
++ /// Total number of bytes that have been released to the system by freeing empty `VkDeviceMemory` objects.
++ VkDeviceSize bytesFreed;
++ /// Number of allocations that have been moved to different places.
++ uint32_t allocationsMoved;
++ /// Number of empty `VkDeviceMemory` objects that have been released to the system.
++ uint32_t deviceMemoryBlocksFreed;
++} VmaDefragmentationStats;
++
++/** @} */
++
++/**
++\addtogroup group_virtual
++@{
++*/
++
++/// Parameters of created #VmaVirtualBlock object to be passed to vmaCreateVirtualBlock().
++typedef struct VmaVirtualBlockCreateInfo
++{
++ /** \brief Total size of the virtual block.
++
++ Sizes can be expressed in bytes or any units you want as long as you are consistent in using them.
++ For example, if you allocate from some array of structures, 1 can mean single instance of entire structure.
++ */
++ VkDeviceSize size;
++
++ /** \brief Use combination of #VmaVirtualBlockCreateFlagBits.
++ */
++ VmaVirtualBlockCreateFlags flags;
++
++ /** \brief Custom CPU memory allocation callbacks. Optional.
++
++ Optional, can be null. When specified, they will be used for all CPU-side memory allocations.
++ */
++ const VkAllocationCallbacks* VMA_NULLABLE pAllocationCallbacks;
++} VmaVirtualBlockCreateInfo;
++
++/// Parameters of created virtual allocation to be passed to vmaVirtualAllocate().
++typedef struct VmaVirtualAllocationCreateInfo
++{
++ /** \brief Size of the allocation.
++
++ Cannot be zero.
++ */
++ VkDeviceSize size;
++ /** \brief Required alignment of the allocation. Optional.
++
++ Must be power of two. Special value 0 has the same meaning as 1 - means no special alignment is required, so allocation can start at any offset.
++ */
++ VkDeviceSize alignment;
++ /** \brief Use combination of #VmaVirtualAllocationCreateFlagBits.
++ */
++ VmaVirtualAllocationCreateFlags flags;
++ /** \brief Custom pointer to be associated with the allocation. Optional.
++
++ It can be any value and can be used for user-defined purposes. It can be fetched or changed later.
++ */
++ void* VMA_NULLABLE pUserData;
++} VmaVirtualAllocationCreateInfo;
++
++/// Parameters of an existing virtual allocation, returned by vmaGetVirtualAllocationInfo().
++typedef struct VmaVirtualAllocationInfo
++{
++ /** \brief Offset of the allocation.
++
++ Offset at which the allocation was made.
++ */
++ VkDeviceSize offset;
++ /** \brief Size of the allocation.
++
++ Same value as passed in VmaVirtualAllocationCreateInfo::size.
++ */
++ VkDeviceSize size;
++ /** \brief Custom pointer associated with the allocation.
++
++ Same value as passed in VmaVirtualAllocationCreateInfo::pUserData or to vmaSetVirtualAllocationUserData().
++ */
++ void* VMA_NULLABLE pUserData;
++} VmaVirtualAllocationInfo;
++
++/** @} */
++
++#endif // _VMA_DATA_TYPES_DECLARATIONS
++
++#ifndef _VMA_FUNCTION_HEADERS
++
++/**
++\addtogroup group_init
++@{
++*/
++
++/// Creates #VmaAllocator object.
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator(
++ const VmaAllocatorCreateInfo* VMA_NOT_NULL pCreateInfo,
++ VmaAllocator VMA_NULLABLE* VMA_NOT_NULL pAllocator);
++
++/// Destroys allocator object.
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyAllocator(
++ VmaAllocator VMA_NULLABLE allocator);
++
++/** \brief Returns information about existing #VmaAllocator object - handle to Vulkan device etc.
++
++It might be useful if you want to keep just the #VmaAllocator handle and fetch other required handles to
++`VkPhysicalDevice`, `VkDevice` etc. every time using this function.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocatorInfo(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocatorInfo* VMA_NOT_NULL pAllocatorInfo);
++
++/**
++PhysicalDeviceProperties are fetched from physicalDevice by the allocator.
++You can access it here, without fetching it again on your own.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetPhysicalDeviceProperties(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VkPhysicalDeviceProperties* VMA_NULLABLE* VMA_NOT_NULL ppPhysicalDeviceProperties);
++
++/**
++PhysicalDeviceMemoryProperties are fetched from physicalDevice by the allocator.
++You can access it here, without fetching it again on your own.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryProperties(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VkPhysicalDeviceMemoryProperties* VMA_NULLABLE* VMA_NOT_NULL ppPhysicalDeviceMemoryProperties);
++
++/**
++\brief Given Memory Type Index, returns Property Flags of this memory type.
++
++This is just a convenience function. Same information can be obtained using
++vmaGetMemoryProperties().
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryTypeProperties(
++ VmaAllocator VMA_NOT_NULL allocator,
++ uint32_t memoryTypeIndex,
++ VkMemoryPropertyFlags* VMA_NOT_NULL pFlags);
++
++/** \brief Sets index of the current frame.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaSetCurrentFrameIndex(
++ VmaAllocator VMA_NOT_NULL allocator,
++ uint32_t frameIndex);
++
++/** @} */
++
++/**
++\addtogroup group_stats
++@{
++*/
++
++/** \brief Retrieves statistics from current state of the Allocator.
++
++This function is called "calculate" not "get" because it has to traverse all
++internal data structures, so it may be quite slow. Use it for debugging purposes.
++For faster but more brief statistics suitable to be called every frame or every allocation,
++use vmaGetHeapBudgets().
++
++Note that when using allocator from multiple threads, returned information may immediately
++become outdated.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStatistics(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaTotalStatistics* VMA_NOT_NULL pStats);
++
++/** \brief Retrieves information about current memory usage and budget for all memory heaps.
++
++\param allocator
++\param[out] pBudgets Must point to array with number of elements at least equal to number of memory heaps in physical device used.
++
++This function is called "get" not "calculate" because it is very fast, suitable to be called
++every frame or every allocation. For more detailed statistics use vmaCalculateStatistics().
++
++Note that when using allocator from multiple threads, returned information may immediately
++become outdated.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetHeapBudgets(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaBudget* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL("VkPhysicalDeviceMemoryProperties::memoryHeapCount") pBudgets);
++
++/** @} */
++
++/**
++\addtogroup group_alloc
++@{
++*/
++
++/**
++\brief Helps to find memoryTypeIndex, given memoryTypeBits and VmaAllocationCreateInfo.
++
++This algorithm tries to find a memory type that:
++
++- Is allowed by memoryTypeBits.
++- Contains all the flags from pAllocationCreateInfo->requiredFlags.
++- Matches intended usage.
++- Has as many flags from pAllocationCreateInfo->preferredFlags as possible.
++
++\return Returns VK_ERROR_FEATURE_NOT_PRESENT if not found. Receiving such result
++from this function or any other allocating function probably means that your
++device doesn't support any memory type with requested features for the specific
++type of resource you want to use it for. Please check parameters of your
++resource, like image layout (OPTIMAL versus LINEAR) or mip level count.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndex(
++ VmaAllocator VMA_NOT_NULL allocator,
++ uint32_t memoryTypeBits,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo,
++ uint32_t* VMA_NOT_NULL pMemoryTypeIndex);
++
++/**
++\brief Helps to find memoryTypeIndex, given VkBufferCreateInfo and VmaAllocationCreateInfo.
++
++It can be useful e.g. to determine value to be used as VmaPoolCreateInfo::memoryTypeIndex.
++It internally creates a temporary, dummy buffer that never has memory bound.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo,
++ uint32_t* VMA_NOT_NULL pMemoryTypeIndex);
++
++/**
++\brief Helps to find memoryTypeIndex, given VkImageCreateInfo and VmaAllocationCreateInfo.
++
++It can be useful e.g. to determine value to be used as VmaPoolCreateInfo::memoryTypeIndex.
++It internally creates a temporary, dummy image that never has memory bound.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo,
++ uint32_t* VMA_NOT_NULL pMemoryTypeIndex);
++
++/** \brief Allocates Vulkan device memory and creates #VmaPool object.
++
++\param allocator Allocator object.
++\param pCreateInfo Parameters of pool to create.
++\param[out] pPool Handle to created pool.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreatePool(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VmaPoolCreateInfo* VMA_NOT_NULL pCreateInfo,
++ VmaPool VMA_NULLABLE* VMA_NOT_NULL pPool);
++
++/** \brief Destroys #VmaPool object and frees Vulkan device memory.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyPool(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaPool VMA_NULLABLE pool);
++
++/** @} */
++
++/**
++\addtogroup group_stats
++@{
++*/
++
++/** \brief Retrieves statistics of existing #VmaPool object.
++
++\param allocator Allocator object.
++\param pool Pool object.
++\param[out] pPoolStats Statistics of specified pool.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStatistics(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaPool VMA_NOT_NULL pool,
++ VmaStatistics* VMA_NOT_NULL pPoolStats);
++
++/** \brief Retrieves detailed statistics of existing #VmaPool object.
++
++\param allocator Allocator object.
++\param pool Pool object.
++\param[out] pPoolStats Statistics of specified pool.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaCalculatePoolStatistics(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaPool VMA_NOT_NULL pool,
++ VmaDetailedStatistics* VMA_NOT_NULL pPoolStats);
++
++/** @} */
++
++/**
++\addtogroup group_alloc
++@{
++*/
++
++/** \brief Checks magic number in margins around all allocations in given memory pool in search for corruptions.
++
++Corruption detection is enabled only when `VMA_DEBUG_DETECT_CORRUPTION` macro is defined to nonzero,
++`VMA_DEBUG_MARGIN` is defined to nonzero and the pool is created in memory type that is
++`HOST_VISIBLE` and `HOST_COHERENT`. For more information, see [Corruption detection](@ref debugging_memory_usage_corruption_detection).
++
++Possible return values:
++
++- `VK_ERROR_FEATURE_NOT_PRESENT` - corruption detection is not enabled for specified pool.
++- `VK_SUCCESS` - corruption detection has been performed and succeeded.
++- `VK_ERROR_UNKNOWN` - corruption detection has been performed and found memory corruptions around one of the allocations.
++ `VMA_ASSERT` is also fired in that case.
++- Other value: Error returned by Vulkan, e.g. memory mapping failure.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckPoolCorruption(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaPool VMA_NOT_NULL pool);
++
++/** \brief Retrieves name of a custom pool.
++
++After the call `ppName` is either null or points to an internally-owned null-terminated string
++containing name of the pool that was previously set. The pointer becomes invalid when the pool is
++destroyed or its name is changed using vmaSetPoolName().
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolName(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaPool VMA_NOT_NULL pool,
++ const char* VMA_NULLABLE* VMA_NOT_NULL ppName);
++
++/** \brief Sets name of a custom pool.
++
++`pName` can be either null or pointer to a null-terminated string with new name for the pool.
++Function makes internal copy of the string, so it can be changed or freed immediately after this call.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaPool VMA_NOT_NULL pool,
++ const char* VMA_NULLABLE pName);
++
++/** \brief General purpose memory allocation.
++
++\param allocator
++\param pVkMemoryRequirements
++\param pCreateInfo
++\param[out] pAllocation Handle to allocated memory.
++\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
++
++You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages().
++
++It is recommended to use vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(),
++vmaCreateBuffer(), vmaCreateImage() instead whenever possible.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VkMemoryRequirements* VMA_NOT_NULL pVkMemoryRequirements,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo,
++ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
++ VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
++
++/** \brief General purpose memory allocation for multiple allocation objects at once.
++
++\param allocator Allocator object.
++\param pVkMemoryRequirements Memory requirements for each allocation.
++\param pCreateInfo Creation parameters for each allocation.
++\param allocationCount Number of allocations to make.
++\param[out] pAllocations Pointer to array that will be filled with handles to created allocations.
++\param[out] pAllocationInfo Optional. Pointer to array that will be filled with parameters of created allocations.
++
++You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages().
++
++Word "pages" is just a suggestion to use this function to allocate pieces of memory needed for sparse binding.
++It is just a general purpose allocation function able to make multiple allocations at once.
++It may be internally optimized to be more efficient than calling vmaAllocateMemory() `allocationCount` times.
++
++All allocations are made using same parameters. All of them are created out of the same memory pool and type.
++If any allocation fails, all allocations already made within this function call are also freed, so that when
++returned result is not `VK_SUCCESS`, `pAllocation` array is always entirely filled with `VK_NULL_HANDLE`.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryPages(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VkMemoryRequirements* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pVkMemoryRequirements,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pCreateInfo,
++ size_t allocationCount,
++ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations,
++ VmaAllocationInfo* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationInfo);
++
++/** \brief Allocates memory suitable for given `VkBuffer`.
++
++\param allocator
++\param buffer
++\param pCreateInfo
++\param[out] pAllocation Handle to allocated memory.
++\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
++
++It only creates #VmaAllocation. To bind the memory to the buffer, use vmaBindBufferMemory().
++
++This is a special-purpose function. In most cases you should use vmaCreateBuffer().
++
++You must free the allocation using vmaFreeMemory() when no longer needed.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForBuffer(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VkBuffer VMA_NOT_NULL_NON_DISPATCHABLE buffer,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo,
++ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
++ VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
++
++/** \brief Allocates memory suitable for given `VkImage`.
++
++\param allocator
++\param image
++\param pCreateInfo
++\param[out] pAllocation Handle to allocated memory.
++\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
++
++It only creates #VmaAllocation. To bind the memory to the buffer, use vmaBindImageMemory().
++
++This is a special-purpose function. In most cases you should use vmaCreateImage().
++
++You must free the allocation using vmaFreeMemory() when no longer needed.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForImage(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VkImage VMA_NOT_NULL_NON_DISPATCHABLE image,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo,
++ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
++ VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
++
++/** \brief Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage().
++
++Passing `VK_NULL_HANDLE` as `allocation` is valid. Such function call is just skipped.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemory(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VmaAllocation VMA_NULLABLE allocation);
++
++/** \brief Frees memory and destroys multiple allocations.
++
++Word "pages" is just a suggestion to use this function to free pieces of memory used for sparse binding.
++It is just a general purpose function to free memory and destroy allocations made using e.g. vmaAllocateMemory(),
++vmaAllocateMemoryPages() and other functions.
++It may be internally optimized to be more efficient than calling vmaFreeMemory() `allocationCount` times.
++
++Allocations in `pAllocations` array can come from any memory pools and types.
++Passing `VK_NULL_HANDLE` as elements of `pAllocations` array is valid. Such entries are just skipped.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemoryPages(
++ VmaAllocator VMA_NOT_NULL allocator,
++ size_t allocationCount,
++ const VmaAllocation VMA_NULLABLE* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations);
++
++/** \brief Returns current information about specified allocation.
++
++Current paramteres of given allocation are returned in `pAllocationInfo`.
++
++Although this function doesn't lock any mutex, so it should be quite efficient,
++you should avoid calling it too often.
++You can retrieve same VmaAllocationInfo structure while creating your resource, from function
++vmaCreateBuffer(), vmaCreateImage(). You can remember it if you are sure parameters don't change
++(e.g. due to defragmentation).
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationInfo(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ VmaAllocationInfo* VMA_NOT_NULL pAllocationInfo);
++
++/** \brief Sets pUserData in given allocation to new value.
++
++The value of pointer `pUserData` is copied to allocation's `pUserData`.
++It is opaque, so you can use it however you want - e.g.
++as a pointer, ordinal number or some handle to you own data.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationUserData(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ void* VMA_NULLABLE pUserData);
++
++/** \brief Sets pName in given allocation to new value.
++
++`pName` must be either null, or pointer to a null-terminated string. The function
++makes local copy of the string and sets it as allocation's `pName`. String
++passed as pName doesn't need to be valid for whole lifetime of the allocation -
++you can free it after this call. String previously pointed by allocation's
++`pName` is freed from memory.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationName(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ const char* VMA_NULLABLE pName);
++
++/**
++\brief Given an allocation, returns Property Flags of its memory type.
++
++This is just a convenience function. Same information can be obtained using
++vmaGetAllocationInfo() + vmaGetMemoryProperties().
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationMemoryProperties(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ VkMemoryPropertyFlags* VMA_NOT_NULL pFlags);
++
++/** \brief Maps memory represented by given allocation and returns pointer to it.
++
++Maps memory represented by given allocation to make it accessible to CPU code.
++When succeeded, `*ppData` contains pointer to first byte of this memory.
++
++\warning
++If the allocation is part of a bigger `VkDeviceMemory` block, returned pointer is
++correctly offsetted to the beginning of region assigned to this particular allocation.
++Unlike the result of `vkMapMemory`, it points to the allocation, not to the beginning of the whole block.
++You should not add VmaAllocationInfo::offset to it!
++
++Mapping is internally reference-counted and synchronized, so despite raw Vulkan
++function `vkMapMemory()` cannot be used to map same block of `VkDeviceMemory`
++multiple times simultaneously, it is safe to call this function on allocations
++assigned to the same memory block. Actual Vulkan memory will be mapped on first
++mapping and unmapped on last unmapping.
++
++If the function succeeded, you must call vmaUnmapMemory() to unmap the
++allocation when mapping is no longer needed or before freeing the allocation, at
++the latest.
++
++It also safe to call this function multiple times on the same allocation. You
++must call vmaUnmapMemory() same number of times as you called vmaMapMemory().
++
++It is also safe to call this function on allocation created with
++#VMA_ALLOCATION_CREATE_MAPPED_BIT flag. Its memory stays mapped all the time.
++You must still call vmaUnmapMemory() same number of times as you called
++vmaMapMemory(). You must not call vmaUnmapMemory() additional time to free the
++"0-th" mapping made automatically due to #VMA_ALLOCATION_CREATE_MAPPED_BIT flag.
++
++This function fails when used on allocation made in memory type that is not
++`HOST_VISIBLE`.
++
++This function doesn't automatically flush or invalidate caches.
++If the allocation is made from a memory types that is not `HOST_COHERENT`,
++you also need to use vmaInvalidateAllocation() / vmaFlushAllocation(), as required by Vulkan specification.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaMapMemory(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ void* VMA_NULLABLE* VMA_NOT_NULL ppData);
++
++/** \brief Unmaps memory represented by given allocation, mapped previously using vmaMapMemory().
++
++For details, see description of vmaMapMemory().
++
++This function doesn't automatically flush or invalidate caches.
++If the allocation is made from a memory types that is not `HOST_COHERENT`,
++you also need to use vmaInvalidateAllocation() / vmaFlushAllocation(), as required by Vulkan specification.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaUnmapMemory(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation);
++
++/** \brief Flushes memory of given allocation.
++
++Calls `vkFlushMappedMemoryRanges()` for memory associated with given range of given allocation.
++It needs to be called after writing to a mapped memory for memory types that are not `HOST_COHERENT`.
++Unmap operation doesn't do that automatically.
++
++- `offset` must be relative to the beginning of allocation.
++- `size` can be `VK_WHOLE_SIZE`. It means all memory from `offset` the the end of given allocation.
++- `offset` and `size` don't have to be aligned.
++ They are internally rounded down/up to multiply of `nonCoherentAtomSize`.
++- If `size` is 0, this call is ignored.
++- If memory type that the `allocation` belongs to is not `HOST_VISIBLE` or it is `HOST_COHERENT`,
++ this call is ignored.
++
++Warning! `offset` and `size` are relative to the contents of given `allocation`.
++If you mean whole allocation, you can pass 0 and `VK_WHOLE_SIZE`, respectively.
++Do not pass allocation's offset as `offset`!!!
++
++This function returns the `VkResult` from `vkFlushMappedMemoryRanges` if it is
++called, otherwise `VK_SUCCESS`.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocation(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ VkDeviceSize offset,
++ VkDeviceSize size);
++
++/** \brief Invalidates memory of given allocation.
++
++Calls `vkInvalidateMappedMemoryRanges()` for memory associated with given range of given allocation.
++It needs to be called before reading from a mapped memory for memory types that are not `HOST_COHERENT`.
++Map operation doesn't do that automatically.
++
++- `offset` must be relative to the beginning of allocation.
++- `size` can be `VK_WHOLE_SIZE`. It means all memory from `offset` the the end of given allocation.
++- `offset` and `size` don't have to be aligned.
++ They are internally rounded down/up to multiply of `nonCoherentAtomSize`.
++- If `size` is 0, this call is ignored.
++- If memory type that the `allocation` belongs to is not `HOST_VISIBLE` or it is `HOST_COHERENT`,
++ this call is ignored.
++
++Warning! `offset` and `size` are relative to the contents of given `allocation`.
++If you mean whole allocation, you can pass 0 and `VK_WHOLE_SIZE`, respectively.
++Do not pass allocation's offset as `offset`!!!
++
++This function returns the `VkResult` from `vkInvalidateMappedMemoryRanges` if
++it is called, otherwise `VK_SUCCESS`.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocation(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ VkDeviceSize offset,
++ VkDeviceSize size);
++
++/** \brief Flushes memory of given set of allocations.
++
++Calls `vkFlushMappedMemoryRanges()` for memory associated with given ranges of given allocations.
++For more information, see documentation of vmaFlushAllocation().
++
++\param allocator
++\param allocationCount
++\param allocations
++\param offsets If not null, it must point to an array of offsets of regions to flush, relative to the beginning of respective allocations. Null means all ofsets are zero.
++\param sizes If not null, it must point to an array of sizes of regions to flush in respective allocations. Null means `VK_WHOLE_SIZE` for all allocations.
++
++This function returns the `VkResult` from `vkFlushMappedMemoryRanges` if it is
++called, otherwise `VK_SUCCESS`.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocations(
++ VmaAllocator VMA_NOT_NULL allocator,
++ uint32_t allocationCount,
++ const VmaAllocation VMA_NOT_NULL* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) allocations,
++ const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) offsets,
++ const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) sizes);
++
++/** \brief Invalidates memory of given set of allocations.
++
++Calls `vkInvalidateMappedMemoryRanges()` for memory associated with given ranges of given allocations.
++For more information, see documentation of vmaInvalidateAllocation().
++
++\param allocator
++\param allocationCount
++\param allocations
++\param offsets If not null, it must point to an array of offsets of regions to flush, relative to the beginning of respective allocations. Null means all ofsets are zero.
++\param sizes If not null, it must point to an array of sizes of regions to flush in respective allocations. Null means `VK_WHOLE_SIZE` for all allocations.
++
++This function returns the `VkResult` from `vkInvalidateMappedMemoryRanges` if it is
++called, otherwise `VK_SUCCESS`.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocations(
++ VmaAllocator VMA_NOT_NULL allocator,
++ uint32_t allocationCount,
++ const VmaAllocation VMA_NOT_NULL* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) allocations,
++ const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) offsets,
++ const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) sizes);
++
++/** \brief Checks magic number in margins around all allocations in given memory types (in both default and custom pools) in search for corruptions.
++
++\param allocator
++\param memoryTypeBits Bit mask, where each bit set means that a memory type with that index should be checked.
++
++Corruption detection is enabled only when `VMA_DEBUG_DETECT_CORRUPTION` macro is defined to nonzero,
++`VMA_DEBUG_MARGIN` is defined to nonzero and only for memory types that are
++`HOST_VISIBLE` and `HOST_COHERENT`. For more information, see [Corruption detection](@ref debugging_memory_usage_corruption_detection).
++
++Possible return values:
++
++- `VK_ERROR_FEATURE_NOT_PRESENT` - corruption detection is not enabled for any of specified memory types.
++- `VK_SUCCESS` - corruption detection has been performed and succeeded.
++- `VK_ERROR_UNKNOWN` - corruption detection has been performed and found memory corruptions around one of the allocations.
++ `VMA_ASSERT` is also fired in that case.
++- Other value: Error returned by Vulkan, e.g. memory mapping failure.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption(
++ VmaAllocator VMA_NOT_NULL allocator,
++ uint32_t memoryTypeBits);
++
++/** \brief Begins defragmentation process.
++
++\param allocator Allocator object.
++\param pInfo Structure filled with parameters of defragmentation.
++\param[out] pContext Context object that must be passed to vmaEndDefragmentation() to finish defragmentation.
++\returns
++- `VK_SUCCESS` if defragmentation can begin.
++- `VK_ERROR_FEATURE_NOT_PRESENT` if defragmentation is not supported.
++
++For more information about defragmentation, see documentation chapter:
++[Defragmentation](@ref defragmentation).
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentation(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VmaDefragmentationInfo* VMA_NOT_NULL pInfo,
++ VmaDefragmentationContext VMA_NULLABLE* VMA_NOT_NULL pContext);
++
++/** \brief Ends defragmentation process.
++
++\param allocator Allocator object.
++\param context Context object that has been created by vmaBeginDefragmentation().
++\param[out] pStats Optional stats for the defragmentation. Can be null.
++
++Use this function to finish defragmentation started by vmaBeginDefragmentation().
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaEndDefragmentation(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaDefragmentationContext VMA_NOT_NULL context,
++ VmaDefragmentationStats* VMA_NULLABLE pStats);
++
++/** \brief Starts single defragmentation pass.
++
++\param allocator Allocator object.
++\param context Context object that has been created by vmaBeginDefragmentation().
++\param[out] pPassInfo Computed informations for current pass.
++\returns
++- `VK_SUCCESS` if no more moves are possible. Then you can omit call to vmaEndDefragmentationPass() and simply end whole defragmentation.
++- `VK_INCOMPLETE` if there are pending moves returned in `pPassInfo`. You need to perform them, call vmaEndDefragmentationPass(),
++ and then preferably try another pass with vmaBeginDefragmentationPass().
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentationPass(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaDefragmentationContext VMA_NOT_NULL context,
++ VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo);
++
++/** \brief Ends single defragmentation pass.
++
++\param allocator Allocator object.
++\param context Context object that has been created by vmaBeginDefragmentation().
++\param pPassInfo Computed informations for current pass filled by vmaBeginDefragmentationPass() and possibly modified by you.
++
++Returns `VK_SUCCESS` if no more moves are possible or `VK_INCOMPLETE` if more defragmentations are possible.
++
++Ends incremental defragmentation pass and commits all defragmentation moves from `pPassInfo`.
++After this call:
++
++- Allocations at `pPassInfo[i].srcAllocation` that had `pPassInfo[i].operation ==` #VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY
++ (which is the default) will be pointing to the new destination place.
++- Allocation at `pPassInfo[i].srcAllocation` that had `pPassInfo[i].operation ==` #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY
++ will be freed.
++
++If no more moves are possible you can end whole defragmentation.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentationPass(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaDefragmentationContext VMA_NOT_NULL context,
++ VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo);
++
++/** \brief Binds buffer to allocation.
++
++Binds specified buffer to region of memory represented by specified allocation.
++Gets `VkDeviceMemory` handle and offset from the allocation.
++If you want to create a buffer, allocate memory for it and bind them together separately,
++you should use this function for binding instead of standard `vkBindBufferMemory()`,
++because it ensures proper synchronization so that when a `VkDeviceMemory` object is used by multiple
++allocations, calls to `vkBind*Memory()` or `vkMapMemory()` won't happen from multiple threads simultaneously
++(which is illegal in Vulkan).
++
++It is recommended to use function vmaCreateBuffer() instead of this one.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ VkBuffer VMA_NOT_NULL_NON_DISPATCHABLE buffer);
++
++/** \brief Binds buffer to allocation with additional parameters.
++
++\param allocator
++\param allocation
++\param allocationLocalOffset Additional offset to be added while binding, relative to the beginning of the `allocation`. Normally it should be 0.
++\param buffer
++\param pNext A chain of structures to be attached to `VkBindBufferMemoryInfoKHR` structure used internally. Normally it should be null.
++
++This function is similar to vmaBindBufferMemory(), but it provides additional parameters.
++
++If `pNext` is not null, #VmaAllocator object must have been created with #VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT flag
++or with VmaAllocatorCreateInfo::vulkanApiVersion `>= VK_API_VERSION_1_1`. Otherwise the call fails.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory2(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ VkDeviceSize allocationLocalOffset,
++ VkBuffer VMA_NOT_NULL_NON_DISPATCHABLE buffer,
++ const void* VMA_NULLABLE pNext);
++
++/** \brief Binds image to allocation.
++
++Binds specified image to region of memory represented by specified allocation.
++Gets `VkDeviceMemory` handle and offset from the allocation.
++If you want to create an image, allocate memory for it and bind them together separately,
++you should use this function for binding instead of standard `vkBindImageMemory()`,
++because it ensures proper synchronization so that when a `VkDeviceMemory` object is used by multiple
++allocations, calls to `vkBind*Memory()` or `vkMapMemory()` won't happen from multiple threads simultaneously
++(which is illegal in Vulkan).
++
++It is recommended to use function vmaCreateImage() instead of this one.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ VkImage VMA_NOT_NULL_NON_DISPATCHABLE image);
++
++/** \brief Binds image to allocation with additional parameters.
++
++\param allocator
++\param allocation
++\param allocationLocalOffset Additional offset to be added while binding, relative to the beginning of the `allocation`. Normally it should be 0.
++\param image
++\param pNext A chain of structures to be attached to `VkBindImageMemoryInfoKHR` structure used internally. Normally it should be null.
++
++This function is similar to vmaBindImageMemory(), but it provides additional parameters.
++
++If `pNext` is not null, #VmaAllocator object must have been created with #VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT flag
++or with VmaAllocatorCreateInfo::vulkanApiVersion `>= VK_API_VERSION_1_1`. Otherwise the call fails.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory2(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ VkDeviceSize allocationLocalOffset,
++ VkImage VMA_NOT_NULL_NON_DISPATCHABLE image,
++ const void* VMA_NULLABLE pNext);
++
++/** \brief Creates a new `VkBuffer`, allocates and binds memory for it.
++
++\param allocator
++\param pBufferCreateInfo
++\param pAllocationCreateInfo
++\param[out] pBuffer Buffer that was created.
++\param[out] pAllocation Allocation that was created.
++\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
++
++This function automatically:
++
++-# Creates buffer.
++-# Allocates appropriate memory for it.
++-# Binds the buffer with the memory.
++
++If any of these operations fail, buffer and allocation are not created,
++returned value is negative error code, `*pBuffer` and `*pAllocation` are null.
++
++If the function succeeded, you must destroy both buffer and allocation when you
++no longer need them using either convenience function vmaDestroyBuffer() or
++separately, using `vkDestroyBuffer()` and vmaFreeMemory().
++
++If #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag was used,
++VK_KHR_dedicated_allocation extension is used internally to query driver whether
++it requires or prefers the new buffer to have dedicated allocation. If yes,
++and if dedicated allocation is possible
++(#VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT is not used), it creates dedicated
++allocation for this buffer, just like when using
++#VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
++
++\note This function creates a new `VkBuffer`. Sub-allocation of parts of one large buffer,
++although recommended as a good practice, is out of scope of this library and could be implemented
++by the user as a higher-level logic on top of VMA.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBuffer(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo,
++ VkBuffer VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pBuffer,
++ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
++ VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
++
++/** \brief Creates a buffer with additional minimum alignment.
++
++Similar to vmaCreateBuffer() but provides additional parameter `minAlignment` which allows to specify custom,
++minimum alignment to be used when placing the buffer inside a larger memory block, which may be needed e.g.
++for interop with OpenGL.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo,
++ VkDeviceSize minAlignment,
++ VkBuffer VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pBuffer,
++ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
++ VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
++
++/** \brief Creates a new `VkBuffer`, binds already created memory for it.
++
++\param allocator
++\param allocation Allocation that provides memory to be used for binding new buffer to it.
++\param pBufferCreateInfo
++\param[out] pBuffer Buffer that was created.
++
++This function automatically:
++
++-# Creates buffer.
++-# Binds the buffer with the supplied memory.
++
++If any of these operations fail, buffer is not created,
++returned value is negative error code and `*pBuffer` is null.
++
++If the function succeeded, you must destroy the buffer when you
++no longer need it using `vkDestroyBuffer()`. If you want to also destroy the corresponding
++allocation you can use convenience function vmaDestroyBuffer().
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingBuffer(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo,
++ VkBuffer VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pBuffer);
++
++/** \brief Destroys Vulkan buffer and frees allocated memory.
++
++This is just a convenience function equivalent to:
++
++\code
++vkDestroyBuffer(device, buffer, allocationCallbacks);
++vmaFreeMemory(allocator, allocation);
++\endcode
++
++It it safe to pass null as buffer and/or allocation.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyBuffer(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VkBuffer VMA_NULLABLE_NON_DISPATCHABLE buffer,
++ VmaAllocation VMA_NULLABLE allocation);
++
++/// Function similar to vmaCreateBuffer().
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage(
++ VmaAllocator VMA_NOT_NULL allocator,
++ const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo,
++ const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo,
++ VkImage VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pImage,
++ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
++ VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
++
++/// Function similar to vmaCreateAliasingBuffer().
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingImage(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo,
++ VkImage VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pImage);
++
++/** \brief Destroys Vulkan image and frees allocated memory.
++
++This is just a convenience function equivalent to:
++
++\code
++vkDestroyImage(device, image, allocationCallbacks);
++vmaFreeMemory(allocator, allocation);
++\endcode
++
++It it safe to pass null as image and/or allocation.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyImage(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VkImage VMA_NULLABLE_NON_DISPATCHABLE image,
++ VmaAllocation VMA_NULLABLE allocation);
++
++/** @} */
++
++/**
++\addtogroup group_virtual
++@{
++*/
++
++/** \brief Creates new #VmaVirtualBlock object.
++
++\param pCreateInfo Parameters for creation.
++\param[out] pVirtualBlock Returned virtual block object or `VMA_NULL` if creation failed.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateVirtualBlock(
++ const VmaVirtualBlockCreateInfo* VMA_NOT_NULL pCreateInfo,
++ VmaVirtualBlock VMA_NULLABLE* VMA_NOT_NULL pVirtualBlock);
++
++/** \brief Destroys #VmaVirtualBlock object.
++
++Please note that you should consciously handle virtual allocations that could remain unfreed in the block.
++You should either free them individually using vmaVirtualFree() or call vmaClearVirtualBlock()
++if you are sure this is what you want. If you do neither, an assert is called.
++
++If you keep pointers to some additional metadata associated with your virtual allocations in their `pUserData`,
++don't forget to free them.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyVirtualBlock(
++ VmaVirtualBlock VMA_NULLABLE virtualBlock);
++
++/** \brief Returns true of the #VmaVirtualBlock is empty - contains 0 virtual allocations and has all its space available for new allocations.
++*/
++VMA_CALL_PRE VkBool32 VMA_CALL_POST vmaIsVirtualBlockEmpty(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock);
++
++/** \brief Returns information about a specific virtual allocation within a virtual block, like its size and `pUserData` pointer.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetVirtualAllocationInfo(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ VmaVirtualAllocation VMA_NOT_NULL_NON_DISPATCHABLE allocation, VmaVirtualAllocationInfo* VMA_NOT_NULL pVirtualAllocInfo);
++
++/** \brief Allocates new virtual allocation inside given #VmaVirtualBlock.
++
++If the allocation fails due to not enough free space available, `VK_ERROR_OUT_OF_DEVICE_MEMORY` is returned
++(despite the function doesn't ever allocate actual GPU memory).
++`pAllocation` is then set to `VK_NULL_HANDLE` and `pOffset`, if not null, it set to `UINT64_MAX`.
++
++\param virtualBlock Virtual block
++\param pCreateInfo Parameters for the allocation
++\param[out] pAllocation Returned handle of the new allocation
++\param[out] pOffset Returned offset of the new allocation. Optional, can be null.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaVirtualAllocate(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ const VmaVirtualAllocationCreateInfo* VMA_NOT_NULL pCreateInfo,
++ VmaVirtualAllocation VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pAllocation,
++ VkDeviceSize* VMA_NULLABLE pOffset);
++
++/** \brief Frees virtual allocation inside given #VmaVirtualBlock.
++
++It is correct to call this function with `allocation == VK_NULL_HANDLE` - it does nothing.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaVirtualFree(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ VmaVirtualAllocation VMA_NULLABLE_NON_DISPATCHABLE allocation);
++
++/** \brief Frees all virtual allocations inside given #VmaVirtualBlock.
++
++You must either call this function or free each virtual allocation individually with vmaVirtualFree()
++before destroying a virtual block. Otherwise, an assert is called.
++
++If you keep pointer to some additional metadata associated with your virtual allocation in its `pUserData`,
++don't forget to free it as well.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaClearVirtualBlock(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock);
++
++/** \brief Changes custom pointer associated with given virtual allocation.
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaSetVirtualAllocationUserData(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ VmaVirtualAllocation VMA_NOT_NULL_NON_DISPATCHABLE allocation,
++ void* VMA_NULLABLE pUserData);
++
++/** \brief Calculates and returns statistics about virtual allocations and memory usage in given #VmaVirtualBlock.
++
++This function is fast to call. For more detailed statistics, see vmaCalculateVirtualBlockStatistics().
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaGetVirtualBlockStatistics(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ VmaStatistics* VMA_NOT_NULL pStats);
++
++/** \brief Calculates and returns detailed statistics about virtual allocations and memory usage in given #VmaVirtualBlock.
++
++This function is slow to call. Use for debugging purposes.
++For less detailed statistics, see vmaGetVirtualBlockStatistics().
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaCalculateVirtualBlockStatistics(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ VmaDetailedStatistics* VMA_NOT_NULL pStats);
++
++/** @} */
++
++#if VMA_STATS_STRING_ENABLED
++/**
++\addtogroup group_stats
++@{
++*/
++
++/** \brief Builds and returns a null-terminated string in JSON format with information about given #VmaVirtualBlock.
++\param virtualBlock Virtual block.
++\param[out] ppStatsString Returned string.
++\param detailedMap Pass `VK_FALSE` to only obtain statistics as returned by vmaCalculateVirtualBlockStatistics(). Pass `VK_TRUE` to also obtain full list of allocations and free spaces.
++
++Returned string must be freed using vmaFreeVirtualBlockStatsString().
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaBuildVirtualBlockStatsString(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ char* VMA_NULLABLE* VMA_NOT_NULL ppStatsString,
++ VkBool32 detailedMap);
++
++/// Frees a string returned by vmaBuildVirtualBlockStatsString().
++VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString(
++ VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ char* VMA_NULLABLE pStatsString);
++
++/** \brief Builds and returns statistics as a null-terminated string in JSON format.
++\param allocator
++\param[out] ppStatsString Must be freed using vmaFreeStatsString() function.
++\param detailedMap
++*/
++VMA_CALL_PRE void VMA_CALL_POST vmaBuildStatsString(
++ VmaAllocator VMA_NOT_NULL allocator,
++ char* VMA_NULLABLE* VMA_NOT_NULL ppStatsString,
++ VkBool32 detailedMap);
++
++VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString(
++ VmaAllocator VMA_NOT_NULL allocator,
++ char* VMA_NULLABLE pStatsString);
++
++/** @} */
++
++#endif // VMA_STATS_STRING_ENABLED
++
++#endif // _VMA_FUNCTION_HEADERS
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif // AMD_VULKAN_MEMORY_ALLOCATOR_H
++
++////////////////////////////////////////////////////////////////////////////////
++////////////////////////////////////////////////////////////////////////////////
++//
++// IMPLEMENTATION
++//
++////////////////////////////////////////////////////////////////////////////////
++////////////////////////////////////////////////////////////////////////////////
++
++// For Visual Studio IntelliSense.
++#if defined(__cplusplus) && defined(__INTELLISENSE__)
++#define VMA_IMPLEMENTATION
++#endif
++
++#ifdef VMA_IMPLEMENTATION
++#undef VMA_IMPLEMENTATION
++
++#include <cstdint>
++#include <cstdlib>
++#include <cstring>
++#include <utility>
++#include <type_traits>
++
++#ifdef _MSC_VER
++ #include <intrin.h> // For functions like __popcnt, _BitScanForward etc.
++#endif
++#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L // C++20
++ #include <bit> // For std::popcount
++#endif
++
++/*******************************************************************************
++CONFIGURATION SECTION
++
++Define some of these macros before each #include of this header or change them
++here if you need other then default behavior depending on your environment.
++*/
++#ifndef _VMA_CONFIGURATION
++
++/*
++Define this macro to 1 to make the library fetch pointers to Vulkan functions
++internally, like:
++
++ vulkanFunctions.vkAllocateMemory = &vkAllocateMemory;
++*/
++#if !defined(VMA_STATIC_VULKAN_FUNCTIONS) && !defined(VK_NO_PROTOTYPES)
++ #define VMA_STATIC_VULKAN_FUNCTIONS 1
++#endif
++
++/*
++Define this macro to 1 to make the library fetch pointers to Vulkan functions
++internally, like:
++
++ vulkanFunctions.vkAllocateMemory = (PFN_vkAllocateMemory)vkGetDeviceProcAddr(device, "vkAllocateMemory");
++
++To use this feature in new versions of VMA you now have to pass
++VmaVulkanFunctions::vkGetInstanceProcAddr and vkGetDeviceProcAddr as
++VmaAllocatorCreateInfo::pVulkanFunctions. Other members can be null.
++*/
++#if !defined(VMA_DYNAMIC_VULKAN_FUNCTIONS)
++ #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
++#endif
++
++#ifndef VMA_USE_STL_SHARED_MUTEX
++ // Compiler conforms to C++17.
++ #if __cplusplus >= 201703L
++ #define VMA_USE_STL_SHARED_MUTEX 1
++ // Visual studio defines __cplusplus properly only when passed additional parameter: /Zc:__cplusplus
++ // Otherwise it is always 199711L, despite shared_mutex works since Visual Studio 2015 Update 2.
++ #elif defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023918 && __cplusplus == 199711L && _MSVC_LANG >= 201703L
++ #define VMA_USE_STL_SHARED_MUTEX 1
++ #else
++ #define VMA_USE_STL_SHARED_MUTEX 0
++ #endif
++#endif
++
++/*
++Define this macro to include custom header files without having to edit this file directly, e.g.:
++
++ // Inside of "my_vma_configuration_user_includes.h":
++
++ #include "my_custom_assert.h" // for MY_CUSTOM_ASSERT
++ #include "my_custom_min.h" // for my_custom_min
++ #include <algorithm>
++ #include <mutex>
++
++ // Inside a different file, which includes "vk_mem_alloc.h":
++
++ #define VMA_CONFIGURATION_USER_INCLUDES_H "my_vma_configuration_user_includes.h"
++ #define VMA_ASSERT(expr) MY_CUSTOM_ASSERT(expr)
++ #define VMA_MIN(v1, v2) (my_custom_min(v1, v2))
++ #include "vk_mem_alloc.h"
++ ...
++
++The following headers are used in this CONFIGURATION section only, so feel free to
++remove them if not needed.
++*/
++#if !defined(VMA_CONFIGURATION_USER_INCLUDES_H)
++ #include <cassert> // for assert
++ #include <algorithm> // for min, max
++ #include <mutex>
++#else
++ #include VMA_CONFIGURATION_USER_INCLUDES_H
++#endif
++
++#ifndef VMA_NULL
++ // Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0.
++ #define VMA_NULL nullptr
++#endif
++
++#if defined(__ANDROID_API__) && (__ANDROID_API__ < 16)
++#include <cstdlib>
++static void* vma_aligned_alloc(size_t alignment, size_t size)
++{
++ // alignment must be >= sizeof(void*)
++ if(alignment < sizeof(void*))
++ {
++ alignment = sizeof(void*);
++ }
++
++ return memalign(alignment, size);
++}
++#elif defined(__APPLE__) || defined(__ANDROID__) || (defined(__linux__) && defined(__GLIBCXX__) && !defined(_GLIBCXX_HAVE_ALIGNED_ALLOC))
++#include <cstdlib>
++
++#if defined(__APPLE__)
++#include <AvailabilityMacros.h>
++#endif
++
++static void* vma_aligned_alloc(size_t alignment, size_t size)
++{
++ // Unfortunately, aligned_alloc causes VMA to crash due to it returning null pointers. (At least under 11.4)
++ // Therefore, for now disable this specific exception until a proper solution is found.
++ //#if defined(__APPLE__) && (defined(MAC_OS_X_VERSION_10_16) || defined(__IPHONE_14_0))
++ //#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_16 || __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0
++ // // For C++14, usr/include/malloc/_malloc.h declares aligned_alloc()) only
++ // // with the MacOSX11.0 SDK in Xcode 12 (which is what adds
++ // // MAC_OS_X_VERSION_10_16), even though the function is marked
++ // // availabe for 10.15. That is why the preprocessor checks for 10.16 but
++ // // the __builtin_available checks for 10.15.
++ // // People who use C++17 could call aligned_alloc with the 10.15 SDK already.
++ // if (__builtin_available(macOS 10.15, iOS 13, *))
++ // return aligned_alloc(alignment, size);
++ //#endif
++ //#endif
++
++ // alignment must be >= sizeof(void*)
++ if(alignment < sizeof(void*))
++ {
++ alignment = sizeof(void*);
++ }
++
++ void *pointer;
++ if(posix_memalign(&pointer, alignment, size) == 0)
++ return pointer;
++ return VMA_NULL;
++}
++#elif defined(_WIN32)
++static void* vma_aligned_alloc(size_t alignment, size_t size)
++{
++ return _aligned_malloc(size, alignment);
++}
++#else
++static void* vma_aligned_alloc(size_t alignment, size_t size)
++{
++ return aligned_alloc(alignment, size);
++}
++#endif
++
++#if defined(_WIN32)
++static void vma_aligned_free(void* ptr)
++{
++ _aligned_free(ptr);
++}
++#else
++static void vma_aligned_free(void* VMA_NULLABLE ptr)
++{
++ free(ptr);
++}
++#endif
++
++// If your compiler is not compatible with C++11 and definition of
++// aligned_alloc() function is missing, uncommeting following line may help:
++
++//#include <malloc.h>
++
++// Normal assert to check for programmer's errors, especially in Debug configuration.
++#ifndef VMA_ASSERT
++ #ifdef NDEBUG
++ #define VMA_ASSERT(expr)
++ #else
++ #define VMA_ASSERT(expr) assert(expr)
++ #endif
++#endif
++
++// Assert that will be called very often, like inside data structures e.g. operator[].
++// Making it non-empty can make program slow.
++#ifndef VMA_HEAVY_ASSERT
++ #ifdef NDEBUG
++ #define VMA_HEAVY_ASSERT(expr)
++ #else
++ #define VMA_HEAVY_ASSERT(expr) //VMA_ASSERT(expr)
++ #endif
++#endif
++
++#ifndef VMA_ALIGN_OF
++ #define VMA_ALIGN_OF(type) (__alignof(type))
++#endif
++
++#ifndef VMA_SYSTEM_ALIGNED_MALLOC
++ #define VMA_SYSTEM_ALIGNED_MALLOC(size, alignment) vma_aligned_alloc((alignment), (size))
++#endif
++
++#ifndef VMA_SYSTEM_ALIGNED_FREE
++ // VMA_SYSTEM_FREE is the old name, but might have been defined by the user
++ #if defined(VMA_SYSTEM_FREE)
++ #define VMA_SYSTEM_ALIGNED_FREE(ptr) VMA_SYSTEM_FREE(ptr)
++ #else
++ #define VMA_SYSTEM_ALIGNED_FREE(ptr) vma_aligned_free(ptr)
++ #endif
++#endif
++
++#ifndef VMA_COUNT_BITS_SET
++ // Returns number of bits set to 1 in (v)
++ #define VMA_COUNT_BITS_SET(v) VmaCountBitsSet(v)
++#endif
++
++#ifndef VMA_BITSCAN_LSB
++ // Scans integer for index of first nonzero value from the Least Significant Bit (LSB). If mask is 0 then returns UINT8_MAX
++ #define VMA_BITSCAN_LSB(mask) VmaBitScanLSB(mask)
++#endif
++
++#ifndef VMA_BITSCAN_MSB
++ // Scans integer for index of first nonzero value from the Most Significant Bit (MSB). If mask is 0 then returns UINT8_MAX
++ #define VMA_BITSCAN_MSB(mask) VmaBitScanMSB(mask)
++#endif
++
++#ifndef VMA_MIN
++ #define VMA_MIN(v1, v2) ((std::min)((v1), (v2)))
++#endif
++
++#ifndef VMA_MAX
++ #define VMA_MAX(v1, v2) ((std::max)((v1), (v2)))
++#endif
++
++#ifndef VMA_SWAP
++ #define VMA_SWAP(v1, v2) std::swap((v1), (v2))
++#endif
++
++#ifndef VMA_SORT
++ #define VMA_SORT(beg, end, cmp) std::sort(beg, end, cmp)
++#endif
++
++#ifndef VMA_DEBUG_LOG
++ #define VMA_DEBUG_LOG(format, ...)
++ /*
++ #define VMA_DEBUG_LOG(format, ...) do { \
++ printf(format, __VA_ARGS__); \
++ printf("\n"); \
++ } while(false)
++ */
++#endif
++
++// Define this macro to 1 to enable functions: vmaBuildStatsString, vmaFreeStatsString.
++#if VMA_STATS_STRING_ENABLED
++ static inline void VmaUint32ToStr(char* VMA_NOT_NULL outStr, size_t strLen, uint32_t num)
++ {
++ snprintf(outStr, strLen, "%u", static_cast<unsigned int>(num));
++ }
++ static inline void VmaUint64ToStr(char* VMA_NOT_NULL outStr, size_t strLen, uint64_t num)
++ {
++ snprintf(outStr, strLen, "%llu", static_cast<unsigned long long>(num));
++ }
++ static inline void VmaPtrToStr(char* VMA_NOT_NULL outStr, size_t strLen, const void* ptr)
++ {
++ snprintf(outStr, strLen, "%p", ptr);
++ }
++#endif
++
++#ifndef VMA_MUTEX
++ class VmaMutex
++ {
++ public:
++ void Lock() { m_Mutex.lock(); }
++ void Unlock() { m_Mutex.unlock(); }
++ bool TryLock() { return m_Mutex.try_lock(); }
++ private:
++ std::mutex m_Mutex;
++ };
++ #define VMA_MUTEX VmaMutex
++#endif
++
++// Read-write mutex, where "read" is shared access, "write" is exclusive access.
++#ifndef VMA_RW_MUTEX
++ #if VMA_USE_STL_SHARED_MUTEX
++ // Use std::shared_mutex from C++17.
++ #include <shared_mutex>
++ class VmaRWMutex
++ {
++ public:
++ void LockRead() { m_Mutex.lock_shared(); }
++ void UnlockRead() { m_Mutex.unlock_shared(); }
++ bool TryLockRead() { return m_Mutex.try_lock_shared(); }
++ void LockWrite() { m_Mutex.lock(); }
++ void UnlockWrite() { m_Mutex.unlock(); }
++ bool TryLockWrite() { return m_Mutex.try_lock(); }
++ private:
++ std::shared_mutex m_Mutex;
++ };
++ #define VMA_RW_MUTEX VmaRWMutex
++ #elif defined(_WIN32) && defined(WINVER) && WINVER >= 0x0600
++ // Use SRWLOCK from WinAPI.
++ // Minimum supported client = Windows Vista, server = Windows Server 2008.
++ class VmaRWMutex
++ {
++ public:
++ VmaRWMutex() { InitializeSRWLock(&m_Lock); }
++ void LockRead() { AcquireSRWLockShared(&m_Lock); }
++ void UnlockRead() { ReleaseSRWLockShared(&m_Lock); }
++ bool TryLockRead() { return TryAcquireSRWLockShared(&m_Lock) != FALSE; }
++ void LockWrite() { AcquireSRWLockExclusive(&m_Lock); }
++ void UnlockWrite() { ReleaseSRWLockExclusive(&m_Lock); }
++ bool TryLockWrite() { return TryAcquireSRWLockExclusive(&m_Lock) != FALSE; }
++ private:
++ SRWLOCK m_Lock;
++ };
++ #define VMA_RW_MUTEX VmaRWMutex
++ #else
++ // Less efficient fallback: Use normal mutex.
++ class VmaRWMutex
++ {
++ public:
++ void LockRead() { m_Mutex.Lock(); }
++ void UnlockRead() { m_Mutex.Unlock(); }
++ bool TryLockRead() { return m_Mutex.TryLock(); }
++ void LockWrite() { m_Mutex.Lock(); }
++ void UnlockWrite() { m_Mutex.Unlock(); }
++ bool TryLockWrite() { return m_Mutex.TryLock(); }
++ private:
++ VMA_MUTEX m_Mutex;
++ };
++ #define VMA_RW_MUTEX VmaRWMutex
++ #endif // #if VMA_USE_STL_SHARED_MUTEX
++#endif // #ifndef VMA_RW_MUTEX
++
++/*
++If providing your own implementation, you need to implement a subset of std::atomic.
++*/
++#ifndef VMA_ATOMIC_UINT32
++ #include <atomic>
++ #define VMA_ATOMIC_UINT32 std::atomic<uint32_t>
++#endif
++
++#ifndef VMA_ATOMIC_UINT64
++ #include <atomic>
++ #define VMA_ATOMIC_UINT64 std::atomic<uint64_t>
++#endif
++
++#ifndef VMA_DEBUG_ALWAYS_DEDICATED_MEMORY
++ /**
++ Every allocation will have its own memory block.
++ Define to 1 for debugging purposes only.
++ */
++ #define VMA_DEBUG_ALWAYS_DEDICATED_MEMORY (0)
++#endif
++
++#ifndef VMA_MIN_ALIGNMENT
++ /**
++ Minimum alignment of all allocations, in bytes.
++ Set to more than 1 for debugging purposes. Must be power of two.
++ */
++ #ifdef VMA_DEBUG_ALIGNMENT // Old name
++ #define VMA_MIN_ALIGNMENT VMA_DEBUG_ALIGNMENT
++ #else
++ #define VMA_MIN_ALIGNMENT (1)
++ #endif
++#endif
++
++#ifndef VMA_DEBUG_MARGIN
++ /**
++ Minimum margin after every allocation, in bytes.
++ Set nonzero for debugging purposes only.
++ */
++ #define VMA_DEBUG_MARGIN (0)
++#endif
++
++#ifndef VMA_DEBUG_INITIALIZE_ALLOCATIONS
++ /**
++ Define this macro to 1 to automatically fill new allocations and destroyed
++ allocations with some bit pattern.
++ */
++ #define VMA_DEBUG_INITIALIZE_ALLOCATIONS (0)
++#endif
++
++#ifndef VMA_DEBUG_DETECT_CORRUPTION
++ /**
++ Define this macro to 1 together with non-zero value of VMA_DEBUG_MARGIN to
++ enable writing magic value to the margin after every allocation and
++ validating it, so that memory corruptions (out-of-bounds writes) are detected.
++ */
++ #define VMA_DEBUG_DETECT_CORRUPTION (0)
++#endif
++
++#ifndef VMA_DEBUG_GLOBAL_MUTEX
++ /**
++ Set this to 1 for debugging purposes only, to enable single mutex protecting all
++ entry calls to the library. Can be useful for debugging multithreading issues.
++ */
++ #define VMA_DEBUG_GLOBAL_MUTEX (0)
++#endif
++
++#ifndef VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY
++ /**
++ Minimum value for VkPhysicalDeviceLimits::bufferImageGranularity.
++ Set to more than 1 for debugging purposes only. Must be power of two.
++ */
++ #define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY (1)
++#endif
++
++#ifndef VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT
++ /*
++ Set this to 1 to make VMA never exceed VkPhysicalDeviceLimits::maxMemoryAllocationCount
++ and return error instead of leaving up to Vulkan implementation what to do in such cases.
++ */
++ #define VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT (0)
++#endif
++
++#ifndef VMA_SMALL_HEAP_MAX_SIZE
++ /// Maximum size of a memory heap in Vulkan to consider it "small".
++ #define VMA_SMALL_HEAP_MAX_SIZE (1024ull * 1024 * 1024)
++#endif
++
++#ifndef VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE
++ /// Default size of a block allocated as single VkDeviceMemory from a "large" heap.
++ #define VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE (256ull * 1024 * 1024)
++#endif
++
++/*
++Mapping hysteresis is a logic that launches when vmaMapMemory/vmaUnmapMemory is called
++or a persistently mapped allocation is created and destroyed several times in a row.
++It keeps additional +1 mapping of a device memory block to prevent calling actual
++vkMapMemory/vkUnmapMemory too many times, which may improve performance and help
++tools like RenderDOc.
++*/
++#ifndef VMA_MAPPING_HYSTERESIS_ENABLED
++ #define VMA_MAPPING_HYSTERESIS_ENABLED 1
++#endif
++
++#ifndef VMA_CLASS_NO_COPY
++ #define VMA_CLASS_NO_COPY(className) \
++ private: \
++ className(const className&) = delete; \
++ className& operator=(const className&) = delete;
++#endif
++
++#define VMA_VALIDATE(cond) do { if(!(cond)) { \
++ VMA_ASSERT(0 && "Validation failed: " #cond); \
++ return false; \
++ } } while(false)
++
++/*******************************************************************************
++END OF CONFIGURATION
++*/
++#endif // _VMA_CONFIGURATION
++
++
++static const uint8_t VMA_ALLOCATION_FILL_PATTERN_CREATED = 0xDC;
++static const uint8_t VMA_ALLOCATION_FILL_PATTERN_DESTROYED = 0xEF;
++// Decimal 2139416166, float NaN, little-endian binary 66 E6 84 7F.
++static const uint32_t VMA_CORRUPTION_DETECTION_MAGIC_VALUE = 0x7F84E666;
++
++// Copy of some Vulkan definitions so we don't need to check their existence just to handle few constants.
++static const uint32_t VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY = 0x00000040;
++static const uint32_t VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY = 0x00000080;
++static const uint32_t VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY = 0x00020000;
++static const uint32_t VK_IMAGE_CREATE_DISJOINT_BIT_COPY = 0x00000200;
++static const int32_t VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT_COPY = 1000158000;
++static const uint32_t VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET = 0x10000000u;
++static const uint32_t VMA_ALLOCATION_TRY_COUNT = 32;
++static const uint32_t VMA_VENDOR_ID_AMD = 4098;
++
++// This one is tricky. Vulkan specification defines this code as available since
++// Vulkan 1.0, but doesn't actually define it in Vulkan SDK earlier than 1.2.131.
++// See pull request #207.
++#define VK_ERROR_UNKNOWN_COPY ((VkResult)-13)
++
++
++#if VMA_STATS_STRING_ENABLED
++// Correspond to values of enum VmaSuballocationType.
++static const char* VMA_SUBALLOCATION_TYPE_NAMES[] =
++{
++ "FREE",
++ "UNKNOWN",
++ "BUFFER",
++ "IMAGE_UNKNOWN",
++ "IMAGE_LINEAR",
++ "IMAGE_OPTIMAL",
++};
++#endif
++
++static VkAllocationCallbacks VmaEmptyAllocationCallbacks =
++ { VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL };
++
++
++#ifndef _VMA_ENUM_DECLARATIONS
++
++enum VmaSuballocationType
++{
++ VMA_SUBALLOCATION_TYPE_FREE = 0,
++ VMA_SUBALLOCATION_TYPE_UNKNOWN = 1,
++ VMA_SUBALLOCATION_TYPE_BUFFER = 2,
++ VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN = 3,
++ VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR = 4,
++ VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL = 5,
++ VMA_SUBALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF
++};
++
++enum VMA_CACHE_OPERATION
++{
++ VMA_CACHE_FLUSH,
++ VMA_CACHE_INVALIDATE
++};
++
++enum class VmaAllocationRequestType
++{
++ Normal,
++ TLSF,
++ // Used by "Linear" algorithm.
++ UpperAddress,
++ EndOf1st,
++ EndOf2nd,
++};
++
++#endif // _VMA_ENUM_DECLARATIONS
++
++#ifndef _VMA_FORWARD_DECLARATIONS
++// Opaque handle used by allocation algorithms to identify single allocation in any conforming way.
++VK_DEFINE_NON_DISPATCHABLE_HANDLE(VmaAllocHandle);
++
++struct VmaMutexLock;
++struct VmaMutexLockRead;
++struct VmaMutexLockWrite;
++
++template<typename T>
++struct AtomicTransactionalIncrement;
++
++template<typename T>
++struct VmaStlAllocator;
++
++template<typename T, typename AllocatorT>
++class VmaVector;
++
++template<typename T, typename AllocatorT, size_t N>
++class VmaSmallVector;
++
++template<typename T>
++class VmaPoolAllocator;
++
++template<typename T>
++struct VmaListItem;
++
++template<typename T>
++class VmaRawList;
++
++template<typename T, typename AllocatorT>
++class VmaList;
++
++template<typename ItemTypeTraits>
++class VmaIntrusiveLinkedList;
++
++// Unused in this version
++#if 0
++template<typename T1, typename T2>
++struct VmaPair;
++template<typename FirstT, typename SecondT>
++struct VmaPairFirstLess;
++
++template<typename KeyT, typename ValueT>
++class VmaMap;
++#endif
++
++#if VMA_STATS_STRING_ENABLED
++class VmaStringBuilder;
++class VmaJsonWriter;
++#endif
++
++class VmaDeviceMemoryBlock;
++
++struct VmaDedicatedAllocationListItemTraits;
++class VmaDedicatedAllocationList;
++
++struct VmaSuballocation;
++struct VmaSuballocationOffsetLess;
++struct VmaSuballocationOffsetGreater;
++struct VmaSuballocationItemSizeLess;
++
++typedef VmaList<VmaSuballocation, VmaStlAllocator<VmaSuballocation>> VmaSuballocationList;
++
++struct VmaAllocationRequest;
++
++class VmaBlockMetadata;
++class VmaBlockMetadata_Linear;
++class VmaBlockMetadata_TLSF;
++
++class VmaBlockVector;
++
++struct VmaPoolListItemTraits;
++
++struct VmaCurrentBudgetData;
++
++class VmaAllocationObjectAllocator;
++
++#endif // _VMA_FORWARD_DECLARATIONS
++
++
++#ifndef _VMA_FUNCTIONS
++
++/*
++Returns number of bits set to 1 in (v).
++
++On specific platforms and compilers you can use instrinsics like:
++
++Visual Studio:
++ return __popcnt(v);
++GCC, Clang:
++ return static_cast<uint32_t>(__builtin_popcount(v));
++
++Define macro VMA_COUNT_BITS_SET to provide your optimized implementation.
++But you need to check in runtime whether user's CPU supports these, as some old processors don't.
++*/
++static inline uint32_t VmaCountBitsSet(uint32_t v)
++{
++#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L // C++20
++ return std::popcount(v);
++#else
++ uint32_t c = v - ((v >> 1) & 0x55555555);
++ c = ((c >> 2) & 0x33333333) + (c & 0x33333333);
++ c = ((c >> 4) + c) & 0x0F0F0F0F;
++ c = ((c >> 8) + c) & 0x00FF00FF;
++ c = ((c >> 16) + c) & 0x0000FFFF;
++ return c;
++#endif
++}
++
++static inline uint8_t VmaBitScanLSB(uint64_t mask)
++{
++#if defined(_MSC_VER) && defined(_WIN64)
++ unsigned long pos;
++ if (_BitScanForward64(&pos, mask))
++ return static_cast<uint8_t>(pos);
++ return UINT8_MAX;
++#elif defined __GNUC__ || defined __clang__
++ return static_cast<uint8_t>(__builtin_ffsll(mask)) - 1U;
++#else
++ uint8_t pos = 0;
++ uint64_t bit = 1;
++ do
++ {
++ if (mask & bit)
++ return pos;
++ bit <<= 1;
++ } while (pos++ < 63);
++ return UINT8_MAX;
++#endif
++}
++
++static inline uint8_t VmaBitScanLSB(uint32_t mask)
++{
++#ifdef _MSC_VER
++ unsigned long pos;
++ if (_BitScanForward(&pos, mask))
++ return static_cast<uint8_t>(pos);
++ return UINT8_MAX;
++#elif defined __GNUC__ || defined __clang__
++ return static_cast<uint8_t>(__builtin_ffs(mask)) - 1U;
++#else
++ uint8_t pos = 0;
++ uint32_t bit = 1;
++ do
++ {
++ if (mask & bit)
++ return pos;
++ bit <<= 1;
++ } while (pos++ < 31);
++ return UINT8_MAX;
++#endif
++}
++
++static inline uint8_t VmaBitScanMSB(uint64_t mask)
++{
++#if defined(_MSC_VER) && defined(_WIN64)
++ unsigned long pos;
++ if (_BitScanReverse64(&pos, mask))
++ return static_cast<uint8_t>(pos);
++#elif defined __GNUC__ || defined __clang__
++ if (mask)
++ return 63 - static_cast<uint8_t>(__builtin_clzll(mask));
++#else
++ uint8_t pos = 63;
++ uint64_t bit = 1ULL << 63;
++ do
++ {
++ if (mask & bit)
++ return pos;
++ bit >>= 1;
++ } while (pos-- > 0);
++#endif
++ return UINT8_MAX;
++}
++
++static inline uint8_t VmaBitScanMSB(uint32_t mask)
++{
++#ifdef _MSC_VER
++ unsigned long pos;
++ if (_BitScanReverse(&pos, mask))
++ return static_cast<uint8_t>(pos);
++#elif defined __GNUC__ || defined __clang__
++ if (mask)
++ return 31 - static_cast<uint8_t>(__builtin_clz(mask));
++#else
++ uint8_t pos = 31;
++ uint32_t bit = 1UL << 31;
++ do
++ {
++ if (mask & bit)
++ return pos;
++ bit >>= 1;
++ } while (pos-- > 0);
++#endif
++ return UINT8_MAX;
++}
++
++/*
++Returns true if given number is a power of two.
++T must be unsigned integer number or signed integer but always nonnegative.
++For 0 returns true.
++*/
++template <typename T>
++inline bool VmaIsPow2(T x)
++{
++ return (x & (x - 1)) == 0;
++}
++
++// Aligns given value up to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 16.
++// Use types like uint32_t, uint64_t as T.
++template <typename T>
++static inline T VmaAlignUp(T val, T alignment)
++{
++ VMA_HEAVY_ASSERT(VmaIsPow2(alignment));
++ return (val + alignment - 1) & ~(alignment - 1);
++}
++
++// Aligns given value down to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 8.
++// Use types like uint32_t, uint64_t as T.
++template <typename T>
++static inline T VmaAlignDown(T val, T alignment)
++{
++ VMA_HEAVY_ASSERT(VmaIsPow2(alignment));
++ return val & ~(alignment - 1);
++}
++
++// Division with mathematical rounding to nearest number.
++template <typename T>
++static inline T VmaRoundDiv(T x, T y)
++{
++ return (x + (y / (T)2)) / y;
++}
++
++// Divide by 'y' and round up to nearest integer.
++template <typename T>
++static inline T VmaDivideRoundingUp(T x, T y)
++{
++ return (x + y - (T)1) / y;
++}
++
++// Returns smallest power of 2 greater or equal to v.
++static inline uint32_t VmaNextPow2(uint32_t v)
++{
++ v--;
++ v |= v >> 1;
++ v |= v >> 2;
++ v |= v >> 4;
++ v |= v >> 8;
++ v |= v >> 16;
++ v++;
++ return v;
++}
++
++static inline uint64_t VmaNextPow2(uint64_t v)
++{
++ v--;
++ v |= v >> 1;
++ v |= v >> 2;
++ v |= v >> 4;
++ v |= v >> 8;
++ v |= v >> 16;
++ v |= v >> 32;
++ v++;
++ return v;
++}
++
++// Returns largest power of 2 less or equal to v.
++static inline uint32_t VmaPrevPow2(uint32_t v)
++{
++ v |= v >> 1;
++ v |= v >> 2;
++ v |= v >> 4;
++ v |= v >> 8;
++ v |= v >> 16;
++ v = v ^ (v >> 1);
++ return v;
++}
++
++static inline uint64_t VmaPrevPow2(uint64_t v)
++{
++ v |= v >> 1;
++ v |= v >> 2;
++ v |= v >> 4;
++ v |= v >> 8;
++ v |= v >> 16;
++ v |= v >> 32;
++ v = v ^ (v >> 1);
++ return v;
++}
++
++static inline bool VmaStrIsEmpty(const char* pStr)
++{
++ return pStr == VMA_NULL || *pStr == '\0';
++}
++
++#ifndef VMA_SORT
++template<typename Iterator, typename Compare>
++Iterator VmaQuickSortPartition(Iterator beg, Iterator end, Compare cmp)
++{
++ Iterator centerValue = end; --centerValue;
++ Iterator insertIndex = beg;
++ for (Iterator memTypeIndex = beg; memTypeIndex < centerValue; ++memTypeIndex)
++ {
++ if (cmp(*memTypeIndex, *centerValue))
++ {
++ if (insertIndex != memTypeIndex)
++ {
++ VMA_SWAP(*memTypeIndex, *insertIndex);
++ }
++ ++insertIndex;
++ }
++ }
++ if (insertIndex != centerValue)
++ {
++ VMA_SWAP(*insertIndex, *centerValue);
++ }
++ return insertIndex;
++}
++
++template<typename Iterator, typename Compare>
++void VmaQuickSort(Iterator beg, Iterator end, Compare cmp)
++{
++ if (beg < end)
++ {
++ Iterator it = VmaQuickSortPartition<Iterator, Compare>(beg, end, cmp);
++ VmaQuickSort<Iterator, Compare>(beg, it, cmp);
++ VmaQuickSort<Iterator, Compare>(it + 1, end, cmp);
++ }
++}
++
++#define VMA_SORT(beg, end, cmp) VmaQuickSort(beg, end, cmp)
++#endif // VMA_SORT
++
++/*
++Returns true if two memory blocks occupy overlapping pages.
++ResourceA must be in less memory offset than ResourceB.
++
++Algorithm is based on "Vulkan 1.0.39 - A Specification (with all registered Vulkan extensions)"
++chapter 11.6 "Resource Memory Association", paragraph "Buffer-Image Granularity".
++*/
++static inline bool VmaBlocksOnSamePage(
++ VkDeviceSize resourceAOffset,
++ VkDeviceSize resourceASize,
++ VkDeviceSize resourceBOffset,
++ VkDeviceSize pageSize)
++{
++ VMA_ASSERT(resourceAOffset + resourceASize <= resourceBOffset && resourceASize > 0 && pageSize > 0);
++ VkDeviceSize resourceAEnd = resourceAOffset + resourceASize - 1;
++ VkDeviceSize resourceAEndPage = resourceAEnd & ~(pageSize - 1);
++ VkDeviceSize resourceBStart = resourceBOffset;
++ VkDeviceSize resourceBStartPage = resourceBStart & ~(pageSize - 1);
++ return resourceAEndPage == resourceBStartPage;
++}
++
++/*
++Returns true if given suballocation types could conflict and must respect
++VkPhysicalDeviceLimits::bufferImageGranularity. They conflict if one is buffer
++or linear image and another one is optimal image. If type is unknown, behave
++conservatively.
++*/
++static inline bool VmaIsBufferImageGranularityConflict(
++ VmaSuballocationType suballocType1,
++ VmaSuballocationType suballocType2)
++{
++ if (suballocType1 > suballocType2)
++ {
++ VMA_SWAP(suballocType1, suballocType2);
++ }
++
++ switch (suballocType1)
++ {
++ case VMA_SUBALLOCATION_TYPE_FREE:
++ return false;
++ case VMA_SUBALLOCATION_TYPE_UNKNOWN:
++ return true;
++ case VMA_SUBALLOCATION_TYPE_BUFFER:
++ return
++ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
++ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
++ case VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN:
++ return
++ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
++ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR ||
++ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
++ case VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR:
++ return
++ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
++ case VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL:
++ return false;
++ default:
++ VMA_ASSERT(0);
++ return true;
++ }
++}
++
++static void VmaWriteMagicValue(void* pData, VkDeviceSize offset)
++{
++#if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION
++ uint32_t* pDst = (uint32_t*)((char*)pData + offset);
++ const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t);
++ for (size_t i = 0; i < numberCount; ++i, ++pDst)
++ {
++ *pDst = VMA_CORRUPTION_DETECTION_MAGIC_VALUE;
++ }
++#else
++ // no-op
++#endif
++}
++
++static bool VmaValidateMagicValue(const void* pData, VkDeviceSize offset)
++{
++#if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION
++ const uint32_t* pSrc = (const uint32_t*)((const char*)pData + offset);
++ const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t);
++ for (size_t i = 0; i < numberCount; ++i, ++pSrc)
++ {
++ if (*pSrc != VMA_CORRUPTION_DETECTION_MAGIC_VALUE)
++ {
++ return false;
++ }
++ }
++#endif
++ return true;
++}
++
++/*
++Fills structure with parameters of an example buffer to be used for transfers
++during GPU memory defragmentation.
++*/
++static void VmaFillGpuDefragmentationBufferCreateInfo(VkBufferCreateInfo& outBufCreateInfo)
++{
++ memset(&outBufCreateInfo, 0, sizeof(outBufCreateInfo));
++ outBufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
++ outBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
++ outBufCreateInfo.size = (VkDeviceSize)VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE; // Example size.
++}
++
++
++/*
++Performs binary search and returns iterator to first element that is greater or
++equal to (key), according to comparison (cmp).
++
++Cmp should return true if first argument is less than second argument.
++
++Returned value is the found element, if present in the collection or place where
++new element with value (key) should be inserted.
++*/
++template <typename CmpLess, typename IterT, typename KeyT>
++static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT& key, const CmpLess& cmp)
++{
++ size_t down = 0, up = (end - beg);
++ while (down < up)
++ {
++ const size_t mid = down + (up - down) / 2; // Overflow-safe midpoint calculation
++ if (cmp(*(beg + mid), key))
++ {
++ down = mid + 1;
++ }
++ else
++ {
++ up = mid;
++ }
++ }
++ return beg + down;
++}
++
++template<typename CmpLess, typename IterT, typename KeyT>
++IterT VmaBinaryFindSorted(const IterT& beg, const IterT& end, const KeyT& value, const CmpLess& cmp)
++{
++ IterT it = VmaBinaryFindFirstNotLess<CmpLess, IterT, KeyT>(
++ beg, end, value, cmp);
++ if (it == end ||
++ (!cmp(*it, value) && !cmp(value, *it)))
++ {
++ return it;
++ }
++ return end;
++}
++
++/*
++Returns true if all pointers in the array are not-null and unique.
++Warning! O(n^2) complexity. Use only inside VMA_HEAVY_ASSERT.
++T must be pointer type, e.g. VmaAllocation, VmaPool.
++*/
++template<typename T>
++static bool VmaValidatePointerArray(uint32_t count, const T* arr)
++{
++ for (uint32_t i = 0; i < count; ++i)
++ {
++ const T iPtr = arr[i];
++ if (iPtr == VMA_NULL)
++ {
++ return false;
++ }
++ for (uint32_t j = i + 1; j < count; ++j)
++ {
++ if (iPtr == arr[j])
++ {
++ return false;
++ }
++ }
++ }
++ return true;
++}
++
++template<typename MainT, typename NewT>
++static inline void VmaPnextChainPushFront(MainT* mainStruct, NewT* newStruct)
++{
++ newStruct->pNext = mainStruct->pNext;
++ mainStruct->pNext = newStruct;
++}
++
++// This is the main algorithm that guides the selection of a memory type best for an allocation -
++// converts usage to required/preferred/not preferred flags.
++static bool FindMemoryPreferences(
++ bool isIntegratedGPU,
++ const VmaAllocationCreateInfo& allocCreateInfo,
++ VkFlags bufImgUsage, // VkBufferCreateInfo::usage or VkImageCreateInfo::usage. UINT32_MAX if unknown.
++ VkMemoryPropertyFlags& outRequiredFlags,
++ VkMemoryPropertyFlags& outPreferredFlags,
++ VkMemoryPropertyFlags& outNotPreferredFlags)
++{
++ outRequiredFlags = allocCreateInfo.requiredFlags;
++ outPreferredFlags = allocCreateInfo.preferredFlags;
++ outNotPreferredFlags = 0;
++
++ switch(allocCreateInfo.usage)
++ {
++ case VMA_MEMORY_USAGE_UNKNOWN:
++ break;
++ case VMA_MEMORY_USAGE_GPU_ONLY:
++ if(!isIntegratedGPU || (outPreferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)
++ {
++ outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ }
++ break;
++ case VMA_MEMORY_USAGE_CPU_ONLY:
++ outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
++ break;
++ case VMA_MEMORY_USAGE_CPU_TO_GPU:
++ outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
++ if(!isIntegratedGPU || (outPreferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)
++ {
++ outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ }
++ break;
++ case VMA_MEMORY_USAGE_GPU_TO_CPU:
++ outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
++ outPreferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
++ break;
++ case VMA_MEMORY_USAGE_CPU_COPY:
++ outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ break;
++ case VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED:
++ outRequiredFlags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
++ break;
++ case VMA_MEMORY_USAGE_AUTO:
++ case VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE:
++ case VMA_MEMORY_USAGE_AUTO_PREFER_HOST:
++ {
++ if(bufImgUsage == UINT32_MAX)
++ {
++ VMA_ASSERT(0 && "VMA_MEMORY_USAGE_AUTO* values can only be used with functions like vmaCreateBuffer, vmaCreateImage so that the details of the created resource are known.");
++ return false;
++ }
++ // This relies on values of VK_IMAGE_USAGE_TRANSFER* being the same VK_BUFFER_IMAGE_TRANSFER*.
++ const bool deviceAccess = (bufImgUsage & ~(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT)) != 0;
++ const bool hostAccessSequentialWrite = (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT) != 0;
++ const bool hostAccessRandom = (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) != 0;
++ const bool hostAccessAllowTransferInstead = (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT) != 0;
++ const bool preferDevice = allocCreateInfo.usage == VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
++ const bool preferHost = allocCreateInfo.usage == VMA_MEMORY_USAGE_AUTO_PREFER_HOST;
++
++ // CPU random access - e.g. a buffer written to or transferred from GPU to read back on CPU.
++ if(hostAccessRandom)
++ {
++ if(!isIntegratedGPU && deviceAccess && hostAccessAllowTransferInstead && !preferHost)
++ {
++ // Nice if it will end up in HOST_VISIBLE, but more importantly prefer DEVICE_LOCAL.
++ // Omitting HOST_VISIBLE here is intentional.
++ // In case there is DEVICE_LOCAL | HOST_VISIBLE | HOST_CACHED, it will pick that one.
++ // Otherwise, this will give same weight to DEVICE_LOCAL as HOST_VISIBLE | HOST_CACHED and select the former if occurs first on the list.
++ outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
++ }
++ else
++ {
++ // Always CPU memory, cached.
++ outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
++ }
++ }
++ // CPU sequential write - may be CPU or host-visible GPU memory, uncached and write-combined.
++ else if(hostAccessSequentialWrite)
++ {
++ // Want uncached and write-combined.
++ outNotPreferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
++
++ if(!isIntegratedGPU && deviceAccess && hostAccessAllowTransferInstead && !preferHost)
++ {
++ outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
++ }
++ else
++ {
++ outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
++ // Direct GPU access, CPU sequential write (e.g. a dynamic uniform buffer updated every frame)
++ if(deviceAccess)
++ {
++ // Could go to CPU memory or GPU BAR/unified. Up to the user to decide. If no preference, choose GPU memory.
++ if(preferHost)
++ outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ else
++ outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ }
++ // GPU no direct access, CPU sequential write (e.g. an upload buffer to be transferred to the GPU)
++ else
++ {
++ // Could go to CPU memory or GPU BAR/unified. Up to the user to decide. If no preference, choose CPU memory.
++ if(preferDevice)
++ outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ else
++ outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ }
++ }
++ }
++ // No CPU access
++ else
++ {
++ // GPU access, no CPU access (e.g. a color attachment image) - prefer GPU memory
++ if(deviceAccess)
++ {
++ // ...unless there is a clear preference from the user not to do so.
++ if(preferHost)
++ outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ else
++ outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ }
++ // No direct GPU access, no CPU access, just transfers.
++ // It may be staging copy intended for e.g. preserving image for next frame (then better GPU memory) or
++ // a "swap file" copy to free some GPU memory (then better CPU memory).
++ // Up to the user to decide. If no preferece, assume the former and choose GPU memory.
++ if(preferHost)
++ outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ else
++ outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++ }
++ break;
++ }
++ default:
++ VMA_ASSERT(0);
++ }
++
++ // Avoid DEVICE_COHERENT unless explicitly requested.
++ if(((allocCreateInfo.requiredFlags | allocCreateInfo.preferredFlags) &
++ (VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY | VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY)) == 0)
++ {
++ outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY;
++ }
++
++ return true;
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// Memory allocation
++
++static void* VmaMalloc(const VkAllocationCallbacks* pAllocationCallbacks, size_t size, size_t alignment)
++{
++ void* result = VMA_NULL;
++ if ((pAllocationCallbacks != VMA_NULL) &&
++ (pAllocationCallbacks->pfnAllocation != VMA_NULL))
++ {
++ result = (*pAllocationCallbacks->pfnAllocation)(
++ pAllocationCallbacks->pUserData,
++ size,
++ alignment,
++ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
++ }
++ else
++ {
++ result = VMA_SYSTEM_ALIGNED_MALLOC(size, alignment);
++ }
++ VMA_ASSERT(result != VMA_NULL && "CPU memory allocation failed.");
++ return result;
++}
++
++static void VmaFree(const VkAllocationCallbacks* pAllocationCallbacks, void* ptr)
++{
++ if ((pAllocationCallbacks != VMA_NULL) &&
++ (pAllocationCallbacks->pfnFree != VMA_NULL))
++ {
++ (*pAllocationCallbacks->pfnFree)(pAllocationCallbacks->pUserData, ptr);
++ }
++ else
++ {
++ VMA_SYSTEM_ALIGNED_FREE(ptr);
++ }
++}
++
++template<typename T>
++static T* VmaAllocate(const VkAllocationCallbacks* pAllocationCallbacks)
++{
++ return (T*)VmaMalloc(pAllocationCallbacks, sizeof(T), VMA_ALIGN_OF(T));
++}
++
++template<typename T>
++static T* VmaAllocateArray(const VkAllocationCallbacks* pAllocationCallbacks, size_t count)
++{
++ return (T*)VmaMalloc(pAllocationCallbacks, sizeof(T) * count, VMA_ALIGN_OF(T));
++}
++
++#define vma_new(allocator, type) new(VmaAllocate<type>(allocator))(type)
++
++#define vma_new_array(allocator, type, count) new(VmaAllocateArray<type>((allocator), (count)))(type)
++
++template<typename T>
++static void vma_delete(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr)
++{
++ ptr->~T();
++ VmaFree(pAllocationCallbacks, ptr);
++}
++
++template<typename T>
++static void vma_delete_array(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr, size_t count)
++{
++ if (ptr != VMA_NULL)
++ {
++ for (size_t i = count; i--; )
++ {
++ ptr[i].~T();
++ }
++ VmaFree(pAllocationCallbacks, ptr);
++ }
++}
++
++static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr)
++{
++ if (srcStr != VMA_NULL)
++ {
++ const size_t len = strlen(srcStr);
++ char* const result = vma_new_array(allocs, char, len + 1);
++ memcpy(result, srcStr, len + 1);
++ return result;
++ }
++ return VMA_NULL;
++}
++
++#if VMA_STATS_STRING_ENABLED
++static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr, size_t strLen)
++{
++ if (srcStr != VMA_NULL)
++ {
++ char* const result = vma_new_array(allocs, char, strLen + 1);
++ memcpy(result, srcStr, strLen);
++ result[strLen] = '\0';
++ return result;
++ }
++ return VMA_NULL;
++}
++#endif // VMA_STATS_STRING_ENABLED
++
++static void VmaFreeString(const VkAllocationCallbacks* allocs, char* str)
++{
++ if (str != VMA_NULL)
++ {
++ const size_t len = strlen(str);
++ vma_delete_array(allocs, str, len + 1);
++ }
++}
++
++template<typename CmpLess, typename VectorT>
++size_t VmaVectorInsertSorted(VectorT& vector, const typename VectorT::value_type& value)
++{
++ const size_t indexToInsert = VmaBinaryFindFirstNotLess(
++ vector.data(),
++ vector.data() + vector.size(),
++ value,
++ CmpLess()) - vector.data();
++ VmaVectorInsert(vector, indexToInsert, value);
++ return indexToInsert;
++}
++
++template<typename CmpLess, typename VectorT>
++bool VmaVectorRemoveSorted(VectorT& vector, const typename VectorT::value_type& value)
++{
++ CmpLess comparator;
++ typename VectorT::iterator it = VmaBinaryFindFirstNotLess(
++ vector.begin(),
++ vector.end(),
++ value,
++ comparator);
++ if ((it != vector.end()) && !comparator(*it, value) && !comparator(value, *it))
++ {
++ size_t indexToRemove = it - vector.begin();
++ VmaVectorRemove(vector, indexToRemove);
++ return true;
++ }
++ return false;
++}
++#endif // _VMA_FUNCTIONS
++
++#ifndef _VMA_STATISTICS_FUNCTIONS
++
++static void VmaClearStatistics(VmaStatistics& outStats)
++{
++ outStats.blockCount = 0;
++ outStats.allocationCount = 0;
++ outStats.blockBytes = 0;
++ outStats.allocationBytes = 0;
++}
++
++static void VmaAddStatistics(VmaStatistics& inoutStats, const VmaStatistics& src)
++{
++ inoutStats.blockCount += src.blockCount;
++ inoutStats.allocationCount += src.allocationCount;
++ inoutStats.blockBytes += src.blockBytes;
++ inoutStats.allocationBytes += src.allocationBytes;
++}
++
++static void VmaClearDetailedStatistics(VmaDetailedStatistics& outStats)
++{
++ VmaClearStatistics(outStats.statistics);
++ outStats.unusedRangeCount = 0;
++ outStats.allocationSizeMin = VK_WHOLE_SIZE;
++ outStats.allocationSizeMax = 0;
++ outStats.unusedRangeSizeMin = VK_WHOLE_SIZE;
++ outStats.unusedRangeSizeMax = 0;
++}
++
++static void VmaAddDetailedStatisticsAllocation(VmaDetailedStatistics& inoutStats, VkDeviceSize size)
++{
++ inoutStats.statistics.allocationCount++;
++ inoutStats.statistics.allocationBytes += size;
++ inoutStats.allocationSizeMin = VMA_MIN(inoutStats.allocationSizeMin, size);
++ inoutStats.allocationSizeMax = VMA_MAX(inoutStats.allocationSizeMax, size);
++}
++
++static void VmaAddDetailedStatisticsUnusedRange(VmaDetailedStatistics& inoutStats, VkDeviceSize size)
++{
++ inoutStats.unusedRangeCount++;
++ inoutStats.unusedRangeSizeMin = VMA_MIN(inoutStats.unusedRangeSizeMin, size);
++ inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, size);
++}
++
++static void VmaAddDetailedStatistics(VmaDetailedStatistics& inoutStats, const VmaDetailedStatistics& src)
++{
++ VmaAddStatistics(inoutStats.statistics, src.statistics);
++ inoutStats.unusedRangeCount += src.unusedRangeCount;
++ inoutStats.allocationSizeMin = VMA_MIN(inoutStats.allocationSizeMin, src.allocationSizeMin);
++ inoutStats.allocationSizeMax = VMA_MAX(inoutStats.allocationSizeMax, src.allocationSizeMax);
++ inoutStats.unusedRangeSizeMin = VMA_MIN(inoutStats.unusedRangeSizeMin, src.unusedRangeSizeMin);
++ inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, src.unusedRangeSizeMax);
++}
++
++#endif // _VMA_STATISTICS_FUNCTIONS
++
++#ifndef _VMA_MUTEX_LOCK
++// Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope).
++struct VmaMutexLock
++{
++ VMA_CLASS_NO_COPY(VmaMutexLock)
++public:
++ VmaMutexLock(VMA_MUTEX& mutex, bool useMutex = true) :
++ m_pMutex(useMutex ? &mutex : VMA_NULL)
++ {
++ if (m_pMutex) { m_pMutex->Lock(); }
++ }
++ ~VmaMutexLock() { if (m_pMutex) { m_pMutex->Unlock(); } }
++
++private:
++ VMA_MUTEX* m_pMutex;
++};
++
++// Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for reading.
++struct VmaMutexLockRead
++{
++ VMA_CLASS_NO_COPY(VmaMutexLockRead)
++public:
++ VmaMutexLockRead(VMA_RW_MUTEX& mutex, bool useMutex) :
++ m_pMutex(useMutex ? &mutex : VMA_NULL)
++ {
++ if (m_pMutex) { m_pMutex->LockRead(); }
++ }
++ ~VmaMutexLockRead() { if (m_pMutex) { m_pMutex->UnlockRead(); } }
++
++private:
++ VMA_RW_MUTEX* m_pMutex;
++};
++
++// Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for writing.
++struct VmaMutexLockWrite
++{
++ VMA_CLASS_NO_COPY(VmaMutexLockWrite)
++public:
++ VmaMutexLockWrite(VMA_RW_MUTEX& mutex, bool useMutex)
++ : m_pMutex(useMutex ? &mutex : VMA_NULL)
++ {
++ if (m_pMutex) { m_pMutex->LockWrite(); }
++ }
++ ~VmaMutexLockWrite() { if (m_pMutex) { m_pMutex->UnlockWrite(); } }
++
++private:
++ VMA_RW_MUTEX* m_pMutex;
++};
++
++#if VMA_DEBUG_GLOBAL_MUTEX
++ static VMA_MUTEX gDebugGlobalMutex;
++ #define VMA_DEBUG_GLOBAL_MUTEX_LOCK VmaMutexLock debugGlobalMutexLock(gDebugGlobalMutex, true);
++#else
++ #define VMA_DEBUG_GLOBAL_MUTEX_LOCK
++#endif
++#endif // _VMA_MUTEX_LOCK
++
++#ifndef _VMA_ATOMIC_TRANSACTIONAL_INCREMENT
++// An object that increments given atomic but decrements it back in the destructor unless Commit() is called.
++template<typename T>
++struct AtomicTransactionalIncrement
++{
++public:
++ typedef std::atomic<T> AtomicT;
++
++ ~AtomicTransactionalIncrement()
++ {
++ if(m_Atomic)
++ --(*m_Atomic);
++ }
++
++ void Commit() { m_Atomic = nullptr; }
++ T Increment(AtomicT* atomic)
++ {
++ m_Atomic = atomic;
++ return m_Atomic->fetch_add(1);
++ }
++
++private:
++ AtomicT* m_Atomic = nullptr;
++};
++#endif // _VMA_ATOMIC_TRANSACTIONAL_INCREMENT
++
++#ifndef _VMA_STL_ALLOCATOR
++// STL-compatible allocator.
++template<typename T>
++struct VmaStlAllocator
++{
++ const VkAllocationCallbacks* const m_pCallbacks;
++ typedef T value_type;
++
++ VmaStlAllocator(const VkAllocationCallbacks* pCallbacks) : m_pCallbacks(pCallbacks) {}
++ template<typename U>
++ VmaStlAllocator(const VmaStlAllocator<U>& src) : m_pCallbacks(src.m_pCallbacks) {}
++ VmaStlAllocator(const VmaStlAllocator&) = default;
++ VmaStlAllocator& operator=(const VmaStlAllocator&) = delete;
++
++ T* allocate(size_t n) { return VmaAllocateArray<T>(m_pCallbacks, n); }
++ void deallocate(T* p, size_t n) { VmaFree(m_pCallbacks, p); }
++
++ template<typename U>
++ bool operator==(const VmaStlAllocator<U>& rhs) const
++ {
++ return m_pCallbacks == rhs.m_pCallbacks;
++ }
++ template<typename U>
++ bool operator!=(const VmaStlAllocator<U>& rhs) const
++ {
++ return m_pCallbacks != rhs.m_pCallbacks;
++ }
++};
++#endif // _VMA_STL_ALLOCATOR
++
++#ifndef _VMA_VECTOR
++/* Class with interface compatible with subset of std::vector.
++T must be POD because constructors and destructors are not called and memcpy is
++used for these objects. */
++template<typename T, typename AllocatorT>
++class VmaVector
++{
++public:
++ typedef T value_type;
++ typedef T* iterator;
++ typedef const T* const_iterator;
++
++ VmaVector(const AllocatorT& allocator);
++ VmaVector(size_t count, const AllocatorT& allocator);
++ // This version of the constructor is here for compatibility with pre-C++14 std::vector.
++ // value is unused.
++ VmaVector(size_t count, const T& value, const AllocatorT& allocator) : VmaVector(count, allocator) {}
++ VmaVector(const VmaVector<T, AllocatorT>& src);
++ VmaVector& operator=(const VmaVector& rhs);
++ ~VmaVector() { VmaFree(m_Allocator.m_pCallbacks, m_pArray); }
++
++ bool empty() const { return m_Count == 0; }
++ size_t size() const { return m_Count; }
++ T* data() { return m_pArray; }
++ T& front() { VMA_HEAVY_ASSERT(m_Count > 0); return m_pArray[0]; }
++ T& back() { VMA_HEAVY_ASSERT(m_Count > 0); return m_pArray[m_Count - 1]; }
++ const T* data() const { return m_pArray; }
++ const T& front() const { VMA_HEAVY_ASSERT(m_Count > 0); return m_pArray[0]; }
++ const T& back() const { VMA_HEAVY_ASSERT(m_Count > 0); return m_pArray[m_Count - 1]; }
++
++ iterator begin() { return m_pArray; }
++ iterator end() { return m_pArray + m_Count; }
++ const_iterator cbegin() const { return m_pArray; }
++ const_iterator cend() const { return m_pArray + m_Count; }
++ const_iterator begin() const { return cbegin(); }
++ const_iterator end() const { return cend(); }
++
++ void pop_front() { VMA_HEAVY_ASSERT(m_Count > 0); remove(0); }
++ void pop_back() { VMA_HEAVY_ASSERT(m_Count > 0); resize(size() - 1); }
++ void push_front(const T& src) { insert(0, src); }
++
++ void push_back(const T& src);
++ void reserve(size_t newCapacity, bool freeMemory = false);
++ void resize(size_t newCount);
++ void clear() { resize(0); }
++ void shrink_to_fit();
++ void insert(size_t index, const T& src);
++ void remove(size_t index);
++
++ T& operator[](size_t index) { VMA_HEAVY_ASSERT(index < m_Count); return m_pArray[index]; }
++ const T& operator[](size_t index) const { VMA_HEAVY_ASSERT(index < m_Count); return m_pArray[index]; }
++
++private:
++ AllocatorT m_Allocator;
++ T* m_pArray;
++ size_t m_Count;
++ size_t m_Capacity;
++};
++
++#ifndef _VMA_VECTOR_FUNCTIONS
++template<typename T, typename AllocatorT>
++VmaVector<T, AllocatorT>::VmaVector(const AllocatorT& allocator)
++ : m_Allocator(allocator),
++ m_pArray(VMA_NULL),
++ m_Count(0),
++ m_Capacity(0) {}
++
++template<typename T, typename AllocatorT>
++VmaVector<T, AllocatorT>::VmaVector(size_t count, const AllocatorT& allocator)
++ : m_Allocator(allocator),
++ m_pArray(count ? (T*)VmaAllocateArray<T>(allocator.m_pCallbacks, count) : VMA_NULL),
++ m_Count(count),
++ m_Capacity(count) {}
++
++template<typename T, typename AllocatorT>
++VmaVector<T, AllocatorT>::VmaVector(const VmaVector& src)
++ : m_Allocator(src.m_Allocator),
++ m_pArray(src.m_Count ? (T*)VmaAllocateArray<T>(src.m_Allocator.m_pCallbacks, src.m_Count) : VMA_NULL),
++ m_Count(src.m_Count),
++ m_Capacity(src.m_Count)
++{
++ if (m_Count != 0)
++ {
++ memcpy(m_pArray, src.m_pArray, m_Count * sizeof(T));
++ }
++}
++
++template<typename T, typename AllocatorT>
++VmaVector<T, AllocatorT>& VmaVector<T, AllocatorT>::operator=(const VmaVector& rhs)
++{
++ if (&rhs != this)
++ {
++ resize(rhs.m_Count);
++ if (m_Count != 0)
++ {
++ memcpy(m_pArray, rhs.m_pArray, m_Count * sizeof(T));
++ }
++ }
++ return *this;
++}
++
++template<typename T, typename AllocatorT>
++void VmaVector<T, AllocatorT>::push_back(const T& src)
++{
++ const size_t newIndex = size();
++ resize(newIndex + 1);
++ m_pArray[newIndex] = src;
++}
++
++template<typename T, typename AllocatorT>
++void VmaVector<T, AllocatorT>::reserve(size_t newCapacity, bool freeMemory)
++{
++ newCapacity = VMA_MAX(newCapacity, m_Count);
++
++ if ((newCapacity < m_Capacity) && !freeMemory)
++ {
++ newCapacity = m_Capacity;
++ }
++
++ if (newCapacity != m_Capacity)
++ {
++ T* const newArray = newCapacity ? VmaAllocateArray<T>(m_Allocator, newCapacity) : VMA_NULL;
++ if (m_Count != 0)
++ {
++ memcpy(newArray, m_pArray, m_Count * sizeof(T));
++ }
++ VmaFree(m_Allocator.m_pCallbacks, m_pArray);
++ m_Capacity = newCapacity;
++ m_pArray = newArray;
++ }
++}
++
++template<typename T, typename AllocatorT>
++void VmaVector<T, AllocatorT>::resize(size_t newCount)
++{
++ size_t newCapacity = m_Capacity;
++ if (newCount > m_Capacity)
++ {
++ newCapacity = VMA_MAX(newCount, VMA_MAX(m_Capacity * 3 / 2, (size_t)8));
++ }
++
++ if (newCapacity != m_Capacity)
++ {
++ T* const newArray = newCapacity ? VmaAllocateArray<T>(m_Allocator.m_pCallbacks, newCapacity) : VMA_NULL;
++ const size_t elementsToCopy = VMA_MIN(m_Count, newCount);
++ if (elementsToCopy != 0)
++ {
++ memcpy(newArray, m_pArray, elementsToCopy * sizeof(T));
++ }
++ VmaFree(m_Allocator.m_pCallbacks, m_pArray);
++ m_Capacity = newCapacity;
++ m_pArray = newArray;
++ }
++
++ m_Count = newCount;
++}
++
++template<typename T, typename AllocatorT>
++void VmaVector<T, AllocatorT>::shrink_to_fit()
++{
++ if (m_Capacity > m_Count)
++ {
++ T* newArray = VMA_NULL;
++ if (m_Count > 0)
++ {
++ newArray = VmaAllocateArray<T>(m_Allocator.m_pCallbacks, m_Count);
++ memcpy(newArray, m_pArray, m_Count * sizeof(T));
++ }
++ VmaFree(m_Allocator.m_pCallbacks, m_pArray);
++ m_Capacity = m_Count;
++ m_pArray = newArray;
++ }
++}
++
++template<typename T, typename AllocatorT>
++void VmaVector<T, AllocatorT>::insert(size_t index, const T& src)
++{
++ VMA_HEAVY_ASSERT(index <= m_Count);
++ const size_t oldCount = size();
++ resize(oldCount + 1);
++ if (index < oldCount)
++ {
++ memmove(m_pArray + (index + 1), m_pArray + index, (oldCount - index) * sizeof(T));
++ }
++ m_pArray[index] = src;
++}
++
++template<typename T, typename AllocatorT>
++void VmaVector<T, AllocatorT>::remove(size_t index)
++{
++ VMA_HEAVY_ASSERT(index < m_Count);
++ const size_t oldCount = size();
++ if (index < oldCount - 1)
++ {
++ memmove(m_pArray + index, m_pArray + (index + 1), (oldCount - index - 1) * sizeof(T));
++ }
++ resize(oldCount - 1);
++}
++#endif // _VMA_VECTOR_FUNCTIONS
++
++template<typename T, typename allocatorT>
++static void VmaVectorInsert(VmaVector<T, allocatorT>& vec, size_t index, const T& item)
++{
++ vec.insert(index, item);
++}
++
++template<typename T, typename allocatorT>
++static void VmaVectorRemove(VmaVector<T, allocatorT>& vec, size_t index)
++{
++ vec.remove(index);
++}
++#endif // _VMA_VECTOR
++
++#ifndef _VMA_SMALL_VECTOR
++/*
++This is a vector (a variable-sized array), optimized for the case when the array is small.
++
++It contains some number of elements in-place, which allows it to avoid heap allocation
++when the actual number of elements is below that threshold. This allows normal "small"
++cases to be fast without losing generality for large inputs.
++*/
++template<typename T, typename AllocatorT, size_t N>
++class VmaSmallVector
++{
++public:
++ typedef T value_type;
++ typedef T* iterator;
++
++ VmaSmallVector(const AllocatorT& allocator);
++ VmaSmallVector(size_t count, const AllocatorT& allocator);
++ template<typename SrcT, typename SrcAllocatorT, size_t SrcN>
++ VmaSmallVector(const VmaSmallVector<SrcT, SrcAllocatorT, SrcN>&) = delete;
++ template<typename SrcT, typename SrcAllocatorT, size_t SrcN>
++ VmaSmallVector<T, AllocatorT, N>& operator=(const VmaSmallVector<SrcT, SrcAllocatorT, SrcN>&) = delete;
++ ~VmaSmallVector() = default;
++
++ bool empty() const { return m_Count == 0; }
++ size_t size() const { return m_Count; }
++ T* data() { return m_Count > N ? m_DynamicArray.data() : m_StaticArray; }
++ T& front() { VMA_HEAVY_ASSERT(m_Count > 0); return data()[0]; }
++ T& back() { VMA_HEAVY_ASSERT(m_Count > 0); return data()[m_Count - 1]; }
++ const T* data() const { return m_Count > N ? m_DynamicArray.data() : m_StaticArray; }
++ const T& front() const { VMA_HEAVY_ASSERT(m_Count > 0); return data()[0]; }
++ const T& back() const { VMA_HEAVY_ASSERT(m_Count > 0); return data()[m_Count - 1]; }
++
++ iterator begin() { return data(); }
++ iterator end() { return data() + m_Count; }
++
++ void pop_front() { VMA_HEAVY_ASSERT(m_Count > 0); remove(0); }
++ void pop_back() { VMA_HEAVY_ASSERT(m_Count > 0); resize(size() - 1); }
++ void push_front(const T& src) { insert(0, src); }
++
++ void push_back(const T& src);
++ void resize(size_t newCount, bool freeMemory = false);
++ void clear(bool freeMemory = false);
++ void insert(size_t index, const T& src);
++ void remove(size_t index);
++
++ T& operator[](size_t index) { VMA_HEAVY_ASSERT(index < m_Count); return data()[index]; }
++ const T& operator[](size_t index) const { VMA_HEAVY_ASSERT(index < m_Count); return data()[index]; }
++
++private:
++ size_t m_Count;
++ T m_StaticArray[N]; // Used when m_Size <= N
++ VmaVector<T, AllocatorT> m_DynamicArray; // Used when m_Size > N
++};
++
++#ifndef _VMA_SMALL_VECTOR_FUNCTIONS
++template<typename T, typename AllocatorT, size_t N>
++VmaSmallVector<T, AllocatorT, N>::VmaSmallVector(const AllocatorT& allocator)
++ : m_Count(0),
++ m_DynamicArray(allocator) {}
++
++template<typename T, typename AllocatorT, size_t N>
++VmaSmallVector<T, AllocatorT, N>::VmaSmallVector(size_t count, const AllocatorT& allocator)
++ : m_Count(count),
++ m_DynamicArray(count > N ? count : 0, allocator) {}
++
++template<typename T, typename AllocatorT, size_t N>
++void VmaSmallVector<T, AllocatorT, N>::push_back(const T& src)
++{
++ const size_t newIndex = size();
++ resize(newIndex + 1);
++ data()[newIndex] = src;
++}
++
++template<typename T, typename AllocatorT, size_t N>
++void VmaSmallVector<T, AllocatorT, N>::resize(size_t newCount, bool freeMemory)
++{
++ if (newCount > N && m_Count > N)
++ {
++ // Any direction, staying in m_DynamicArray
++ m_DynamicArray.resize(newCount);
++ if (freeMemory)
++ {
++ m_DynamicArray.shrink_to_fit();
++ }
++ }
++ else if (newCount > N && m_Count <= N)
++ {
++ // Growing, moving from m_StaticArray to m_DynamicArray
++ m_DynamicArray.resize(newCount);
++ if (m_Count > 0)
++ {
++ memcpy(m_DynamicArray.data(), m_StaticArray, m_Count * sizeof(T));
++ }
++ }
++ else if (newCount <= N && m_Count > N)
++ {
++ // Shrinking, moving from m_DynamicArray to m_StaticArray
++ if (newCount > 0)
++ {
++ memcpy(m_StaticArray, m_DynamicArray.data(), newCount * sizeof(T));
++ }
++ m_DynamicArray.resize(0);
++ if (freeMemory)
++ {
++ m_DynamicArray.shrink_to_fit();
++ }
++ }
++ else
++ {
++ // Any direction, staying in m_StaticArray - nothing to do here
++ }
++ m_Count = newCount;
++}
++
++template<typename T, typename AllocatorT, size_t N>
++void VmaSmallVector<T, AllocatorT, N>::clear(bool freeMemory)
++{
++ m_DynamicArray.clear();
++ if (freeMemory)
++ {
++ m_DynamicArray.shrink_to_fit();
++ }
++ m_Count = 0;
++}
++
++template<typename T, typename AllocatorT, size_t N>
++void VmaSmallVector<T, AllocatorT, N>::insert(size_t index, const T& src)
++{
++ VMA_HEAVY_ASSERT(index <= m_Count);
++ const size_t oldCount = size();
++ resize(oldCount + 1);
++ T* const dataPtr = data();
++ if (index < oldCount)
++ {
++ // I know, this could be more optimal for case where memmove can be memcpy directly from m_StaticArray to m_DynamicArray.
++ memmove(dataPtr + (index + 1), dataPtr + index, (oldCount - index) * sizeof(T));
++ }
++ dataPtr[index] = src;
++}
++
++template<typename T, typename AllocatorT, size_t N>
++void VmaSmallVector<T, AllocatorT, N>::remove(size_t index)
++{
++ VMA_HEAVY_ASSERT(index < m_Count);
++ const size_t oldCount = size();
++ if (index < oldCount - 1)
++ {
++ // I know, this could be more optimal for case where memmove can be memcpy directly from m_DynamicArray to m_StaticArray.
++ T* const dataPtr = data();
++ memmove(dataPtr + index, dataPtr + (index + 1), (oldCount - index - 1) * sizeof(T));
++ }
++ resize(oldCount - 1);
++}
++#endif // _VMA_SMALL_VECTOR_FUNCTIONS
++#endif // _VMA_SMALL_VECTOR
++
++#ifndef _VMA_POOL_ALLOCATOR
++/*
++Allocator for objects of type T using a list of arrays (pools) to speed up
++allocation. Number of elements that can be allocated is not bounded because
++allocator can create multiple blocks.
++*/
++template<typename T>
++class VmaPoolAllocator
++{
++ VMA_CLASS_NO_COPY(VmaPoolAllocator)
++public:
++ VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, uint32_t firstBlockCapacity);
++ ~VmaPoolAllocator();
++ template<typename... Types> T* Alloc(Types&&... args);
++ void Free(T* ptr);
++
++private:
++ union Item
++ {
++ uint32_t NextFreeIndex;
++ alignas(T) char Value[sizeof(T)];
++ };
++ struct ItemBlock
++ {
++ Item* pItems;
++ uint32_t Capacity;
++ uint32_t FirstFreeIndex;
++ };
++
++ const VkAllocationCallbacks* m_pAllocationCallbacks;
++ const uint32_t m_FirstBlockCapacity;
++ VmaVector<ItemBlock, VmaStlAllocator<ItemBlock>> m_ItemBlocks;
++
++ ItemBlock& CreateNewBlock();
++};
++
++#ifndef _VMA_POOL_ALLOCATOR_FUNCTIONS
++template<typename T>
++VmaPoolAllocator<T>::VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, uint32_t firstBlockCapacity)
++ : m_pAllocationCallbacks(pAllocationCallbacks),
++ m_FirstBlockCapacity(firstBlockCapacity),
++ m_ItemBlocks(VmaStlAllocator<ItemBlock>(pAllocationCallbacks))
++{
++ VMA_ASSERT(m_FirstBlockCapacity > 1);
++}
++
++template<typename T>
++VmaPoolAllocator<T>::~VmaPoolAllocator()
++{
++ for (size_t i = m_ItemBlocks.size(); i--;)
++ vma_delete_array(m_pAllocationCallbacks, m_ItemBlocks[i].pItems, m_ItemBlocks[i].Capacity);
++ m_ItemBlocks.clear();
++}
++
++template<typename T>
++template<typename... Types> T* VmaPoolAllocator<T>::Alloc(Types&&... args)
++{
++ for (size_t i = m_ItemBlocks.size(); i--; )
++ {
++ ItemBlock& block = m_ItemBlocks[i];
++ // This block has some free items: Use first one.
++ if (block.FirstFreeIndex != UINT32_MAX)
++ {
++ Item* const pItem = &block.pItems[block.FirstFreeIndex];
++ block.FirstFreeIndex = pItem->NextFreeIndex;
++ T* result = (T*)&pItem->Value;
++ new(result)T(std::forward<Types>(args)...); // Explicit constructor call.
++ return result;
++ }
++ }
++
++ // No block has free item: Create new one and use it.
++ ItemBlock& newBlock = CreateNewBlock();
++ Item* const pItem = &newBlock.pItems[0];
++ newBlock.FirstFreeIndex = pItem->NextFreeIndex;
++ T* result = (T*)&pItem->Value;
++ new(result) T(std::forward<Types>(args)...); // Explicit constructor call.
++ return result;
++}
++
++template<typename T>
++void VmaPoolAllocator<T>::Free(T* ptr)
++{
++ // Search all memory blocks to find ptr.
++ for (size_t i = m_ItemBlocks.size(); i--; )
++ {
++ ItemBlock& block = m_ItemBlocks[i];
++
++ // Casting to union.
++ Item* pItemPtr;
++ memcpy(&pItemPtr, &ptr, sizeof(pItemPtr));
++
++ // Check if pItemPtr is in address range of this block.
++ if ((pItemPtr >= block.pItems) && (pItemPtr < block.pItems + block.Capacity))
++ {
++ ptr->~T(); // Explicit destructor call.
++ const uint32_t index = static_cast<uint32_t>(pItemPtr - block.pItems);
++ pItemPtr->NextFreeIndex = block.FirstFreeIndex;
++ block.FirstFreeIndex = index;
++ return;
++ }
++ }
++ VMA_ASSERT(0 && "Pointer doesn't belong to this memory pool.");
++}
++
++template<typename T>
++typename VmaPoolAllocator<T>::ItemBlock& VmaPoolAllocator<T>::CreateNewBlock()
++{
++ const uint32_t newBlockCapacity = m_ItemBlocks.empty() ?
++ m_FirstBlockCapacity : m_ItemBlocks.back().Capacity * 3 / 2;
++
++ const ItemBlock newBlock =
++ {
++ vma_new_array(m_pAllocationCallbacks, Item, newBlockCapacity),
++ newBlockCapacity,
++ 0
++ };
++
++ m_ItemBlocks.push_back(newBlock);
++
++ // Setup singly-linked list of all free items in this block.
++ for (uint32_t i = 0; i < newBlockCapacity - 1; ++i)
++ newBlock.pItems[i].NextFreeIndex = i + 1;
++ newBlock.pItems[newBlockCapacity - 1].NextFreeIndex = UINT32_MAX;
++ return m_ItemBlocks.back();
++}
++#endif // _VMA_POOL_ALLOCATOR_FUNCTIONS
++#endif // _VMA_POOL_ALLOCATOR
++
++#ifndef _VMA_RAW_LIST
++template<typename T>
++struct VmaListItem
++{
++ VmaListItem* pPrev;
++ VmaListItem* pNext;
++ T Value;
++};
++
++// Doubly linked list.
++template<typename T>
++class VmaRawList
++{
++ VMA_CLASS_NO_COPY(VmaRawList)
++public:
++ typedef VmaListItem<T> ItemType;
++
++ VmaRawList(const VkAllocationCallbacks* pAllocationCallbacks);
++ // Intentionally not calling Clear, because that would be unnecessary
++ // computations to return all items to m_ItemAllocator as free.
++ ~VmaRawList() = default;
++
++ size_t GetCount() const { return m_Count; }
++ bool IsEmpty() const { return m_Count == 0; }
++
++ ItemType* Front() { return m_pFront; }
++ ItemType* Back() { return m_pBack; }
++ const ItemType* Front() const { return m_pFront; }
++ const ItemType* Back() const { return m_pBack; }
++
++ ItemType* PushFront();
++ ItemType* PushBack();
++ ItemType* PushFront(const T& value);
++ ItemType* PushBack(const T& value);
++ void PopFront();
++ void PopBack();
++
++ // Item can be null - it means PushBack.
++ ItemType* InsertBefore(ItemType* pItem);
++ // Item can be null - it means PushFront.
++ ItemType* InsertAfter(ItemType* pItem);
++ ItemType* InsertBefore(ItemType* pItem, const T& value);
++ ItemType* InsertAfter(ItemType* pItem, const T& value);
++
++ void Clear();
++ void Remove(ItemType* pItem);
++
++private:
++ const VkAllocationCallbacks* const m_pAllocationCallbacks;
++ VmaPoolAllocator<ItemType> m_ItemAllocator;
++ ItemType* m_pFront;
++ ItemType* m_pBack;
++ size_t m_Count;
++};
++
++#ifndef _VMA_RAW_LIST_FUNCTIONS
++template<typename T>
++VmaRawList<T>::VmaRawList(const VkAllocationCallbacks* pAllocationCallbacks)
++ : m_pAllocationCallbacks(pAllocationCallbacks),
++ m_ItemAllocator(pAllocationCallbacks, 128),
++ m_pFront(VMA_NULL),
++ m_pBack(VMA_NULL),
++ m_Count(0) {}
++
++template<typename T>
++VmaListItem<T>* VmaRawList<T>::PushFront()
++{
++ ItemType* const pNewItem = m_ItemAllocator.Alloc();
++ pNewItem->pPrev = VMA_NULL;
++ if (IsEmpty())
++ {
++ pNewItem->pNext = VMA_NULL;
++ m_pFront = pNewItem;
++ m_pBack = pNewItem;
++ m_Count = 1;
++ }
++ else
++ {
++ pNewItem->pNext = m_pFront;
++ m_pFront->pPrev = pNewItem;
++ m_pFront = pNewItem;
++ ++m_Count;
++ }
++ return pNewItem;
++}
++
++template<typename T>
++VmaListItem<T>* VmaRawList<T>::PushBack()
++{
++ ItemType* const pNewItem = m_ItemAllocator.Alloc();
++ pNewItem->pNext = VMA_NULL;
++ if(IsEmpty())
++ {
++ pNewItem->pPrev = VMA_NULL;
++ m_pFront = pNewItem;
++ m_pBack = pNewItem;
++ m_Count = 1;
++ }
++ else
++ {
++ pNewItem->pPrev = m_pBack;
++ m_pBack->pNext = pNewItem;
++ m_pBack = pNewItem;
++ ++m_Count;
++ }
++ return pNewItem;
++}
++
++template<typename T>
++VmaListItem<T>* VmaRawList<T>::PushFront(const T& value)
++{
++ ItemType* const pNewItem = PushFront();
++ pNewItem->Value = value;
++ return pNewItem;
++}
++
++template<typename T>
++VmaListItem<T>* VmaRawList<T>::PushBack(const T& value)
++{
++ ItemType* const pNewItem = PushBack();
++ pNewItem->Value = value;
++ return pNewItem;
++}
++
++template<typename T>
++void VmaRawList<T>::PopFront()
++{
++ VMA_HEAVY_ASSERT(m_Count > 0);
++ ItemType* const pFrontItem = m_pFront;
++ ItemType* const pNextItem = pFrontItem->pNext;
++ if (pNextItem != VMA_NULL)
++ {
++ pNextItem->pPrev = VMA_NULL;
++ }
++ m_pFront = pNextItem;
++ m_ItemAllocator.Free(pFrontItem);
++ --m_Count;
++}
++
++template<typename T>
++void VmaRawList<T>::PopBack()
++{
++ VMA_HEAVY_ASSERT(m_Count > 0);
++ ItemType* const pBackItem = m_pBack;
++ ItemType* const pPrevItem = pBackItem->pPrev;
++ if(pPrevItem != VMA_NULL)
++ {
++ pPrevItem->pNext = VMA_NULL;
++ }
++ m_pBack = pPrevItem;
++ m_ItemAllocator.Free(pBackItem);
++ --m_Count;
++}
++
++template<typename T>
++void VmaRawList<T>::Clear()
++{
++ if (IsEmpty() == false)
++ {
++ ItemType* pItem = m_pBack;
++ while (pItem != VMA_NULL)
++ {
++ ItemType* const pPrevItem = pItem->pPrev;
++ m_ItemAllocator.Free(pItem);
++ pItem = pPrevItem;
++ }
++ m_pFront = VMA_NULL;
++ m_pBack = VMA_NULL;
++ m_Count = 0;
++ }
++}
++
++template<typename T>
++void VmaRawList<T>::Remove(ItemType* pItem)
++{
++ VMA_HEAVY_ASSERT(pItem != VMA_NULL);
++ VMA_HEAVY_ASSERT(m_Count > 0);
++
++ if(pItem->pPrev != VMA_NULL)
++ {
++ pItem->pPrev->pNext = pItem->pNext;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(m_pFront == pItem);
++ m_pFront = pItem->pNext;
++ }
++
++ if(pItem->pNext != VMA_NULL)
++ {
++ pItem->pNext->pPrev = pItem->pPrev;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(m_pBack == pItem);
++ m_pBack = pItem->pPrev;
++ }
++
++ m_ItemAllocator.Free(pItem);
++ --m_Count;
++}
++
++template<typename T>
++VmaListItem<T>* VmaRawList<T>::InsertBefore(ItemType* pItem)
++{
++ if(pItem != VMA_NULL)
++ {
++ ItemType* const prevItem = pItem->pPrev;
++ ItemType* const newItem = m_ItemAllocator.Alloc();
++ newItem->pPrev = prevItem;
++ newItem->pNext = pItem;
++ pItem->pPrev = newItem;
++ if(prevItem != VMA_NULL)
++ {
++ prevItem->pNext = newItem;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(m_pFront == pItem);
++ m_pFront = newItem;
++ }
++ ++m_Count;
++ return newItem;
++ }
++ else
++ return PushBack();
++}
++
++template<typename T>
++VmaListItem<T>* VmaRawList<T>::InsertAfter(ItemType* pItem)
++{
++ if(pItem != VMA_NULL)
++ {
++ ItemType* const nextItem = pItem->pNext;
++ ItemType* const newItem = m_ItemAllocator.Alloc();
++ newItem->pNext = nextItem;
++ newItem->pPrev = pItem;
++ pItem->pNext = newItem;
++ if(nextItem != VMA_NULL)
++ {
++ nextItem->pPrev = newItem;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(m_pBack == pItem);
++ m_pBack = newItem;
++ }
++ ++m_Count;
++ return newItem;
++ }
++ else
++ return PushFront();
++}
++
++template<typename T>
++VmaListItem<T>* VmaRawList<T>::InsertBefore(ItemType* pItem, const T& value)
++{
++ ItemType* const newItem = InsertBefore(pItem);
++ newItem->Value = value;
++ return newItem;
++}
++
++template<typename T>
++VmaListItem<T>* VmaRawList<T>::InsertAfter(ItemType* pItem, const T& value)
++{
++ ItemType* const newItem = InsertAfter(pItem);
++ newItem->Value = value;
++ return newItem;
++}
++#endif // _VMA_RAW_LIST_FUNCTIONS
++#endif // _VMA_RAW_LIST
++
++#ifndef _VMA_LIST
++template<typename T, typename AllocatorT>
++class VmaList
++{
++ VMA_CLASS_NO_COPY(VmaList)
++public:
++ class reverse_iterator;
++ class const_iterator;
++ class const_reverse_iterator;
++
++ class iterator
++ {
++ friend class const_iterator;
++ friend class VmaList<T, AllocatorT>;
++ public:
++ iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {}
++ iterator(const reverse_iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
++
++ T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; }
++ T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; }
++
++ bool operator==(const iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem == rhs.m_pItem; }
++ bool operator!=(const iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; }
++
++ iterator operator++(int) { iterator result = *this; ++*this; return result; }
++ iterator operator--(int) { iterator result = *this; --*this; return result; }
++
++ iterator& operator++() { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); m_pItem = m_pItem->pNext; return *this; }
++ iterator& operator--();
++
++ private:
++ VmaRawList<T>* m_pList;
++ VmaListItem<T>* m_pItem;
++
++ iterator(VmaRawList<T>* pList, VmaListItem<T>* pItem) : m_pList(pList), m_pItem(pItem) {}
++ };
++ class reverse_iterator
++ {
++ friend class const_reverse_iterator;
++ friend class VmaList<T, AllocatorT>;
++ public:
++ reverse_iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {}
++ reverse_iterator(const iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
++
++ T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; }
++ T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; }
++
++ bool operator==(const reverse_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem == rhs.m_pItem; }
++ bool operator!=(const reverse_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; }
++
++ reverse_iterator operator++(int) { reverse_iterator result = *this; ++* this; return result; }
++ reverse_iterator operator--(int) { reverse_iterator result = *this; --* this; return result; }
++
++ reverse_iterator& operator++() { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); m_pItem = m_pItem->pPrev; return *this; }
++ reverse_iterator& operator--();
++
++ private:
++ VmaRawList<T>* m_pList;
++ VmaListItem<T>* m_pItem;
++
++ reverse_iterator(VmaRawList<T>* pList, VmaListItem<T>* pItem) : m_pList(pList), m_pItem(pItem) {}
++ };
++ class const_iterator
++ {
++ friend class VmaList<T, AllocatorT>;
++ public:
++ const_iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {}
++ const_iterator(const iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
++ const_iterator(const reverse_iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
++
++ iterator drop_const() { return { const_cast<VmaRawList<T>*>(m_pList), const_cast<VmaListItem<T>*>(m_pItem) }; }
++
++ const T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; }
++ const T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; }
++
++ bool operator==(const const_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem == rhs.m_pItem; }
++ bool operator!=(const const_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; }
++
++ const_iterator operator++(int) { const_iterator result = *this; ++* this; return result; }
++ const_iterator operator--(int) { const_iterator result = *this; --* this; return result; }
++
++ const_iterator& operator++() { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); m_pItem = m_pItem->pNext; return *this; }
++ const_iterator& operator--();
++
++ private:
++ const VmaRawList<T>* m_pList;
++ const VmaListItem<T>* m_pItem;
++
++ const_iterator(const VmaRawList<T>* pList, const VmaListItem<T>* pItem) : m_pList(pList), m_pItem(pItem) {}
++ };
++ class const_reverse_iterator
++ {
++ friend class VmaList<T, AllocatorT>;
++ public:
++ const_reverse_iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {}
++ const_reverse_iterator(const reverse_iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
++ const_reverse_iterator(const iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {}
++
++ reverse_iterator drop_const() { return { const_cast<VmaRawList<T>*>(m_pList), const_cast<VmaListItem<T>*>(m_pItem) }; }
++
++ const T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; }
++ const T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; }
++
++ bool operator==(const const_reverse_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem == rhs.m_pItem; }
++ bool operator!=(const const_reverse_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; }
++
++ const_reverse_iterator operator++(int) { const_reverse_iterator result = *this; ++* this; return result; }
++ const_reverse_iterator operator--(int) { const_reverse_iterator result = *this; --* this; return result; }
++
++ const_reverse_iterator& operator++() { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); m_pItem = m_pItem->pPrev; return *this; }
++ const_reverse_iterator& operator--();
++
++ private:
++ const VmaRawList<T>* m_pList;
++ const VmaListItem<T>* m_pItem;
++
++ const_reverse_iterator(const VmaRawList<T>* pList, const VmaListItem<T>* pItem) : m_pList(pList), m_pItem(pItem) {}
++ };
++
++ VmaList(const AllocatorT& allocator) : m_RawList(allocator.m_pCallbacks) {}
++
++ bool empty() const { return m_RawList.IsEmpty(); }
++ size_t size() const { return m_RawList.GetCount(); }
++
++ iterator begin() { return iterator(&m_RawList, m_RawList.Front()); }
++ iterator end() { return iterator(&m_RawList, VMA_NULL); }
++
++ const_iterator cbegin() const { return const_iterator(&m_RawList, m_RawList.Front()); }
++ const_iterator cend() const { return const_iterator(&m_RawList, VMA_NULL); }
++
++ const_iterator begin() const { return cbegin(); }
++ const_iterator end() const { return cend(); }
++
++ reverse_iterator rbegin() { return reverse_iterator(&m_RawList, m_RawList.Back()); }
++ reverse_iterator rend() { return reverse_iterator(&m_RawList, VMA_NULL); }
++
++ const_reverse_iterator crbegin() const { return const_reverse_iterator(&m_RawList, m_RawList.Back()); }
++ const_reverse_iterator crend() const { return const_reverse_iterator(&m_RawList, VMA_NULL); }
++
++ const_reverse_iterator rbegin() const { return crbegin(); }
++ const_reverse_iterator rend() const { return crend(); }
++
++ void push_back(const T& value) { m_RawList.PushBack(value); }
++ iterator insert(iterator it, const T& value) { return iterator(&m_RawList, m_RawList.InsertBefore(it.m_pItem, value)); }
++
++ void clear() { m_RawList.Clear(); }
++ void erase(iterator it) { m_RawList.Remove(it.m_pItem); }
++
++private:
++ VmaRawList<T> m_RawList;
++};
++
++#ifndef _VMA_LIST_FUNCTIONS
++template<typename T, typename AllocatorT>
++typename VmaList<T, AllocatorT>::iterator& VmaList<T, AllocatorT>::iterator::operator--()
++{
++ if (m_pItem != VMA_NULL)
++ {
++ m_pItem = m_pItem->pPrev;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(!m_pList->IsEmpty());
++ m_pItem = m_pList->Back();
++ }
++ return *this;
++}
++
++template<typename T, typename AllocatorT>
++typename VmaList<T, AllocatorT>::reverse_iterator& VmaList<T, AllocatorT>::reverse_iterator::operator--()
++{
++ if (m_pItem != VMA_NULL)
++ {
++ m_pItem = m_pItem->pNext;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(!m_pList->IsEmpty());
++ m_pItem = m_pList->Front();
++ }
++ return *this;
++}
++
++template<typename T, typename AllocatorT>
++typename VmaList<T, AllocatorT>::const_iterator& VmaList<T, AllocatorT>::const_iterator::operator--()
++{
++ if (m_pItem != VMA_NULL)
++ {
++ m_pItem = m_pItem->pPrev;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(!m_pList->IsEmpty());
++ m_pItem = m_pList->Back();
++ }
++ return *this;
++}
++
++template<typename T, typename AllocatorT>
++typename VmaList<T, AllocatorT>::const_reverse_iterator& VmaList<T, AllocatorT>::const_reverse_iterator::operator--()
++{
++ if (m_pItem != VMA_NULL)
++ {
++ m_pItem = m_pItem->pNext;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(!m_pList->IsEmpty());
++ m_pItem = m_pList->Back();
++ }
++ return *this;
++}
++#endif // _VMA_LIST_FUNCTIONS
++#endif // _VMA_LIST
++
++#ifndef _VMA_INTRUSIVE_LINKED_LIST
++/*
++Expected interface of ItemTypeTraits:
++struct MyItemTypeTraits
++{
++ typedef MyItem ItemType;
++ static ItemType* GetPrev(const ItemType* item) { return item->myPrevPtr; }
++ static ItemType* GetNext(const ItemType* item) { return item->myNextPtr; }
++ static ItemType*& AccessPrev(ItemType* item) { return item->myPrevPtr; }
++ static ItemType*& AccessNext(ItemType* item) { return item->myNextPtr; }
++};
++*/
++template<typename ItemTypeTraits>
++class VmaIntrusiveLinkedList
++{
++public:
++ typedef typename ItemTypeTraits::ItemType ItemType;
++ static ItemType* GetPrev(const ItemType* item) { return ItemTypeTraits::GetPrev(item); }
++ static ItemType* GetNext(const ItemType* item) { return ItemTypeTraits::GetNext(item); }
++
++ // Movable, not copyable.
++ VmaIntrusiveLinkedList() = default;
++ VmaIntrusiveLinkedList(VmaIntrusiveLinkedList && src);
++ VmaIntrusiveLinkedList(const VmaIntrusiveLinkedList&) = delete;
++ VmaIntrusiveLinkedList& operator=(VmaIntrusiveLinkedList&& src);
++ VmaIntrusiveLinkedList& operator=(const VmaIntrusiveLinkedList&) = delete;
++ ~VmaIntrusiveLinkedList() { VMA_HEAVY_ASSERT(IsEmpty()); }
++
++ size_t GetCount() const { return m_Count; }
++ bool IsEmpty() const { return m_Count == 0; }
++ ItemType* Front() { return m_Front; }
++ ItemType* Back() { return m_Back; }
++ const ItemType* Front() const { return m_Front; }
++ const ItemType* Back() const { return m_Back; }
++
++ void PushBack(ItemType* item);
++ void PushFront(ItemType* item);
++ ItemType* PopBack();
++ ItemType* PopFront();
++
++ // MyItem can be null - it means PushBack.
++ void InsertBefore(ItemType* existingItem, ItemType* newItem);
++ // MyItem can be null - it means PushFront.
++ void InsertAfter(ItemType* existingItem, ItemType* newItem);
++ void Remove(ItemType* item);
++ void RemoveAll();
++
++private:
++ ItemType* m_Front = VMA_NULL;
++ ItemType* m_Back = VMA_NULL;
++ size_t m_Count = 0;
++};
++
++#ifndef _VMA_INTRUSIVE_LINKED_LIST_FUNCTIONS
++template<typename ItemTypeTraits>
++VmaIntrusiveLinkedList<ItemTypeTraits>::VmaIntrusiveLinkedList(VmaIntrusiveLinkedList&& src)
++ : m_Front(src.m_Front), m_Back(src.m_Back), m_Count(src.m_Count)
++{
++ src.m_Front = src.m_Back = VMA_NULL;
++ src.m_Count = 0;
++}
++
++template<typename ItemTypeTraits>
++VmaIntrusiveLinkedList<ItemTypeTraits>& VmaIntrusiveLinkedList<ItemTypeTraits>::operator=(VmaIntrusiveLinkedList&& src)
++{
++ if (&src != this)
++ {
++ VMA_HEAVY_ASSERT(IsEmpty());
++ m_Front = src.m_Front;
++ m_Back = src.m_Back;
++ m_Count = src.m_Count;
++ src.m_Front = src.m_Back = VMA_NULL;
++ src.m_Count = 0;
++ }
++ return *this;
++}
++
++template<typename ItemTypeTraits>
++void VmaIntrusiveLinkedList<ItemTypeTraits>::PushBack(ItemType* item)
++{
++ VMA_HEAVY_ASSERT(ItemTypeTraits::GetPrev(item) == VMA_NULL && ItemTypeTraits::GetNext(item) == VMA_NULL);
++ if (IsEmpty())
++ {
++ m_Front = item;
++ m_Back = item;
++ m_Count = 1;
++ }
++ else
++ {
++ ItemTypeTraits::AccessPrev(item) = m_Back;
++ ItemTypeTraits::AccessNext(m_Back) = item;
++ m_Back = item;
++ ++m_Count;
++ }
++}
++
++template<typename ItemTypeTraits>
++void VmaIntrusiveLinkedList<ItemTypeTraits>::PushFront(ItemType* item)
++{
++ VMA_HEAVY_ASSERT(ItemTypeTraits::GetPrev(item) == VMA_NULL && ItemTypeTraits::GetNext(item) == VMA_NULL);
++ if (IsEmpty())
++ {
++ m_Front = item;
++ m_Back = item;
++ m_Count = 1;
++ }
++ else
++ {
++ ItemTypeTraits::AccessNext(item) = m_Front;
++ ItemTypeTraits::AccessPrev(m_Front) = item;
++ m_Front = item;
++ ++m_Count;
++ }
++}
++
++template<typename ItemTypeTraits>
++typename VmaIntrusiveLinkedList<ItemTypeTraits>::ItemType* VmaIntrusiveLinkedList<ItemTypeTraits>::PopBack()
++{
++ VMA_HEAVY_ASSERT(m_Count > 0);
++ ItemType* const backItem = m_Back;
++ ItemType* const prevItem = ItemTypeTraits::GetPrev(backItem);
++ if (prevItem != VMA_NULL)
++ {
++ ItemTypeTraits::AccessNext(prevItem) = VMA_NULL;
++ }
++ m_Back = prevItem;
++ --m_Count;
++ ItemTypeTraits::AccessPrev(backItem) = VMA_NULL;
++ ItemTypeTraits::AccessNext(backItem) = VMA_NULL;
++ return backItem;
++}
++
++template<typename ItemTypeTraits>
++typename VmaIntrusiveLinkedList<ItemTypeTraits>::ItemType* VmaIntrusiveLinkedList<ItemTypeTraits>::PopFront()
++{
++ VMA_HEAVY_ASSERT(m_Count > 0);
++ ItemType* const frontItem = m_Front;
++ ItemType* const nextItem = ItemTypeTraits::GetNext(frontItem);
++ if (nextItem != VMA_NULL)
++ {
++ ItemTypeTraits::AccessPrev(nextItem) = VMA_NULL;
++ }
++ m_Front = nextItem;
++ --m_Count;
++ ItemTypeTraits::AccessPrev(frontItem) = VMA_NULL;
++ ItemTypeTraits::AccessNext(frontItem) = VMA_NULL;
++ return frontItem;
++}
++
++template<typename ItemTypeTraits>
++void VmaIntrusiveLinkedList<ItemTypeTraits>::InsertBefore(ItemType* existingItem, ItemType* newItem)
++{
++ VMA_HEAVY_ASSERT(newItem != VMA_NULL && ItemTypeTraits::GetPrev(newItem) == VMA_NULL && ItemTypeTraits::GetNext(newItem) == VMA_NULL);
++ if (existingItem != VMA_NULL)
++ {
++ ItemType* const prevItem = ItemTypeTraits::GetPrev(existingItem);
++ ItemTypeTraits::AccessPrev(newItem) = prevItem;
++ ItemTypeTraits::AccessNext(newItem) = existingItem;
++ ItemTypeTraits::AccessPrev(existingItem) = newItem;
++ if (prevItem != VMA_NULL)
++ {
++ ItemTypeTraits::AccessNext(prevItem) = newItem;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(m_Front == existingItem);
++ m_Front = newItem;
++ }
++ ++m_Count;
++ }
++ else
++ PushBack(newItem);
++}
++
++template<typename ItemTypeTraits>
++void VmaIntrusiveLinkedList<ItemTypeTraits>::InsertAfter(ItemType* existingItem, ItemType* newItem)
++{
++ VMA_HEAVY_ASSERT(newItem != VMA_NULL && ItemTypeTraits::GetPrev(newItem) == VMA_NULL && ItemTypeTraits::GetNext(newItem) == VMA_NULL);
++ if (existingItem != VMA_NULL)
++ {
++ ItemType* const nextItem = ItemTypeTraits::GetNext(existingItem);
++ ItemTypeTraits::AccessNext(newItem) = nextItem;
++ ItemTypeTraits::AccessPrev(newItem) = existingItem;
++ ItemTypeTraits::AccessNext(existingItem) = newItem;
++ if (nextItem != VMA_NULL)
++ {
++ ItemTypeTraits::AccessPrev(nextItem) = newItem;
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(m_Back == existingItem);
++ m_Back = newItem;
++ }
++ ++m_Count;
++ }
++ else
++ return PushFront(newItem);
++}
++
++template<typename ItemTypeTraits>
++void VmaIntrusiveLinkedList<ItemTypeTraits>::Remove(ItemType* item)
++{
++ VMA_HEAVY_ASSERT(item != VMA_NULL && m_Count > 0);
++ if (ItemTypeTraits::GetPrev(item) != VMA_NULL)
++ {
++ ItemTypeTraits::AccessNext(ItemTypeTraits::AccessPrev(item)) = ItemTypeTraits::GetNext(item);
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(m_Front == item);
++ m_Front = ItemTypeTraits::GetNext(item);
++ }
++
++ if (ItemTypeTraits::GetNext(item) != VMA_NULL)
++ {
++ ItemTypeTraits::AccessPrev(ItemTypeTraits::AccessNext(item)) = ItemTypeTraits::GetPrev(item);
++ }
++ else
++ {
++ VMA_HEAVY_ASSERT(m_Back == item);
++ m_Back = ItemTypeTraits::GetPrev(item);
++ }
++ ItemTypeTraits::AccessPrev(item) = VMA_NULL;
++ ItemTypeTraits::AccessNext(item) = VMA_NULL;
++ --m_Count;
++}
++
++template<typename ItemTypeTraits>
++void VmaIntrusiveLinkedList<ItemTypeTraits>::RemoveAll()
++{
++ if (!IsEmpty())
++ {
++ ItemType* item = m_Back;
++ while (item != VMA_NULL)
++ {
++ ItemType* const prevItem = ItemTypeTraits::AccessPrev(item);
++ ItemTypeTraits::AccessPrev(item) = VMA_NULL;
++ ItemTypeTraits::AccessNext(item) = VMA_NULL;
++ item = prevItem;
++ }
++ m_Front = VMA_NULL;
++ m_Back = VMA_NULL;
++ m_Count = 0;
++ }
++}
++#endif // _VMA_INTRUSIVE_LINKED_LIST_FUNCTIONS
++#endif // _VMA_INTRUSIVE_LINKED_LIST
++
++// Unused in this version.
++#if 0
++
++#ifndef _VMA_PAIR
++template<typename T1, typename T2>
++struct VmaPair
++{
++ T1 first;
++ T2 second;
++
++ VmaPair() : first(), second() {}
++ VmaPair(const T1& firstSrc, const T2& secondSrc) : first(firstSrc), second(secondSrc) {}
++};
++
++template<typename FirstT, typename SecondT>
++struct VmaPairFirstLess
++{
++ bool operator()(const VmaPair<FirstT, SecondT>& lhs, const VmaPair<FirstT, SecondT>& rhs) const
++ {
++ return lhs.first < rhs.first;
++ }
++ bool operator()(const VmaPair<FirstT, SecondT>& lhs, const FirstT& rhsFirst) const
++ {
++ return lhs.first < rhsFirst;
++ }
++};
++#endif // _VMA_PAIR
++
++#ifndef _VMA_MAP
++/* Class compatible with subset of interface of std::unordered_map.
++KeyT, ValueT must be POD because they will be stored in VmaVector.
++*/
++template<typename KeyT, typename ValueT>
++class VmaMap
++{
++public:
++ typedef VmaPair<KeyT, ValueT> PairType;
++ typedef PairType* iterator;
++
++ VmaMap(const VmaStlAllocator<PairType>& allocator) : m_Vector(allocator) {}
++
++ iterator begin() { return m_Vector.begin(); }
++ iterator end() { return m_Vector.end(); }
++ size_t size() { return m_Vector.size(); }
++
++ void insert(const PairType& pair);
++ iterator find(const KeyT& key);
++ void erase(iterator it);
++
++private:
++ VmaVector< PairType, VmaStlAllocator<PairType>> m_Vector;
++};
++
++#ifndef _VMA_MAP_FUNCTIONS
++template<typename KeyT, typename ValueT>
++void VmaMap<KeyT, ValueT>::insert(const PairType& pair)
++{
++ const size_t indexToInsert = VmaBinaryFindFirstNotLess(
++ m_Vector.data(),
++ m_Vector.data() + m_Vector.size(),
++ pair,
++ VmaPairFirstLess<KeyT, ValueT>()) - m_Vector.data();
++ VmaVectorInsert(m_Vector, indexToInsert, pair);
++}
++
++template<typename KeyT, typename ValueT>
++VmaPair<KeyT, ValueT>* VmaMap<KeyT, ValueT>::find(const KeyT& key)
++{
++ PairType* it = VmaBinaryFindFirstNotLess(
++ m_Vector.data(),
++ m_Vector.data() + m_Vector.size(),
++ key,
++ VmaPairFirstLess<KeyT, ValueT>());
++ if ((it != m_Vector.end()) && (it->first == key))
++ {
++ return it;
++ }
++ else
++ {
++ return m_Vector.end();
++ }
++}
++
++template<typename KeyT, typename ValueT>
++void VmaMap<KeyT, ValueT>::erase(iterator it)
++{
++ VmaVectorRemove(m_Vector, it - m_Vector.begin());
++}
++#endif // _VMA_MAP_FUNCTIONS
++#endif // _VMA_MAP
++
++#endif // #if 0
++
++#if !defined(_VMA_STRING_BUILDER) && VMA_STATS_STRING_ENABLED
++class VmaStringBuilder
++{
++public:
++ VmaStringBuilder(const VkAllocationCallbacks* allocationCallbacks) : m_Data(VmaStlAllocator<char>(allocationCallbacks)) {}
++ ~VmaStringBuilder() = default;
++
++ size_t GetLength() const { return m_Data.size(); }
++ const char* GetData() const { return m_Data.data(); }
++ void AddNewLine() { Add('\n'); }
++ void Add(char ch) { m_Data.push_back(ch); }
++
++ void Add(const char* pStr);
++ void AddNumber(uint32_t num);
++ void AddNumber(uint64_t num);
++ void AddPointer(const void* ptr);
++
++private:
++ VmaVector<char, VmaStlAllocator<char>> m_Data;
++};
++
++#ifndef _VMA_STRING_BUILDER_FUNCTIONS
++void VmaStringBuilder::Add(const char* pStr)
++{
++ const size_t strLen = strlen(pStr);
++ if (strLen > 0)
++ {
++ const size_t oldCount = m_Data.size();
++ m_Data.resize(oldCount + strLen);
++ memcpy(m_Data.data() + oldCount, pStr, strLen);
++ }
++}
++
++void VmaStringBuilder::AddNumber(uint32_t num)
++{
++ char buf[11];
++ buf[10] = '\0';
++ char* p = &buf[10];
++ do
++ {
++ *--p = '0' + (num % 10);
++ num /= 10;
++ } while (num);
++ Add(p);
++}
++
++void VmaStringBuilder::AddNumber(uint64_t num)
++{
++ char buf[21];
++ buf[20] = '\0';
++ char* p = &buf[20];
++ do
++ {
++ *--p = '0' + (num % 10);
++ num /= 10;
++ } while (num);
++ Add(p);
++}
++
++void VmaStringBuilder::AddPointer(const void* ptr)
++{
++ char buf[21];
++ VmaPtrToStr(buf, sizeof(buf), ptr);
++ Add(buf);
++}
++#endif //_VMA_STRING_BUILDER_FUNCTIONS
++#endif // _VMA_STRING_BUILDER
++
++#if !defined(_VMA_JSON_WRITER) && VMA_STATS_STRING_ENABLED
++/*
++Allows to conveniently build a correct JSON document to be written to the
++VmaStringBuilder passed to the constructor.
++*/
++class VmaJsonWriter
++{
++ VMA_CLASS_NO_COPY(VmaJsonWriter)
++public:
++ // sb - string builder to write the document to. Must remain alive for the whole lifetime of this object.
++ VmaJsonWriter(const VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder& sb);
++ ~VmaJsonWriter();
++
++ // Begins object by writing "{".
++ // Inside an object, you must call pairs of WriteString and a value, e.g.:
++ // j.BeginObject(true); j.WriteString("A"); j.WriteNumber(1); j.WriteString("B"); j.WriteNumber(2); j.EndObject();
++ // Will write: { "A": 1, "B": 2 }
++ void BeginObject(bool singleLine = false);
++ // Ends object by writing "}".
++ void EndObject();
++
++ // Begins array by writing "[".
++ // Inside an array, you can write a sequence of any values.
++ void BeginArray(bool singleLine = false);
++ // Ends array by writing "[".
++ void EndArray();
++
++ // Writes a string value inside "".
++ // pStr can contain any ANSI characters, including '"', new line etc. - they will be properly escaped.
++ void WriteString(const char* pStr);
++
++ // Begins writing a string value.
++ // Call BeginString, ContinueString, ContinueString, ..., EndString instead of
++ // WriteString to conveniently build the string content incrementally, made of
++ // parts including numbers.
++ void BeginString(const char* pStr = VMA_NULL);
++ // Posts next part of an open string.
++ void ContinueString(const char* pStr);
++ // Posts next part of an open string. The number is converted to decimal characters.
++ void ContinueString(uint32_t n);
++ void ContinueString(uint64_t n);
++ void ContinueString_Size(size_t n);
++ // Posts next part of an open string. Pointer value is converted to characters
++ // using "%p" formatting - shown as hexadecimal number, e.g.: 000000081276Ad00
++ void ContinueString_Pointer(const void* ptr);
++ // Ends writing a string value by writing '"'.
++ void EndString(const char* pStr = VMA_NULL);
++
++ // Writes a number value.
++ void WriteNumber(uint32_t n);
++ void WriteNumber(uint64_t n);
++ void WriteSize(size_t n);
++ // Writes a boolean value - false or true.
++ void WriteBool(bool b);
++ // Writes a null value.
++ void WriteNull();
++
++private:
++ enum COLLECTION_TYPE
++ {
++ COLLECTION_TYPE_OBJECT,
++ COLLECTION_TYPE_ARRAY,
++ };
++ struct StackItem
++ {
++ COLLECTION_TYPE type;
++ uint32_t valueCount;
++ bool singleLineMode;
++ };
++
++ static const char* const INDENT;
++
++ VmaStringBuilder& m_SB;
++ VmaVector< StackItem, VmaStlAllocator<StackItem> > m_Stack;
++ bool m_InsideString;
++
++ // Write size_t for less than 64bits
++ void WriteSize(size_t n, std::integral_constant<bool, false>) { m_SB.AddNumber(static_cast<uint32_t>(n)); }
++ // Write size_t for 64bits
++ void WriteSize(size_t n, std::integral_constant<bool, true>) { m_SB.AddNumber(static_cast<uint64_t>(n)); }
++
++ void BeginValue(bool isString);
++ void WriteIndent(bool oneLess = false);
++};
++const char* const VmaJsonWriter::INDENT = " ";
++
++#ifndef _VMA_JSON_WRITER_FUNCTIONS
++VmaJsonWriter::VmaJsonWriter(const VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder& sb)
++ : m_SB(sb),
++ m_Stack(VmaStlAllocator<StackItem>(pAllocationCallbacks)),
++ m_InsideString(false) {}
++
++VmaJsonWriter::~VmaJsonWriter()
++{
++ VMA_ASSERT(!m_InsideString);
++ VMA_ASSERT(m_Stack.empty());
++}
++
++void VmaJsonWriter::BeginObject(bool singleLine)
++{
++ VMA_ASSERT(!m_InsideString);
++
++ BeginValue(false);
++ m_SB.Add('{');
++
++ StackItem item;
++ item.type = COLLECTION_TYPE_OBJECT;
++ item.valueCount = 0;
++ item.singleLineMode = singleLine;
++ m_Stack.push_back(item);
++}
++
++void VmaJsonWriter::EndObject()
++{
++ VMA_ASSERT(!m_InsideString);
++
++ WriteIndent(true);
++ m_SB.Add('}');
++
++ VMA_ASSERT(!m_Stack.empty() && m_Stack.back().type == COLLECTION_TYPE_OBJECT);
++ m_Stack.pop_back();
++}
++
++void VmaJsonWriter::BeginArray(bool singleLine)
++{
++ VMA_ASSERT(!m_InsideString);
++
++ BeginValue(false);
++ m_SB.Add('[');
++
++ StackItem item;
++ item.type = COLLECTION_TYPE_ARRAY;
++ item.valueCount = 0;
++ item.singleLineMode = singleLine;
++ m_Stack.push_back(item);
++}
++
++void VmaJsonWriter::EndArray()
++{
++ VMA_ASSERT(!m_InsideString);
++
++ WriteIndent(true);
++ m_SB.Add(']');
++
++ VMA_ASSERT(!m_Stack.empty() && m_Stack.back().type == COLLECTION_TYPE_ARRAY);
++ m_Stack.pop_back();
++}
++
++void VmaJsonWriter::WriteString(const char* pStr)
++{
++ BeginString(pStr);
++ EndString();
++}
++
++void VmaJsonWriter::BeginString(const char* pStr)
++{
++ VMA_ASSERT(!m_InsideString);
++
++ BeginValue(true);
++ m_SB.Add('"');
++ m_InsideString = true;
++ if (pStr != VMA_NULL && pStr[0] != '\0')
++ {
++ ContinueString(pStr);
++ }
++}
++
++void VmaJsonWriter::ContinueString(const char* pStr)
++{
++ VMA_ASSERT(m_InsideString);
++
++ const size_t strLen = strlen(pStr);
++ for (size_t i = 0; i < strLen; ++i)
++ {
++ char ch = pStr[i];
++ if (ch == '\\')
++ {
++ m_SB.Add("\\\\");
++ }
++ else if (ch == '"')
++ {
++ m_SB.Add("\\\"");
++ }
++ else if (ch >= 32)
++ {
++ m_SB.Add(ch);
++ }
++ else switch (ch)
++ {
++ case '\b':
++ m_SB.Add("\\b");
++ break;
++ case '\f':
++ m_SB.Add("\\f");
++ break;
++ case '\n':
++ m_SB.Add("\\n");
++ break;
++ case '\r':
++ m_SB.Add("\\r");
++ break;
++ case '\t':
++ m_SB.Add("\\t");
++ break;
++ default:
++ VMA_ASSERT(0 && "Character not currently supported.");
++ break;
++ }
++ }
++}
++
++void VmaJsonWriter::ContinueString(uint32_t n)
++{
++ VMA_ASSERT(m_InsideString);
++ m_SB.AddNumber(n);
++}
++
++void VmaJsonWriter::ContinueString(uint64_t n)
++{
++ VMA_ASSERT(m_InsideString);
++ m_SB.AddNumber(n);
++}
++
++void VmaJsonWriter::ContinueString_Size(size_t n)
++{
++ VMA_ASSERT(m_InsideString);
++ // Fix for AppleClang incorrect type casting
++ // TODO: Change to if constexpr when C++17 used as minimal standard
++ WriteSize(n, std::is_same<size_t, uint64_t>{});
++}
++
++void VmaJsonWriter::ContinueString_Pointer(const void* ptr)
++{
++ VMA_ASSERT(m_InsideString);
++ m_SB.AddPointer(ptr);
++}
++
++void VmaJsonWriter::EndString(const char* pStr)
++{
++ VMA_ASSERT(m_InsideString);
++ if (pStr != VMA_NULL && pStr[0] != '\0')
++ {
++ ContinueString(pStr);
++ }
++ m_SB.Add('"');
++ m_InsideString = false;
++}
++
++void VmaJsonWriter::WriteNumber(uint32_t n)
++{
++ VMA_ASSERT(!m_InsideString);
++ BeginValue(false);
++ m_SB.AddNumber(n);
++}
++
++void VmaJsonWriter::WriteNumber(uint64_t n)
++{
++ VMA_ASSERT(!m_InsideString);
++ BeginValue(false);
++ m_SB.AddNumber(n);
++}
++
++void VmaJsonWriter::WriteSize(size_t n)
++{
++ VMA_ASSERT(!m_InsideString);
++ BeginValue(false);
++ // Fix for AppleClang incorrect type casting
++ // TODO: Change to if constexpr when C++17 used as minimal standard
++ WriteSize(n, std::is_same<size_t, uint64_t>{});
++}
++
++void VmaJsonWriter::WriteBool(bool b)
++{
++ VMA_ASSERT(!m_InsideString);
++ BeginValue(false);
++ m_SB.Add(b ? "true" : "false");
++}
++
++void VmaJsonWriter::WriteNull()
++{
++ VMA_ASSERT(!m_InsideString);
++ BeginValue(false);
++ m_SB.Add("null");
++}
++
++void VmaJsonWriter::BeginValue(bool isString)
++{
++ if (!m_Stack.empty())
++ {
++ StackItem& currItem = m_Stack.back();
++ if (currItem.type == COLLECTION_TYPE_OBJECT &&
++ currItem.valueCount % 2 == 0)
++ {
++ VMA_ASSERT(isString);
++ }
++
++ if (currItem.type == COLLECTION_TYPE_OBJECT &&
++ currItem.valueCount % 2 != 0)
++ {
++ m_SB.Add(": ");
++ }
++ else if (currItem.valueCount > 0)
++ {
++ m_SB.Add(", ");
++ WriteIndent();
++ }
++ else
++ {
++ WriteIndent();
++ }
++ ++currItem.valueCount;
++ }
++}
++
++void VmaJsonWriter::WriteIndent(bool oneLess)
++{
++ if (!m_Stack.empty() && !m_Stack.back().singleLineMode)
++ {
++ m_SB.AddNewLine();
++
++ size_t count = m_Stack.size();
++ if (count > 0 && oneLess)
++ {
++ --count;
++ }
++ for (size_t i = 0; i < count; ++i)
++ {
++ m_SB.Add(INDENT);
++ }
++ }
++}
++#endif // _VMA_JSON_WRITER_FUNCTIONS
++
++static void VmaPrintDetailedStatistics(VmaJsonWriter& json, const VmaDetailedStatistics& stat)
++{
++ json.BeginObject();
++
++ json.WriteString("BlockCount");
++ json.WriteNumber(stat.statistics.blockCount);
++ json.WriteString("BlockBytes");
++ json.WriteNumber(stat.statistics.blockBytes);
++ json.WriteString("AllocationCount");
++ json.WriteNumber(stat.statistics.allocationCount);
++ json.WriteString("AllocationBytes");
++ json.WriteNumber(stat.statistics.allocationBytes);
++ json.WriteString("UnusedRangeCount");
++ json.WriteNumber(stat.unusedRangeCount);
++
++ if (stat.statistics.allocationCount > 1)
++ {
++ json.WriteString("AllocationSizeMin");
++ json.WriteNumber(stat.allocationSizeMin);
++ json.WriteString("AllocationSizeMax");
++ json.WriteNumber(stat.allocationSizeMax);
++ }
++ if (stat.unusedRangeCount > 1)
++ {
++ json.WriteString("UnusedRangeSizeMin");
++ json.WriteNumber(stat.unusedRangeSizeMin);
++ json.WriteString("UnusedRangeSizeMax");
++ json.WriteNumber(stat.unusedRangeSizeMax);
++ }
++ json.EndObject();
++}
++#endif // _VMA_JSON_WRITER
++
++#ifndef _VMA_MAPPING_HYSTERESIS
++
++class VmaMappingHysteresis
++{
++ VMA_CLASS_NO_COPY(VmaMappingHysteresis)
++public:
++ VmaMappingHysteresis() = default;
++
++ uint32_t GetExtraMapping() const { return m_ExtraMapping; }
++
++ // Call when Map was called.
++ // Returns true if switched to extra +1 mapping reference count.
++ bool PostMap()
++ {
++#if VMA_MAPPING_HYSTERESIS_ENABLED
++ if(m_ExtraMapping == 0)
++ {
++ ++m_MajorCounter;
++ if(m_MajorCounter >= COUNTER_MIN_EXTRA_MAPPING)
++ {
++ m_ExtraMapping = 1;
++ m_MajorCounter = 0;
++ m_MinorCounter = 0;
++ return true;
++ }
++ }
++ else // m_ExtraMapping == 1
++ PostMinorCounter();
++#endif // #if VMA_MAPPING_HYSTERESIS_ENABLED
++ return false;
++ }
++
++ // Call when Unmap was called.
++ void PostUnmap()
++ {
++#if VMA_MAPPING_HYSTERESIS_ENABLED
++ if(m_ExtraMapping == 0)
++ ++m_MajorCounter;
++ else // m_ExtraMapping == 1
++ PostMinorCounter();
++#endif // #if VMA_MAPPING_HYSTERESIS_ENABLED
++ }
++
++ // Call when allocation was made from the memory block.
++ void PostAlloc()
++ {
++#if VMA_MAPPING_HYSTERESIS_ENABLED
++ if(m_ExtraMapping == 1)
++ ++m_MajorCounter;
++ else // m_ExtraMapping == 0
++ PostMinorCounter();
++#endif // #if VMA_MAPPING_HYSTERESIS_ENABLED
++ }
++
++ // Call when allocation was freed from the memory block.
++ // Returns true if switched to extra -1 mapping reference count.
++ bool PostFree()
++ {
++#if VMA_MAPPING_HYSTERESIS_ENABLED
++ if(m_ExtraMapping == 1)
++ {
++ ++m_MajorCounter;
++ if(m_MajorCounter >= COUNTER_MIN_EXTRA_MAPPING &&
++ m_MajorCounter > m_MinorCounter + 1)
++ {
++ m_ExtraMapping = 0;
++ m_MajorCounter = 0;
++ m_MinorCounter = 0;
++ return true;
++ }
++ }
++ else // m_ExtraMapping == 0
++ PostMinorCounter();
++#endif // #if VMA_MAPPING_HYSTERESIS_ENABLED
++ return false;
++ }
++
++private:
++ static const int32_t COUNTER_MIN_EXTRA_MAPPING = 7;
++
++ uint32_t m_MinorCounter = 0;
++ uint32_t m_MajorCounter = 0;
++ uint32_t m_ExtraMapping = 0; // 0 or 1.
++
++ void PostMinorCounter()
++ {
++ if(m_MinorCounter < m_MajorCounter)
++ {
++ ++m_MinorCounter;
++ }
++ else if(m_MajorCounter > 0)
++ {
++ --m_MajorCounter;
++ --m_MinorCounter;
++ }
++ }
++};
++
++#endif // _VMA_MAPPING_HYSTERESIS
++
++#ifndef _VMA_DEVICE_MEMORY_BLOCK
++/*
++Represents a single block of device memory (`VkDeviceMemory`) with all the
++data about its regions (aka suballocations, #VmaAllocation), assigned and free.
++
++Thread-safety:
++- Access to m_pMetadata must be externally synchronized.
++- Map, Unmap, Bind* are synchronized internally.
++*/
++class VmaDeviceMemoryBlock
++{
++ VMA_CLASS_NO_COPY(VmaDeviceMemoryBlock)
++public:
++ VmaBlockMetadata* m_pMetadata;
++
++ VmaDeviceMemoryBlock(VmaAllocator hAllocator);
++ ~VmaDeviceMemoryBlock();
++
++ // Always call after construction.
++ void Init(
++ VmaAllocator hAllocator,
++ VmaPool hParentPool,
++ uint32_t newMemoryTypeIndex,
++ VkDeviceMemory newMemory,
++ VkDeviceSize newSize,
++ uint32_t id,
++ uint32_t algorithm,
++ VkDeviceSize bufferImageGranularity);
++ // Always call before destruction.
++ void Destroy(VmaAllocator allocator);
++
++ VmaPool GetParentPool() const { return m_hParentPool; }
++ VkDeviceMemory GetDeviceMemory() const { return m_hMemory; }
++ uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }
++ uint32_t GetId() const { return m_Id; }
++ void* GetMappedData() const { return m_pMappedData; }
++ uint32_t GetMapRefCount() const { return m_MapCount; }
++
++ // Call when allocation/free was made from m_pMetadata.
++ // Used for m_MappingHysteresis.
++ void PostAlloc() { m_MappingHysteresis.PostAlloc(); }
++ void PostFree(VmaAllocator hAllocator);
++
++ // Validates all data structures inside this object. If not valid, returns false.
++ bool Validate() const;
++ VkResult CheckCorruption(VmaAllocator hAllocator);
++
++ // ppData can be null.
++ VkResult Map(VmaAllocator hAllocator, uint32_t count, void** ppData);
++ void Unmap(VmaAllocator hAllocator, uint32_t count);
++
++ VkResult WriteMagicValueAfterAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize);
++ VkResult ValidateMagicValueAfterAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize);
++
++ VkResult BindBufferMemory(
++ const VmaAllocator hAllocator,
++ const VmaAllocation hAllocation,
++ VkDeviceSize allocationLocalOffset,
++ VkBuffer hBuffer,
++ const void* pNext);
++ VkResult BindImageMemory(
++ const VmaAllocator hAllocator,
++ const VmaAllocation hAllocation,
++ VkDeviceSize allocationLocalOffset,
++ VkImage hImage,
++ const void* pNext);
++
++private:
++ VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
++ uint32_t m_MemoryTypeIndex;
++ uint32_t m_Id;
++ VkDeviceMemory m_hMemory;
++
++ /*
++ Protects access to m_hMemory so it is not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.
++ Also protects m_MapCount, m_pMappedData.
++ Allocations, deallocations, any change in m_pMetadata is protected by parent's VmaBlockVector::m_Mutex.
++ */
++ VMA_MUTEX m_MapAndBindMutex;
++ VmaMappingHysteresis m_MappingHysteresis;
++ uint32_t m_MapCount;
++ void* m_pMappedData;
++};
++#endif // _VMA_DEVICE_MEMORY_BLOCK
++
++#ifndef _VMA_ALLOCATION_T
++struct VmaAllocation_T
++{
++ friend struct VmaDedicatedAllocationListItemTraits;
++
++ enum FLAGS
++ {
++ FLAG_PERSISTENT_MAP = 0x01,
++ FLAG_MAPPING_ALLOWED = 0x02,
++ };
++
++public:
++ enum ALLOCATION_TYPE
++ {
++ ALLOCATION_TYPE_NONE,
++ ALLOCATION_TYPE_BLOCK,
++ ALLOCATION_TYPE_DEDICATED,
++ };
++
++ // This struct is allocated using VmaPoolAllocator.
++ VmaAllocation_T(bool mappingAllowed);
++ ~VmaAllocation_T();
++
++ void InitBlockAllocation(
++ VmaDeviceMemoryBlock* block,
++ VmaAllocHandle allocHandle,
++ VkDeviceSize alignment,
++ VkDeviceSize size,
++ uint32_t memoryTypeIndex,
++ VmaSuballocationType suballocationType,
++ bool mapped);
++ // pMappedData not null means allocation is created with MAPPED flag.
++ void InitDedicatedAllocation(
++ VmaPool hParentPool,
++ uint32_t memoryTypeIndex,
++ VkDeviceMemory hMemory,
++ VmaSuballocationType suballocationType,
++ void* pMappedData,
++ VkDeviceSize size);
++
++ ALLOCATION_TYPE GetType() const { return (ALLOCATION_TYPE)m_Type; }
++ VkDeviceSize GetAlignment() const { return m_Alignment; }
++ VkDeviceSize GetSize() const { return m_Size; }
++ void* GetUserData() const { return m_pUserData; }
++ const char* GetName() const { return m_pName; }
++ VmaSuballocationType GetSuballocationType() const { return (VmaSuballocationType)m_SuballocationType; }
++
++ VmaDeviceMemoryBlock* GetBlock() const { VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK); return m_BlockAllocation.m_Block; }
++ uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }
++ bool IsPersistentMap() const { return (m_Flags & FLAG_PERSISTENT_MAP) != 0; }
++ bool IsMappingAllowed() const { return (m_Flags & FLAG_MAPPING_ALLOWED) != 0; }
++
++ void SetUserData(VmaAllocator hAllocator, void* pUserData) { m_pUserData = pUserData; }
++ void SetName(VmaAllocator hAllocator, const char* pName);
++ void FreeName(VmaAllocator hAllocator);
++ uint8_t SwapBlockAllocation(VmaAllocator hAllocator, VmaAllocation allocation);
++ VmaAllocHandle GetAllocHandle() const;
++ VkDeviceSize GetOffset() const;
++ VmaPool GetParentPool() const;
++ VkDeviceMemory GetMemory() const;
++ void* GetMappedData() const;
++
++ void BlockAllocMap();
++ void BlockAllocUnmap();
++ VkResult DedicatedAllocMap(VmaAllocator hAllocator, void** ppData);
++ void DedicatedAllocUnmap(VmaAllocator hAllocator);
++
++#if VMA_STATS_STRING_ENABLED
++ uint32_t GetBufferImageUsage() const { return m_BufferImageUsage; }
++
++ void InitBufferImageUsage(uint32_t bufferImageUsage);
++ void PrintParameters(class VmaJsonWriter& json) const;
++#endif
++
++private:
++ // Allocation out of VmaDeviceMemoryBlock.
++ struct BlockAllocation
++ {
++ VmaDeviceMemoryBlock* m_Block;
++ VmaAllocHandle m_AllocHandle;
++ };
++ // Allocation for an object that has its own private VkDeviceMemory.
++ struct DedicatedAllocation
++ {
++ VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
++ VkDeviceMemory m_hMemory;
++ void* m_pMappedData; // Not null means memory is mapped.
++ VmaAllocation_T* m_Prev;
++ VmaAllocation_T* m_Next;
++ };
++ union
++ {
++ // Allocation out of VmaDeviceMemoryBlock.
++ BlockAllocation m_BlockAllocation;
++ // Allocation for an object that has its own private VkDeviceMemory.
++ DedicatedAllocation m_DedicatedAllocation;
++ };
++
++ VkDeviceSize m_Alignment;
++ VkDeviceSize m_Size;
++ void* m_pUserData;
++ char* m_pName;
++ uint32_t m_MemoryTypeIndex;
++ uint8_t m_Type; // ALLOCATION_TYPE
++ uint8_t m_SuballocationType; // VmaSuballocationType
++ // Reference counter for vmaMapMemory()/vmaUnmapMemory().
++ uint8_t m_MapCount;
++ uint8_t m_Flags; // enum FLAGS
++#if VMA_STATS_STRING_ENABLED
++ uint32_t m_BufferImageUsage; // 0 if unknown.
++#endif
++};
++#endif // _VMA_ALLOCATION_T
++
++#ifndef _VMA_DEDICATED_ALLOCATION_LIST_ITEM_TRAITS
++struct VmaDedicatedAllocationListItemTraits
++{
++ typedef VmaAllocation_T ItemType;
++
++ static ItemType* GetPrev(const ItemType* item)
++ {
++ VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);
++ return item->m_DedicatedAllocation.m_Prev;
++ }
++ static ItemType* GetNext(const ItemType* item)
++ {
++ VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);
++ return item->m_DedicatedAllocation.m_Next;
++ }
++ static ItemType*& AccessPrev(ItemType* item)
++ {
++ VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);
++ return item->m_DedicatedAllocation.m_Prev;
++ }
++ static ItemType*& AccessNext(ItemType* item)
++ {
++ VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);
++ return item->m_DedicatedAllocation.m_Next;
++ }
++};
++#endif // _VMA_DEDICATED_ALLOCATION_LIST_ITEM_TRAITS
++
++#ifndef _VMA_DEDICATED_ALLOCATION_LIST
++/*
++Stores linked list of VmaAllocation_T objects.
++Thread-safe, synchronized internally.
++*/
++class VmaDedicatedAllocationList
++{
++public:
++ VmaDedicatedAllocationList() {}
++ ~VmaDedicatedAllocationList();
++
++ void Init(bool useMutex) { m_UseMutex = useMutex; }
++ bool Validate();
++
++ void AddDetailedStatistics(VmaDetailedStatistics& inoutStats);
++ void AddStatistics(VmaStatistics& inoutStats);
++#if VMA_STATS_STRING_ENABLED
++ // Writes JSON array with the list of allocations.
++ void BuildStatsString(VmaJsonWriter& json);
++#endif
++
++ bool IsEmpty();
++ void Register(VmaAllocation alloc);
++ void Unregister(VmaAllocation alloc);
++
++private:
++ typedef VmaIntrusiveLinkedList<VmaDedicatedAllocationListItemTraits> DedicatedAllocationLinkedList;
++
++ bool m_UseMutex = true;
++ VMA_RW_MUTEX m_Mutex;
++ DedicatedAllocationLinkedList m_AllocationList;
++};
++
++#ifndef _VMA_DEDICATED_ALLOCATION_LIST_FUNCTIONS
++
++VmaDedicatedAllocationList::~VmaDedicatedAllocationList()
++{
++ VMA_HEAVY_ASSERT(Validate());
++
++ if (!m_AllocationList.IsEmpty())
++ {
++ VMA_ASSERT(false && "Unfreed dedicated allocations found!");
++ }
++}
++
++bool VmaDedicatedAllocationList::Validate()
++{
++ const size_t declaredCount = m_AllocationList.GetCount();
++ size_t actualCount = 0;
++ VmaMutexLockRead lock(m_Mutex, m_UseMutex);
++ for (VmaAllocation alloc = m_AllocationList.Front();
++ alloc != VMA_NULL; alloc = m_AllocationList.GetNext(alloc))
++ {
++ ++actualCount;
++ }
++ VMA_VALIDATE(actualCount == declaredCount);
++
++ return true;
++}
++
++void VmaDedicatedAllocationList::AddDetailedStatistics(VmaDetailedStatistics& inoutStats)
++{
++ for(auto* item = m_AllocationList.Front(); item != nullptr; item = DedicatedAllocationLinkedList::GetNext(item))
++ {
++ const VkDeviceSize size = item->GetSize();
++ inoutStats.statistics.blockCount++;
++ inoutStats.statistics.blockBytes += size;
++ VmaAddDetailedStatisticsAllocation(inoutStats, item->GetSize());
++ }
++}
++
++void VmaDedicatedAllocationList::AddStatistics(VmaStatistics& inoutStats)
++{
++ VmaMutexLockRead lock(m_Mutex, m_UseMutex);
++
++ const uint32_t allocCount = (uint32_t)m_AllocationList.GetCount();
++ inoutStats.blockCount += allocCount;
++ inoutStats.allocationCount += allocCount;
++
++ for(auto* item = m_AllocationList.Front(); item != nullptr; item = DedicatedAllocationLinkedList::GetNext(item))
++ {
++ const VkDeviceSize size = item->GetSize();
++ inoutStats.blockBytes += size;
++ inoutStats.allocationBytes += size;
++ }
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaDedicatedAllocationList::BuildStatsString(VmaJsonWriter& json)
++{
++ VmaMutexLockRead lock(m_Mutex, m_UseMutex);
++ json.BeginArray();
++ for (VmaAllocation alloc = m_AllocationList.Front();
++ alloc != VMA_NULL; alloc = m_AllocationList.GetNext(alloc))
++ {
++ json.BeginObject(true);
++ alloc->PrintParameters(json);
++ json.EndObject();
++ }
++ json.EndArray();
++}
++#endif // VMA_STATS_STRING_ENABLED
++
++bool VmaDedicatedAllocationList::IsEmpty()
++{
++ VmaMutexLockRead lock(m_Mutex, m_UseMutex);
++ return m_AllocationList.IsEmpty();
++}
++
++void VmaDedicatedAllocationList::Register(VmaAllocation alloc)
++{
++ VmaMutexLockWrite lock(m_Mutex, m_UseMutex);
++ m_AllocationList.PushBack(alloc);
++}
++
++void VmaDedicatedAllocationList::Unregister(VmaAllocation alloc)
++{
++ VmaMutexLockWrite lock(m_Mutex, m_UseMutex);
++ m_AllocationList.Remove(alloc);
++}
++#endif // _VMA_DEDICATED_ALLOCATION_LIST_FUNCTIONS
++#endif // _VMA_DEDICATED_ALLOCATION_LIST
++
++#ifndef _VMA_SUBALLOCATION
++/*
++Represents a region of VmaDeviceMemoryBlock that is either assigned and returned as
++allocated memory block or free.
++*/
++struct VmaSuballocation
++{
++ VkDeviceSize offset;
++ VkDeviceSize size;
++ void* userData;
++ VmaSuballocationType type;
++};
++
++// Comparator for offsets.
++struct VmaSuballocationOffsetLess
++{
++ bool operator()(const VmaSuballocation& lhs, const VmaSuballocation& rhs) const
++ {
++ return lhs.offset < rhs.offset;
++ }
++};
++
++struct VmaSuballocationOffsetGreater
++{
++ bool operator()(const VmaSuballocation& lhs, const VmaSuballocation& rhs) const
++ {
++ return lhs.offset > rhs.offset;
++ }
++};
++
++struct VmaSuballocationItemSizeLess
++{
++ bool operator()(const VmaSuballocationList::iterator lhs,
++ const VmaSuballocationList::iterator rhs) const
++ {
++ return lhs->size < rhs->size;
++ }
++
++ bool operator()(const VmaSuballocationList::iterator lhs,
++ VkDeviceSize rhsSize) const
++ {
++ return lhs->size < rhsSize;
++ }
++};
++#endif // _VMA_SUBALLOCATION
++
++#ifndef _VMA_ALLOCATION_REQUEST
++/*
++Parameters of planned allocation inside a VmaDeviceMemoryBlock.
++item points to a FREE suballocation.
++*/
++struct VmaAllocationRequest
++{
++ VmaAllocHandle allocHandle;
++ VkDeviceSize size;
++ VmaSuballocationList::iterator item;
++ void* customData;
++ uint64_t algorithmData;
++ VmaAllocationRequestType type;
++};
++#endif // _VMA_ALLOCATION_REQUEST
++
++#ifndef _VMA_BLOCK_METADATA
++/*
++Data structure used for bookkeeping of allocations and unused ranges of memory
++in a single VkDeviceMemory block.
++*/
++class VmaBlockMetadata
++{
++public:
++ // pAllocationCallbacks, if not null, must be owned externally - alive and unchanged for the whole lifetime of this object.
++ VmaBlockMetadata(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual);
++ virtual ~VmaBlockMetadata() = default;
++
++ virtual void Init(VkDeviceSize size) { m_Size = size; }
++ bool IsVirtual() const { return m_IsVirtual; }
++ VkDeviceSize GetSize() const { return m_Size; }
++
++ // Validates all data structures inside this object. If not valid, returns false.
++ virtual bool Validate() const = 0;
++ virtual size_t GetAllocationCount() const = 0;
++ virtual size_t GetFreeRegionsCount() const = 0;
++ virtual VkDeviceSize GetSumFreeSize() const = 0;
++ // Returns true if this block is empty - contains only single free suballocation.
++ virtual bool IsEmpty() const = 0;
++ virtual void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) = 0;
++ virtual VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const = 0;
++ virtual void* GetAllocationUserData(VmaAllocHandle allocHandle) const = 0;
++
++ virtual VmaAllocHandle GetAllocationListBegin() const = 0;
++ virtual VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const = 0;
++ virtual VkDeviceSize GetNextFreeRegionSize(VmaAllocHandle alloc) const = 0;
++
++ // Shouldn't modify blockCount.
++ virtual void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const = 0;
++ virtual void AddStatistics(VmaStatistics& inoutStats) const = 0;
++
++#if VMA_STATS_STRING_ENABLED
++ virtual void PrintDetailedMap(class VmaJsonWriter& json) const = 0;
++#endif
++
++ // Tries to find a place for suballocation with given parameters inside this block.
++ // If succeeded, fills pAllocationRequest and returns true.
++ // If failed, returns false.
++ virtual bool CreateAllocationRequest(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ bool upperAddress,
++ VmaSuballocationType allocType,
++ // Always one of VMA_ALLOCATION_CREATE_STRATEGY_* or VMA_ALLOCATION_INTERNAL_STRATEGY_* flags.
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest) = 0;
++
++ virtual VkResult CheckCorruption(const void* pBlockData) = 0;
++
++ // Makes actual allocation based on request. Request must already be checked and valid.
++ virtual void Alloc(
++ const VmaAllocationRequest& request,
++ VmaSuballocationType type,
++ void* userData) = 0;
++
++ // Frees suballocation assigned to given memory region.
++ virtual void Free(VmaAllocHandle allocHandle) = 0;
++
++ // Frees all allocations.
++ // Careful! Don't call it if there are VmaAllocation objects owned by userData of cleared allocations!
++ virtual void Clear() = 0;
++
++ virtual void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) = 0;
++ virtual void DebugLogAllAllocations() const = 0;
++
++protected:
++ const VkAllocationCallbacks* GetAllocationCallbacks() const { return m_pAllocationCallbacks; }
++ VkDeviceSize GetBufferImageGranularity() const { return m_BufferImageGranularity; }
++ VkDeviceSize GetDebugMargin() const { return IsVirtual() ? 0 : VMA_DEBUG_MARGIN; }
++
++ void DebugLogAllocation(VkDeviceSize offset, VkDeviceSize size, void* userData) const;
++#if VMA_STATS_STRING_ENABLED
++ // mapRefCount == UINT32_MAX means unspecified.
++ void PrintDetailedMap_Begin(class VmaJsonWriter& json,
++ VkDeviceSize unusedBytes,
++ size_t allocationCount,
++ size_t unusedRangeCount) const;
++ void PrintDetailedMap_Allocation(class VmaJsonWriter& json,
++ VkDeviceSize offset, VkDeviceSize size, void* userData) const;
++ void PrintDetailedMap_UnusedRange(class VmaJsonWriter& json,
++ VkDeviceSize offset,
++ VkDeviceSize size) const;
++ void PrintDetailedMap_End(class VmaJsonWriter& json) const;
++#endif
++
++private:
++ VkDeviceSize m_Size;
++ const VkAllocationCallbacks* m_pAllocationCallbacks;
++ const VkDeviceSize m_BufferImageGranularity;
++ const bool m_IsVirtual;
++};
++
++#ifndef _VMA_BLOCK_METADATA_FUNCTIONS
++VmaBlockMetadata::VmaBlockMetadata(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual)
++ : m_Size(0),
++ m_pAllocationCallbacks(pAllocationCallbacks),
++ m_BufferImageGranularity(bufferImageGranularity),
++ m_IsVirtual(isVirtual) {}
++
++void VmaBlockMetadata::DebugLogAllocation(VkDeviceSize offset, VkDeviceSize size, void* userData) const
++{
++ if (IsVirtual())
++ {
++ VMA_DEBUG_LOG("UNFREED VIRTUAL ALLOCATION; Offset: %llu; Size: %llu; UserData: %p", offset, size, userData);
++ }
++ else
++ {
++ VMA_ASSERT(userData != VMA_NULL);
++ VmaAllocation allocation = reinterpret_cast<VmaAllocation>(userData);
++
++ userData = allocation->GetUserData();
++ const char* name = allocation->GetName();
++
++#if VMA_STATS_STRING_ENABLED
++ VMA_DEBUG_LOG("UNFREED ALLOCATION; Offset: %llu; Size: %llu; UserData: %p; Name: %s; Type: %s; Usage: %u",
++ offset, size, userData, name ? name : "vma_empty",
++ VMA_SUBALLOCATION_TYPE_NAMES[allocation->GetSuballocationType()],
++ allocation->GetBufferImageUsage());
++#else
++ VMA_DEBUG_LOG("UNFREED ALLOCATION; Offset: %llu; Size: %llu; UserData: %p; Name: %s; Type: %u",
++ offset, size, userData, name ? name : "vma_empty",
++ (uint32_t)allocation->GetSuballocationType());
++#endif // VMA_STATS_STRING_ENABLED
++ }
++
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaBlockMetadata::PrintDetailedMap_Begin(class VmaJsonWriter& json,
++ VkDeviceSize unusedBytes, size_t allocationCount, size_t unusedRangeCount) const
++{
++ json.WriteString("TotalBytes");
++ json.WriteNumber(GetSize());
++
++ json.WriteString("UnusedBytes");
++ json.WriteSize(unusedBytes);
++
++ json.WriteString("Allocations");
++ json.WriteSize(allocationCount);
++
++ json.WriteString("UnusedRanges");
++ json.WriteSize(unusedRangeCount);
++
++ json.WriteString("Suballocations");
++ json.BeginArray();
++}
++
++void VmaBlockMetadata::PrintDetailedMap_Allocation(class VmaJsonWriter& json,
++ VkDeviceSize offset, VkDeviceSize size, void* userData) const
++{
++ json.BeginObject(true);
++
++ json.WriteString("Offset");
++ json.WriteNumber(offset);
++
++ if (IsVirtual())
++ {
++ json.WriteString("Size");
++ json.WriteNumber(size);
++ if (userData)
++ {
++ json.WriteString("CustomData");
++ json.BeginString();
++ json.ContinueString_Pointer(userData);
++ json.EndString();
++ }
++ }
++ else
++ {
++ ((VmaAllocation)userData)->PrintParameters(json);
++ }
++
++ json.EndObject();
++}
++
++void VmaBlockMetadata::PrintDetailedMap_UnusedRange(class VmaJsonWriter& json,
++ VkDeviceSize offset, VkDeviceSize size) const
++{
++ json.BeginObject(true);
++
++ json.WriteString("Offset");
++ json.WriteNumber(offset);
++
++ json.WriteString("Type");
++ json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[VMA_SUBALLOCATION_TYPE_FREE]);
++
++ json.WriteString("Size");
++ json.WriteNumber(size);
++
++ json.EndObject();
++}
++
++void VmaBlockMetadata::PrintDetailedMap_End(class VmaJsonWriter& json) const
++{
++ json.EndArray();
++}
++#endif // VMA_STATS_STRING_ENABLED
++#endif // _VMA_BLOCK_METADATA_FUNCTIONS
++#endif // _VMA_BLOCK_METADATA
++
++#ifndef _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY
++// Before deleting object of this class remember to call 'Destroy()'
++class VmaBlockBufferImageGranularity final
++{
++public:
++ struct ValidationContext
++ {
++ const VkAllocationCallbacks* allocCallbacks;
++ uint16_t* pageAllocs;
++ };
++
++ VmaBlockBufferImageGranularity(VkDeviceSize bufferImageGranularity);
++ ~VmaBlockBufferImageGranularity();
++
++ bool IsEnabled() const { return m_BufferImageGranularity > MAX_LOW_BUFFER_IMAGE_GRANULARITY; }
++
++ void Init(const VkAllocationCallbacks* pAllocationCallbacks, VkDeviceSize size);
++ // Before destroying object you must call free it's memory
++ void Destroy(const VkAllocationCallbacks* pAllocationCallbacks);
++
++ void RoundupAllocRequest(VmaSuballocationType allocType,
++ VkDeviceSize& inOutAllocSize,
++ VkDeviceSize& inOutAllocAlignment) const;
++
++ bool CheckConflictAndAlignUp(VkDeviceSize& inOutAllocOffset,
++ VkDeviceSize allocSize,
++ VkDeviceSize blockOffset,
++ VkDeviceSize blockSize,
++ VmaSuballocationType allocType) const;
++
++ void AllocPages(uint8_t allocType, VkDeviceSize offset, VkDeviceSize size);
++ void FreePages(VkDeviceSize offset, VkDeviceSize size);
++ void Clear();
++
++ ValidationContext StartValidation(const VkAllocationCallbacks* pAllocationCallbacks,
++ bool isVirutal) const;
++ bool Validate(ValidationContext& ctx, VkDeviceSize offset, VkDeviceSize size) const;
++ bool FinishValidation(ValidationContext& ctx) const;
++
++private:
++ static const uint16_t MAX_LOW_BUFFER_IMAGE_GRANULARITY = 256;
++
++ struct RegionInfo
++ {
++ uint8_t allocType;
++ uint16_t allocCount;
++ };
++
++ VkDeviceSize m_BufferImageGranularity;
++ uint32_t m_RegionCount;
++ RegionInfo* m_RegionInfo;
++
++ uint32_t GetStartPage(VkDeviceSize offset) const { return OffsetToPageIndex(offset & ~(m_BufferImageGranularity - 1)); }
++ uint32_t GetEndPage(VkDeviceSize offset, VkDeviceSize size) const { return OffsetToPageIndex((offset + size - 1) & ~(m_BufferImageGranularity - 1)); }
++
++ uint32_t OffsetToPageIndex(VkDeviceSize offset) const;
++ void AllocPage(RegionInfo& page, uint8_t allocType);
++};
++
++#ifndef _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY_FUNCTIONS
++VmaBlockBufferImageGranularity::VmaBlockBufferImageGranularity(VkDeviceSize bufferImageGranularity)
++ : m_BufferImageGranularity(bufferImageGranularity),
++ m_RegionCount(0),
++ m_RegionInfo(VMA_NULL) {}
++
++VmaBlockBufferImageGranularity::~VmaBlockBufferImageGranularity()
++{
++ VMA_ASSERT(m_RegionInfo == VMA_NULL && "Free not called before destroying object!");
++}
++
++void VmaBlockBufferImageGranularity::Init(const VkAllocationCallbacks* pAllocationCallbacks, VkDeviceSize size)
++{
++ if (IsEnabled())
++ {
++ m_RegionCount = static_cast<uint32_t>(VmaDivideRoundingUp(size, m_BufferImageGranularity));
++ m_RegionInfo = vma_new_array(pAllocationCallbacks, RegionInfo, m_RegionCount);
++ memset(m_RegionInfo, 0, m_RegionCount * sizeof(RegionInfo));
++ }
++}
++
++void VmaBlockBufferImageGranularity::Destroy(const VkAllocationCallbacks* pAllocationCallbacks)
++{
++ if (m_RegionInfo)
++ {
++ vma_delete_array(pAllocationCallbacks, m_RegionInfo, m_RegionCount);
++ m_RegionInfo = VMA_NULL;
++ }
++}
++
++void VmaBlockBufferImageGranularity::RoundupAllocRequest(VmaSuballocationType allocType,
++ VkDeviceSize& inOutAllocSize,
++ VkDeviceSize& inOutAllocAlignment) const
++{
++ if (m_BufferImageGranularity > 1 &&
++ m_BufferImageGranularity <= MAX_LOW_BUFFER_IMAGE_GRANULARITY)
++ {
++ if (allocType == VMA_SUBALLOCATION_TYPE_UNKNOWN ||
++ allocType == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
++ allocType == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL)
++ {
++ inOutAllocAlignment = VMA_MAX(inOutAllocAlignment, m_BufferImageGranularity);
++ inOutAllocSize = VmaAlignUp(inOutAllocSize, m_BufferImageGranularity);
++ }
++ }
++}
++
++bool VmaBlockBufferImageGranularity::CheckConflictAndAlignUp(VkDeviceSize& inOutAllocOffset,
++ VkDeviceSize allocSize,
++ VkDeviceSize blockOffset,
++ VkDeviceSize blockSize,
++ VmaSuballocationType allocType) const
++{
++ if (IsEnabled())
++ {
++ uint32_t startPage = GetStartPage(inOutAllocOffset);
++ if (m_RegionInfo[startPage].allocCount > 0 &&
++ VmaIsBufferImageGranularityConflict(static_cast<VmaSuballocationType>(m_RegionInfo[startPage].allocType), allocType))
++ {
++ inOutAllocOffset = VmaAlignUp(inOutAllocOffset, m_BufferImageGranularity);
++ if (blockSize < allocSize + inOutAllocOffset - blockOffset)
++ return true;
++ ++startPage;
++ }
++ uint32_t endPage = GetEndPage(inOutAllocOffset, allocSize);
++ if (endPage != startPage &&
++ m_RegionInfo[endPage].allocCount > 0 &&
++ VmaIsBufferImageGranularityConflict(static_cast<VmaSuballocationType>(m_RegionInfo[endPage].allocType), allocType))
++ {
++ return true;
++ }
++ }
++ return false;
++}
++
++void VmaBlockBufferImageGranularity::AllocPages(uint8_t allocType, VkDeviceSize offset, VkDeviceSize size)
++{
++ if (IsEnabled())
++ {
++ uint32_t startPage = GetStartPage(offset);
++ AllocPage(m_RegionInfo[startPage], allocType);
++
++ uint32_t endPage = GetEndPage(offset, size);
++ if (startPage != endPage)
++ AllocPage(m_RegionInfo[endPage], allocType);
++ }
++}
++
++void VmaBlockBufferImageGranularity::FreePages(VkDeviceSize offset, VkDeviceSize size)
++{
++ if (IsEnabled())
++ {
++ uint32_t startPage = GetStartPage(offset);
++ --m_RegionInfo[startPage].allocCount;
++ if (m_RegionInfo[startPage].allocCount == 0)
++ m_RegionInfo[startPage].allocType = VMA_SUBALLOCATION_TYPE_FREE;
++ uint32_t endPage = GetEndPage(offset, size);
++ if (startPage != endPage)
++ {
++ --m_RegionInfo[endPage].allocCount;
++ if (m_RegionInfo[endPage].allocCount == 0)
++ m_RegionInfo[endPage].allocType = VMA_SUBALLOCATION_TYPE_FREE;
++ }
++ }
++}
++
++void VmaBlockBufferImageGranularity::Clear()
++{
++ if (m_RegionInfo)
++ memset(m_RegionInfo, 0, m_RegionCount * sizeof(RegionInfo));
++}
++
++VmaBlockBufferImageGranularity::ValidationContext VmaBlockBufferImageGranularity::StartValidation(
++ const VkAllocationCallbacks* pAllocationCallbacks, bool isVirutal) const
++{
++ ValidationContext ctx{ pAllocationCallbacks, VMA_NULL };
++ if (!isVirutal && IsEnabled())
++ {
++ ctx.pageAllocs = vma_new_array(pAllocationCallbacks, uint16_t, m_RegionCount);
++ memset(ctx.pageAllocs, 0, m_RegionCount * sizeof(uint16_t));
++ }
++ return ctx;
++}
++
++bool VmaBlockBufferImageGranularity::Validate(ValidationContext& ctx,
++ VkDeviceSize offset, VkDeviceSize size) const
++{
++ if (IsEnabled())
++ {
++ uint32_t start = GetStartPage(offset);
++ ++ctx.pageAllocs[start];
++ VMA_VALIDATE(m_RegionInfo[start].allocCount > 0);
++
++ uint32_t end = GetEndPage(offset, size);
++ if (start != end)
++ {
++ ++ctx.pageAllocs[end];
++ VMA_VALIDATE(m_RegionInfo[end].allocCount > 0);
++ }
++ }
++ return true;
++}
++
++bool VmaBlockBufferImageGranularity::FinishValidation(ValidationContext& ctx) const
++{
++ // Check proper page structure
++ if (IsEnabled())
++ {
++ VMA_ASSERT(ctx.pageAllocs != VMA_NULL && "Validation context not initialized!");
++
++ for (uint32_t page = 0; page < m_RegionCount; ++page)
++ {
++ VMA_VALIDATE(ctx.pageAllocs[page] == m_RegionInfo[page].allocCount);
++ }
++ vma_delete_array(ctx.allocCallbacks, ctx.pageAllocs, m_RegionCount);
++ ctx.pageAllocs = VMA_NULL;
++ }
++ return true;
++}
++
++uint32_t VmaBlockBufferImageGranularity::OffsetToPageIndex(VkDeviceSize offset) const
++{
++ return static_cast<uint32_t>(offset >> VMA_BITSCAN_MSB(m_BufferImageGranularity));
++}
++
++void VmaBlockBufferImageGranularity::AllocPage(RegionInfo& page, uint8_t allocType)
++{
++ // When current alloc type is free then it can be overriden by new type
++ if (page.allocCount == 0 || (page.allocCount > 0 && page.allocType == VMA_SUBALLOCATION_TYPE_FREE))
++ page.allocType = allocType;
++
++ ++page.allocCount;
++}
++#endif // _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY_FUNCTIONS
++#endif // _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY
++
++#if 0
++#ifndef _VMA_BLOCK_METADATA_GENERIC
++class VmaBlockMetadata_Generic : public VmaBlockMetadata
++{
++ friend class VmaDefragmentationAlgorithm_Generic;
++ friend class VmaDefragmentationAlgorithm_Fast;
++ VMA_CLASS_NO_COPY(VmaBlockMetadata_Generic)
++public:
++ VmaBlockMetadata_Generic(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual);
++ virtual ~VmaBlockMetadata_Generic() = default;
++
++ size_t GetAllocationCount() const override { return m_Suballocations.size() - m_FreeCount; }
++ VkDeviceSize GetSumFreeSize() const override { return m_SumFreeSize; }
++ bool IsEmpty() const override { return (m_Suballocations.size() == 1) && (m_FreeCount == 1); }
++ void Free(VmaAllocHandle allocHandle) override { FreeSuballocation(FindAtOffset((VkDeviceSize)allocHandle - 1)); }
++ VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle - 1; };
++
++ void Init(VkDeviceSize size) override;
++ bool Validate() const override;
++
++ void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const override;
++ void AddStatistics(VmaStatistics& inoutStats) const override;
++
++#if VMA_STATS_STRING_ENABLED
++ void PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const override;
++#endif
++
++ bool CreateAllocationRequest(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ bool upperAddress,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest) override;
++
++ VkResult CheckCorruption(const void* pBlockData) override;
++
++ void Alloc(
++ const VmaAllocationRequest& request,
++ VmaSuballocationType type,
++ void* userData) override;
++
++ void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override;
++ void* GetAllocationUserData(VmaAllocHandle allocHandle) const override;
++ VmaAllocHandle GetAllocationListBegin() const override;
++ VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override;
++ void Clear() override;
++ void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override;
++ void DebugLogAllAllocations() const override;
++
++private:
++ uint32_t m_FreeCount;
++ VkDeviceSize m_SumFreeSize;
++ VmaSuballocationList m_Suballocations;
++ // Suballocations that are free. Sorted by size, ascending.
++ VmaVector<VmaSuballocationList::iterator, VmaStlAllocator<VmaSuballocationList::iterator>> m_FreeSuballocationsBySize;
++
++ VkDeviceSize AlignAllocationSize(VkDeviceSize size) const { return IsVirtual() ? size : VmaAlignUp(size, (VkDeviceSize)16); }
++
++ VmaSuballocationList::iterator FindAtOffset(VkDeviceSize offset) const;
++ bool ValidateFreeSuballocationList() const;
++
++ // Checks if requested suballocation with given parameters can be placed in given pFreeSuballocItem.
++ // If yes, fills pOffset and returns true. If no, returns false.
++ bool CheckAllocation(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ VmaSuballocationType allocType,
++ VmaSuballocationList::const_iterator suballocItem,
++ VmaAllocHandle* pAllocHandle) const;
++
++ // Given free suballocation, it merges it with following one, which must also be free.
++ void MergeFreeWithNext(VmaSuballocationList::iterator item);
++ // Releases given suballocation, making it free.
++ // Merges it with adjacent free suballocations if applicable.
++ // Returns iterator to new free suballocation at this place.
++ VmaSuballocationList::iterator FreeSuballocation(VmaSuballocationList::iterator suballocItem);
++ // Given free suballocation, it inserts it into sorted list of
++ // m_FreeSuballocationsBySize if it is suitable.
++ void RegisterFreeSuballocation(VmaSuballocationList::iterator item);
++ // Given free suballocation, it removes it from sorted list of
++ // m_FreeSuballocationsBySize if it is suitable.
++ void UnregisterFreeSuballocation(VmaSuballocationList::iterator item);
++};
++
++#ifndef _VMA_BLOCK_METADATA_GENERIC_FUNCTIONS
++VmaBlockMetadata_Generic::VmaBlockMetadata_Generic(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual)
++ : VmaBlockMetadata(pAllocationCallbacks, bufferImageGranularity, isVirtual),
++ m_FreeCount(0),
++ m_SumFreeSize(0),
++ m_Suballocations(VmaStlAllocator<VmaSuballocation>(pAllocationCallbacks)),
++ m_FreeSuballocationsBySize(VmaStlAllocator<VmaSuballocationList::iterator>(pAllocationCallbacks)) {}
++
++void VmaBlockMetadata_Generic::Init(VkDeviceSize size)
++{
++ VmaBlockMetadata::Init(size);
++
++ m_FreeCount = 1;
++ m_SumFreeSize = size;
++
++ VmaSuballocation suballoc = {};
++ suballoc.offset = 0;
++ suballoc.size = size;
++ suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
++
++ m_Suballocations.push_back(suballoc);
++ m_FreeSuballocationsBySize.push_back(m_Suballocations.begin());
++}
++
++bool VmaBlockMetadata_Generic::Validate() const
++{
++ VMA_VALIDATE(!m_Suballocations.empty());
++
++ // Expected offset of new suballocation as calculated from previous ones.
++ VkDeviceSize calculatedOffset = 0;
++ // Expected number of free suballocations as calculated from traversing their list.
++ uint32_t calculatedFreeCount = 0;
++ // Expected sum size of free suballocations as calculated from traversing their list.
++ VkDeviceSize calculatedSumFreeSize = 0;
++ // Expected number of free suballocations that should be registered in
++ // m_FreeSuballocationsBySize calculated from traversing their list.
++ size_t freeSuballocationsToRegister = 0;
++ // True if previous visited suballocation was free.
++ bool prevFree = false;
++
++ const VkDeviceSize debugMargin = GetDebugMargin();
++
++ for (const auto& subAlloc : m_Suballocations)
++ {
++ // Actual offset of this suballocation doesn't match expected one.
++ VMA_VALIDATE(subAlloc.offset == calculatedOffset);
++
++ const bool currFree = (subAlloc.type == VMA_SUBALLOCATION_TYPE_FREE);
++ // Two adjacent free suballocations are invalid. They should be merged.
++ VMA_VALIDATE(!prevFree || !currFree);
++
++ VmaAllocation alloc = (VmaAllocation)subAlloc.userData;
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE(currFree == (alloc == VK_NULL_HANDLE));
++ }
++
++ if (currFree)
++ {
++ calculatedSumFreeSize += subAlloc.size;
++ ++calculatedFreeCount;
++ ++freeSuballocationsToRegister;
++
++ // Margin required between allocations - every free space must be at least that large.
++ VMA_VALIDATE(subAlloc.size >= debugMargin);
++ }
++ else
++ {
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE((VkDeviceSize)alloc->GetAllocHandle() == subAlloc.offset + 1);
++ VMA_VALIDATE(alloc->GetSize() == subAlloc.size);
++ }
++
++ // Margin required between allocations - previous allocation must be free.
++ VMA_VALIDATE(debugMargin == 0 || prevFree);
++ }
++
++ calculatedOffset += subAlloc.size;
++ prevFree = currFree;
++ }
++
++ // Number of free suballocations registered in m_FreeSuballocationsBySize doesn't
++ // match expected one.
++ VMA_VALIDATE(m_FreeSuballocationsBySize.size() == freeSuballocationsToRegister);
++
++ VkDeviceSize lastSize = 0;
++ for (size_t i = 0; i < m_FreeSuballocationsBySize.size(); ++i)
++ {
++ VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[i];
++
++ // Only free suballocations can be registered in m_FreeSuballocationsBySize.
++ VMA_VALIDATE(suballocItem->type == VMA_SUBALLOCATION_TYPE_FREE);
++ // They must be sorted by size ascending.
++ VMA_VALIDATE(suballocItem->size >= lastSize);
++
++ lastSize = suballocItem->size;
++ }
++
++ // Check if totals match calculated values.
++ VMA_VALIDATE(ValidateFreeSuballocationList());
++ VMA_VALIDATE(calculatedOffset == GetSize());
++ VMA_VALIDATE(calculatedSumFreeSize == m_SumFreeSize);
++ VMA_VALIDATE(calculatedFreeCount == m_FreeCount);
++
++ return true;
++}
++
++void VmaBlockMetadata_Generic::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const
++{
++ const uint32_t rangeCount = (uint32_t)m_Suballocations.size();
++ inoutStats.statistics.blockCount++;
++ inoutStats.statistics.blockBytes += GetSize();
++
++ for (const auto& suballoc : m_Suballocations)
++ {
++ if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)
++ VmaAddDetailedStatisticsAllocation(inoutStats, suballoc.size);
++ else
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, suballoc.size);
++ }
++}
++
++void VmaBlockMetadata_Generic::AddStatistics(VmaStatistics& inoutStats) const
++{
++ inoutStats.blockCount++;
++ inoutStats.allocationCount += (uint32_t)m_Suballocations.size() - m_FreeCount;
++ inoutStats.blockBytes += GetSize();
++ inoutStats.allocationBytes += GetSize() - m_SumFreeSize;
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaBlockMetadata_Generic::PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const
++{
++ PrintDetailedMap_Begin(json,
++ m_SumFreeSize, // unusedBytes
++ m_Suballocations.size() - (size_t)m_FreeCount, // allocationCount
++ m_FreeCount, // unusedRangeCount
++ mapRefCount);
++
++ for (const auto& suballoc : m_Suballocations)
++ {
++ if (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ PrintDetailedMap_UnusedRange(json, suballoc.offset, suballoc.size);
++ }
++ else
++ {
++ PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.size, suballoc.userData);
++ }
++ }
++
++ PrintDetailedMap_End(json);
++}
++#endif // VMA_STATS_STRING_ENABLED
++
++bool VmaBlockMetadata_Generic::CreateAllocationRequest(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ bool upperAddress,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest)
++{
++ VMA_ASSERT(allocSize > 0);
++ VMA_ASSERT(!upperAddress);
++ VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);
++ VMA_ASSERT(pAllocationRequest != VMA_NULL);
++ VMA_HEAVY_ASSERT(Validate());
++
++ allocSize = AlignAllocationSize(allocSize);
++
++ pAllocationRequest->type = VmaAllocationRequestType::Normal;
++ pAllocationRequest->size = allocSize;
++
++ const VkDeviceSize debugMargin = GetDebugMargin();
++
++ // There is not enough total free space in this block to fulfill the request: Early return.
++ if (m_SumFreeSize < allocSize + debugMargin)
++ {
++ return false;
++ }
++
++ // New algorithm, efficiently searching freeSuballocationsBySize.
++ const size_t freeSuballocCount = m_FreeSuballocationsBySize.size();
++ if (freeSuballocCount > 0)
++ {
++ if (strategy == 0 ||
++ strategy == VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT)
++ {
++ // Find first free suballocation with size not less than allocSize + debugMargin.
++ VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess(
++ m_FreeSuballocationsBySize.data(),
++ m_FreeSuballocationsBySize.data() + freeSuballocCount,
++ allocSize + debugMargin,
++ VmaSuballocationItemSizeLess());
++ size_t index = it - m_FreeSuballocationsBySize.data();
++ for (; index < freeSuballocCount; ++index)
++ {
++ if (CheckAllocation(
++ allocSize,
++ allocAlignment,
++ allocType,
++ m_FreeSuballocationsBySize[index],
++ &pAllocationRequest->allocHandle))
++ {
++ pAllocationRequest->item = m_FreeSuballocationsBySize[index];
++ return true;
++ }
++ }
++ }
++ else if (strategy == VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET)
++ {
++ for (VmaSuballocationList::iterator it = m_Suballocations.begin();
++ it != m_Suballocations.end();
++ ++it)
++ {
++ if (it->type == VMA_SUBALLOCATION_TYPE_FREE && CheckAllocation(
++ allocSize,
++ allocAlignment,
++ allocType,
++ it,
++ &pAllocationRequest->allocHandle))
++ {
++ pAllocationRequest->item = it;
++ return true;
++ }
++ }
++ }
++ else
++ {
++ VMA_ASSERT(strategy & (VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT | VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT ));
++ // Search staring from biggest suballocations.
++ for (size_t index = freeSuballocCount; index--; )
++ {
++ if (CheckAllocation(
++ allocSize,
++ allocAlignment,
++ allocType,
++ m_FreeSuballocationsBySize[index],
++ &pAllocationRequest->allocHandle))
++ {
++ pAllocationRequest->item = m_FreeSuballocationsBySize[index];
++ return true;
++ }
++ }
++ }
++ }
++
++ return false;
++}
++
++VkResult VmaBlockMetadata_Generic::CheckCorruption(const void* pBlockData)
++{
++ for (auto& suballoc : m_Suballocations)
++ {
++ if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ if (!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size))
++ {
++ VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!");
++ return VK_ERROR_UNKNOWN_COPY;
++ }
++ }
++ }
++
++ return VK_SUCCESS;
++}
++
++void VmaBlockMetadata_Generic::Alloc(
++ const VmaAllocationRequest& request,
++ VmaSuballocationType type,
++ void* userData)
++{
++ VMA_ASSERT(request.type == VmaAllocationRequestType::Normal);
++ VMA_ASSERT(request.item != m_Suballocations.end());
++ VmaSuballocation& suballoc = *request.item;
++ // Given suballocation is a free block.
++ VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
++
++ // Given offset is inside this suballocation.
++ VMA_ASSERT((VkDeviceSize)request.allocHandle - 1 >= suballoc.offset);
++ const VkDeviceSize paddingBegin = (VkDeviceSize)request.allocHandle - suballoc.offset - 1;
++ VMA_ASSERT(suballoc.size >= paddingBegin + request.size);
++ const VkDeviceSize paddingEnd = suballoc.size - paddingBegin - request.size;
++
++ // Unregister this free suballocation from m_FreeSuballocationsBySize and update
++ // it to become used.
++ UnregisterFreeSuballocation(request.item);
++
++ suballoc.offset = (VkDeviceSize)request.allocHandle - 1;
++ suballoc.size = request.size;
++ suballoc.type = type;
++ suballoc.userData = userData;
++
++ // If there are any free bytes remaining at the end, insert new free suballocation after current one.
++ if (paddingEnd)
++ {
++ VmaSuballocation paddingSuballoc = {};
++ paddingSuballoc.offset = suballoc.offset + suballoc.size;
++ paddingSuballoc.size = paddingEnd;
++ paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
++ VmaSuballocationList::iterator next = request.item;
++ ++next;
++ const VmaSuballocationList::iterator paddingEndItem =
++ m_Suballocations.insert(next, paddingSuballoc);
++ RegisterFreeSuballocation(paddingEndItem);
++ }
++
++ // If there are any free bytes remaining at the beginning, insert new free suballocation before current one.
++ if (paddingBegin)
++ {
++ VmaSuballocation paddingSuballoc = {};
++ paddingSuballoc.offset = suballoc.offset - paddingBegin;
++ paddingSuballoc.size = paddingBegin;
++ paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
++ const VmaSuballocationList::iterator paddingBeginItem =
++ m_Suballocations.insert(request.item, paddingSuballoc);
++ RegisterFreeSuballocation(paddingBeginItem);
++ }
++
++ // Update totals.
++ m_FreeCount = m_FreeCount - 1;
++ if (paddingBegin > 0)
++ {
++ ++m_FreeCount;
++ }
++ if (paddingEnd > 0)
++ {
++ ++m_FreeCount;
++ }
++ m_SumFreeSize -= request.size;
++}
++
++void VmaBlockMetadata_Generic::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo)
++{
++ outInfo.offset = (VkDeviceSize)allocHandle - 1;
++ const VmaSuballocation& suballoc = *FindAtOffset(outInfo.offset);
++ outInfo.size = suballoc.size;
++ outInfo.pUserData = suballoc.userData;
++}
++
++void* VmaBlockMetadata_Generic::GetAllocationUserData(VmaAllocHandle allocHandle) const
++{
++ return FindAtOffset((VkDeviceSize)allocHandle - 1)->userData;
++}
++
++VmaAllocHandle VmaBlockMetadata_Generic::GetAllocationListBegin() const
++{
++ if (IsEmpty())
++ return VK_NULL_HANDLE;
++
++ for (const auto& suballoc : m_Suballocations)
++ {
++ if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)
++ return (VmaAllocHandle)(suballoc.offset + 1);
++ }
++ VMA_ASSERT(false && "Should contain at least 1 allocation!");
++ return VK_NULL_HANDLE;
++}
++
++VmaAllocHandle VmaBlockMetadata_Generic::GetNextAllocation(VmaAllocHandle prevAlloc) const
++{
++ VmaSuballocationList::const_iterator prev = FindAtOffset((VkDeviceSize)prevAlloc - 1);
++
++ for (VmaSuballocationList::const_iterator it = ++prev; it != m_Suballocations.end(); ++it)
++ {
++ if (it->type != VMA_SUBALLOCATION_TYPE_FREE)
++ return (VmaAllocHandle)(it->offset + 1);
++ }
++ return VK_NULL_HANDLE;
++}
++
++void VmaBlockMetadata_Generic::Clear()
++{
++ const VkDeviceSize size = GetSize();
++
++ VMA_ASSERT(IsVirtual());
++ m_FreeCount = 1;
++ m_SumFreeSize = size;
++ m_Suballocations.clear();
++ m_FreeSuballocationsBySize.clear();
++
++ VmaSuballocation suballoc = {};
++ suballoc.offset = 0;
++ suballoc.size = size;
++ suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
++ m_Suballocations.push_back(suballoc);
++
++ m_FreeSuballocationsBySize.push_back(m_Suballocations.begin());
++}
++
++void VmaBlockMetadata_Generic::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData)
++{
++ VmaSuballocation& suballoc = *FindAtOffset((VkDeviceSize)allocHandle - 1);
++ suballoc.userData = userData;
++}
++
++void VmaBlockMetadata_Generic::DebugLogAllAllocations() const
++{
++ for (const auto& suballoc : m_Suballocations)
++ {
++ if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)
++ DebugLogAllocation(suballoc.offset, suballoc.size, suballoc.userData);
++ }
++}
++
++VmaSuballocationList::iterator VmaBlockMetadata_Generic::FindAtOffset(VkDeviceSize offset) const
++{
++ VMA_HEAVY_ASSERT(!m_Suballocations.empty());
++ const VkDeviceSize last = m_Suballocations.rbegin()->offset;
++ if (last == offset)
++ return m_Suballocations.rbegin().drop_const();
++ const VkDeviceSize first = m_Suballocations.begin()->offset;
++ if (first == offset)
++ return m_Suballocations.begin().drop_const();
++
++ const size_t suballocCount = m_Suballocations.size();
++ const VkDeviceSize step = (last - first + m_Suballocations.begin()->size) / suballocCount;
++ auto findSuballocation = [&](auto begin, auto end) -> VmaSuballocationList::iterator
++ {
++ for (auto suballocItem = begin;
++ suballocItem != end;
++ ++suballocItem)
++ {
++ if (suballocItem->offset == offset)
++ return suballocItem.drop_const();
++ }
++ VMA_ASSERT(false && "Not found!");
++ return m_Suballocations.end().drop_const();
++ };
++ // If requested offset is closer to the end of range, search from the end
++ if (offset - first > suballocCount * step / 2)
++ {
++ return findSuballocation(m_Suballocations.rbegin(), m_Suballocations.rend());
++ }
++ return findSuballocation(m_Suballocations.begin(), m_Suballocations.end());
++}
++
++bool VmaBlockMetadata_Generic::ValidateFreeSuballocationList() const
++{
++ VkDeviceSize lastSize = 0;
++ for (size_t i = 0, count = m_FreeSuballocationsBySize.size(); i < count; ++i)
++ {
++ const VmaSuballocationList::iterator it = m_FreeSuballocationsBySize[i];
++
++ VMA_VALIDATE(it->type == VMA_SUBALLOCATION_TYPE_FREE);
++ VMA_VALIDATE(it->size >= lastSize);
++ lastSize = it->size;
++ }
++ return true;
++}
++
++bool VmaBlockMetadata_Generic::CheckAllocation(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ VmaSuballocationType allocType,
++ VmaSuballocationList::const_iterator suballocItem,
++ VmaAllocHandle* pAllocHandle) const
++{
++ VMA_ASSERT(allocSize > 0);
++ VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);
++ VMA_ASSERT(suballocItem != m_Suballocations.cend());
++ VMA_ASSERT(pAllocHandle != VMA_NULL);
++
++ const VkDeviceSize debugMargin = GetDebugMargin();
++ const VkDeviceSize bufferImageGranularity = GetBufferImageGranularity();
++
++ const VmaSuballocation& suballoc = *suballocItem;
++ VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
++
++ // Size of this suballocation is too small for this request: Early return.
++ if (suballoc.size < allocSize)
++ {
++ return false;
++ }
++
++ // Start from offset equal to beginning of this suballocation.
++ VkDeviceSize offset = suballoc.offset + (suballocItem == m_Suballocations.cbegin() ? 0 : GetDebugMargin());
++
++ // Apply debugMargin from the end of previous alloc.
++ if (debugMargin > 0)
++ {
++ offset += debugMargin;
++ }
++
++ // Apply alignment.
++ offset = VmaAlignUp(offset, allocAlignment);
++
++ // Check previous suballocations for BufferImageGranularity conflicts.
++ // Make bigger alignment if necessary.
++ if (bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment)
++ {
++ bool bufferImageGranularityConflict = false;
++ VmaSuballocationList::const_iterator prevSuballocItem = suballocItem;
++ while (prevSuballocItem != m_Suballocations.cbegin())
++ {
++ --prevSuballocItem;
++ const VmaSuballocation& prevSuballoc = *prevSuballocItem;
++ if (VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, offset, bufferImageGranularity))
++ {
++ if (VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))
++ {
++ bufferImageGranularityConflict = true;
++ break;
++ }
++ }
++ else
++ // Already on previous page.
++ break;
++ }
++ if (bufferImageGranularityConflict)
++ {
++ offset = VmaAlignUp(offset, bufferImageGranularity);
++ }
++ }
++
++ // Calculate padding at the beginning based on current offset.
++ const VkDeviceSize paddingBegin = offset - suballoc.offset;
++
++ // Fail if requested size plus margin after is bigger than size of this suballocation.
++ if (paddingBegin + allocSize + debugMargin > suballoc.size)
++ {
++ return false;
++ }
++
++ // Check next suballocations for BufferImageGranularity conflicts.
++ // If conflict exists, allocation cannot be made here.
++ if (allocSize % bufferImageGranularity || offset % bufferImageGranularity)
++ {
++ VmaSuballocationList::const_iterator nextSuballocItem = suballocItem;
++ ++nextSuballocItem;
++ while (nextSuballocItem != m_Suballocations.cend())
++ {
++ const VmaSuballocation& nextSuballoc = *nextSuballocItem;
++ if (VmaBlocksOnSamePage(offset, allocSize, nextSuballoc.offset, bufferImageGranularity))
++ {
++ if (VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))
++ {
++ return false;
++ }
++ }
++ else
++ {
++ // Already on next page.
++ break;
++ }
++ ++nextSuballocItem;
++ }
++ }
++
++ *pAllocHandle = (VmaAllocHandle)(offset + 1);
++ // All tests passed: Success. pAllocHandle is already filled.
++ return true;
++}
++
++void VmaBlockMetadata_Generic::MergeFreeWithNext(VmaSuballocationList::iterator item)
++{
++ VMA_ASSERT(item != m_Suballocations.end());
++ VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE);
++
++ VmaSuballocationList::iterator nextItem = item;
++ ++nextItem;
++ VMA_ASSERT(nextItem != m_Suballocations.end());
++ VMA_ASSERT(nextItem->type == VMA_SUBALLOCATION_TYPE_FREE);
++
++ item->size += nextItem->size;
++ --m_FreeCount;
++ m_Suballocations.erase(nextItem);
++}
++
++VmaSuballocationList::iterator VmaBlockMetadata_Generic::FreeSuballocation(VmaSuballocationList::iterator suballocItem)
++{
++ // Change this suballocation to be marked as free.
++ VmaSuballocation& suballoc = *suballocItem;
++ suballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
++ suballoc.userData = VMA_NULL;
++
++ // Update totals.
++ ++m_FreeCount;
++ m_SumFreeSize += suballoc.size;
++
++ // Merge with previous and/or next suballocation if it's also free.
++ bool mergeWithNext = false;
++ bool mergeWithPrev = false;
++
++ VmaSuballocationList::iterator nextItem = suballocItem;
++ ++nextItem;
++ if ((nextItem != m_Suballocations.end()) && (nextItem->type == VMA_SUBALLOCATION_TYPE_FREE))
++ {
++ mergeWithNext = true;
++ }
++
++ VmaSuballocationList::iterator prevItem = suballocItem;
++ if (suballocItem != m_Suballocations.begin())
++ {
++ --prevItem;
++ if (prevItem->type == VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ mergeWithPrev = true;
++ }
++ }
++
++ if (mergeWithNext)
++ {
++ UnregisterFreeSuballocation(nextItem);
++ MergeFreeWithNext(suballocItem);
++ }
++
++ if (mergeWithPrev)
++ {
++ UnregisterFreeSuballocation(prevItem);
++ MergeFreeWithNext(prevItem);
++ RegisterFreeSuballocation(prevItem);
++ return prevItem;
++ }
++ else
++ {
++ RegisterFreeSuballocation(suballocItem);
++ return suballocItem;
++ }
++}
++
++void VmaBlockMetadata_Generic::RegisterFreeSuballocation(VmaSuballocationList::iterator item)
++{
++ VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE);
++ VMA_ASSERT(item->size > 0);
++
++ // You may want to enable this validation at the beginning or at the end of
++ // this function, depending on what do you want to check.
++ VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());
++
++ if (m_FreeSuballocationsBySize.empty())
++ {
++ m_FreeSuballocationsBySize.push_back(item);
++ }
++ else
++ {
++ VmaVectorInsertSorted<VmaSuballocationItemSizeLess>(m_FreeSuballocationsBySize, item);
++ }
++
++ //VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());
++}
++
++void VmaBlockMetadata_Generic::UnregisterFreeSuballocation(VmaSuballocationList::iterator item)
++{
++ VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE);
++ VMA_ASSERT(item->size > 0);
++
++ // You may want to enable this validation at the beginning or at the end of
++ // this function, depending on what do you want to check.
++ VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());
++
++ VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess(
++ m_FreeSuballocationsBySize.data(),
++ m_FreeSuballocationsBySize.data() + m_FreeSuballocationsBySize.size(),
++ item,
++ VmaSuballocationItemSizeLess());
++ for (size_t index = it - m_FreeSuballocationsBySize.data();
++ index < m_FreeSuballocationsBySize.size();
++ ++index)
++ {
++ if (m_FreeSuballocationsBySize[index] == item)
++ {
++ VmaVectorRemove(m_FreeSuballocationsBySize, index);
++ return;
++ }
++ VMA_ASSERT((m_FreeSuballocationsBySize[index]->size == item->size) && "Not found.");
++ }
++ VMA_ASSERT(0 && "Not found.");
++
++ //VMA_HEAVY_ASSERT(ValidateFreeSuballocationList());
++}
++#endif // _VMA_BLOCK_METADATA_GENERIC_FUNCTIONS
++#endif // _VMA_BLOCK_METADATA_GENERIC
++#endif // #if 0
++
++#ifndef _VMA_BLOCK_METADATA_LINEAR
++/*
++Allocations and their references in internal data structure look like this:
++
++if(m_2ndVectorMode == SECOND_VECTOR_EMPTY):
++
++ 0 +-------+
++ | |
++ | |
++ | |
++ +-------+
++ | Alloc | 1st[m_1stNullItemsBeginCount]
++ +-------+
++ | Alloc | 1st[m_1stNullItemsBeginCount + 1]
++ +-------+
++ | ... |
++ +-------+
++ | Alloc | 1st[1st.size() - 1]
++ +-------+
++ | |
++ | |
++ | |
++GetSize() +-------+
++
++if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER):
++
++ 0 +-------+
++ | Alloc | 2nd[0]
++ +-------+
++ | Alloc | 2nd[1]
++ +-------+
++ | ... |
++ +-------+
++ | Alloc | 2nd[2nd.size() - 1]
++ +-------+
++ | |
++ | |
++ | |
++ +-------+
++ | Alloc | 1st[m_1stNullItemsBeginCount]
++ +-------+
++ | Alloc | 1st[m_1stNullItemsBeginCount + 1]
++ +-------+
++ | ... |
++ +-------+
++ | Alloc | 1st[1st.size() - 1]
++ +-------+
++ | |
++GetSize() +-------+
++
++if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK):
++
++ 0 +-------+
++ | |
++ | |
++ | |
++ +-------+
++ | Alloc | 1st[m_1stNullItemsBeginCount]
++ +-------+
++ | Alloc | 1st[m_1stNullItemsBeginCount + 1]
++ +-------+
++ | ... |
++ +-------+
++ | Alloc | 1st[1st.size() - 1]
++ +-------+
++ | |
++ | |
++ | |
++ +-------+
++ | Alloc | 2nd[2nd.size() - 1]
++ +-------+
++ | ... |
++ +-------+
++ | Alloc | 2nd[1]
++ +-------+
++ | Alloc | 2nd[0]
++GetSize() +-------+
++
++*/
++class VmaBlockMetadata_Linear : public VmaBlockMetadata
++{
++ VMA_CLASS_NO_COPY(VmaBlockMetadata_Linear)
++public:
++ VmaBlockMetadata_Linear(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual);
++ virtual ~VmaBlockMetadata_Linear() = default;
++
++ VkDeviceSize GetSumFreeSize() const override { return m_SumFreeSize; }
++ bool IsEmpty() const override { return GetAllocationCount() == 0; }
++ VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle - 1; };
++
++ void Init(VkDeviceSize size) override;
++ bool Validate() const override;
++ size_t GetAllocationCount() const override;
++ size_t GetFreeRegionsCount() const override;
++
++ void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const override;
++ void AddStatistics(VmaStatistics& inoutStats) const override;
++
++#if VMA_STATS_STRING_ENABLED
++ void PrintDetailedMap(class VmaJsonWriter& json) const override;
++#endif
++
++ bool CreateAllocationRequest(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ bool upperAddress,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest) override;
++
++ VkResult CheckCorruption(const void* pBlockData) override;
++
++ void Alloc(
++ const VmaAllocationRequest& request,
++ VmaSuballocationType type,
++ void* userData) override;
++
++ void Free(VmaAllocHandle allocHandle) override;
++ void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override;
++ void* GetAllocationUserData(VmaAllocHandle allocHandle) const override;
++ VmaAllocHandle GetAllocationListBegin() const override;
++ VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override;
++ VkDeviceSize GetNextFreeRegionSize(VmaAllocHandle alloc) const override;
++ void Clear() override;
++ void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override;
++ void DebugLogAllAllocations() const override;
++
++private:
++ /*
++ There are two suballocation vectors, used in ping-pong way.
++ The one with index m_1stVectorIndex is called 1st.
++ The one with index (m_1stVectorIndex ^ 1) is called 2nd.
++ 2nd can be non-empty only when 1st is not empty.
++ When 2nd is not empty, m_2ndVectorMode indicates its mode of operation.
++ */
++ typedef VmaVector<VmaSuballocation, VmaStlAllocator<VmaSuballocation>> SuballocationVectorType;
++
++ enum SECOND_VECTOR_MODE
++ {
++ SECOND_VECTOR_EMPTY,
++ /*
++ Suballocations in 2nd vector are created later than the ones in 1st, but they
++ all have smaller offset.
++ */
++ SECOND_VECTOR_RING_BUFFER,
++ /*
++ Suballocations in 2nd vector are upper side of double stack.
++ They all have offsets higher than those in 1st vector.
++ Top of this stack means smaller offsets, but higher indices in this vector.
++ */
++ SECOND_VECTOR_DOUBLE_STACK,
++ };
++
++ VkDeviceSize m_SumFreeSize;
++ SuballocationVectorType m_Suballocations0, m_Suballocations1;
++ uint32_t m_1stVectorIndex;
++ SECOND_VECTOR_MODE m_2ndVectorMode;
++ // Number of items in 1st vector with hAllocation = null at the beginning.
++ size_t m_1stNullItemsBeginCount;
++ // Number of other items in 1st vector with hAllocation = null somewhere in the middle.
++ size_t m_1stNullItemsMiddleCount;
++ // Number of items in 2nd vector with hAllocation = null.
++ size_t m_2ndNullItemsCount;
++
++ SuballocationVectorType& AccessSuballocations1st() { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; }
++ SuballocationVectorType& AccessSuballocations2nd() { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; }
++ const SuballocationVectorType& AccessSuballocations1st() const { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; }
++ const SuballocationVectorType& AccessSuballocations2nd() const { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; }
++
++ VmaSuballocation& FindSuballocation(VkDeviceSize offset) const;
++ bool ShouldCompact1st() const;
++ void CleanupAfterFree();
++
++ bool CreateAllocationRequest_LowerAddress(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest);
++ bool CreateAllocationRequest_UpperAddress(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest);
++};
++
++#ifndef _VMA_BLOCK_METADATA_LINEAR_FUNCTIONS
++VmaBlockMetadata_Linear::VmaBlockMetadata_Linear(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual)
++ : VmaBlockMetadata(pAllocationCallbacks, bufferImageGranularity, isVirtual),
++ m_SumFreeSize(0),
++ m_Suballocations0(VmaStlAllocator<VmaSuballocation>(pAllocationCallbacks)),
++ m_Suballocations1(VmaStlAllocator<VmaSuballocation>(pAllocationCallbacks)),
++ m_1stVectorIndex(0),
++ m_2ndVectorMode(SECOND_VECTOR_EMPTY),
++ m_1stNullItemsBeginCount(0),
++ m_1stNullItemsMiddleCount(0),
++ m_2ndNullItemsCount(0) {}
++
++void VmaBlockMetadata_Linear::Init(VkDeviceSize size)
++{
++ VmaBlockMetadata::Init(size);
++ m_SumFreeSize = size;
++}
++
++bool VmaBlockMetadata_Linear::Validate() const
++{
++ const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++
++ VMA_VALIDATE(suballocations2nd.empty() == (m_2ndVectorMode == SECOND_VECTOR_EMPTY));
++ VMA_VALIDATE(!suballocations1st.empty() ||
++ suballocations2nd.empty() ||
++ m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER);
++
++ if (!suballocations1st.empty())
++ {
++ // Null item at the beginning should be accounted into m_1stNullItemsBeginCount.
++ VMA_VALIDATE(suballocations1st[m_1stNullItemsBeginCount].type != VMA_SUBALLOCATION_TYPE_FREE);
++ // Null item at the end should be just pop_back().
++ VMA_VALIDATE(suballocations1st.back().type != VMA_SUBALLOCATION_TYPE_FREE);
++ }
++ if (!suballocations2nd.empty())
++ {
++ // Null item at the end should be just pop_back().
++ VMA_VALIDATE(suballocations2nd.back().type != VMA_SUBALLOCATION_TYPE_FREE);
++ }
++
++ VMA_VALIDATE(m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount <= suballocations1st.size());
++ VMA_VALIDATE(m_2ndNullItemsCount <= suballocations2nd.size());
++
++ VkDeviceSize sumUsedSize = 0;
++ const size_t suballoc1stCount = suballocations1st.size();
++ const VkDeviceSize debugMargin = GetDebugMargin();
++ VkDeviceSize offset = 0;
++
++ if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)
++ {
++ const size_t suballoc2ndCount = suballocations2nd.size();
++ size_t nullItem2ndCount = 0;
++ for (size_t i = 0; i < suballoc2ndCount; ++i)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[i];
++ const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
++
++ VmaAllocation const alloc = (VmaAllocation)suballoc.userData;
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE(currFree == (alloc == VK_NULL_HANDLE));
++ }
++ VMA_VALIDATE(suballoc.offset >= offset);
++
++ if (!currFree)
++ {
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE((VkDeviceSize)alloc->GetAllocHandle() == suballoc.offset + 1);
++ VMA_VALIDATE(alloc->GetSize() == suballoc.size);
++ }
++ sumUsedSize += suballoc.size;
++ }
++ else
++ {
++ ++nullItem2ndCount;
++ }
++
++ offset = suballoc.offset + suballoc.size + debugMargin;
++ }
++
++ VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount);
++ }
++
++ for (size_t i = 0; i < m_1stNullItemsBeginCount; ++i)
++ {
++ const VmaSuballocation& suballoc = suballocations1st[i];
++ VMA_VALIDATE(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE &&
++ suballoc.userData == VMA_NULL);
++ }
++
++ size_t nullItem1stCount = m_1stNullItemsBeginCount;
++
++ for (size_t i = m_1stNullItemsBeginCount; i < suballoc1stCount; ++i)
++ {
++ const VmaSuballocation& suballoc = suballocations1st[i];
++ const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
++
++ VmaAllocation const alloc = (VmaAllocation)suballoc.userData;
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE(currFree == (alloc == VK_NULL_HANDLE));
++ }
++ VMA_VALIDATE(suballoc.offset >= offset);
++ VMA_VALIDATE(i >= m_1stNullItemsBeginCount || currFree);
++
++ if (!currFree)
++ {
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE((VkDeviceSize)alloc->GetAllocHandle() == suballoc.offset + 1);
++ VMA_VALIDATE(alloc->GetSize() == suballoc.size);
++ }
++ sumUsedSize += suballoc.size;
++ }
++ else
++ {
++ ++nullItem1stCount;
++ }
++
++ offset = suballoc.offset + suballoc.size + debugMargin;
++ }
++ VMA_VALIDATE(nullItem1stCount == m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount);
++
++ if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
++ {
++ const size_t suballoc2ndCount = suballocations2nd.size();
++ size_t nullItem2ndCount = 0;
++ for (size_t i = suballoc2ndCount; i--; )
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[i];
++ const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE);
++
++ VmaAllocation const alloc = (VmaAllocation)suballoc.userData;
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE(currFree == (alloc == VK_NULL_HANDLE));
++ }
++ VMA_VALIDATE(suballoc.offset >= offset);
++
++ if (!currFree)
++ {
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE((VkDeviceSize)alloc->GetAllocHandle() == suballoc.offset + 1);
++ VMA_VALIDATE(alloc->GetSize() == suballoc.size);
++ }
++ sumUsedSize += suballoc.size;
++ }
++ else
++ {
++ ++nullItem2ndCount;
++ }
++
++ offset = suballoc.offset + suballoc.size + debugMargin;
++ }
++
++ VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount);
++ }
++
++ VMA_VALIDATE(offset <= GetSize());
++ VMA_VALIDATE(m_SumFreeSize == GetSize() - sumUsedSize);
++
++ return true;
++}
++
++size_t VmaBlockMetadata_Linear::GetAllocationCount() const
++{
++ return AccessSuballocations1st().size() - m_1stNullItemsBeginCount - m_1stNullItemsMiddleCount +
++ AccessSuballocations2nd().size() - m_2ndNullItemsCount;
++}
++
++size_t VmaBlockMetadata_Linear::GetFreeRegionsCount() const
++{
++ // Function only used for defragmentation, which is disabled for this algorithm
++ VMA_ASSERT(0);
++ return SIZE_MAX;
++}
++
++void VmaBlockMetadata_Linear::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const
++{
++ const VkDeviceSize size = GetSize();
++ const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++ const size_t suballoc1stCount = suballocations1st.size();
++ const size_t suballoc2ndCount = suballocations2nd.size();
++
++ inoutStats.statistics.blockCount++;
++ inoutStats.statistics.blockBytes += size;
++
++ VkDeviceSize lastOffset = 0;
++
++ if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)
++ {
++ const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;
++ size_t nextAlloc2ndIndex = 0;
++ while (lastOffset < freeSpace2ndTo1stEnd)
++ {
++ // Find next non-null allocation or move nextAllocIndex to the end.
++ while (nextAlloc2ndIndex < suballoc2ndCount &&
++ suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL)
++ {
++ ++nextAlloc2ndIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc2ndIndex < suballoc2ndCount)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize);
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ VmaAddDetailedStatisticsAllocation(inoutStats, suballoc.size);
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ ++nextAlloc2ndIndex;
++ }
++ // We are at the end.
++ else
++ {
++ // There is free space from lastOffset to freeSpace2ndTo1stEnd.
++ if (lastOffset < freeSpace2ndTo1stEnd)
++ {
++ const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset;
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize);
++ }
++
++ // End of loop.
++ lastOffset = freeSpace2ndTo1stEnd;
++ }
++ }
++ }
++
++ size_t nextAlloc1stIndex = m_1stNullItemsBeginCount;
++ const VkDeviceSize freeSpace1stTo2ndEnd =
++ m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size;
++ while (lastOffset < freeSpace1stTo2ndEnd)
++ {
++ // Find next non-null allocation or move nextAllocIndex to the end.
++ while (nextAlloc1stIndex < suballoc1stCount &&
++ suballocations1st[nextAlloc1stIndex].userData == VMA_NULL)
++ {
++ ++nextAlloc1stIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc1stIndex < suballoc1stCount)
++ {
++ const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize);
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ VmaAddDetailedStatisticsAllocation(inoutStats, suballoc.size);
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ ++nextAlloc1stIndex;
++ }
++ // We are at the end.
++ else
++ {
++ // There is free space from lastOffset to freeSpace1stTo2ndEnd.
++ if (lastOffset < freeSpace1stTo2ndEnd)
++ {
++ const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset;
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize);
++ }
++
++ // End of loop.
++ lastOffset = freeSpace1stTo2ndEnd;
++ }
++ }
++
++ if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
++ {
++ size_t nextAlloc2ndIndex = suballocations2nd.size() - 1;
++ while (lastOffset < size)
++ {
++ // Find next non-null allocation or move nextAllocIndex to the end.
++ while (nextAlloc2ndIndex != SIZE_MAX &&
++ suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL)
++ {
++ --nextAlloc2ndIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc2ndIndex != SIZE_MAX)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize);
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ VmaAddDetailedStatisticsAllocation(inoutStats, suballoc.size);
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ --nextAlloc2ndIndex;
++ }
++ // We are at the end.
++ else
++ {
++ // There is free space from lastOffset to size.
++ if (lastOffset < size)
++ {
++ const VkDeviceSize unusedRangeSize = size - lastOffset;
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize);
++ }
++
++ // End of loop.
++ lastOffset = size;
++ }
++ }
++ }
++}
++
++void VmaBlockMetadata_Linear::AddStatistics(VmaStatistics& inoutStats) const
++{
++ const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++ const VkDeviceSize size = GetSize();
++ const size_t suballoc1stCount = suballocations1st.size();
++ const size_t suballoc2ndCount = suballocations2nd.size();
++
++ inoutStats.blockCount++;
++ inoutStats.blockBytes += size;
++ inoutStats.allocationBytes += size - m_SumFreeSize;
++
++ VkDeviceSize lastOffset = 0;
++
++ if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)
++ {
++ const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;
++ size_t nextAlloc2ndIndex = m_1stNullItemsBeginCount;
++ while (lastOffset < freeSpace2ndTo1stEnd)
++ {
++ // Find next non-null allocation or move nextAlloc2ndIndex to the end.
++ while (nextAlloc2ndIndex < suballoc2ndCount &&
++ suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL)
++ {
++ ++nextAlloc2ndIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc2ndIndex < suballoc2ndCount)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ ++inoutStats.allocationCount;
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ ++nextAlloc2ndIndex;
++ }
++ // We are at the end.
++ else
++ {
++ if (lastOffset < freeSpace2ndTo1stEnd)
++ {
++ // There is free space from lastOffset to freeSpace2ndTo1stEnd.
++ const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset;
++ }
++
++ // End of loop.
++ lastOffset = freeSpace2ndTo1stEnd;
++ }
++ }
++ }
++
++ size_t nextAlloc1stIndex = m_1stNullItemsBeginCount;
++ const VkDeviceSize freeSpace1stTo2ndEnd =
++ m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size;
++ while (lastOffset < freeSpace1stTo2ndEnd)
++ {
++ // Find next non-null allocation or move nextAllocIndex to the end.
++ while (nextAlloc1stIndex < suballoc1stCount &&
++ suballocations1st[nextAlloc1stIndex].userData == VMA_NULL)
++ {
++ ++nextAlloc1stIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc1stIndex < suballoc1stCount)
++ {
++ const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ ++inoutStats.allocationCount;
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ ++nextAlloc1stIndex;
++ }
++ // We are at the end.
++ else
++ {
++ if (lastOffset < freeSpace1stTo2ndEnd)
++ {
++ // There is free space from lastOffset to freeSpace1stTo2ndEnd.
++ const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset;
++ }
++
++ // End of loop.
++ lastOffset = freeSpace1stTo2ndEnd;
++ }
++ }
++
++ if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
++ {
++ size_t nextAlloc2ndIndex = suballocations2nd.size() - 1;
++ while (lastOffset < size)
++ {
++ // Find next non-null allocation or move nextAlloc2ndIndex to the end.
++ while (nextAlloc2ndIndex != SIZE_MAX &&
++ suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL)
++ {
++ --nextAlloc2ndIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc2ndIndex != SIZE_MAX)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ ++inoutStats.allocationCount;
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ --nextAlloc2ndIndex;
++ }
++ // We are at the end.
++ else
++ {
++ if (lastOffset < size)
++ {
++ // There is free space from lastOffset to size.
++ const VkDeviceSize unusedRangeSize = size - lastOffset;
++ }
++
++ // End of loop.
++ lastOffset = size;
++ }
++ }
++ }
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaBlockMetadata_Linear::PrintDetailedMap(class VmaJsonWriter& json) const
++{
++ const VkDeviceSize size = GetSize();
++ const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++ const size_t suballoc1stCount = suballocations1st.size();
++ const size_t suballoc2ndCount = suballocations2nd.size();
++
++ // FIRST PASS
++
++ size_t unusedRangeCount = 0;
++ VkDeviceSize usedBytes = 0;
++
++ VkDeviceSize lastOffset = 0;
++
++ size_t alloc2ndCount = 0;
++ if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)
++ {
++ const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;
++ size_t nextAlloc2ndIndex = 0;
++ while (lastOffset < freeSpace2ndTo1stEnd)
++ {
++ // Find next non-null allocation or move nextAlloc2ndIndex to the end.
++ while (nextAlloc2ndIndex < suballoc2ndCount &&
++ suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL)
++ {
++ ++nextAlloc2ndIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc2ndIndex < suballoc2ndCount)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ ++unusedRangeCount;
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ ++alloc2ndCount;
++ usedBytes += suballoc.size;
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ ++nextAlloc2ndIndex;
++ }
++ // We are at the end.
++ else
++ {
++ if (lastOffset < freeSpace2ndTo1stEnd)
++ {
++ // There is free space from lastOffset to freeSpace2ndTo1stEnd.
++ ++unusedRangeCount;
++ }
++
++ // End of loop.
++ lastOffset = freeSpace2ndTo1stEnd;
++ }
++ }
++ }
++
++ size_t nextAlloc1stIndex = m_1stNullItemsBeginCount;
++ size_t alloc1stCount = 0;
++ const VkDeviceSize freeSpace1stTo2ndEnd =
++ m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size;
++ while (lastOffset < freeSpace1stTo2ndEnd)
++ {
++ // Find next non-null allocation or move nextAllocIndex to the end.
++ while (nextAlloc1stIndex < suballoc1stCount &&
++ suballocations1st[nextAlloc1stIndex].userData == VMA_NULL)
++ {
++ ++nextAlloc1stIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc1stIndex < suballoc1stCount)
++ {
++ const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ ++unusedRangeCount;
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ ++alloc1stCount;
++ usedBytes += suballoc.size;
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ ++nextAlloc1stIndex;
++ }
++ // We are at the end.
++ else
++ {
++ if (lastOffset < size)
++ {
++ // There is free space from lastOffset to freeSpace1stTo2ndEnd.
++ ++unusedRangeCount;
++ }
++
++ // End of loop.
++ lastOffset = freeSpace1stTo2ndEnd;
++ }
++ }
++
++ if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
++ {
++ size_t nextAlloc2ndIndex = suballocations2nd.size() - 1;
++ while (lastOffset < size)
++ {
++ // Find next non-null allocation or move nextAlloc2ndIndex to the end.
++ while (nextAlloc2ndIndex != SIZE_MAX &&
++ suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL)
++ {
++ --nextAlloc2ndIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc2ndIndex != SIZE_MAX)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ ++unusedRangeCount;
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ ++alloc2ndCount;
++ usedBytes += suballoc.size;
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ --nextAlloc2ndIndex;
++ }
++ // We are at the end.
++ else
++ {
++ if (lastOffset < size)
++ {
++ // There is free space from lastOffset to size.
++ ++unusedRangeCount;
++ }
++
++ // End of loop.
++ lastOffset = size;
++ }
++ }
++ }
++
++ const VkDeviceSize unusedBytes = size - usedBytes;
++ PrintDetailedMap_Begin(json, unusedBytes, alloc1stCount + alloc2ndCount, unusedRangeCount);
++
++ // SECOND PASS
++ lastOffset = 0;
++
++ if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)
++ {
++ const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset;
++ size_t nextAlloc2ndIndex = 0;
++ while (lastOffset < freeSpace2ndTo1stEnd)
++ {
++ // Find next non-null allocation or move nextAlloc2ndIndex to the end.
++ while (nextAlloc2ndIndex < suballoc2ndCount &&
++ suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL)
++ {
++ ++nextAlloc2ndIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc2ndIndex < suballoc2ndCount)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;
++ PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.size, suballoc.userData);
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ ++nextAlloc2ndIndex;
++ }
++ // We are at the end.
++ else
++ {
++ if (lastOffset < freeSpace2ndTo1stEnd)
++ {
++ // There is free space from lastOffset to freeSpace2ndTo1stEnd.
++ const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset;
++ PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);
++ }
++
++ // End of loop.
++ lastOffset = freeSpace2ndTo1stEnd;
++ }
++ }
++ }
++
++ nextAlloc1stIndex = m_1stNullItemsBeginCount;
++ while (lastOffset < freeSpace1stTo2ndEnd)
++ {
++ // Find next non-null allocation or move nextAllocIndex to the end.
++ while (nextAlloc1stIndex < suballoc1stCount &&
++ suballocations1st[nextAlloc1stIndex].userData == VMA_NULL)
++ {
++ ++nextAlloc1stIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc1stIndex < suballoc1stCount)
++ {
++ const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;
++ PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.size, suballoc.userData);
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ ++nextAlloc1stIndex;
++ }
++ // We are at the end.
++ else
++ {
++ if (lastOffset < freeSpace1stTo2ndEnd)
++ {
++ // There is free space from lastOffset to freeSpace1stTo2ndEnd.
++ const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset;
++ PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);
++ }
++
++ // End of loop.
++ lastOffset = freeSpace1stTo2ndEnd;
++ }
++ }
++
++ if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
++ {
++ size_t nextAlloc2ndIndex = suballocations2nd.size() - 1;
++ while (lastOffset < size)
++ {
++ // Find next non-null allocation or move nextAlloc2ndIndex to the end.
++ while (nextAlloc2ndIndex != SIZE_MAX &&
++ suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL)
++ {
++ --nextAlloc2ndIndex;
++ }
++
++ // Found non-null allocation.
++ if (nextAlloc2ndIndex != SIZE_MAX)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex];
++
++ // 1. Process free space before this allocation.
++ if (lastOffset < suballoc.offset)
++ {
++ // There is free space from lastOffset to suballoc.offset.
++ const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset;
++ PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);
++ }
++
++ // 2. Process this allocation.
++ // There is allocation with suballoc.offset, suballoc.size.
++ PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.size, suballoc.userData);
++
++ // 3. Prepare for next iteration.
++ lastOffset = suballoc.offset + suballoc.size;
++ --nextAlloc2ndIndex;
++ }
++ // We are at the end.
++ else
++ {
++ if (lastOffset < size)
++ {
++ // There is free space from lastOffset to size.
++ const VkDeviceSize unusedRangeSize = size - lastOffset;
++ PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize);
++ }
++
++ // End of loop.
++ lastOffset = size;
++ }
++ }
++ }
++
++ PrintDetailedMap_End(json);
++}
++#endif // VMA_STATS_STRING_ENABLED
++
++bool VmaBlockMetadata_Linear::CreateAllocationRequest(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ bool upperAddress,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest)
++{
++ VMA_ASSERT(allocSize > 0);
++ VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE);
++ VMA_ASSERT(pAllocationRequest != VMA_NULL);
++ VMA_HEAVY_ASSERT(Validate());
++ pAllocationRequest->size = allocSize;
++ return upperAddress ?
++ CreateAllocationRequest_UpperAddress(
++ allocSize, allocAlignment, allocType, strategy, pAllocationRequest) :
++ CreateAllocationRequest_LowerAddress(
++ allocSize, allocAlignment, allocType, strategy, pAllocationRequest);
++}
++
++VkResult VmaBlockMetadata_Linear::CheckCorruption(const void* pBlockData)
++{
++ VMA_ASSERT(!IsVirtual());
++ SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ for (size_t i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i < count; ++i)
++ {
++ const VmaSuballocation& suballoc = suballocations1st[i];
++ if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ if (!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size))
++ {
++ VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!");
++ return VK_ERROR_UNKNOWN_COPY;
++ }
++ }
++ }
++
++ SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++ for (size_t i = 0, count = suballocations2nd.size(); i < count; ++i)
++ {
++ const VmaSuballocation& suballoc = suballocations2nd[i];
++ if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ if (!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size))
++ {
++ VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!");
++ return VK_ERROR_UNKNOWN_COPY;
++ }
++ }
++ }
++
++ return VK_SUCCESS;
++}
++
++void VmaBlockMetadata_Linear::Alloc(
++ const VmaAllocationRequest& request,
++ VmaSuballocationType type,
++ void* userData)
++{
++ const VkDeviceSize offset = (VkDeviceSize)request.allocHandle - 1;
++ const VmaSuballocation newSuballoc = { offset, request.size, userData, type };
++
++ switch (request.type)
++ {
++ case VmaAllocationRequestType::UpperAddress:
++ {
++ VMA_ASSERT(m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER &&
++ "CRITICAL ERROR: Trying to use linear allocator as double stack while it was already used as ring buffer.");
++ SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++ suballocations2nd.push_back(newSuballoc);
++ m_2ndVectorMode = SECOND_VECTOR_DOUBLE_STACK;
++ }
++ break;
++ case VmaAllocationRequestType::EndOf1st:
++ {
++ SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++
++ VMA_ASSERT(suballocations1st.empty() ||
++ offset >= suballocations1st.back().offset + suballocations1st.back().size);
++ // Check if it fits before the end of the block.
++ VMA_ASSERT(offset + request.size <= GetSize());
++
++ suballocations1st.push_back(newSuballoc);
++ }
++ break;
++ case VmaAllocationRequestType::EndOf2nd:
++ {
++ SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ // New allocation at the end of 2-part ring buffer, so before first allocation from 1st vector.
++ VMA_ASSERT(!suballocations1st.empty() &&
++ offset + request.size <= suballocations1st[m_1stNullItemsBeginCount].offset);
++ SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++
++ switch (m_2ndVectorMode)
++ {
++ case SECOND_VECTOR_EMPTY:
++ // First allocation from second part ring buffer.
++ VMA_ASSERT(suballocations2nd.empty());
++ m_2ndVectorMode = SECOND_VECTOR_RING_BUFFER;
++ break;
++ case SECOND_VECTOR_RING_BUFFER:
++ // 2-part ring buffer is already started.
++ VMA_ASSERT(!suballocations2nd.empty());
++ break;
++ case SECOND_VECTOR_DOUBLE_STACK:
++ VMA_ASSERT(0 && "CRITICAL ERROR: Trying to use linear allocator as ring buffer while it was already used as double stack.");
++ break;
++ default:
++ VMA_ASSERT(0);
++ }
++
++ suballocations2nd.push_back(newSuballoc);
++ }
++ break;
++ default:
++ VMA_ASSERT(0 && "CRITICAL INTERNAL ERROR.");
++ }
++
++ m_SumFreeSize -= newSuballoc.size;
++}
++
++void VmaBlockMetadata_Linear::Free(VmaAllocHandle allocHandle)
++{
++ SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++ VkDeviceSize offset = (VkDeviceSize)allocHandle - 1;
++
++ if (!suballocations1st.empty())
++ {
++ // First allocation: Mark it as next empty at the beginning.
++ VmaSuballocation& firstSuballoc = suballocations1st[m_1stNullItemsBeginCount];
++ if (firstSuballoc.offset == offset)
++ {
++ firstSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE;
++ firstSuballoc.userData = VMA_NULL;
++ m_SumFreeSize += firstSuballoc.size;
++ ++m_1stNullItemsBeginCount;
++ CleanupAfterFree();
++ return;
++ }
++ }
++
++ // Last allocation in 2-part ring buffer or top of upper stack (same logic).
++ if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ||
++ m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
++ {
++ VmaSuballocation& lastSuballoc = suballocations2nd.back();
++ if (lastSuballoc.offset == offset)
++ {
++ m_SumFreeSize += lastSuballoc.size;
++ suballocations2nd.pop_back();
++ CleanupAfterFree();
++ return;
++ }
++ }
++ // Last allocation in 1st vector.
++ else if (m_2ndVectorMode == SECOND_VECTOR_EMPTY)
++ {
++ VmaSuballocation& lastSuballoc = suballocations1st.back();
++ if (lastSuballoc.offset == offset)
++ {
++ m_SumFreeSize += lastSuballoc.size;
++ suballocations1st.pop_back();
++ CleanupAfterFree();
++ return;
++ }
++ }
++
++ VmaSuballocation refSuballoc;
++ refSuballoc.offset = offset;
++ // Rest of members stays uninitialized intentionally for better performance.
++
++ // Item from the middle of 1st vector.
++ {
++ const SuballocationVectorType::iterator it = VmaBinaryFindSorted(
++ suballocations1st.begin() + m_1stNullItemsBeginCount,
++ suballocations1st.end(),
++ refSuballoc,
++ VmaSuballocationOffsetLess());
++ if (it != suballocations1st.end())
++ {
++ it->type = VMA_SUBALLOCATION_TYPE_FREE;
++ it->userData = VMA_NULL;
++ ++m_1stNullItemsMiddleCount;
++ m_SumFreeSize += it->size;
++ CleanupAfterFree();
++ return;
++ }
++ }
++
++ if (m_2ndVectorMode != SECOND_VECTOR_EMPTY)
++ {
++ // Item from the middle of 2nd vector.
++ const SuballocationVectorType::iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ?
++ VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetLess()) :
++ VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetGreater());
++ if (it != suballocations2nd.end())
++ {
++ it->type = VMA_SUBALLOCATION_TYPE_FREE;
++ it->userData = VMA_NULL;
++ ++m_2ndNullItemsCount;
++ m_SumFreeSize += it->size;
++ CleanupAfterFree();
++ return;
++ }
++ }
++
++ VMA_ASSERT(0 && "Allocation to free not found in linear allocator!");
++}
++
++void VmaBlockMetadata_Linear::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo)
++{
++ outInfo.offset = (VkDeviceSize)allocHandle - 1;
++ VmaSuballocation& suballoc = FindSuballocation(outInfo.offset);
++ outInfo.size = suballoc.size;
++ outInfo.pUserData = suballoc.userData;
++}
++
++void* VmaBlockMetadata_Linear::GetAllocationUserData(VmaAllocHandle allocHandle) const
++{
++ return FindSuballocation((VkDeviceSize)allocHandle - 1).userData;
++}
++
++VmaAllocHandle VmaBlockMetadata_Linear::GetAllocationListBegin() const
++{
++ // Function only used for defragmentation, which is disabled for this algorithm
++ VMA_ASSERT(0);
++ return VK_NULL_HANDLE;
++}
++
++VmaAllocHandle VmaBlockMetadata_Linear::GetNextAllocation(VmaAllocHandle prevAlloc) const
++{
++ // Function only used for defragmentation, which is disabled for this algorithm
++ VMA_ASSERT(0);
++ return VK_NULL_HANDLE;
++}
++
++VkDeviceSize VmaBlockMetadata_Linear::GetNextFreeRegionSize(VmaAllocHandle alloc) const
++{
++ // Function only used for defragmentation, which is disabled for this algorithm
++ VMA_ASSERT(0);
++ return 0;
++}
++
++void VmaBlockMetadata_Linear::Clear()
++{
++ m_SumFreeSize = GetSize();
++ m_Suballocations0.clear();
++ m_Suballocations1.clear();
++ // Leaving m_1stVectorIndex unchanged - it doesn't matter.
++ m_2ndVectorMode = SECOND_VECTOR_EMPTY;
++ m_1stNullItemsBeginCount = 0;
++ m_1stNullItemsMiddleCount = 0;
++ m_2ndNullItemsCount = 0;
++}
++
++void VmaBlockMetadata_Linear::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData)
++{
++ VmaSuballocation& suballoc = FindSuballocation((VkDeviceSize)allocHandle - 1);
++ suballoc.userData = userData;
++}
++
++void VmaBlockMetadata_Linear::DebugLogAllAllocations() const
++{
++ const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ for (auto it = suballocations1st.begin() + m_1stNullItemsBeginCount; it != suballocations1st.end(); ++it)
++ if (it->type != VMA_SUBALLOCATION_TYPE_FREE)
++ DebugLogAllocation(it->offset, it->size, it->userData);
++
++ const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++ for (auto it = suballocations2nd.begin(); it != suballocations2nd.end(); ++it)
++ if (it->type != VMA_SUBALLOCATION_TYPE_FREE)
++ DebugLogAllocation(it->offset, it->size, it->userData);
++}
++
++VmaSuballocation& VmaBlockMetadata_Linear::FindSuballocation(VkDeviceSize offset) const
++{
++ const SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++
++ VmaSuballocation refSuballoc;
++ refSuballoc.offset = offset;
++ // Rest of members stays uninitialized intentionally for better performance.
++
++ // Item from the 1st vector.
++ {
++ SuballocationVectorType::const_iterator it = VmaBinaryFindSorted(
++ suballocations1st.begin() + m_1stNullItemsBeginCount,
++ suballocations1st.end(),
++ refSuballoc,
++ VmaSuballocationOffsetLess());
++ if (it != suballocations1st.end())
++ {
++ return const_cast<VmaSuballocation&>(*it);
++ }
++ }
++
++ if (m_2ndVectorMode != SECOND_VECTOR_EMPTY)
++ {
++ // Rest of members stays uninitialized intentionally for better performance.
++ SuballocationVectorType::const_iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ?
++ VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetLess()) :
++ VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetGreater());
++ if (it != suballocations2nd.end())
++ {
++ return const_cast<VmaSuballocation&>(*it);
++ }
++ }
++
++ VMA_ASSERT(0 && "Allocation not found in linear allocator!");
++ return const_cast<VmaSuballocation&>(suballocations1st.back()); // Should never occur.
++}
++
++bool VmaBlockMetadata_Linear::ShouldCompact1st() const
++{
++ const size_t nullItemCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount;
++ const size_t suballocCount = AccessSuballocations1st().size();
++ return suballocCount > 32 && nullItemCount * 2 >= (suballocCount - nullItemCount) * 3;
++}
++
++void VmaBlockMetadata_Linear::CleanupAfterFree()
++{
++ SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++
++ if (IsEmpty())
++ {
++ suballocations1st.clear();
++ suballocations2nd.clear();
++ m_1stNullItemsBeginCount = 0;
++ m_1stNullItemsMiddleCount = 0;
++ m_2ndNullItemsCount = 0;
++ m_2ndVectorMode = SECOND_VECTOR_EMPTY;
++ }
++ else
++ {
++ const size_t suballoc1stCount = suballocations1st.size();
++ const size_t nullItem1stCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount;
++ VMA_ASSERT(nullItem1stCount <= suballoc1stCount);
++
++ // Find more null items at the beginning of 1st vector.
++ while (m_1stNullItemsBeginCount < suballoc1stCount &&
++ suballocations1st[m_1stNullItemsBeginCount].type == VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ ++m_1stNullItemsBeginCount;
++ --m_1stNullItemsMiddleCount;
++ }
++
++ // Find more null items at the end of 1st vector.
++ while (m_1stNullItemsMiddleCount > 0 &&
++ suballocations1st.back().type == VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ --m_1stNullItemsMiddleCount;
++ suballocations1st.pop_back();
++ }
++
++ // Find more null items at the end of 2nd vector.
++ while (m_2ndNullItemsCount > 0 &&
++ suballocations2nd.back().type == VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ --m_2ndNullItemsCount;
++ suballocations2nd.pop_back();
++ }
++
++ // Find more null items at the beginning of 2nd vector.
++ while (m_2ndNullItemsCount > 0 &&
++ suballocations2nd[0].type == VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ --m_2ndNullItemsCount;
++ VmaVectorRemove(suballocations2nd, 0);
++ }
++
++ if (ShouldCompact1st())
++ {
++ const size_t nonNullItemCount = suballoc1stCount - nullItem1stCount;
++ size_t srcIndex = m_1stNullItemsBeginCount;
++ for (size_t dstIndex = 0; dstIndex < nonNullItemCount; ++dstIndex)
++ {
++ while (suballocations1st[srcIndex].type == VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ ++srcIndex;
++ }
++ if (dstIndex != srcIndex)
++ {
++ suballocations1st[dstIndex] = suballocations1st[srcIndex];
++ }
++ ++srcIndex;
++ }
++ suballocations1st.resize(nonNullItemCount);
++ m_1stNullItemsBeginCount = 0;
++ m_1stNullItemsMiddleCount = 0;
++ }
++
++ // 2nd vector became empty.
++ if (suballocations2nd.empty())
++ {
++ m_2ndVectorMode = SECOND_VECTOR_EMPTY;
++ }
++
++ // 1st vector became empty.
++ if (suballocations1st.size() - m_1stNullItemsBeginCount == 0)
++ {
++ suballocations1st.clear();
++ m_1stNullItemsBeginCount = 0;
++
++ if (!suballocations2nd.empty() && m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)
++ {
++ // Swap 1st with 2nd. Now 2nd is empty.
++ m_2ndVectorMode = SECOND_VECTOR_EMPTY;
++ m_1stNullItemsMiddleCount = m_2ndNullItemsCount;
++ while (m_1stNullItemsBeginCount < suballocations2nd.size() &&
++ suballocations2nd[m_1stNullItemsBeginCount].type == VMA_SUBALLOCATION_TYPE_FREE)
++ {
++ ++m_1stNullItemsBeginCount;
++ --m_1stNullItemsMiddleCount;
++ }
++ m_2ndNullItemsCount = 0;
++ m_1stVectorIndex ^= 1;
++ }
++ }
++ }
++
++ VMA_HEAVY_ASSERT(Validate());
++}
++
++bool VmaBlockMetadata_Linear::CreateAllocationRequest_LowerAddress(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest)
++{
++ const VkDeviceSize blockSize = GetSize();
++ const VkDeviceSize debugMargin = GetDebugMargin();
++ const VkDeviceSize bufferImageGranularity = GetBufferImageGranularity();
++ SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++
++ if (m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
++ {
++ // Try to allocate at the end of 1st vector.
++
++ VkDeviceSize resultBaseOffset = 0;
++ if (!suballocations1st.empty())
++ {
++ const VmaSuballocation& lastSuballoc = suballocations1st.back();
++ resultBaseOffset = lastSuballoc.offset + lastSuballoc.size + debugMargin;
++ }
++
++ // Start from offset equal to beginning of free space.
++ VkDeviceSize resultOffset = resultBaseOffset;
++
++ // Apply alignment.
++ resultOffset = VmaAlignUp(resultOffset, allocAlignment);
++
++ // Check previous suballocations for BufferImageGranularity conflicts.
++ // Make bigger alignment if necessary.
++ if (bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations1st.empty())
++ {
++ bool bufferImageGranularityConflict = false;
++ for (size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; )
++ {
++ const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex];
++ if (VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity))
++ {
++ if (VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))
++ {
++ bufferImageGranularityConflict = true;
++ break;
++ }
++ }
++ else
++ // Already on previous page.
++ break;
++ }
++ if (bufferImageGranularityConflict)
++ {
++ resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity);
++ }
++ }
++
++ const VkDeviceSize freeSpaceEnd = m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ?
++ suballocations2nd.back().offset : blockSize;
++
++ // There is enough free space at the end after alignment.
++ if (resultOffset + allocSize + debugMargin <= freeSpaceEnd)
++ {
++ // Check next suballocations for BufferImageGranularity conflicts.
++ // If conflict exists, allocation cannot be made here.
++ if ((allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity) && m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK)
++ {
++ for (size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; )
++ {
++ const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex];
++ if (VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))
++ {
++ if (VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))
++ {
++ return false;
++ }
++ }
++ else
++ {
++ // Already on previous page.
++ break;
++ }
++ }
++ }
++
++ // All tests passed: Success.
++ pAllocationRequest->allocHandle = (VmaAllocHandle)(resultOffset + 1);
++ // pAllocationRequest->item, customData unused.
++ pAllocationRequest->type = VmaAllocationRequestType::EndOf1st;
++ return true;
++ }
++ }
++
++ // Wrap-around to end of 2nd vector. Try to allocate there, watching for the
++ // beginning of 1st vector as the end of free space.
++ if (m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)
++ {
++ VMA_ASSERT(!suballocations1st.empty());
++
++ VkDeviceSize resultBaseOffset = 0;
++ if (!suballocations2nd.empty())
++ {
++ const VmaSuballocation& lastSuballoc = suballocations2nd.back();
++ resultBaseOffset = lastSuballoc.offset + lastSuballoc.size + debugMargin;
++ }
++
++ // Start from offset equal to beginning of free space.
++ VkDeviceSize resultOffset = resultBaseOffset;
++
++ // Apply alignment.
++ resultOffset = VmaAlignUp(resultOffset, allocAlignment);
++
++ // Check previous suballocations for BufferImageGranularity conflicts.
++ // Make bigger alignment if necessary.
++ if (bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations2nd.empty())
++ {
++ bool bufferImageGranularityConflict = false;
++ for (size_t prevSuballocIndex = suballocations2nd.size(); prevSuballocIndex--; )
++ {
++ const VmaSuballocation& prevSuballoc = suballocations2nd[prevSuballocIndex];
++ if (VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity))
++ {
++ if (VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType))
++ {
++ bufferImageGranularityConflict = true;
++ break;
++ }
++ }
++ else
++ // Already on previous page.
++ break;
++ }
++ if (bufferImageGranularityConflict)
++ {
++ resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity);
++ }
++ }
++
++ size_t index1st = m_1stNullItemsBeginCount;
++
++ // There is enough free space at the end after alignment.
++ if ((index1st == suballocations1st.size() && resultOffset + allocSize + debugMargin <= blockSize) ||
++ (index1st < suballocations1st.size() && resultOffset + allocSize + debugMargin <= suballocations1st[index1st].offset))
++ {
++ // Check next suballocations for BufferImageGranularity conflicts.
++ // If conflict exists, allocation cannot be made here.
++ if (allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity)
++ {
++ for (size_t nextSuballocIndex = index1st;
++ nextSuballocIndex < suballocations1st.size();
++ nextSuballocIndex++)
++ {
++ const VmaSuballocation& nextSuballoc = suballocations1st[nextSuballocIndex];
++ if (VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))
++ {
++ if (VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type))
++ {
++ return false;
++ }
++ }
++ else
++ {
++ // Already on next page.
++ break;
++ }
++ }
++ }
++
++ // All tests passed: Success.
++ pAllocationRequest->allocHandle = (VmaAllocHandle)(resultOffset + 1);
++ pAllocationRequest->type = VmaAllocationRequestType::EndOf2nd;
++ // pAllocationRequest->item, customData unused.
++ return true;
++ }
++ }
++
++ return false;
++}
++
++bool VmaBlockMetadata_Linear::CreateAllocationRequest_UpperAddress(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest)
++{
++ const VkDeviceSize blockSize = GetSize();
++ const VkDeviceSize bufferImageGranularity = GetBufferImageGranularity();
++ SuballocationVectorType& suballocations1st = AccessSuballocations1st();
++ SuballocationVectorType& suballocations2nd = AccessSuballocations2nd();
++
++ if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER)
++ {
++ VMA_ASSERT(0 && "Trying to use pool with linear algorithm as double stack, while it is already being used as ring buffer.");
++ return false;
++ }
++
++ // Try to allocate before 2nd.back(), or end of block if 2nd.empty().
++ if (allocSize > blockSize)
++ {
++ return false;
++ }
++ VkDeviceSize resultBaseOffset = blockSize - allocSize;
++ if (!suballocations2nd.empty())
++ {
++ const VmaSuballocation& lastSuballoc = suballocations2nd.back();
++ resultBaseOffset = lastSuballoc.offset - allocSize;
++ if (allocSize > lastSuballoc.offset)
++ {
++ return false;
++ }
++ }
++
++ // Start from offset equal to end of free space.
++ VkDeviceSize resultOffset = resultBaseOffset;
++
++ const VkDeviceSize debugMargin = GetDebugMargin();
++
++ // Apply debugMargin at the end.
++ if (debugMargin > 0)
++ {
++ if (resultOffset < debugMargin)
++ {
++ return false;
++ }
++ resultOffset -= debugMargin;
++ }
++
++ // Apply alignment.
++ resultOffset = VmaAlignDown(resultOffset, allocAlignment);
++
++ // Check next suballocations from 2nd for BufferImageGranularity conflicts.
++ // Make bigger alignment if necessary.
++ if (bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations2nd.empty())
++ {
++ bool bufferImageGranularityConflict = false;
++ for (size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; )
++ {
++ const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex];
++ if (VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity))
++ {
++ if (VmaIsBufferImageGranularityConflict(nextSuballoc.type, allocType))
++ {
++ bufferImageGranularityConflict = true;
++ break;
++ }
++ }
++ else
++ // Already on previous page.
++ break;
++ }
++ if (bufferImageGranularityConflict)
++ {
++ resultOffset = VmaAlignDown(resultOffset, bufferImageGranularity);
++ }
++ }
++
++ // There is enough free space.
++ const VkDeviceSize endOf1st = !suballocations1st.empty() ?
++ suballocations1st.back().offset + suballocations1st.back().size :
++ 0;
++ if (endOf1st + debugMargin <= resultOffset)
++ {
++ // Check previous suballocations for BufferImageGranularity conflicts.
++ // If conflict exists, allocation cannot be made here.
++ if (bufferImageGranularity > 1)
++ {
++ for (size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; )
++ {
++ const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex];
++ if (VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity))
++ {
++ if (VmaIsBufferImageGranularityConflict(allocType, prevSuballoc.type))
++ {
++ return false;
++ }
++ }
++ else
++ {
++ // Already on next page.
++ break;
++ }
++ }
++ }
++
++ // All tests passed: Success.
++ pAllocationRequest->allocHandle = (VmaAllocHandle)(resultOffset + 1);
++ // pAllocationRequest->item unused.
++ pAllocationRequest->type = VmaAllocationRequestType::UpperAddress;
++ return true;
++ }
++
++ return false;
++}
++#endif // _VMA_BLOCK_METADATA_LINEAR_FUNCTIONS
++#endif // _VMA_BLOCK_METADATA_LINEAR
++
++#if 0
++#ifndef _VMA_BLOCK_METADATA_BUDDY
++/*
++- GetSize() is the original size of allocated memory block.
++- m_UsableSize is this size aligned down to a power of two.
++ All allocations and calculations happen relative to m_UsableSize.
++- GetUnusableSize() is the difference between them.
++ It is reported as separate, unused range, not available for allocations.
++
++Node at level 0 has size = m_UsableSize.
++Each next level contains nodes with size 2 times smaller than current level.
++m_LevelCount is the maximum number of levels to use in the current object.
++*/
++class VmaBlockMetadata_Buddy : public VmaBlockMetadata
++{
++ VMA_CLASS_NO_COPY(VmaBlockMetadata_Buddy)
++public:
++ VmaBlockMetadata_Buddy(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual);
++ virtual ~VmaBlockMetadata_Buddy();
++
++ size_t GetAllocationCount() const override { return m_AllocationCount; }
++ VkDeviceSize GetSumFreeSize() const override { return m_SumFreeSize + GetUnusableSize(); }
++ bool IsEmpty() const override { return m_Root->type == Node::TYPE_FREE; }
++ VkResult CheckCorruption(const void* pBlockData) override { return VK_ERROR_FEATURE_NOT_PRESENT; }
++ VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle - 1; };
++ void DebugLogAllAllocations() const override { DebugLogAllAllocationNode(m_Root, 0); }
++
++ void Init(VkDeviceSize size) override;
++ bool Validate() const override;
++
++ void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const override;
++ void AddStatistics(VmaStatistics& inoutStats) const override;
++
++#if VMA_STATS_STRING_ENABLED
++ void PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const override;
++#endif
++
++ bool CreateAllocationRequest(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ bool upperAddress,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest) override;
++
++ void Alloc(
++ const VmaAllocationRequest& request,
++ VmaSuballocationType type,
++ void* userData) override;
++
++ void Free(VmaAllocHandle allocHandle) override;
++ void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override;
++ void* GetAllocationUserData(VmaAllocHandle allocHandle) const override;
++ VmaAllocHandle GetAllocationListBegin() const override;
++ VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override;
++ void Clear() override;
++ void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override;
++
++private:
++ static const size_t MAX_LEVELS = 48;
++
++ struct ValidationContext
++ {
++ size_t calculatedAllocationCount = 0;
++ size_t calculatedFreeCount = 0;
++ VkDeviceSize calculatedSumFreeSize = 0;
++ };
++ struct Node
++ {
++ VkDeviceSize offset;
++ enum TYPE
++ {
++ TYPE_FREE,
++ TYPE_ALLOCATION,
++ TYPE_SPLIT,
++ TYPE_COUNT
++ } type;
++ Node* parent;
++ Node* buddy;
++
++ union
++ {
++ struct
++ {
++ Node* prev;
++ Node* next;
++ } free;
++ struct
++ {
++ void* userData;
++ } allocation;
++ struct
++ {
++ Node* leftChild;
++ } split;
++ };
++ };
++
++ // Size of the memory block aligned down to a power of two.
++ VkDeviceSize m_UsableSize;
++ uint32_t m_LevelCount;
++ VmaPoolAllocator<Node> m_NodeAllocator;
++ Node* m_Root;
++ struct
++ {
++ Node* front;
++ Node* back;
++ } m_FreeList[MAX_LEVELS];
++
++ // Number of nodes in the tree with type == TYPE_ALLOCATION.
++ size_t m_AllocationCount;
++ // Number of nodes in the tree with type == TYPE_FREE.
++ size_t m_FreeCount;
++ // Doesn't include space wasted due to internal fragmentation - allocation sizes are just aligned up to node sizes.
++ // Doesn't include unusable size.
++ VkDeviceSize m_SumFreeSize;
++
++ VkDeviceSize GetUnusableSize() const { return GetSize() - m_UsableSize; }
++ VkDeviceSize LevelToNodeSize(uint32_t level) const { return m_UsableSize >> level; }
++
++ VkDeviceSize AlignAllocationSize(VkDeviceSize size) const
++ {
++ if (!IsVirtual())
++ {
++ size = VmaAlignUp(size, (VkDeviceSize)16);
++ }
++ return VmaNextPow2(size);
++ }
++ Node* FindAllocationNode(VkDeviceSize offset, uint32_t& outLevel) const;
++ void DeleteNodeChildren(Node* node);
++ bool ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const;
++ uint32_t AllocSizeToLevel(VkDeviceSize allocSize) const;
++ void AddNodeToDetailedStatistics(VmaDetailedStatistics& inoutStats, const Node* node, VkDeviceSize levelNodeSize) const;
++ // Adds node to the front of FreeList at given level.
++ // node->type must be FREE.
++ // node->free.prev, next can be undefined.
++ void AddToFreeListFront(uint32_t level, Node* node);
++ // Removes node from FreeList at given level.
++ // node->type must be FREE.
++ // node->free.prev, next stay untouched.
++ void RemoveFromFreeList(uint32_t level, Node* node);
++ void DebugLogAllAllocationNode(Node* node, uint32_t level) const;
++
++#if VMA_STATS_STRING_ENABLED
++ void PrintDetailedMapNode(class VmaJsonWriter& json, const Node* node, VkDeviceSize levelNodeSize) const;
++#endif
++};
++
++#ifndef _VMA_BLOCK_METADATA_BUDDY_FUNCTIONS
++VmaBlockMetadata_Buddy::VmaBlockMetadata_Buddy(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual)
++ : VmaBlockMetadata(pAllocationCallbacks, bufferImageGranularity, isVirtual),
++ m_NodeAllocator(pAllocationCallbacks, 32), // firstBlockCapacity
++ m_Root(VMA_NULL),
++ m_AllocationCount(0),
++ m_FreeCount(1),
++ m_SumFreeSize(0)
++{
++ memset(m_FreeList, 0, sizeof(m_FreeList));
++}
++
++VmaBlockMetadata_Buddy::~VmaBlockMetadata_Buddy()
++{
++ DeleteNodeChildren(m_Root);
++ m_NodeAllocator.Free(m_Root);
++}
++
++void VmaBlockMetadata_Buddy::Init(VkDeviceSize size)
++{
++ VmaBlockMetadata::Init(size);
++
++ m_UsableSize = VmaPrevPow2(size);
++ m_SumFreeSize = m_UsableSize;
++
++ // Calculate m_LevelCount.
++ const VkDeviceSize minNodeSize = IsVirtual() ? 1 : 16;
++ m_LevelCount = 1;
++ while (m_LevelCount < MAX_LEVELS &&
++ LevelToNodeSize(m_LevelCount) >= minNodeSize)
++ {
++ ++m_LevelCount;
++ }
++
++ Node* rootNode = m_NodeAllocator.Alloc();
++ rootNode->offset = 0;
++ rootNode->type = Node::TYPE_FREE;
++ rootNode->parent = VMA_NULL;
++ rootNode->buddy = VMA_NULL;
++
++ m_Root = rootNode;
++ AddToFreeListFront(0, rootNode);
++}
++
++bool VmaBlockMetadata_Buddy::Validate() const
++{
++ // Validate tree.
++ ValidationContext ctx;
++ if (!ValidateNode(ctx, VMA_NULL, m_Root, 0, LevelToNodeSize(0)))
++ {
++ VMA_VALIDATE(false && "ValidateNode failed.");
++ }
++ VMA_VALIDATE(m_AllocationCount == ctx.calculatedAllocationCount);
++ VMA_VALIDATE(m_SumFreeSize == ctx.calculatedSumFreeSize);
++
++ // Validate free node lists.
++ for (uint32_t level = 0; level < m_LevelCount; ++level)
++ {
++ VMA_VALIDATE(m_FreeList[level].front == VMA_NULL ||
++ m_FreeList[level].front->free.prev == VMA_NULL);
++
++ for (Node* node = m_FreeList[level].front;
++ node != VMA_NULL;
++ node = node->free.next)
++ {
++ VMA_VALIDATE(node->type == Node::TYPE_FREE);
++
++ if (node->free.next == VMA_NULL)
++ {
++ VMA_VALIDATE(m_FreeList[level].back == node);
++ }
++ else
++ {
++ VMA_VALIDATE(node->free.next->free.prev == node);
++ }
++ }
++ }
++
++ // Validate that free lists ar higher levels are empty.
++ for (uint32_t level = m_LevelCount; level < MAX_LEVELS; ++level)
++ {
++ VMA_VALIDATE(m_FreeList[level].front == VMA_NULL && m_FreeList[level].back == VMA_NULL);
++ }
++
++ return true;
++}
++
++void VmaBlockMetadata_Buddy::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const
++{
++ inoutStats.statistics.blockCount++;
++ inoutStats.statistics.blockBytes += GetSize();
++
++ AddNodeToDetailedStatistics(inoutStats, m_Root, LevelToNodeSize(0));
++
++ const VkDeviceSize unusableSize = GetUnusableSize();
++ if (unusableSize > 0)
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, unusableSize);
++}
++
++void VmaBlockMetadata_Buddy::AddStatistics(VmaStatistics& inoutStats) const
++{
++ inoutStats.blockCount++;
++ inoutStats.allocationCount += (uint32_t)m_AllocationCount;
++ inoutStats.blockBytes += GetSize();
++ inoutStats.allocationBytes += GetSize() - m_SumFreeSize;
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaBlockMetadata_Buddy::PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const
++{
++ VmaDetailedStatistics stats;
++ VmaClearDetailedStatistics(stats);
++ AddDetailedStatistics(stats);
++
++ PrintDetailedMap_Begin(
++ json,
++ stats.statistics.blockBytes - stats.statistics.allocationBytes,
++ stats.statistics.allocationCount,
++ stats.unusedRangeCount,
++ mapRefCount);
++
++ PrintDetailedMapNode(json, m_Root, LevelToNodeSize(0));
++
++ const VkDeviceSize unusableSize = GetUnusableSize();
++ if (unusableSize > 0)
++ {
++ PrintDetailedMap_UnusedRange(json,
++ m_UsableSize, // offset
++ unusableSize); // size
++ }
++
++ PrintDetailedMap_End(json);
++}
++#endif // VMA_STATS_STRING_ENABLED
++
++bool VmaBlockMetadata_Buddy::CreateAllocationRequest(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ bool upperAddress,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest)
++{
++ VMA_ASSERT(!upperAddress && "VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT can be used only with linear algorithm.");
++
++ allocSize = AlignAllocationSize(allocSize);
++
++ // Simple way to respect bufferImageGranularity. May be optimized some day.
++ // Whenever it might be an OPTIMAL image...
++ if (allocType == VMA_SUBALLOCATION_TYPE_UNKNOWN ||
++ allocType == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
++ allocType == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL)
++ {
++ allocAlignment = VMA_MAX(allocAlignment, GetBufferImageGranularity());
++ allocSize = VmaAlignUp(allocSize, GetBufferImageGranularity());
++ }
++
++ if (allocSize > m_UsableSize)
++ {
++ return false;
++ }
++
++ const uint32_t targetLevel = AllocSizeToLevel(allocSize);
++ for (uint32_t level = targetLevel; level--; )
++ {
++ for (Node* freeNode = m_FreeList[level].front;
++ freeNode != VMA_NULL;
++ freeNode = freeNode->free.next)
++ {
++ if (freeNode->offset % allocAlignment == 0)
++ {
++ pAllocationRequest->type = VmaAllocationRequestType::Normal;
++ pAllocationRequest->allocHandle = (VmaAllocHandle)(freeNode->offset + 1);
++ pAllocationRequest->size = allocSize;
++ pAllocationRequest->customData = (void*)(uintptr_t)level;
++ return true;
++ }
++ }
++ }
++
++ return false;
++}
++
++void VmaBlockMetadata_Buddy::Alloc(
++ const VmaAllocationRequest& request,
++ VmaSuballocationType type,
++ void* userData)
++{
++ VMA_ASSERT(request.type == VmaAllocationRequestType::Normal);
++
++ const uint32_t targetLevel = AllocSizeToLevel(request.size);
++ uint32_t currLevel = (uint32_t)(uintptr_t)request.customData;
++
++ Node* currNode = m_FreeList[currLevel].front;
++ VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE);
++ const VkDeviceSize offset = (VkDeviceSize)request.allocHandle - 1;
++ while (currNode->offset != offset)
++ {
++ currNode = currNode->free.next;
++ VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE);
++ }
++
++ // Go down, splitting free nodes.
++ while (currLevel < targetLevel)
++ {
++ // currNode is already first free node at currLevel.
++ // Remove it from list of free nodes at this currLevel.
++ RemoveFromFreeList(currLevel, currNode);
++
++ const uint32_t childrenLevel = currLevel + 1;
++
++ // Create two free sub-nodes.
++ Node* leftChild = m_NodeAllocator.Alloc();
++ Node* rightChild = m_NodeAllocator.Alloc();
++
++ leftChild->offset = currNode->offset;
++ leftChild->type = Node::TYPE_FREE;
++ leftChild->parent = currNode;
++ leftChild->buddy = rightChild;
++
++ rightChild->offset = currNode->offset + LevelToNodeSize(childrenLevel);
++ rightChild->type = Node::TYPE_FREE;
++ rightChild->parent = currNode;
++ rightChild->buddy = leftChild;
++
++ // Convert current currNode to split type.
++ currNode->type = Node::TYPE_SPLIT;
++ currNode->split.leftChild = leftChild;
++
++ // Add child nodes to free list. Order is important!
++ AddToFreeListFront(childrenLevel, rightChild);
++ AddToFreeListFront(childrenLevel, leftChild);
++
++ ++m_FreeCount;
++ ++currLevel;
++ currNode = m_FreeList[currLevel].front;
++
++ /*
++ We can be sure that currNode, as left child of node previously split,
++ also fulfills the alignment requirement.
++ */
++ }
++
++ // Remove from free list.
++ VMA_ASSERT(currLevel == targetLevel &&
++ currNode != VMA_NULL &&
++ currNode->type == Node::TYPE_FREE);
++ RemoveFromFreeList(currLevel, currNode);
++
++ // Convert to allocation node.
++ currNode->type = Node::TYPE_ALLOCATION;
++ currNode->allocation.userData = userData;
++
++ ++m_AllocationCount;
++ --m_FreeCount;
++ m_SumFreeSize -= request.size;
++}
++
++void VmaBlockMetadata_Buddy::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo)
++{
++ uint32_t level = 0;
++ outInfo.offset = (VkDeviceSize)allocHandle - 1;
++ const Node* const node = FindAllocationNode(outInfo.offset, level);
++ outInfo.size = LevelToNodeSize(level);
++ outInfo.pUserData = node->allocation.userData;
++}
++
++void* VmaBlockMetadata_Buddy::GetAllocationUserData(VmaAllocHandle allocHandle) const
++{
++ uint32_t level = 0;
++ const Node* const node = FindAllocationNode((VkDeviceSize)allocHandle - 1, level);
++ return node->allocation.userData;
++}
++
++VmaAllocHandle VmaBlockMetadata_Buddy::GetAllocationListBegin() const
++{
++ // Function only used for defragmentation, which is disabled for this algorithm
++ return VK_NULL_HANDLE;
++}
++
++VmaAllocHandle VmaBlockMetadata_Buddy::GetNextAllocation(VmaAllocHandle prevAlloc) const
++{
++ // Function only used for defragmentation, which is disabled for this algorithm
++ return VK_NULL_HANDLE;
++}
++
++void VmaBlockMetadata_Buddy::DeleteNodeChildren(Node* node)
++{
++ if (node->type == Node::TYPE_SPLIT)
++ {
++ DeleteNodeChildren(node->split.leftChild->buddy);
++ DeleteNodeChildren(node->split.leftChild);
++ const VkAllocationCallbacks* allocationCallbacks = GetAllocationCallbacks();
++ m_NodeAllocator.Free(node->split.leftChild->buddy);
++ m_NodeAllocator.Free(node->split.leftChild);
++ }
++}
++
++void VmaBlockMetadata_Buddy::Clear()
++{
++ DeleteNodeChildren(m_Root);
++ m_Root->type = Node::TYPE_FREE;
++ m_AllocationCount = 0;
++ m_FreeCount = 1;
++ m_SumFreeSize = m_UsableSize;
++}
++
++void VmaBlockMetadata_Buddy::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData)
++{
++ uint32_t level = 0;
++ Node* const node = FindAllocationNode((VkDeviceSize)allocHandle - 1, level);
++ node->allocation.userData = userData;
++}
++
++VmaBlockMetadata_Buddy::Node* VmaBlockMetadata_Buddy::FindAllocationNode(VkDeviceSize offset, uint32_t& outLevel) const
++{
++ Node* node = m_Root;
++ VkDeviceSize nodeOffset = 0;
++ outLevel = 0;
++ VkDeviceSize levelNodeSize = LevelToNodeSize(0);
++ while (node->type == Node::TYPE_SPLIT)
++ {
++ const VkDeviceSize nextLevelNodeSize = levelNodeSize >> 1;
++ if (offset < nodeOffset + nextLevelNodeSize)
++ {
++ node = node->split.leftChild;
++ }
++ else
++ {
++ node = node->split.leftChild->buddy;
++ nodeOffset += nextLevelNodeSize;
++ }
++ ++outLevel;
++ levelNodeSize = nextLevelNodeSize;
++ }
++
++ VMA_ASSERT(node != VMA_NULL && node->type == Node::TYPE_ALLOCATION);
++ return node;
++}
++
++bool VmaBlockMetadata_Buddy::ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const
++{
++ VMA_VALIDATE(level < m_LevelCount);
++ VMA_VALIDATE(curr->parent == parent);
++ VMA_VALIDATE((curr->buddy == VMA_NULL) == (parent == VMA_NULL));
++ VMA_VALIDATE(curr->buddy == VMA_NULL || curr->buddy->buddy == curr);
++ switch (curr->type)
++ {
++ case Node::TYPE_FREE:
++ // curr->free.prev, next are validated separately.
++ ctx.calculatedSumFreeSize += levelNodeSize;
++ ++ctx.calculatedFreeCount;
++ break;
++ case Node::TYPE_ALLOCATION:
++ ++ctx.calculatedAllocationCount;
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE(curr->allocation.userData != VMA_NULL);
++ }
++ break;
++ case Node::TYPE_SPLIT:
++ {
++ const uint32_t childrenLevel = level + 1;
++ const VkDeviceSize childrenLevelNodeSize = levelNodeSize >> 1;
++ const Node* const leftChild = curr->split.leftChild;
++ VMA_VALIDATE(leftChild != VMA_NULL);
++ VMA_VALIDATE(leftChild->offset == curr->offset);
++ if (!ValidateNode(ctx, curr, leftChild, childrenLevel, childrenLevelNodeSize))
++ {
++ VMA_VALIDATE(false && "ValidateNode for left child failed.");
++ }
++ const Node* const rightChild = leftChild->buddy;
++ VMA_VALIDATE(rightChild->offset == curr->offset + childrenLevelNodeSize);
++ if (!ValidateNode(ctx, curr, rightChild, childrenLevel, childrenLevelNodeSize))
++ {
++ VMA_VALIDATE(false && "ValidateNode for right child failed.");
++ }
++ }
++ break;
++ default:
++ return false;
++ }
++
++ return true;
++}
++
++uint32_t VmaBlockMetadata_Buddy::AllocSizeToLevel(VkDeviceSize allocSize) const
++{
++ // I know this could be optimized somehow e.g. by using std::log2p1 from C++20.
++ uint32_t level = 0;
++ VkDeviceSize currLevelNodeSize = m_UsableSize;
++ VkDeviceSize nextLevelNodeSize = currLevelNodeSize >> 1;
++ while (allocSize <= nextLevelNodeSize && level + 1 < m_LevelCount)
++ {
++ ++level;
++ currLevelNodeSize >>= 1;
++ nextLevelNodeSize >>= 1;
++ }
++ return level;
++}
++
++void VmaBlockMetadata_Buddy::Free(VmaAllocHandle allocHandle)
++{
++ uint32_t level = 0;
++ Node* node = FindAllocationNode((VkDeviceSize)allocHandle - 1, level);
++
++ ++m_FreeCount;
++ --m_AllocationCount;
++ m_SumFreeSize += LevelToNodeSize(level);
++
++ node->type = Node::TYPE_FREE;
++
++ // Join free nodes if possible.
++ while (level > 0 && node->buddy->type == Node::TYPE_FREE)
++ {
++ RemoveFromFreeList(level, node->buddy);
++ Node* const parent = node->parent;
++
++ m_NodeAllocator.Free(node->buddy);
++ m_NodeAllocator.Free(node);
++ parent->type = Node::TYPE_FREE;
++
++ node = parent;
++ --level;
++ --m_FreeCount;
++ }
++
++ AddToFreeListFront(level, node);
++}
++
++void VmaBlockMetadata_Buddy::AddNodeToDetailedStatistics(VmaDetailedStatistics& inoutStats, const Node* node, VkDeviceSize levelNodeSize) const
++{
++ switch (node->type)
++ {
++ case Node::TYPE_FREE:
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, levelNodeSize);
++ break;
++ case Node::TYPE_ALLOCATION:
++ VmaAddDetailedStatisticsAllocation(inoutStats, levelNodeSize);
++ break;
++ case Node::TYPE_SPLIT:
++ {
++ const VkDeviceSize childrenNodeSize = levelNodeSize / 2;
++ const Node* const leftChild = node->split.leftChild;
++ AddNodeToDetailedStatistics(inoutStats, leftChild, childrenNodeSize);
++ const Node* const rightChild = leftChild->buddy;
++ AddNodeToDetailedStatistics(inoutStats, rightChild, childrenNodeSize);
++ }
++ break;
++ default:
++ VMA_ASSERT(0);
++ }
++}
++
++void VmaBlockMetadata_Buddy::AddToFreeListFront(uint32_t level, Node* node)
++{
++ VMA_ASSERT(node->type == Node::TYPE_FREE);
++
++ // List is empty.
++ Node* const frontNode = m_FreeList[level].front;
++ if (frontNode == VMA_NULL)
++ {
++ VMA_ASSERT(m_FreeList[level].back == VMA_NULL);
++ node->free.prev = node->free.next = VMA_NULL;
++ m_FreeList[level].front = m_FreeList[level].back = node;
++ }
++ else
++ {
++ VMA_ASSERT(frontNode->free.prev == VMA_NULL);
++ node->free.prev = VMA_NULL;
++ node->free.next = frontNode;
++ frontNode->free.prev = node;
++ m_FreeList[level].front = node;
++ }
++}
++
++void VmaBlockMetadata_Buddy::RemoveFromFreeList(uint32_t level, Node* node)
++{
++ VMA_ASSERT(m_FreeList[level].front != VMA_NULL);
++
++ // It is at the front.
++ if (node->free.prev == VMA_NULL)
++ {
++ VMA_ASSERT(m_FreeList[level].front == node);
++ m_FreeList[level].front = node->free.next;
++ }
++ else
++ {
++ Node* const prevFreeNode = node->free.prev;
++ VMA_ASSERT(prevFreeNode->free.next == node);
++ prevFreeNode->free.next = node->free.next;
++ }
++
++ // It is at the back.
++ if (node->free.next == VMA_NULL)
++ {
++ VMA_ASSERT(m_FreeList[level].back == node);
++ m_FreeList[level].back = node->free.prev;
++ }
++ else
++ {
++ Node* const nextFreeNode = node->free.next;
++ VMA_ASSERT(nextFreeNode->free.prev == node);
++ nextFreeNode->free.prev = node->free.prev;
++ }
++}
++
++void VmaBlockMetadata_Buddy::DebugLogAllAllocationNode(Node* node, uint32_t level) const
++{
++ switch (node->type)
++ {
++ case Node::TYPE_FREE:
++ break;
++ case Node::TYPE_ALLOCATION:
++ DebugLogAllocation(node->offset, LevelToNodeSize(level), node->allocation.userData);
++ break;
++ case Node::TYPE_SPLIT:
++ {
++ ++level;
++ DebugLogAllAllocationNode(node->split.leftChild, level);
++ DebugLogAllAllocationNode(node->split.leftChild->buddy, level);
++ }
++ break;
++ default:
++ VMA_ASSERT(0);
++ }
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaBlockMetadata_Buddy::PrintDetailedMapNode(class VmaJsonWriter& json, const Node* node, VkDeviceSize levelNodeSize) const
++{
++ switch (node->type)
++ {
++ case Node::TYPE_FREE:
++ PrintDetailedMap_UnusedRange(json, node->offset, levelNodeSize);
++ break;
++ case Node::TYPE_ALLOCATION:
++ PrintDetailedMap_Allocation(json, node->offset, levelNodeSize, node->allocation.userData);
++ break;
++ case Node::TYPE_SPLIT:
++ {
++ const VkDeviceSize childrenNodeSize = levelNodeSize / 2;
++ const Node* const leftChild = node->split.leftChild;
++ PrintDetailedMapNode(json, leftChild, childrenNodeSize);
++ const Node* const rightChild = leftChild->buddy;
++ PrintDetailedMapNode(json, rightChild, childrenNodeSize);
++ }
++ break;
++ default:
++ VMA_ASSERT(0);
++ }
++}
++#endif // VMA_STATS_STRING_ENABLED
++#endif // _VMA_BLOCK_METADATA_BUDDY_FUNCTIONS
++#endif // _VMA_BLOCK_METADATA_BUDDY
++#endif // #if 0
++
++#ifndef _VMA_BLOCK_METADATA_TLSF
++// To not search current larger region if first allocation won't succeed and skip to smaller range
++// use with VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT as strategy in CreateAllocationRequest().
++// When fragmentation and reusal of previous blocks doesn't matter then use with
++// VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT for fastest alloc time possible.
++class VmaBlockMetadata_TLSF : public VmaBlockMetadata
++{
++ VMA_CLASS_NO_COPY(VmaBlockMetadata_TLSF)
++public:
++ VmaBlockMetadata_TLSF(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual);
++ virtual ~VmaBlockMetadata_TLSF();
++
++ size_t GetAllocationCount() const override { return m_AllocCount; }
++ size_t GetFreeRegionsCount() const override { return m_BlocksFreeCount + 1; }
++ VkDeviceSize GetSumFreeSize() const override { return m_BlocksFreeSize + m_NullBlock->size; }
++ bool IsEmpty() const override { return m_NullBlock->offset == 0; }
++ VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return ((Block*)allocHandle)->offset; };
++
++ void Init(VkDeviceSize size) override;
++ bool Validate() const override;
++
++ void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const override;
++ void AddStatistics(VmaStatistics& inoutStats) const override;
++
++#if VMA_STATS_STRING_ENABLED
++ void PrintDetailedMap(class VmaJsonWriter& json) const override;
++#endif
++
++ bool CreateAllocationRequest(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ bool upperAddress,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest) override;
++
++ VkResult CheckCorruption(const void* pBlockData) override;
++ void Alloc(
++ const VmaAllocationRequest& request,
++ VmaSuballocationType type,
++ void* userData) override;
++
++ void Free(VmaAllocHandle allocHandle) override;
++ void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override;
++ void* GetAllocationUserData(VmaAllocHandle allocHandle) const override;
++ VmaAllocHandle GetAllocationListBegin() const override;
++ VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override;
++ VkDeviceSize GetNextFreeRegionSize(VmaAllocHandle alloc) const override;
++ void Clear() override;
++ void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override;
++ void DebugLogAllAllocations() const override;
++
++private:
++ // According to original paper it should be preferable 4 or 5:
++ // M. Masmano, I. Ripoll, A. Crespo, and J. Real "TLSF: a New Dynamic Memory Allocator for Real-Time Systems"
++ // http://www.gii.upv.es/tlsf/files/ecrts04_tlsf.pdf
++ static const uint8_t SECOND_LEVEL_INDEX = 5;
++ static const uint16_t SMALL_BUFFER_SIZE = 256;
++ static const uint32_t INITIAL_BLOCK_ALLOC_COUNT = 16;
++ static const uint8_t MEMORY_CLASS_SHIFT = 7;
++ static const uint8_t MAX_MEMORY_CLASSES = 65 - MEMORY_CLASS_SHIFT;
++
++ class Block
++ {
++ public:
++ VkDeviceSize offset;
++ VkDeviceSize size;
++ Block* prevPhysical;
++ Block* nextPhysical;
++
++ void MarkFree() { prevFree = VMA_NULL; }
++ void MarkTaken() { prevFree = this; }
++ bool IsFree() const { return prevFree != this; }
++ void*& UserData() { VMA_HEAVY_ASSERT(!IsFree()); return userData; }
++ Block*& PrevFree() { return prevFree; }
++ Block*& NextFree() { VMA_HEAVY_ASSERT(IsFree()); return nextFree; }
++
++ private:
++ Block* prevFree; // Address of the same block here indicates that block is taken
++ union
++ {
++ Block* nextFree;
++ void* userData;
++ };
++ };
++
++ size_t m_AllocCount;
++ // Total number of free blocks besides null block
++ size_t m_BlocksFreeCount;
++ // Total size of free blocks excluding null block
++ VkDeviceSize m_BlocksFreeSize;
++ uint32_t m_IsFreeBitmap;
++ uint8_t m_MemoryClasses;
++ uint32_t m_InnerIsFreeBitmap[MAX_MEMORY_CLASSES];
++ uint32_t m_ListsCount;
++ /*
++ * 0: 0-3 lists for small buffers
++ * 1+: 0-(2^SLI-1) lists for normal buffers
++ */
++ Block** m_FreeList;
++ VmaPoolAllocator<Block> m_BlockAllocator;
++ Block* m_NullBlock;
++ VmaBlockBufferImageGranularity m_GranularityHandler;
++
++ uint8_t SizeToMemoryClass(VkDeviceSize size) const;
++ uint16_t SizeToSecondIndex(VkDeviceSize size, uint8_t memoryClass) const;
++ uint32_t GetListIndex(uint8_t memoryClass, uint16_t secondIndex) const;
++ uint32_t GetListIndex(VkDeviceSize size) const;
++
++ void RemoveFreeBlock(Block* block);
++ void InsertFreeBlock(Block* block);
++ void MergeBlock(Block* block, Block* prev);
++
++ Block* FindFreeBlock(VkDeviceSize size, uint32_t& listIndex) const;
++ bool CheckBlock(
++ Block& block,
++ uint32_t listIndex,
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ VmaSuballocationType allocType,
++ VmaAllocationRequest* pAllocationRequest);
++};
++
++#ifndef _VMA_BLOCK_METADATA_TLSF_FUNCTIONS
++VmaBlockMetadata_TLSF::VmaBlockMetadata_TLSF(const VkAllocationCallbacks* pAllocationCallbacks,
++ VkDeviceSize bufferImageGranularity, bool isVirtual)
++ : VmaBlockMetadata(pAllocationCallbacks, bufferImageGranularity, isVirtual),
++ m_AllocCount(0),
++ m_BlocksFreeCount(0),
++ m_BlocksFreeSize(0),
++ m_IsFreeBitmap(0),
++ m_MemoryClasses(0),
++ m_ListsCount(0),
++ m_FreeList(VMA_NULL),
++ m_BlockAllocator(pAllocationCallbacks, INITIAL_BLOCK_ALLOC_COUNT),
++ m_NullBlock(VMA_NULL),
++ m_GranularityHandler(bufferImageGranularity) {}
++
++VmaBlockMetadata_TLSF::~VmaBlockMetadata_TLSF()
++{
++ if (m_FreeList)
++ vma_delete_array(GetAllocationCallbacks(), m_FreeList, m_ListsCount);
++ m_GranularityHandler.Destroy(GetAllocationCallbacks());
++}
++
++void VmaBlockMetadata_TLSF::Init(VkDeviceSize size)
++{
++ VmaBlockMetadata::Init(size);
++
++ if (!IsVirtual())
++ m_GranularityHandler.Init(GetAllocationCallbacks(), size);
++
++ m_NullBlock = m_BlockAllocator.Alloc();
++ m_NullBlock->size = size;
++ m_NullBlock->offset = 0;
++ m_NullBlock->prevPhysical = VMA_NULL;
++ m_NullBlock->nextPhysical = VMA_NULL;
++ m_NullBlock->MarkFree();
++ m_NullBlock->NextFree() = VMA_NULL;
++ m_NullBlock->PrevFree() = VMA_NULL;
++ uint8_t memoryClass = SizeToMemoryClass(size);
++ uint16_t sli = SizeToSecondIndex(size, memoryClass);
++ m_ListsCount = (memoryClass == 0 ? 0 : (memoryClass - 1) * (1UL << SECOND_LEVEL_INDEX) + sli) + 1;
++ if (IsVirtual())
++ m_ListsCount += 1UL << SECOND_LEVEL_INDEX;
++ else
++ m_ListsCount += 4;
++
++ m_MemoryClasses = memoryClass + 2;
++ memset(m_InnerIsFreeBitmap, 0, MAX_MEMORY_CLASSES * sizeof(uint32_t));
++
++ m_FreeList = vma_new_array(GetAllocationCallbacks(), Block*, m_ListsCount);
++ memset(m_FreeList, 0, m_ListsCount * sizeof(Block*));
++}
++
++bool VmaBlockMetadata_TLSF::Validate() const
++{
++ VMA_VALIDATE(GetSumFreeSize() <= GetSize());
++
++ VkDeviceSize calculatedSize = m_NullBlock->size;
++ VkDeviceSize calculatedFreeSize = m_NullBlock->size;
++ size_t allocCount = 0;
++ size_t freeCount = 0;
++
++ // Check integrity of free lists
++ for (uint32_t list = 0; list < m_ListsCount; ++list)
++ {
++ Block* block = m_FreeList[list];
++ if (block != VMA_NULL)
++ {
++ VMA_VALIDATE(block->IsFree());
++ VMA_VALIDATE(block->PrevFree() == VMA_NULL);
++ while (block->NextFree())
++ {
++ VMA_VALIDATE(block->NextFree()->IsFree());
++ VMA_VALIDATE(block->NextFree()->PrevFree() == block);
++ block = block->NextFree();
++ }
++ }
++ }
++
++ VkDeviceSize nextOffset = m_NullBlock->offset;
++ auto validateCtx = m_GranularityHandler.StartValidation(GetAllocationCallbacks(), IsVirtual());
++
++ VMA_VALIDATE(m_NullBlock->nextPhysical == VMA_NULL);
++ if (m_NullBlock->prevPhysical)
++ {
++ VMA_VALIDATE(m_NullBlock->prevPhysical->nextPhysical == m_NullBlock);
++ }
++ // Check all blocks
++ for (Block* prev = m_NullBlock->prevPhysical; prev != VMA_NULL; prev = prev->prevPhysical)
++ {
++ VMA_VALIDATE(prev->offset + prev->size == nextOffset);
++ nextOffset = prev->offset;
++ calculatedSize += prev->size;
++
++ uint32_t listIndex = GetListIndex(prev->size);
++ if (prev->IsFree())
++ {
++ ++freeCount;
++ // Check if free block belongs to free list
++ Block* freeBlock = m_FreeList[listIndex];
++ VMA_VALIDATE(freeBlock != VMA_NULL);
++
++ bool found = false;
++ do
++ {
++ if (freeBlock == prev)
++ found = true;
++
++ freeBlock = freeBlock->NextFree();
++ } while (!found && freeBlock != VMA_NULL);
++
++ VMA_VALIDATE(found);
++ calculatedFreeSize += prev->size;
++ }
++ else
++ {
++ ++allocCount;
++ // Check if taken block is not on a free list
++ Block* freeBlock = m_FreeList[listIndex];
++ while (freeBlock)
++ {
++ VMA_VALIDATE(freeBlock != prev);
++ freeBlock = freeBlock->NextFree();
++ }
++
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE(m_GranularityHandler.Validate(validateCtx, prev->offset, prev->size));
++ }
++ }
++
++ if (prev->prevPhysical)
++ {
++ VMA_VALIDATE(prev->prevPhysical->nextPhysical == prev);
++ }
++ }
++
++ if (!IsVirtual())
++ {
++ VMA_VALIDATE(m_GranularityHandler.FinishValidation(validateCtx));
++ }
++
++ VMA_VALIDATE(nextOffset == 0);
++ VMA_VALIDATE(calculatedSize == GetSize());
++ VMA_VALIDATE(calculatedFreeSize == GetSumFreeSize());
++ VMA_VALIDATE(allocCount == m_AllocCount);
++ VMA_VALIDATE(freeCount == m_BlocksFreeCount);
++
++ return true;
++}
++
++void VmaBlockMetadata_TLSF::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const
++{
++ inoutStats.statistics.blockCount++;
++ inoutStats.statistics.blockBytes += GetSize();
++ if (m_NullBlock->size > 0)
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, m_NullBlock->size);
++
++ for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical)
++ {
++ if (block->IsFree())
++ VmaAddDetailedStatisticsUnusedRange(inoutStats, block->size);
++ else
++ VmaAddDetailedStatisticsAllocation(inoutStats, block->size);
++ }
++}
++
++void VmaBlockMetadata_TLSF::AddStatistics(VmaStatistics& inoutStats) const
++{
++ inoutStats.blockCount++;
++ inoutStats.allocationCount += (uint32_t)m_AllocCount;
++ inoutStats.blockBytes += GetSize();
++ inoutStats.allocationBytes += GetSize() - GetSumFreeSize();
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaBlockMetadata_TLSF::PrintDetailedMap(class VmaJsonWriter& json) const
++{
++ size_t blockCount = m_AllocCount + m_BlocksFreeCount;
++ VmaStlAllocator<Block*> allocator(GetAllocationCallbacks());
++ VmaVector<Block*, VmaStlAllocator<Block*>> blockList(blockCount, allocator);
++
++ size_t i = blockCount;
++ for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical)
++ {
++ blockList[--i] = block;
++ }
++ VMA_ASSERT(i == 0);
++
++ VmaDetailedStatistics stats;
++ VmaClearDetailedStatistics(stats);
++ AddDetailedStatistics(stats);
++
++ PrintDetailedMap_Begin(json,
++ stats.statistics.blockBytes - stats.statistics.allocationBytes,
++ stats.statistics.allocationCount,
++ stats.unusedRangeCount);
++
++ for (; i < blockCount; ++i)
++ {
++ Block* block = blockList[i];
++ if (block->IsFree())
++ PrintDetailedMap_UnusedRange(json, block->offset, block->size);
++ else
++ PrintDetailedMap_Allocation(json, block->offset, block->size, block->UserData());
++ }
++ if (m_NullBlock->size > 0)
++ PrintDetailedMap_UnusedRange(json, m_NullBlock->offset, m_NullBlock->size);
++
++ PrintDetailedMap_End(json);
++}
++#endif
++
++bool VmaBlockMetadata_TLSF::CreateAllocationRequest(
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ bool upperAddress,
++ VmaSuballocationType allocType,
++ uint32_t strategy,
++ VmaAllocationRequest* pAllocationRequest)
++{
++ VMA_ASSERT(allocSize > 0 && "Cannot allocate empty block!");
++ VMA_ASSERT(!upperAddress && "VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT can be used only with linear algorithm.");
++
++ // For small granularity round up
++ if (!IsVirtual())
++ m_GranularityHandler.RoundupAllocRequest(allocType, allocSize, allocAlignment);
++
++ allocSize += GetDebugMargin();
++ // Quick check for too small pool
++ if (allocSize > GetSumFreeSize())
++ return false;
++
++ // If no free blocks in pool then check only null block
++ if (m_BlocksFreeCount == 0)
++ return CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest);
++
++ // Round up to the next block
++ VkDeviceSize sizeForNextList = allocSize;
++ VkDeviceSize smallSizeStep = SMALL_BUFFER_SIZE / (IsVirtual() ? 1 << SECOND_LEVEL_INDEX : 4);
++ if (allocSize > SMALL_BUFFER_SIZE)
++ {
++ sizeForNextList += (1ULL << (VMA_BITSCAN_MSB(allocSize) - SECOND_LEVEL_INDEX));
++ }
++ else if (allocSize > SMALL_BUFFER_SIZE - smallSizeStep)
++ sizeForNextList = SMALL_BUFFER_SIZE + 1;
++ else
++ sizeForNextList += smallSizeStep;
++
++ uint32_t nextListIndex = 0;
++ uint32_t prevListIndex = 0;
++ Block* nextListBlock = VMA_NULL;
++ Block* prevListBlock = VMA_NULL;
++
++ // Check blocks according to strategies
++ if (strategy & VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT)
++ {
++ // Quick check for larger block first
++ nextListBlock = FindFreeBlock(sizeForNextList, nextListIndex);
++ if (nextListBlock != VMA_NULL && CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++
++ // If not fitted then null block
++ if (CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++
++ // Null block failed, search larger bucket
++ while (nextListBlock)
++ {
++ if (CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++ nextListBlock = nextListBlock->NextFree();
++ }
++
++ // Failed again, check best fit bucket
++ prevListBlock = FindFreeBlock(allocSize, prevListIndex);
++ while (prevListBlock)
++ {
++ if (CheckBlock(*prevListBlock, prevListIndex, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++ prevListBlock = prevListBlock->NextFree();
++ }
++ }
++ else if (strategy & VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT)
++ {
++ // Check best fit bucket
++ prevListBlock = FindFreeBlock(allocSize, prevListIndex);
++ while (prevListBlock)
++ {
++ if (CheckBlock(*prevListBlock, prevListIndex, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++ prevListBlock = prevListBlock->NextFree();
++ }
++
++ // If failed check null block
++ if (CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++
++ // Check larger bucket
++ nextListBlock = FindFreeBlock(sizeForNextList, nextListIndex);
++ while (nextListBlock)
++ {
++ if (CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++ nextListBlock = nextListBlock->NextFree();
++ }
++ }
++ else if (strategy & VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT )
++ {
++ // Perform search from the start
++ VmaStlAllocator<Block*> allocator(GetAllocationCallbacks());
++ VmaVector<Block*, VmaStlAllocator<Block*>> blockList(m_BlocksFreeCount, allocator);
++
++ size_t i = m_BlocksFreeCount;
++ for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical)
++ {
++ if (block->IsFree() && block->size >= allocSize)
++ blockList[--i] = block;
++ }
++
++ for (; i < m_BlocksFreeCount; ++i)
++ {
++ Block& block = *blockList[i];
++ if (CheckBlock(block, GetListIndex(block.size), allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++ }
++
++ // If failed check null block
++ if (CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++
++ // Whole range searched, no more memory
++ return false;
++ }
++ else
++ {
++ // Check larger bucket
++ nextListBlock = FindFreeBlock(sizeForNextList, nextListIndex);
++ while (nextListBlock)
++ {
++ if (CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++ nextListBlock = nextListBlock->NextFree();
++ }
++
++ // If failed check null block
++ if (CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++
++ // Check best fit bucket
++ prevListBlock = FindFreeBlock(allocSize, prevListIndex);
++ while (prevListBlock)
++ {
++ if (CheckBlock(*prevListBlock, prevListIndex, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++ prevListBlock = prevListBlock->NextFree();
++ }
++ }
++
++ // Worst case, full search has to be done
++ while (++nextListIndex < m_ListsCount)
++ {
++ nextListBlock = m_FreeList[nextListIndex];
++ while (nextListBlock)
++ {
++ if (CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest))
++ return true;
++ nextListBlock = nextListBlock->NextFree();
++ }
++ }
++
++ // No more memory sadly
++ return false;
++}
++
++VkResult VmaBlockMetadata_TLSF::CheckCorruption(const void* pBlockData)
++{
++ for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical)
++ {
++ if (!block->IsFree())
++ {
++ if (!VmaValidateMagicValue(pBlockData, block->offset + block->size))
++ {
++ VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!");
++ return VK_ERROR_UNKNOWN_COPY;
++ }
++ }
++ }
++
++ return VK_SUCCESS;
++}
++
++void VmaBlockMetadata_TLSF::Alloc(
++ const VmaAllocationRequest& request,
++ VmaSuballocationType type,
++ void* userData)
++{
++ VMA_ASSERT(request.type == VmaAllocationRequestType::TLSF);
++
++ // Get block and pop it from the free list
++ Block* currentBlock = (Block*)request.allocHandle;
++ VkDeviceSize offset = request.algorithmData;
++ VMA_ASSERT(currentBlock != VMA_NULL);
++ VMA_ASSERT(currentBlock->offset <= offset);
++
++ if (currentBlock != m_NullBlock)
++ RemoveFreeBlock(currentBlock);
++
++ VkDeviceSize debugMargin = GetDebugMargin();
++ VkDeviceSize misssingAlignment = offset - currentBlock->offset;
++
++ // Append missing alignment to prev block or create new one
++ if (misssingAlignment)
++ {
++ Block* prevBlock = currentBlock->prevPhysical;
++ VMA_ASSERT(prevBlock != VMA_NULL && "There should be no missing alignment at offset 0!");
++
++ if (prevBlock->IsFree() && prevBlock->size != debugMargin)
++ {
++ uint32_t oldList = GetListIndex(prevBlock->size);
++ prevBlock->size += misssingAlignment;
++ // Check if new size crosses list bucket
++ if (oldList != GetListIndex(prevBlock->size))
++ {
++ prevBlock->size -= misssingAlignment;
++ RemoveFreeBlock(prevBlock);
++ prevBlock->size += misssingAlignment;
++ InsertFreeBlock(prevBlock);
++ }
++ else
++ m_BlocksFreeSize += misssingAlignment;
++ }
++ else
++ {
++ Block* newBlock = m_BlockAllocator.Alloc();
++ currentBlock->prevPhysical = newBlock;
++ prevBlock->nextPhysical = newBlock;
++ newBlock->prevPhysical = prevBlock;
++ newBlock->nextPhysical = currentBlock;
++ newBlock->size = misssingAlignment;
++ newBlock->offset = currentBlock->offset;
++ newBlock->MarkTaken();
++
++ InsertFreeBlock(newBlock);
++ }
++
++ currentBlock->size -= misssingAlignment;
++ currentBlock->offset += misssingAlignment;
++ }
++
++ VkDeviceSize size = request.size + debugMargin;
++ if (currentBlock->size == size)
++ {
++ if (currentBlock == m_NullBlock)
++ {
++ // Setup new null block
++ m_NullBlock = m_BlockAllocator.Alloc();
++ m_NullBlock->size = 0;
++ m_NullBlock->offset = currentBlock->offset + size;
++ m_NullBlock->prevPhysical = currentBlock;
++ m_NullBlock->nextPhysical = VMA_NULL;
++ m_NullBlock->MarkFree();
++ m_NullBlock->PrevFree() = VMA_NULL;
++ m_NullBlock->NextFree() = VMA_NULL;
++ currentBlock->nextPhysical = m_NullBlock;
++ currentBlock->MarkTaken();
++ }
++ }
++ else
++ {
++ VMA_ASSERT(currentBlock->size > size && "Proper block already found, shouldn't find smaller one!");
++
++ // Create new free block
++ Block* newBlock = m_BlockAllocator.Alloc();
++ newBlock->size = currentBlock->size - size;
++ newBlock->offset = currentBlock->offset + size;
++ newBlock->prevPhysical = currentBlock;
++ newBlock->nextPhysical = currentBlock->nextPhysical;
++ currentBlock->nextPhysical = newBlock;
++ currentBlock->size = size;
++
++ if (currentBlock == m_NullBlock)
++ {
++ m_NullBlock = newBlock;
++ m_NullBlock->MarkFree();
++ m_NullBlock->NextFree() = VMA_NULL;
++ m_NullBlock->PrevFree() = VMA_NULL;
++ currentBlock->MarkTaken();
++ }
++ else
++ {
++ newBlock->nextPhysical->prevPhysical = newBlock;
++ newBlock->MarkTaken();
++ InsertFreeBlock(newBlock);
++ }
++ }
++ currentBlock->UserData() = userData;
++
++ if (debugMargin > 0)
++ {
++ currentBlock->size -= debugMargin;
++ Block* newBlock = m_BlockAllocator.Alloc();
++ newBlock->size = debugMargin;
++ newBlock->offset = currentBlock->offset + currentBlock->size;
++ newBlock->prevPhysical = currentBlock;
++ newBlock->nextPhysical = currentBlock->nextPhysical;
++ newBlock->MarkTaken();
++ currentBlock->nextPhysical->prevPhysical = newBlock;
++ currentBlock->nextPhysical = newBlock;
++ InsertFreeBlock(newBlock);
++ }
++
++ if (!IsVirtual())
++ m_GranularityHandler.AllocPages((uint8_t)(uintptr_t)request.customData,
++ currentBlock->offset, currentBlock->size);
++ ++m_AllocCount;
++}
++
++void VmaBlockMetadata_TLSF::Free(VmaAllocHandle allocHandle)
++{
++ Block* block = (Block*)allocHandle;
++ Block* next = block->nextPhysical;
++ VMA_ASSERT(!block->IsFree() && "Block is already free!");
++
++ if (!IsVirtual())
++ m_GranularityHandler.FreePages(block->offset, block->size);
++ --m_AllocCount;
++
++ VkDeviceSize debugMargin = GetDebugMargin();
++ if (debugMargin > 0)
++ {
++ RemoveFreeBlock(next);
++ MergeBlock(next, block);
++ block = next;
++ next = next->nextPhysical;
++ }
++
++ // Try merging
++ Block* prev = block->prevPhysical;
++ if (prev != VMA_NULL && prev->IsFree() && prev->size != debugMargin)
++ {
++ RemoveFreeBlock(prev);
++ MergeBlock(block, prev);
++ }
++
++ if (!next->IsFree())
++ InsertFreeBlock(block);
++ else if (next == m_NullBlock)
++ MergeBlock(m_NullBlock, block);
++ else
++ {
++ RemoveFreeBlock(next);
++ MergeBlock(next, block);
++ InsertFreeBlock(next);
++ }
++}
++
++void VmaBlockMetadata_TLSF::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo)
++{
++ Block* block = (Block*)allocHandle;
++ VMA_ASSERT(!block->IsFree() && "Cannot get allocation info for free block!");
++ outInfo.offset = block->offset;
++ outInfo.size = block->size;
++ outInfo.pUserData = block->UserData();
++}
++
++void* VmaBlockMetadata_TLSF::GetAllocationUserData(VmaAllocHandle allocHandle) const
++{
++ Block* block = (Block*)allocHandle;
++ VMA_ASSERT(!block->IsFree() && "Cannot get user data for free block!");
++ return block->UserData();
++}
++
++VmaAllocHandle VmaBlockMetadata_TLSF::GetAllocationListBegin() const
++{
++ if (m_AllocCount == 0)
++ return VK_NULL_HANDLE;
++
++ for (Block* block = m_NullBlock->prevPhysical; block; block = block->prevPhysical)
++ {
++ if (!block->IsFree())
++ return (VmaAllocHandle)block;
++ }
++ VMA_ASSERT(false && "If m_AllocCount > 0 then should find any allocation!");
++ return VK_NULL_HANDLE;
++}
++
++VmaAllocHandle VmaBlockMetadata_TLSF::GetNextAllocation(VmaAllocHandle prevAlloc) const
++{
++ Block* startBlock = (Block*)prevAlloc;
++ VMA_ASSERT(!startBlock->IsFree() && "Incorrect block!");
++
++ for (Block* block = startBlock->prevPhysical; block; block = block->prevPhysical)
++ {
++ if (!block->IsFree())
++ return (VmaAllocHandle)block;
++ }
++ return VK_NULL_HANDLE;
++}
++
++VkDeviceSize VmaBlockMetadata_TLSF::GetNextFreeRegionSize(VmaAllocHandle alloc) const
++{
++ Block* block = (Block*)alloc;
++ VMA_ASSERT(!block->IsFree() && "Incorrect block!");
++
++ if (block->prevPhysical)
++ return block->prevPhysical->IsFree() ? block->prevPhysical->size : 0;
++ return 0;
++}
++
++void VmaBlockMetadata_TLSF::Clear()
++{
++ m_AllocCount = 0;
++ m_BlocksFreeCount = 0;
++ m_BlocksFreeSize = 0;
++ m_IsFreeBitmap = 0;
++ m_NullBlock->offset = 0;
++ m_NullBlock->size = GetSize();
++ Block* block = m_NullBlock->prevPhysical;
++ m_NullBlock->prevPhysical = VMA_NULL;
++ while (block)
++ {
++ Block* prev = block->prevPhysical;
++ m_BlockAllocator.Free(block);
++ block = prev;
++ }
++ memset(m_FreeList, 0, m_ListsCount * sizeof(Block*));
++ memset(m_InnerIsFreeBitmap, 0, m_MemoryClasses * sizeof(uint32_t));
++ m_GranularityHandler.Clear();
++}
++
++void VmaBlockMetadata_TLSF::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData)
++{
++ Block* block = (Block*)allocHandle;
++ VMA_ASSERT(!block->IsFree() && "Trying to set user data for not allocated block!");
++ block->UserData() = userData;
++}
++
++void VmaBlockMetadata_TLSF::DebugLogAllAllocations() const
++{
++ for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical)
++ if (!block->IsFree())
++ DebugLogAllocation(block->offset, block->size, block->UserData());
++}
++
++uint8_t VmaBlockMetadata_TLSF::SizeToMemoryClass(VkDeviceSize size) const
++{
++ if (size > SMALL_BUFFER_SIZE)
++ return VMA_BITSCAN_MSB(size) - MEMORY_CLASS_SHIFT;
++ return 0;
++}
++
++uint16_t VmaBlockMetadata_TLSF::SizeToSecondIndex(VkDeviceSize size, uint8_t memoryClass) const
++{
++ if (memoryClass == 0)
++ {
++ if (IsVirtual())
++ return static_cast<uint16_t>((size - 1) / 8);
++ else
++ return static_cast<uint16_t>((size - 1) / 64);
++ }
++ return static_cast<uint16_t>((size >> (memoryClass + MEMORY_CLASS_SHIFT - SECOND_LEVEL_INDEX)) ^ (1U << SECOND_LEVEL_INDEX));
++}
++
++uint32_t VmaBlockMetadata_TLSF::GetListIndex(uint8_t memoryClass, uint16_t secondIndex) const
++{
++ if (memoryClass == 0)
++ return secondIndex;
++
++ const uint32_t index = static_cast<uint32_t>(memoryClass - 1) * (1 << SECOND_LEVEL_INDEX) + secondIndex;
++ if (IsVirtual())
++ return index + (1 << SECOND_LEVEL_INDEX);
++ else
++ return index + 4;
++}
++
++uint32_t VmaBlockMetadata_TLSF::GetListIndex(VkDeviceSize size) const
++{
++ uint8_t memoryClass = SizeToMemoryClass(size);
++ return GetListIndex(memoryClass, SizeToSecondIndex(size, memoryClass));
++}
++
++void VmaBlockMetadata_TLSF::RemoveFreeBlock(Block* block)
++{
++ VMA_ASSERT(block != m_NullBlock);
++ VMA_ASSERT(block->IsFree());
++
++ if (block->NextFree() != VMA_NULL)
++ block->NextFree()->PrevFree() = block->PrevFree();
++ if (block->PrevFree() != VMA_NULL)
++ block->PrevFree()->NextFree() = block->NextFree();
++ else
++ {
++ uint8_t memClass = SizeToMemoryClass(block->size);
++ uint16_t secondIndex = SizeToSecondIndex(block->size, memClass);
++ uint32_t index = GetListIndex(memClass, secondIndex);
++ VMA_ASSERT(m_FreeList[index] == block);
++ m_FreeList[index] = block->NextFree();
++ if (block->NextFree() == VMA_NULL)
++ {
++ m_InnerIsFreeBitmap[memClass] &= ~(1U << secondIndex);
++ if (m_InnerIsFreeBitmap[memClass] == 0)
++ m_IsFreeBitmap &= ~(1UL << memClass);
++ }
++ }
++ block->MarkTaken();
++ block->UserData() = VMA_NULL;
++ --m_BlocksFreeCount;
++ m_BlocksFreeSize -= block->size;
++}
++
++void VmaBlockMetadata_TLSF::InsertFreeBlock(Block* block)
++{
++ VMA_ASSERT(block != m_NullBlock);
++ VMA_ASSERT(!block->IsFree() && "Cannot insert block twice!");
++
++ uint8_t memClass = SizeToMemoryClass(block->size);
++ uint16_t secondIndex = SizeToSecondIndex(block->size, memClass);
++ uint32_t index = GetListIndex(memClass, secondIndex);
++ VMA_ASSERT(index < m_ListsCount);
++ block->PrevFree() = VMA_NULL;
++ block->NextFree() = m_FreeList[index];
++ m_FreeList[index] = block;
++ if (block->NextFree() != VMA_NULL)
++ block->NextFree()->PrevFree() = block;
++ else
++ {
++ m_InnerIsFreeBitmap[memClass] |= 1U << secondIndex;
++ m_IsFreeBitmap |= 1UL << memClass;
++ }
++ ++m_BlocksFreeCount;
++ m_BlocksFreeSize += block->size;
++}
++
++void VmaBlockMetadata_TLSF::MergeBlock(Block* block, Block* prev)
++{
++ VMA_ASSERT(block->prevPhysical == prev && "Cannot merge seperate physical regions!");
++ VMA_ASSERT(!prev->IsFree() && "Cannot merge block that belongs to free list!");
++
++ block->offset = prev->offset;
++ block->size += prev->size;
++ block->prevPhysical = prev->prevPhysical;
++ if (block->prevPhysical)
++ block->prevPhysical->nextPhysical = block;
++ m_BlockAllocator.Free(prev);
++}
++
++VmaBlockMetadata_TLSF::Block* VmaBlockMetadata_TLSF::FindFreeBlock(VkDeviceSize size, uint32_t& listIndex) const
++{
++ uint8_t memoryClass = SizeToMemoryClass(size);
++ uint32_t innerFreeMap = m_InnerIsFreeBitmap[memoryClass] & (~0U << SizeToSecondIndex(size, memoryClass));
++ if (!innerFreeMap)
++ {
++ // Check higher levels for avaiable blocks
++ uint32_t freeMap = m_IsFreeBitmap & (~0UL << (memoryClass + 1));
++ if (!freeMap)
++ return VMA_NULL; // No more memory avaible
++
++ // Find lowest free region
++ memoryClass = VMA_BITSCAN_LSB(freeMap);
++ innerFreeMap = m_InnerIsFreeBitmap[memoryClass];
++ VMA_ASSERT(innerFreeMap != 0);
++ }
++ // Find lowest free subregion
++ listIndex = GetListIndex(memoryClass, VMA_BITSCAN_LSB(innerFreeMap));
++ VMA_ASSERT(m_FreeList[listIndex]);
++ return m_FreeList[listIndex];
++}
++
++bool VmaBlockMetadata_TLSF::CheckBlock(
++ Block& block,
++ uint32_t listIndex,
++ VkDeviceSize allocSize,
++ VkDeviceSize allocAlignment,
++ VmaSuballocationType allocType,
++ VmaAllocationRequest* pAllocationRequest)
++{
++ VMA_ASSERT(block.IsFree() && "Block is already taken!");
++
++ VkDeviceSize alignedOffset = VmaAlignUp(block.offset, allocAlignment);
++ if (block.size < allocSize + alignedOffset - block.offset)
++ return false;
++
++ // Check for granularity conflicts
++ if (!IsVirtual() &&
++ m_GranularityHandler.CheckConflictAndAlignUp(alignedOffset, allocSize, block.offset, block.size, allocType))
++ return false;
++
++ // Alloc successful
++ pAllocationRequest->type = VmaAllocationRequestType::TLSF;
++ pAllocationRequest->allocHandle = (VmaAllocHandle)&block;
++ pAllocationRequest->size = allocSize - GetDebugMargin();
++ pAllocationRequest->customData = (void*)allocType;
++ pAllocationRequest->algorithmData = alignedOffset;
++
++ // Place block at the start of list if it's normal block
++ if (listIndex != m_ListsCount && block.PrevFree())
++ {
++ block.PrevFree()->NextFree() = block.NextFree();
++ if (block.NextFree())
++ block.NextFree()->PrevFree() = block.PrevFree();
++ block.PrevFree() = VMA_NULL;
++ block.NextFree() = m_FreeList[listIndex];
++ m_FreeList[listIndex] = &block;
++ if (block.NextFree())
++ block.NextFree()->PrevFree() = &block;
++ }
++
++ return true;
++}
++#endif // _VMA_BLOCK_METADATA_TLSF_FUNCTIONS
++#endif // _VMA_BLOCK_METADATA_TLSF
++
++#ifndef _VMA_BLOCK_VECTOR
++/*
++Sequence of VmaDeviceMemoryBlock. Represents memory blocks allocated for a specific
++Vulkan memory type.
++
++Synchronized internally with a mutex.
++*/
++class VmaBlockVector
++{
++ friend struct VmaDefragmentationContext_T;
++ VMA_CLASS_NO_COPY(VmaBlockVector)
++public:
++ VmaBlockVector(
++ VmaAllocator hAllocator,
++ VmaPool hParentPool,
++ uint32_t memoryTypeIndex,
++ VkDeviceSize preferredBlockSize,
++ size_t minBlockCount,
++ size_t maxBlockCount,
++ VkDeviceSize bufferImageGranularity,
++ bool explicitBlockSize,
++ uint32_t algorithm,
++ float priority,
++ VkDeviceSize minAllocationAlignment,
++ void* pMemoryAllocateNext);
++ ~VmaBlockVector();
++
++ VmaAllocator GetAllocator() const { return m_hAllocator; }
++ VmaPool GetParentPool() const { return m_hParentPool; }
++ bool IsCustomPool() const { return m_hParentPool != VMA_NULL; }
++ uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }
++ VkDeviceSize GetPreferredBlockSize() const { return m_PreferredBlockSize; }
++ VkDeviceSize GetBufferImageGranularity() const { return m_BufferImageGranularity; }
++ uint32_t GetAlgorithm() const { return m_Algorithm; }
++ bool HasExplicitBlockSize() const { return m_ExplicitBlockSize; }
++ float GetPriority() const { return m_Priority; }
++ const void* GetAllocationNextPtr() const { return m_pMemoryAllocateNext; }
++ // To be used only while the m_Mutex is locked. Used during defragmentation.
++ size_t GetBlockCount() const { return m_Blocks.size(); }
++ // To be used only while the m_Mutex is locked. Used during defragmentation.
++ VmaDeviceMemoryBlock* GetBlock(size_t index) const { return m_Blocks[index]; }
++ VMA_RW_MUTEX &GetMutex() { return m_Mutex; }
++
++ VkResult CreateMinBlocks();
++ void AddStatistics(VmaStatistics& inoutStats);
++ void AddDetailedStatistics(VmaDetailedStatistics& inoutStats);
++ bool IsEmpty();
++ bool IsCorruptionDetectionEnabled() const;
++
++ VkResult Allocate(
++ VkDeviceSize size,
++ VkDeviceSize alignment,
++ const VmaAllocationCreateInfo& createInfo,
++ VmaSuballocationType suballocType,
++ size_t allocationCount,
++ VmaAllocation* pAllocations);
++
++ void Free(const VmaAllocation hAllocation);
++
++#if VMA_STATS_STRING_ENABLED
++ void PrintDetailedMap(class VmaJsonWriter& json);
++#endif
++
++ VkResult CheckCorruption();
++
++private:
++ const VmaAllocator m_hAllocator;
++ const VmaPool m_hParentPool;
++ const uint32_t m_MemoryTypeIndex;
++ const VkDeviceSize m_PreferredBlockSize;
++ const size_t m_MinBlockCount;
++ const size_t m_MaxBlockCount;
++ const VkDeviceSize m_BufferImageGranularity;
++ const bool m_ExplicitBlockSize;
++ const uint32_t m_Algorithm;
++ const float m_Priority;
++ const VkDeviceSize m_MinAllocationAlignment;
++
++ void* const m_pMemoryAllocateNext;
++ VMA_RW_MUTEX m_Mutex;
++ // Incrementally sorted by sumFreeSize, ascending.
++ VmaVector<VmaDeviceMemoryBlock*, VmaStlAllocator<VmaDeviceMemoryBlock*>> m_Blocks;
++ uint32_t m_NextBlockId;
++ bool m_IncrementalSort = true;
++
++ void SetIncrementalSort(bool val) { m_IncrementalSort = val; }
++
++ VkDeviceSize CalcMaxBlockSize() const;
++ // Finds and removes given block from vector.
++ void Remove(VmaDeviceMemoryBlock* pBlock);
++ // Performs single step in sorting m_Blocks. They may not be fully sorted
++ // after this call.
++ void IncrementallySortBlocks();
++ void SortByFreeSize();
++
++ VkResult AllocatePage(
++ VkDeviceSize size,
++ VkDeviceSize alignment,
++ const VmaAllocationCreateInfo& createInfo,
++ VmaSuballocationType suballocType,
++ VmaAllocation* pAllocation);
++
++ VkResult AllocateFromBlock(
++ VmaDeviceMemoryBlock* pBlock,
++ VkDeviceSize size,
++ VkDeviceSize alignment,
++ VmaAllocationCreateFlags allocFlags,
++ void* pUserData,
++ VmaSuballocationType suballocType,
++ uint32_t strategy,
++ VmaAllocation* pAllocation);
++
++ VkResult CommitAllocationRequest(
++ VmaAllocationRequest& allocRequest,
++ VmaDeviceMemoryBlock* pBlock,
++ VkDeviceSize alignment,
++ VmaAllocationCreateFlags allocFlags,
++ void* pUserData,
++ VmaSuballocationType suballocType,
++ VmaAllocation* pAllocation);
++
++ VkResult CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex);
++ bool HasEmptyBlock();
++};
++#endif // _VMA_BLOCK_VECTOR
++
++#ifndef _VMA_DEFRAGMENTATION_CONTEXT
++struct VmaDefragmentationContext_T
++{
++ VMA_CLASS_NO_COPY(VmaDefragmentationContext_T)
++public:
++ VmaDefragmentationContext_T(
++ VmaAllocator hAllocator,
++ const VmaDefragmentationInfo& info);
++ ~VmaDefragmentationContext_T();
++
++ void GetStats(VmaDefragmentationStats& outStats) { outStats = m_GlobalStats; }
++
++ VkResult DefragmentPassBegin(VmaDefragmentationPassMoveInfo& moveInfo);
++ VkResult DefragmentPassEnd(VmaDefragmentationPassMoveInfo& moveInfo);
++
++private:
++ // Max number of allocations to ignore due to size constraints before ending single pass
++ static const uint8_t MAX_ALLOCS_TO_IGNORE = 16;
++ enum class CounterStatus { Pass, Ignore, End };
++
++ struct FragmentedBlock
++ {
++ uint32_t data;
++ VmaDeviceMemoryBlock* block;
++ };
++ struct StateBalanced
++ {
++ VkDeviceSize avgFreeSize = 0;
++ VkDeviceSize avgAllocSize = UINT64_MAX;
++ };
++ struct StateExtensive
++ {
++ enum class Operation : uint8_t
++ {
++ FindFreeBlockBuffer, FindFreeBlockTexture, FindFreeBlockAll,
++ MoveBuffers, MoveTextures, MoveAll,
++ Cleanup, Done
++ };
++
++ Operation operation = Operation::FindFreeBlockTexture;
++ size_t firstFreeBlock = SIZE_MAX;
++ };
++ struct MoveAllocationData
++ {
++ VkDeviceSize size;
++ VkDeviceSize alignment;
++ VmaSuballocationType type;
++ VmaAllocationCreateFlags flags;
++ VmaDefragmentationMove move = {};
++ };
++
++ const VkDeviceSize m_MaxPassBytes;
++ const uint32_t m_MaxPassAllocations;
++
++ VmaStlAllocator<VmaDefragmentationMove> m_MoveAllocator;
++ VmaVector<VmaDefragmentationMove, VmaStlAllocator<VmaDefragmentationMove>> m_Moves;
++
++ uint8_t m_IgnoredAllocs = 0;
++ uint32_t m_Algorithm;
++ uint32_t m_BlockVectorCount;
++ VmaBlockVector* m_PoolBlockVector;
++ VmaBlockVector** m_pBlockVectors;
++ size_t m_ImmovableBlockCount = 0;
++ VmaDefragmentationStats m_GlobalStats = { 0 };
++ VmaDefragmentationStats m_PassStats = { 0 };
++ void* m_AlgorithmState = VMA_NULL;
++
++ static MoveAllocationData GetMoveData(VmaAllocHandle handle, VmaBlockMetadata* metadata);
++ CounterStatus CheckCounters(VkDeviceSize bytes);
++ bool IncrementCounters(VkDeviceSize bytes);
++ bool ReallocWithinBlock(VmaBlockVector& vector, VmaDeviceMemoryBlock* block);
++ bool AllocInOtherBlock(size_t start, size_t end, MoveAllocationData& data, VmaBlockVector& vector);
++
++ bool ComputeDefragmentation(VmaBlockVector& vector, size_t index);
++ bool ComputeDefragmentation_Fast(VmaBlockVector& vector);
++ bool ComputeDefragmentation_Balanced(VmaBlockVector& vector, size_t index, bool update);
++ bool ComputeDefragmentation_Full(VmaBlockVector& vector);
++ bool ComputeDefragmentation_Extensive(VmaBlockVector& vector, size_t index);
++
++ void UpdateVectorStatistics(VmaBlockVector& vector, StateBalanced& state);
++ bool MoveDataToFreeBlocks(VmaSuballocationType currentType,
++ VmaBlockVector& vector, size_t firstFreeBlock,
++ bool& texturePresent, bool& bufferPresent, bool& otherPresent);
++};
++#endif // _VMA_DEFRAGMENTATION_CONTEXT
++
++#ifndef _VMA_POOL_T
++struct VmaPool_T
++{
++ friend struct VmaPoolListItemTraits;
++ VMA_CLASS_NO_COPY(VmaPool_T)
++public:
++ VmaBlockVector m_BlockVector;
++ VmaDedicatedAllocationList m_DedicatedAllocations;
++
++ VmaPool_T(
++ VmaAllocator hAllocator,
++ const VmaPoolCreateInfo& createInfo,
++ VkDeviceSize preferredBlockSize);
++ ~VmaPool_T();
++
++ uint32_t GetId() const { return m_Id; }
++ void SetId(uint32_t id) { VMA_ASSERT(m_Id == 0); m_Id = id; }
++
++ const char* GetName() const { return m_Name; }
++ void SetName(const char* pName);
++
++#if VMA_STATS_STRING_ENABLED
++ //void PrintDetailedMap(class VmaStringBuilder& sb);
++#endif
++
++private:
++ uint32_t m_Id;
++ char* m_Name;
++ VmaPool_T* m_PrevPool = VMA_NULL;
++ VmaPool_T* m_NextPool = VMA_NULL;
++};
++
++struct VmaPoolListItemTraits
++{
++ typedef VmaPool_T ItemType;
++
++ static ItemType* GetPrev(const ItemType* item) { return item->m_PrevPool; }
++ static ItemType* GetNext(const ItemType* item) { return item->m_NextPool; }
++ static ItemType*& AccessPrev(ItemType* item) { return item->m_PrevPool; }
++ static ItemType*& AccessNext(ItemType* item) { return item->m_NextPool; }
++};
++#endif // _VMA_POOL_T
++
++#ifndef _VMA_CURRENT_BUDGET_DATA
++struct VmaCurrentBudgetData
++{
++ VMA_ATOMIC_UINT32 m_BlockCount[VK_MAX_MEMORY_HEAPS];
++ VMA_ATOMIC_UINT32 m_AllocationCount[VK_MAX_MEMORY_HEAPS];
++ VMA_ATOMIC_UINT64 m_BlockBytes[VK_MAX_MEMORY_HEAPS];
++ VMA_ATOMIC_UINT64 m_AllocationBytes[VK_MAX_MEMORY_HEAPS];
++
++#if VMA_MEMORY_BUDGET
++ VMA_ATOMIC_UINT32 m_OperationsSinceBudgetFetch;
++ VMA_RW_MUTEX m_BudgetMutex;
++ uint64_t m_VulkanUsage[VK_MAX_MEMORY_HEAPS];
++ uint64_t m_VulkanBudget[VK_MAX_MEMORY_HEAPS];
++ uint64_t m_BlockBytesAtBudgetFetch[VK_MAX_MEMORY_HEAPS];
++#endif // VMA_MEMORY_BUDGET
++
++ VmaCurrentBudgetData();
++
++ void AddAllocation(uint32_t heapIndex, VkDeviceSize allocationSize);
++ void RemoveAllocation(uint32_t heapIndex, VkDeviceSize allocationSize);
++};
++
++#ifndef _VMA_CURRENT_BUDGET_DATA_FUNCTIONS
++VmaCurrentBudgetData::VmaCurrentBudgetData()
++{
++ for (uint32_t heapIndex = 0; heapIndex < VK_MAX_MEMORY_HEAPS; ++heapIndex)
++ {
++ m_BlockCount[heapIndex] = 0;
++ m_AllocationCount[heapIndex] = 0;
++ m_BlockBytes[heapIndex] = 0;
++ m_AllocationBytes[heapIndex] = 0;
++#if VMA_MEMORY_BUDGET
++ m_VulkanUsage[heapIndex] = 0;
++ m_VulkanBudget[heapIndex] = 0;
++ m_BlockBytesAtBudgetFetch[heapIndex] = 0;
++#endif
++ }
++
++#if VMA_MEMORY_BUDGET
++ m_OperationsSinceBudgetFetch = 0;
++#endif
++}
++
++void VmaCurrentBudgetData::AddAllocation(uint32_t heapIndex, VkDeviceSize allocationSize)
++{
++ m_AllocationBytes[heapIndex] += allocationSize;
++ ++m_AllocationCount[heapIndex];
++#if VMA_MEMORY_BUDGET
++ ++m_OperationsSinceBudgetFetch;
++#endif
++}
++
++void VmaCurrentBudgetData::RemoveAllocation(uint32_t heapIndex, VkDeviceSize allocationSize)
++{
++ VMA_ASSERT(m_AllocationBytes[heapIndex] >= allocationSize);
++ m_AllocationBytes[heapIndex] -= allocationSize;
++ VMA_ASSERT(m_AllocationCount[heapIndex] > 0);
++ --m_AllocationCount[heapIndex];
++#if VMA_MEMORY_BUDGET
++ ++m_OperationsSinceBudgetFetch;
++#endif
++}
++#endif // _VMA_CURRENT_BUDGET_DATA_FUNCTIONS
++#endif // _VMA_CURRENT_BUDGET_DATA
++
++#ifndef _VMA_ALLOCATION_OBJECT_ALLOCATOR
++/*
++Thread-safe wrapper over VmaPoolAllocator free list, for allocation of VmaAllocation_T objects.
++*/
++class VmaAllocationObjectAllocator
++{
++ VMA_CLASS_NO_COPY(VmaAllocationObjectAllocator)
++public:
++ VmaAllocationObjectAllocator(const VkAllocationCallbacks* pAllocationCallbacks)
++ : m_Allocator(pAllocationCallbacks, 1024) {}
++
++ template<typename... Types> VmaAllocation Allocate(Types&&... args);
++ void Free(VmaAllocation hAlloc);
++
++private:
++ VMA_MUTEX m_Mutex;
++ VmaPoolAllocator<VmaAllocation_T> m_Allocator;
++};
++
++template<typename... Types>
++VmaAllocation VmaAllocationObjectAllocator::Allocate(Types&&... args)
++{
++ VmaMutexLock mutexLock(m_Mutex);
++ return m_Allocator.Alloc<Types...>(std::forward<Types>(args)...);
++}
++
++void VmaAllocationObjectAllocator::Free(VmaAllocation hAlloc)
++{
++ VmaMutexLock mutexLock(m_Mutex);
++ m_Allocator.Free(hAlloc);
++}
++#endif // _VMA_ALLOCATION_OBJECT_ALLOCATOR
++
++#ifndef _VMA_VIRTUAL_BLOCK_T
++struct VmaVirtualBlock_T
++{
++ VMA_CLASS_NO_COPY(VmaVirtualBlock_T)
++public:
++ const bool m_AllocationCallbacksSpecified;
++ const VkAllocationCallbacks m_AllocationCallbacks;
++
++ VmaVirtualBlock_T(const VmaVirtualBlockCreateInfo& createInfo);
++ ~VmaVirtualBlock_T();
++
++ VkResult Init() { return VK_SUCCESS; }
++ bool IsEmpty() const { return m_Metadata->IsEmpty(); }
++ void Free(VmaVirtualAllocation allocation) { m_Metadata->Free((VmaAllocHandle)allocation); }
++ void SetAllocationUserData(VmaVirtualAllocation allocation, void* userData) { m_Metadata->SetAllocationUserData((VmaAllocHandle)allocation, userData); }
++ void Clear() { m_Metadata->Clear(); }
++
++ const VkAllocationCallbacks* GetAllocationCallbacks() const;
++ void GetAllocationInfo(VmaVirtualAllocation allocation, VmaVirtualAllocationInfo& outInfo);
++ VkResult Allocate(const VmaVirtualAllocationCreateInfo& createInfo, VmaVirtualAllocation& outAllocation,
++ VkDeviceSize* outOffset);
++ void GetStatistics(VmaStatistics& outStats) const;
++ void CalculateDetailedStatistics(VmaDetailedStatistics& outStats) const;
++#if VMA_STATS_STRING_ENABLED
++ void BuildStatsString(bool detailedMap, VmaStringBuilder& sb) const;
++#endif
++
++private:
++ VmaBlockMetadata* m_Metadata;
++};
++
++#ifndef _VMA_VIRTUAL_BLOCK_T_FUNCTIONS
++VmaVirtualBlock_T::VmaVirtualBlock_T(const VmaVirtualBlockCreateInfo& createInfo)
++ : m_AllocationCallbacksSpecified(createInfo.pAllocationCallbacks != VMA_NULL),
++ m_AllocationCallbacks(createInfo.pAllocationCallbacks != VMA_NULL ? *createInfo.pAllocationCallbacks : VmaEmptyAllocationCallbacks)
++{
++ const uint32_t algorithm = createInfo.flags & VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK;
++ switch (algorithm)
++ {
++ default:
++ VMA_ASSERT(0);
++ case 0:
++ m_Metadata = vma_new(GetAllocationCallbacks(), VmaBlockMetadata_TLSF)(VK_NULL_HANDLE, 1, true);
++ break;
++ case VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT:
++ m_Metadata = vma_new(GetAllocationCallbacks(), VmaBlockMetadata_Linear)(VK_NULL_HANDLE, 1, true);
++ break;
++ }
++
++ m_Metadata->Init(createInfo.size);
++}
++
++VmaVirtualBlock_T::~VmaVirtualBlock_T()
++{
++ // Define macro VMA_DEBUG_LOG to receive the list of the unfreed allocations
++ if (!m_Metadata->IsEmpty())
++ m_Metadata->DebugLogAllAllocations();
++ // This is the most important assert in the entire library.
++ // Hitting it means you have some memory leak - unreleased virtual allocations.
++ VMA_ASSERT(m_Metadata->IsEmpty() && "Some virtual allocations were not freed before destruction of this virtual block!");
++
++ vma_delete(GetAllocationCallbacks(), m_Metadata);
++}
++
++const VkAllocationCallbacks* VmaVirtualBlock_T::GetAllocationCallbacks() const
++{
++ return m_AllocationCallbacksSpecified ? &m_AllocationCallbacks : VMA_NULL;
++}
++
++void VmaVirtualBlock_T::GetAllocationInfo(VmaVirtualAllocation allocation, VmaVirtualAllocationInfo& outInfo)
++{
++ m_Metadata->GetAllocationInfo((VmaAllocHandle)allocation, outInfo);
++}
++
++VkResult VmaVirtualBlock_T::Allocate(const VmaVirtualAllocationCreateInfo& createInfo, VmaVirtualAllocation& outAllocation,
++ VkDeviceSize* outOffset)
++{
++ VmaAllocationRequest request = {};
++ if (m_Metadata->CreateAllocationRequest(
++ createInfo.size, // allocSize
++ VMA_MAX(createInfo.alignment, (VkDeviceSize)1), // allocAlignment
++ (createInfo.flags & VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0, // upperAddress
++ VMA_SUBALLOCATION_TYPE_UNKNOWN, // allocType - unimportant
++ createInfo.flags & VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK, // strategy
++ &request))
++ {
++ m_Metadata->Alloc(request,
++ VMA_SUBALLOCATION_TYPE_UNKNOWN, // type - unimportant
++ createInfo.pUserData);
++ outAllocation = (VmaVirtualAllocation)request.allocHandle;
++ if(outOffset)
++ *outOffset = m_Metadata->GetAllocationOffset(request.allocHandle);
++ return VK_SUCCESS;
++ }
++ outAllocation = (VmaVirtualAllocation)VK_NULL_HANDLE;
++ if (outOffset)
++ *outOffset = UINT64_MAX;
++ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
++}
++
++void VmaVirtualBlock_T::GetStatistics(VmaStatistics& outStats) const
++{
++ VmaClearStatistics(outStats);
++ m_Metadata->AddStatistics(outStats);
++}
++
++void VmaVirtualBlock_T::CalculateDetailedStatistics(VmaDetailedStatistics& outStats) const
++{
++ VmaClearDetailedStatistics(outStats);
++ m_Metadata->AddDetailedStatistics(outStats);
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaVirtualBlock_T::BuildStatsString(bool detailedMap, VmaStringBuilder& sb) const
++{
++ VmaJsonWriter json(GetAllocationCallbacks(), sb);
++ json.BeginObject();
++
++ VmaDetailedStatistics stats;
++ CalculateDetailedStatistics(stats);
++
++ json.WriteString("Stats");
++ VmaPrintDetailedStatistics(json, stats);
++
++ if (detailedMap)
++ {
++ json.WriteString("Details");
++ json.BeginObject();
++ m_Metadata->PrintDetailedMap(json);
++ json.EndObject();
++ }
++
++ json.EndObject();
++}
++#endif // VMA_STATS_STRING_ENABLED
++#endif // _VMA_VIRTUAL_BLOCK_T_FUNCTIONS
++#endif // _VMA_VIRTUAL_BLOCK_T
++
++
++// Main allocator object.
++struct VmaAllocator_T
++{
++ VMA_CLASS_NO_COPY(VmaAllocator_T)
++public:
++ bool m_UseMutex;
++ uint32_t m_VulkanApiVersion;
++ bool m_UseKhrDedicatedAllocation; // Can be set only if m_VulkanApiVersion < VK_MAKE_VERSION(1, 1, 0).
++ bool m_UseKhrBindMemory2; // Can be set only if m_VulkanApiVersion < VK_MAKE_VERSION(1, 1, 0).
++ bool m_UseExtMemoryBudget;
++ bool m_UseAmdDeviceCoherentMemory;
++ bool m_UseKhrBufferDeviceAddress;
++ bool m_UseExtMemoryPriority;
++ VkDevice m_hDevice;
++ VkInstance m_hInstance;
++ bool m_AllocationCallbacksSpecified;
++ VkAllocationCallbacks m_AllocationCallbacks;
++ VmaDeviceMemoryCallbacks m_DeviceMemoryCallbacks;
++ VmaAllocationObjectAllocator m_AllocationObjectAllocator;
++
++ // Each bit (1 << i) is set if HeapSizeLimit is enabled for that heap, so cannot allocate more than the heap size.
++ uint32_t m_HeapSizeLimitMask;
++
++ VkPhysicalDeviceProperties m_PhysicalDeviceProperties;
++ VkPhysicalDeviceMemoryProperties m_MemProps;
++
++ // Default pools.
++ VmaBlockVector* m_pBlockVectors[VK_MAX_MEMORY_TYPES];
++ VmaDedicatedAllocationList m_DedicatedAllocations[VK_MAX_MEMORY_TYPES];
++
++ VmaCurrentBudgetData m_Budget;
++ VMA_ATOMIC_UINT32 m_DeviceMemoryCount; // Total number of VkDeviceMemory objects.
++
++ VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo);
++ VkResult Init(const VmaAllocatorCreateInfo* pCreateInfo);
++ ~VmaAllocator_T();
++
++ const VkAllocationCallbacks* GetAllocationCallbacks() const
++ {
++ return m_AllocationCallbacksSpecified ? &m_AllocationCallbacks : VMA_NULL;
++ }
++ const VmaVulkanFunctions& GetVulkanFunctions() const
++ {
++ return m_VulkanFunctions;
++ }
++
++ VkPhysicalDevice GetPhysicalDevice() const { return m_PhysicalDevice; }
++
++ VkDeviceSize GetBufferImageGranularity() const
++ {
++ return VMA_MAX(
++ static_cast<VkDeviceSize>(VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY),
++ m_PhysicalDeviceProperties.limits.bufferImageGranularity);
++ }
++
++ uint32_t GetMemoryHeapCount() const { return m_MemProps.memoryHeapCount; }
++ uint32_t GetMemoryTypeCount() const { return m_MemProps.memoryTypeCount; }
++
++ uint32_t MemoryTypeIndexToHeapIndex(uint32_t memTypeIndex) const
++ {
++ VMA_ASSERT(memTypeIndex < m_MemProps.memoryTypeCount);
++ return m_MemProps.memoryTypes[memTypeIndex].heapIndex;
++ }
++ // True when specific memory type is HOST_VISIBLE but not HOST_COHERENT.
++ bool IsMemoryTypeNonCoherent(uint32_t memTypeIndex) const
++ {
++ return (m_MemProps.memoryTypes[memTypeIndex].propertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) ==
++ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
++ }
++ // Minimum alignment for all allocations in specific memory type.
++ VkDeviceSize GetMemoryTypeMinAlignment(uint32_t memTypeIndex) const
++ {
++ return IsMemoryTypeNonCoherent(memTypeIndex) ?
++ VMA_MAX((VkDeviceSize)VMA_MIN_ALIGNMENT, m_PhysicalDeviceProperties.limits.nonCoherentAtomSize) :
++ (VkDeviceSize)VMA_MIN_ALIGNMENT;
++ }
++
++ bool IsIntegratedGpu() const
++ {
++ return m_PhysicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
++ }
++
++ uint32_t GetGlobalMemoryTypeBits() const { return m_GlobalMemoryTypeBits; }
++
++ void GetBufferMemoryRequirements(
++ VkBuffer hBuffer,
++ VkMemoryRequirements& memReq,
++ bool& requiresDedicatedAllocation,
++ bool& prefersDedicatedAllocation) const;
++ void GetImageMemoryRequirements(
++ VkImage hImage,
++ VkMemoryRequirements& memReq,
++ bool& requiresDedicatedAllocation,
++ bool& prefersDedicatedAllocation) const;
++ VkResult FindMemoryTypeIndex(
++ uint32_t memoryTypeBits,
++ const VmaAllocationCreateInfo* pAllocationCreateInfo,
++ VkFlags bufImgUsage, // VkBufferCreateInfo::usage or VkImageCreateInfo::usage. UINT32_MAX if unknown.
++ uint32_t* pMemoryTypeIndex) const;
++
++ // Main allocation function.
++ VkResult AllocateMemory(
++ const VkMemoryRequirements& vkMemReq,
++ bool requiresDedicatedAllocation,
++ bool prefersDedicatedAllocation,
++ VkBuffer dedicatedBuffer,
++ VkImage dedicatedImage,
++ VkFlags dedicatedBufferImageUsage, // UINT32_MAX if unknown.
++ const VmaAllocationCreateInfo& createInfo,
++ VmaSuballocationType suballocType,
++ size_t allocationCount,
++ VmaAllocation* pAllocations);
++
++ // Main deallocation function.
++ void FreeMemory(
++ size_t allocationCount,
++ const VmaAllocation* pAllocations);
++
++ void CalculateStatistics(VmaTotalStatistics* pStats);
++
++ void GetHeapBudgets(
++ VmaBudget* outBudgets, uint32_t firstHeap, uint32_t heapCount);
++
++#if VMA_STATS_STRING_ENABLED
++ void PrintDetailedMap(class VmaJsonWriter& json);
++#endif
++
++ void GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationInfo* pAllocationInfo);
++
++ VkResult CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPool* pPool);
++ void DestroyPool(VmaPool pool);
++ void GetPoolStatistics(VmaPool pool, VmaStatistics* pPoolStats);
++ void CalculatePoolStatistics(VmaPool pool, VmaDetailedStatistics* pPoolStats);
++
++ void SetCurrentFrameIndex(uint32_t frameIndex);
++ uint32_t GetCurrentFrameIndex() const { return m_CurrentFrameIndex.load(); }
++
++ VkResult CheckPoolCorruption(VmaPool hPool);
++ VkResult CheckCorruption(uint32_t memoryTypeBits);
++
++ // Call to Vulkan function vkAllocateMemory with accompanying bookkeeping.
++ VkResult AllocateVulkanMemory(const VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory);
++ // Call to Vulkan function vkFreeMemory with accompanying bookkeeping.
++ void FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory);
++ // Call to Vulkan function vkBindBufferMemory or vkBindBufferMemory2KHR.
++ VkResult BindVulkanBuffer(
++ VkDeviceMemory memory,
++ VkDeviceSize memoryOffset,
++ VkBuffer buffer,
++ const void* pNext);
++ // Call to Vulkan function vkBindImageMemory or vkBindImageMemory2KHR.
++ VkResult BindVulkanImage(
++ VkDeviceMemory memory,
++ VkDeviceSize memoryOffset,
++ VkImage image,
++ const void* pNext);
++
++ VkResult Map(VmaAllocation hAllocation, void** ppData);
++ void Unmap(VmaAllocation hAllocation);
++
++ VkResult BindBufferMemory(
++ VmaAllocation hAllocation,
++ VkDeviceSize allocationLocalOffset,
++ VkBuffer hBuffer,
++ const void* pNext);
++ VkResult BindImageMemory(
++ VmaAllocation hAllocation,
++ VkDeviceSize allocationLocalOffset,
++ VkImage hImage,
++ const void* pNext);
++
++ VkResult FlushOrInvalidateAllocation(
++ VmaAllocation hAllocation,
++ VkDeviceSize offset, VkDeviceSize size,
++ VMA_CACHE_OPERATION op);
++ VkResult FlushOrInvalidateAllocations(
++ uint32_t allocationCount,
++ const VmaAllocation* allocations,
++ const VkDeviceSize* offsets, const VkDeviceSize* sizes,
++ VMA_CACHE_OPERATION op);
++
++ void FillAllocation(const VmaAllocation hAllocation, uint8_t pattern);
++
++ /*
++ Returns bit mask of memory types that can support defragmentation on GPU as
++ they support creation of required buffer for copy operations.
++ */
++ uint32_t GetGpuDefragmentationMemoryTypeBits();
++
++#if VMA_EXTERNAL_MEMORY
++ VkExternalMemoryHandleTypeFlagsKHR GetExternalMemoryHandleTypeFlags(uint32_t memTypeIndex) const
++ {
++ return m_TypeExternalMemoryHandleTypes[memTypeIndex];
++ }
++#endif // #if VMA_EXTERNAL_MEMORY
++
++private:
++ VkDeviceSize m_PreferredLargeHeapBlockSize;
++
++ VkPhysicalDevice m_PhysicalDevice;
++ VMA_ATOMIC_UINT32 m_CurrentFrameIndex;
++ VMA_ATOMIC_UINT32 m_GpuDefragmentationMemoryTypeBits; // UINT32_MAX means uninitialized.
++#if VMA_EXTERNAL_MEMORY
++ VkExternalMemoryHandleTypeFlagsKHR m_TypeExternalMemoryHandleTypes[VK_MAX_MEMORY_TYPES];
++#endif // #if VMA_EXTERNAL_MEMORY
++
++ VMA_RW_MUTEX m_PoolsMutex;
++ typedef VmaIntrusiveLinkedList<VmaPoolListItemTraits> PoolList;
++ // Protected by m_PoolsMutex.
++ PoolList m_Pools;
++ uint32_t m_NextPoolId;
++
++ VmaVulkanFunctions m_VulkanFunctions;
++
++ // Global bit mask AND-ed with any memoryTypeBits to disallow certain memory types.
++ uint32_t m_GlobalMemoryTypeBits;
++
++ void ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunctions);
++
++#if VMA_STATIC_VULKAN_FUNCTIONS == 1
++ void ImportVulkanFunctions_Static();
++#endif
++
++ void ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVulkanFunctions);
++
++#if VMA_DYNAMIC_VULKAN_FUNCTIONS == 1
++ void ImportVulkanFunctions_Dynamic();
++#endif
++
++ void ValidateVulkanFunctions();
++
++ VkDeviceSize CalcPreferredBlockSize(uint32_t memTypeIndex);
++
++ VkResult AllocateMemoryOfType(
++ VmaPool pool,
++ VkDeviceSize size,
++ VkDeviceSize alignment,
++ bool dedicatedPreferred,
++ VkBuffer dedicatedBuffer,
++ VkImage dedicatedImage,
++ VkFlags dedicatedBufferImageUsage,
++ const VmaAllocationCreateInfo& createInfo,
++ uint32_t memTypeIndex,
++ VmaSuballocationType suballocType,
++ VmaDedicatedAllocationList& dedicatedAllocations,
++ VmaBlockVector& blockVector,
++ size_t allocationCount,
++ VmaAllocation* pAllocations);
++
++ // Helper function only to be used inside AllocateDedicatedMemory.
++ VkResult AllocateDedicatedMemoryPage(
++ VmaPool pool,
++ VkDeviceSize size,
++ VmaSuballocationType suballocType,
++ uint32_t memTypeIndex,
++ const VkMemoryAllocateInfo& allocInfo,
++ bool map,
++ bool isUserDataString,
++ bool isMappingAllowed,
++ void* pUserData,
++ VmaAllocation* pAllocation);
++
++ // Allocates and registers new VkDeviceMemory specifically for dedicated allocations.
++ VkResult AllocateDedicatedMemory(
++ VmaPool pool,
++ VkDeviceSize size,
++ VmaSuballocationType suballocType,
++ VmaDedicatedAllocationList& dedicatedAllocations,
++ uint32_t memTypeIndex,
++ bool map,
++ bool isUserDataString,
++ bool isMappingAllowed,
++ bool canAliasMemory,
++ void* pUserData,
++ float priority,
++ VkBuffer dedicatedBuffer,
++ VkImage dedicatedImage,
++ VkFlags dedicatedBufferImageUsage,
++ size_t allocationCount,
++ VmaAllocation* pAllocations,
++ const void* pNextChain = nullptr);
++
++ void FreeDedicatedMemory(const VmaAllocation allocation);
++
++ VkResult CalcMemTypeParams(
++ VmaAllocationCreateInfo& outCreateInfo,
++ uint32_t memTypeIndex,
++ VkDeviceSize size,
++ size_t allocationCount);
++ VkResult CalcAllocationParams(
++ VmaAllocationCreateInfo& outCreateInfo,
++ bool dedicatedRequired,
++ bool dedicatedPreferred);
++
++ /*
++ Calculates and returns bit mask of memory types that can support defragmentation
++ on GPU as they support creation of required buffer for copy operations.
++ */
++ uint32_t CalculateGpuDefragmentationMemoryTypeBits() const;
++ uint32_t CalculateGlobalMemoryTypeBits() const;
++
++ bool GetFlushOrInvalidateRange(
++ VmaAllocation allocation,
++ VkDeviceSize offset, VkDeviceSize size,
++ VkMappedMemoryRange& outRange) const;
++
++#if VMA_MEMORY_BUDGET
++ void UpdateVulkanBudget();
++#endif // #if VMA_MEMORY_BUDGET
++};
++
++
++#ifndef _VMA_MEMORY_FUNCTIONS
++static void* VmaMalloc(VmaAllocator hAllocator, size_t size, size_t alignment)
++{
++ return VmaMalloc(&hAllocator->m_AllocationCallbacks, size, alignment);
++}
++
++static void VmaFree(VmaAllocator hAllocator, void* ptr)
++{
++ VmaFree(&hAllocator->m_AllocationCallbacks, ptr);
++}
++
++template<typename T>
++static T* VmaAllocate(VmaAllocator hAllocator)
++{
++ return (T*)VmaMalloc(hAllocator, sizeof(T), VMA_ALIGN_OF(T));
++}
++
++template<typename T>
++static T* VmaAllocateArray(VmaAllocator hAllocator, size_t count)
++{
++ return (T*)VmaMalloc(hAllocator, sizeof(T) * count, VMA_ALIGN_OF(T));
++}
++
++template<typename T>
++static void vma_delete(VmaAllocator hAllocator, T* ptr)
++{
++ if(ptr != VMA_NULL)
++ {
++ ptr->~T();
++ VmaFree(hAllocator, ptr);
++ }
++}
++
++template<typename T>
++static void vma_delete_array(VmaAllocator hAllocator, T* ptr, size_t count)
++{
++ if(ptr != VMA_NULL)
++ {
++ for(size_t i = count; i--; )
++ ptr[i].~T();
++ VmaFree(hAllocator, ptr);
++ }
++}
++#endif // _VMA_MEMORY_FUNCTIONS
++
++#ifndef _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
++VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator)
++ : m_pMetadata(VMA_NULL),
++ m_MemoryTypeIndex(UINT32_MAX),
++ m_Id(0),
++ m_hMemory(VK_NULL_HANDLE),
++ m_MapCount(0),
++ m_pMappedData(VMA_NULL) {}
++
++VmaDeviceMemoryBlock::~VmaDeviceMemoryBlock()
++{
++ VMA_ASSERT(m_MapCount == 0 && "VkDeviceMemory block is being destroyed while it is still mapped.");
++ VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);
++}
++
++void VmaDeviceMemoryBlock::Init(
++ VmaAllocator hAllocator,
++ VmaPool hParentPool,
++ uint32_t newMemoryTypeIndex,
++ VkDeviceMemory newMemory,
++ VkDeviceSize newSize,
++ uint32_t id,
++ uint32_t algorithm,
++ VkDeviceSize bufferImageGranularity)
++{
++ VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);
++
++ m_hParentPool = hParentPool;
++ m_MemoryTypeIndex = newMemoryTypeIndex;
++ m_Id = id;
++ m_hMemory = newMemory;
++
++ switch (algorithm)
++ {
++ case VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT:
++ m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Linear)(hAllocator->GetAllocationCallbacks(),
++ bufferImageGranularity, false); // isVirtual
++ break;
++ default:
++ VMA_ASSERT(0);
++ // Fall-through.
++ case 0:
++ m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_TLSF)(hAllocator->GetAllocationCallbacks(),
++ bufferImageGranularity, false); // isVirtual
++ }
++ m_pMetadata->Init(newSize);
++}
++
++void VmaDeviceMemoryBlock::Destroy(VmaAllocator allocator)
++{
++ // Define macro VMA_DEBUG_LOG to receive the list of the unfreed allocations
++ if (!m_pMetadata->IsEmpty())
++ m_pMetadata->DebugLogAllAllocations();
++ // This is the most important assert in the entire library.
++ // Hitting it means you have some memory leak - unreleased VmaAllocation objects.
++ VMA_ASSERT(m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!");
++
++ VMA_ASSERT(m_hMemory != VK_NULL_HANDLE);
++ allocator->FreeVulkanMemory(m_MemoryTypeIndex, m_pMetadata->GetSize(), m_hMemory);
++ m_hMemory = VK_NULL_HANDLE;
++
++ vma_delete(allocator, m_pMetadata);
++ m_pMetadata = VMA_NULL;
++}
++
++void VmaDeviceMemoryBlock::PostFree(VmaAllocator hAllocator)
++{
++ if(m_MappingHysteresis.PostFree())
++ {
++ VMA_ASSERT(m_MappingHysteresis.GetExtraMapping() == 0);
++ if (m_MapCount == 0)
++ {
++ m_pMappedData = VMA_NULL;
++ (*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_hMemory);
++ }
++ }
++}
++
++bool VmaDeviceMemoryBlock::Validate() const
++{
++ VMA_VALIDATE((m_hMemory != VK_NULL_HANDLE) &&
++ (m_pMetadata->GetSize() != 0));
++
++ return m_pMetadata->Validate();
++}
++
++VkResult VmaDeviceMemoryBlock::CheckCorruption(VmaAllocator hAllocator)
++{
++ void* pData = nullptr;
++ VkResult res = Map(hAllocator, 1, &pData);
++ if (res != VK_SUCCESS)
++ {
++ return res;
++ }
++
++ res = m_pMetadata->CheckCorruption(pData);
++
++ Unmap(hAllocator, 1);
++
++ return res;
++}
++
++VkResult VmaDeviceMemoryBlock::Map(VmaAllocator hAllocator, uint32_t count, void** ppData)
++{
++ if (count == 0)
++ {
++ return VK_SUCCESS;
++ }
++
++ VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
++ const uint32_t oldTotalMapCount = m_MapCount + m_MappingHysteresis.GetExtraMapping();
++ m_MappingHysteresis.PostMap();
++ if (oldTotalMapCount != 0)
++ {
++ m_MapCount += count;
++ VMA_ASSERT(m_pMappedData != VMA_NULL);
++ if (ppData != VMA_NULL)
++ {
++ *ppData = m_pMappedData;
++ }
++ return VK_SUCCESS;
++ }
++ else
++ {
++ VkResult result = (*hAllocator->GetVulkanFunctions().vkMapMemory)(
++ hAllocator->m_hDevice,
++ m_hMemory,
++ 0, // offset
++ VK_WHOLE_SIZE,
++ 0, // flags
++ &m_pMappedData);
++ if (result == VK_SUCCESS)
++ {
++ if (ppData != VMA_NULL)
++ {
++ *ppData = m_pMappedData;
++ }
++ m_MapCount = count;
++ }
++ return result;
++ }
++}
++
++void VmaDeviceMemoryBlock::Unmap(VmaAllocator hAllocator, uint32_t count)
++{
++ if (count == 0)
++ {
++ return;
++ }
++
++ VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
++ if (m_MapCount >= count)
++ {
++ m_MapCount -= count;
++ const uint32_t totalMapCount = m_MapCount + m_MappingHysteresis.GetExtraMapping();
++ if (totalMapCount == 0)
++ {
++ m_pMappedData = VMA_NULL;
++ (*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_hMemory);
++ }
++ m_MappingHysteresis.PostUnmap();
++ }
++ else
++ {
++ VMA_ASSERT(0 && "VkDeviceMemory block is being unmapped while it was not previously mapped.");
++ }
++}
++
++VkResult VmaDeviceMemoryBlock::WriteMagicValueAfterAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize)
++{
++ VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION);
++
++ void* pData;
++ VkResult res = Map(hAllocator, 1, &pData);
++ if (res != VK_SUCCESS)
++ {
++ return res;
++ }
++
++ VmaWriteMagicValue(pData, allocOffset + allocSize);
++
++ Unmap(hAllocator, 1);
++ return VK_SUCCESS;
++}
++
++VkResult VmaDeviceMemoryBlock::ValidateMagicValueAfterAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize)
++{
++ VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION);
++
++ void* pData;
++ VkResult res = Map(hAllocator, 1, &pData);
++ if (res != VK_SUCCESS)
++ {
++ return res;
++ }
++
++ if (!VmaValidateMagicValue(pData, allocOffset + allocSize))
++ {
++ VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER FREED ALLOCATION!");
++ }
++
++ Unmap(hAllocator, 1);
++ return VK_SUCCESS;
++}
++
++VkResult VmaDeviceMemoryBlock::BindBufferMemory(
++ const VmaAllocator hAllocator,
++ const VmaAllocation hAllocation,
++ VkDeviceSize allocationLocalOffset,
++ VkBuffer hBuffer,
++ const void* pNext)
++{
++ VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK &&
++ hAllocation->GetBlock() == this);
++ VMA_ASSERT(allocationLocalOffset < hAllocation->GetSize() &&
++ "Invalid allocationLocalOffset. Did you forget that this offset is relative to the beginning of the allocation, not the whole memory block?");
++ const VkDeviceSize memoryOffset = hAllocation->GetOffset() + allocationLocalOffset;
++ // This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads.
++ VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
++ return hAllocator->BindVulkanBuffer(m_hMemory, memoryOffset, hBuffer, pNext);
++}
++
++VkResult VmaDeviceMemoryBlock::BindImageMemory(
++ const VmaAllocator hAllocator,
++ const VmaAllocation hAllocation,
++ VkDeviceSize allocationLocalOffset,
++ VkImage hImage,
++ const void* pNext)
++{
++ VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK &&
++ hAllocation->GetBlock() == this);
++ VMA_ASSERT(allocationLocalOffset < hAllocation->GetSize() &&
++ "Invalid allocationLocalOffset. Did you forget that this offset is relative to the beginning of the allocation, not the whole memory block?");
++ const VkDeviceSize memoryOffset = hAllocation->GetOffset() + allocationLocalOffset;
++ // This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads.
++ VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
++ return hAllocator->BindVulkanImage(m_hMemory, memoryOffset, hImage, pNext);
++}
++#endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
++
++#ifndef _VMA_ALLOCATION_T_FUNCTIONS
++VmaAllocation_T::VmaAllocation_T(bool mappingAllowed)
++ : m_Alignment{ 1 },
++ m_Size{ 0 },
++ m_pUserData{ VMA_NULL },
++ m_pName{ VMA_NULL },
++ m_MemoryTypeIndex{ 0 },
++ m_Type{ (uint8_t)ALLOCATION_TYPE_NONE },
++ m_SuballocationType{ (uint8_t)VMA_SUBALLOCATION_TYPE_UNKNOWN },
++ m_MapCount{ 0 },
++ m_Flags{ 0 }
++{
++ if(mappingAllowed)
++ m_Flags |= (uint8_t)FLAG_MAPPING_ALLOWED;
++
++#if VMA_STATS_STRING_ENABLED
++ m_BufferImageUsage = 0;
++#endif
++}
++
++VmaAllocation_T::~VmaAllocation_T()
++{
++ VMA_ASSERT(m_MapCount == 0 && "Allocation was not unmapped before destruction.");
++
++ // Check if owned string was freed.
++ VMA_ASSERT(m_pName == VMA_NULL);
++}
++
++void VmaAllocation_T::InitBlockAllocation(
++ VmaDeviceMemoryBlock* block,
++ VmaAllocHandle allocHandle,
++ VkDeviceSize alignment,
++ VkDeviceSize size,
++ uint32_t memoryTypeIndex,
++ VmaSuballocationType suballocationType,
++ bool mapped)
++{
++ VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE);
++ VMA_ASSERT(block != VMA_NULL);
++ m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK;
++ m_Alignment = alignment;
++ m_Size = size;
++ m_MemoryTypeIndex = memoryTypeIndex;
++ if(mapped)
++ {
++ VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
++ m_Flags |= (uint8_t)FLAG_PERSISTENT_MAP;
++ }
++ m_SuballocationType = (uint8_t)suballocationType;
++ m_BlockAllocation.m_Block = block;
++ m_BlockAllocation.m_AllocHandle = allocHandle;
++}
++
++void VmaAllocation_T::InitDedicatedAllocation(
++ VmaPool hParentPool,
++ uint32_t memoryTypeIndex,
++ VkDeviceMemory hMemory,
++ VmaSuballocationType suballocationType,
++ void* pMappedData,
++ VkDeviceSize size)
++{
++ VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE);
++ VMA_ASSERT(hMemory != VK_NULL_HANDLE);
++ m_Type = (uint8_t)ALLOCATION_TYPE_DEDICATED;
++ m_Alignment = 0;
++ m_Size = size;
++ m_MemoryTypeIndex = memoryTypeIndex;
++ m_SuballocationType = (uint8_t)suballocationType;
++ if(pMappedData != VMA_NULL)
++ {
++ VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
++ m_Flags |= (uint8_t)FLAG_PERSISTENT_MAP;
++ }
++ m_DedicatedAllocation.m_hParentPool = hParentPool;
++ m_DedicatedAllocation.m_hMemory = hMemory;
++ m_DedicatedAllocation.m_pMappedData = pMappedData;
++ m_DedicatedAllocation.m_Prev = VMA_NULL;
++ m_DedicatedAllocation.m_Next = VMA_NULL;
++}
++
++void VmaAllocation_T::SetName(VmaAllocator hAllocator, const char* pName)
++{
++ VMA_ASSERT(pName == VMA_NULL || pName != m_pName);
++
++ FreeName(hAllocator);
++
++ if (pName != VMA_NULL)
++ m_pName = VmaCreateStringCopy(hAllocator->GetAllocationCallbacks(), pName);
++}
++
++uint8_t VmaAllocation_T::SwapBlockAllocation(VmaAllocator hAllocator, VmaAllocation allocation)
++{
++ VMA_ASSERT(allocation != VMA_NULL);
++ VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK);
++ VMA_ASSERT(allocation->m_Type == ALLOCATION_TYPE_BLOCK);
++
++ if (m_MapCount != 0)
++ m_BlockAllocation.m_Block->Unmap(hAllocator, m_MapCount);
++
++ m_BlockAllocation.m_Block->m_pMetadata->SetAllocationUserData(m_BlockAllocation.m_AllocHandle, allocation);
++ VMA_SWAP(m_BlockAllocation, allocation->m_BlockAllocation);
++ m_BlockAllocation.m_Block->m_pMetadata->SetAllocationUserData(m_BlockAllocation.m_AllocHandle, this);
++
++#if VMA_STATS_STRING_ENABLED
++ VMA_SWAP(m_BufferImageUsage, allocation->m_BufferImageUsage);
++#endif
++ return m_MapCount;
++}
++
++VmaAllocHandle VmaAllocation_T::GetAllocHandle() const
++{
++ switch (m_Type)
++ {
++ case ALLOCATION_TYPE_BLOCK:
++ return m_BlockAllocation.m_AllocHandle;
++ case ALLOCATION_TYPE_DEDICATED:
++ return VK_NULL_HANDLE;
++ default:
++ VMA_ASSERT(0);
++ return VK_NULL_HANDLE;
++ }
++}
++
++VkDeviceSize VmaAllocation_T::GetOffset() const
++{
++ switch (m_Type)
++ {
++ case ALLOCATION_TYPE_BLOCK:
++ return m_BlockAllocation.m_Block->m_pMetadata->GetAllocationOffset(m_BlockAllocation.m_AllocHandle);
++ case ALLOCATION_TYPE_DEDICATED:
++ return 0;
++ default:
++ VMA_ASSERT(0);
++ return 0;
++ }
++}
++
++VmaPool VmaAllocation_T::GetParentPool() const
++{
++ switch (m_Type)
++ {
++ case ALLOCATION_TYPE_BLOCK:
++ return m_BlockAllocation.m_Block->GetParentPool();
++ case ALLOCATION_TYPE_DEDICATED:
++ return m_DedicatedAllocation.m_hParentPool;
++ default:
++ VMA_ASSERT(0);
++ return VK_NULL_HANDLE;
++ }
++}
++
++VkDeviceMemory VmaAllocation_T::GetMemory() const
++{
++ switch (m_Type)
++ {
++ case ALLOCATION_TYPE_BLOCK:
++ return m_BlockAllocation.m_Block->GetDeviceMemory();
++ case ALLOCATION_TYPE_DEDICATED:
++ return m_DedicatedAllocation.m_hMemory;
++ default:
++ VMA_ASSERT(0);
++ return VK_NULL_HANDLE;
++ }
++}
++
++void* VmaAllocation_T::GetMappedData() const
++{
++ switch (m_Type)
++ {
++ case ALLOCATION_TYPE_BLOCK:
++ if (m_MapCount != 0 || IsPersistentMap())
++ {
++ void* pBlockData = m_BlockAllocation.m_Block->GetMappedData();
++ VMA_ASSERT(pBlockData != VMA_NULL);
++ return (char*)pBlockData + GetOffset();
++ }
++ else
++ {
++ return VMA_NULL;
++ }
++ break;
++ case ALLOCATION_TYPE_DEDICATED:
++ VMA_ASSERT((m_DedicatedAllocation.m_pMappedData != VMA_NULL) == (m_MapCount != 0 || IsPersistentMap()));
++ return m_DedicatedAllocation.m_pMappedData;
++ default:
++ VMA_ASSERT(0);
++ return VMA_NULL;
++ }
++}
++
++void VmaAllocation_T::BlockAllocMap()
++{
++ VMA_ASSERT(GetType() == ALLOCATION_TYPE_BLOCK);
++ VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
++
++ if (m_MapCount < 0xFF)
++ {
++ ++m_MapCount;
++ }
++ else
++ {
++ VMA_ASSERT(0 && "Allocation mapped too many times simultaneously.");
++ }
++}
++
++void VmaAllocation_T::BlockAllocUnmap()
++{
++ VMA_ASSERT(GetType() == ALLOCATION_TYPE_BLOCK);
++
++ if (m_MapCount > 0)
++ {
++ --m_MapCount;
++ }
++ else
++ {
++ VMA_ASSERT(0 && "Unmapping allocation not previously mapped.");
++ }
++}
++
++VkResult VmaAllocation_T::DedicatedAllocMap(VmaAllocator hAllocator, void** ppData)
++{
++ VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);
++ VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it.");
++
++ if (m_MapCount != 0 || IsPersistentMap())
++ {
++ if (m_MapCount < 0xFF)
++ {
++ VMA_ASSERT(m_DedicatedAllocation.m_pMappedData != VMA_NULL);
++ *ppData = m_DedicatedAllocation.m_pMappedData;
++ ++m_MapCount;
++ return VK_SUCCESS;
++ }
++ else
++ {
++ VMA_ASSERT(0 && "Dedicated allocation mapped too many times simultaneously.");
++ return VK_ERROR_MEMORY_MAP_FAILED;
++ }
++ }
++ else
++ {
++ VkResult result = (*hAllocator->GetVulkanFunctions().vkMapMemory)(
++ hAllocator->m_hDevice,
++ m_DedicatedAllocation.m_hMemory,
++ 0, // offset
++ VK_WHOLE_SIZE,
++ 0, // flags
++ ppData);
++ if (result == VK_SUCCESS)
++ {
++ m_DedicatedAllocation.m_pMappedData = *ppData;
++ m_MapCount = 1;
++ }
++ return result;
++ }
++}
++
++void VmaAllocation_T::DedicatedAllocUnmap(VmaAllocator hAllocator)
++{
++ VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED);
++
++ if (m_MapCount > 0)
++ {
++ --m_MapCount;
++ if (m_MapCount == 0 && !IsPersistentMap())
++ {
++ m_DedicatedAllocation.m_pMappedData = VMA_NULL;
++ (*hAllocator->GetVulkanFunctions().vkUnmapMemory)(
++ hAllocator->m_hDevice,
++ m_DedicatedAllocation.m_hMemory);
++ }
++ }
++ else
++ {
++ VMA_ASSERT(0 && "Unmapping dedicated allocation not previously mapped.");
++ }
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaAllocation_T::InitBufferImageUsage(uint32_t bufferImageUsage)
++{
++ VMA_ASSERT(m_BufferImageUsage == 0);
++ m_BufferImageUsage = bufferImageUsage;
++}
++
++void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const
++{
++ json.WriteString("Type");
++ json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[m_SuballocationType]);
++
++ json.WriteString("Size");
++ json.WriteNumber(m_Size);
++ json.WriteString("Usage");
++ json.WriteNumber(m_BufferImageUsage);
++
++ if (m_pUserData != VMA_NULL)
++ {
++ json.WriteString("CustomData");
++ json.BeginString();
++ json.ContinueString_Pointer(m_pUserData);
++ json.EndString();
++ }
++ if (m_pName != VMA_NULL)
++ {
++ json.WriteString("Name");
++ json.WriteString(m_pName);
++ }
++}
++#endif // VMA_STATS_STRING_ENABLED
++
++void VmaAllocation_T::FreeName(VmaAllocator hAllocator)
++{
++ if(m_pName)
++ {
++ VmaFreeString(hAllocator->GetAllocationCallbacks(), m_pName);
++ m_pName = VMA_NULL;
++ }
++}
++#endif // _VMA_ALLOCATION_T_FUNCTIONS
++
++#ifndef _VMA_BLOCK_VECTOR_FUNCTIONS
++VmaBlockVector::VmaBlockVector(
++ VmaAllocator hAllocator,
++ VmaPool hParentPool,
++ uint32_t memoryTypeIndex,
++ VkDeviceSize preferredBlockSize,
++ size_t minBlockCount,
++ size_t maxBlockCount,
++ VkDeviceSize bufferImageGranularity,
++ bool explicitBlockSize,
++ uint32_t algorithm,
++ float priority,
++ VkDeviceSize minAllocationAlignment,
++ void* pMemoryAllocateNext)
++ : m_hAllocator(hAllocator),
++ m_hParentPool(hParentPool),
++ m_MemoryTypeIndex(memoryTypeIndex),
++ m_PreferredBlockSize(preferredBlockSize),
++ m_MinBlockCount(minBlockCount),
++ m_MaxBlockCount(maxBlockCount),
++ m_BufferImageGranularity(bufferImageGranularity),
++ m_ExplicitBlockSize(explicitBlockSize),
++ m_Algorithm(algorithm),
++ m_Priority(priority),
++ m_MinAllocationAlignment(minAllocationAlignment),
++ m_pMemoryAllocateNext(pMemoryAllocateNext),
++ m_Blocks(VmaStlAllocator<VmaDeviceMemoryBlock*>(hAllocator->GetAllocationCallbacks())),
++ m_NextBlockId(0) {}
++
++VmaBlockVector::~VmaBlockVector()
++{
++ for (size_t i = m_Blocks.size(); i--; )
++ {
++ m_Blocks[i]->Destroy(m_hAllocator);
++ vma_delete(m_hAllocator, m_Blocks[i]);
++ }
++}
++
++VkResult VmaBlockVector::CreateMinBlocks()
++{
++ for (size_t i = 0; i < m_MinBlockCount; ++i)
++ {
++ VkResult res = CreateBlock(m_PreferredBlockSize, VMA_NULL);
++ if (res != VK_SUCCESS)
++ {
++ return res;
++ }
++ }
++ return VK_SUCCESS;
++}
++
++void VmaBlockVector::AddStatistics(VmaStatistics& inoutStats)
++{
++ VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex);
++
++ const size_t blockCount = m_Blocks.size();
++ for (uint32_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
++ {
++ const VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex];
++ VMA_ASSERT(pBlock);
++ VMA_HEAVY_ASSERT(pBlock->Validate());
++ pBlock->m_pMetadata->AddStatistics(inoutStats);
++ }
++}
++
++void VmaBlockVector::AddDetailedStatistics(VmaDetailedStatistics& inoutStats)
++{
++ VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex);
++
++ const size_t blockCount = m_Blocks.size();
++ for (uint32_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
++ {
++ const VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex];
++ VMA_ASSERT(pBlock);
++ VMA_HEAVY_ASSERT(pBlock->Validate());
++ pBlock->m_pMetadata->AddDetailedStatistics(inoutStats);
++ }
++}
++
++bool VmaBlockVector::IsEmpty()
++{
++ VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex);
++ return m_Blocks.empty();
++}
++
++bool VmaBlockVector::IsCorruptionDetectionEnabled() const
++{
++ const uint32_t requiredMemFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
++ return (VMA_DEBUG_DETECT_CORRUPTION != 0) &&
++ (VMA_DEBUG_MARGIN > 0) &&
++ (m_Algorithm == 0 || m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) &&
++ (m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags & requiredMemFlags) == requiredMemFlags;
++}
++
++VkResult VmaBlockVector::Allocate(
++ VkDeviceSize size,
++ VkDeviceSize alignment,
++ const VmaAllocationCreateInfo& createInfo,
++ VmaSuballocationType suballocType,
++ size_t allocationCount,
++ VmaAllocation* pAllocations)
++{
++ size_t allocIndex;
++ VkResult res = VK_SUCCESS;
++
++ alignment = VMA_MAX(alignment, m_MinAllocationAlignment);
++
++ if (IsCorruptionDetectionEnabled())
++ {
++ size = VmaAlignUp<VkDeviceSize>(size, sizeof(VMA_CORRUPTION_DETECTION_MAGIC_VALUE));
++ alignment = VmaAlignUp<VkDeviceSize>(alignment, sizeof(VMA_CORRUPTION_DETECTION_MAGIC_VALUE));
++ }
++
++ {
++ VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex);
++ for (allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
++ {
++ res = AllocatePage(
++ size,
++ alignment,
++ createInfo,
++ suballocType,
++ pAllocations + allocIndex);
++ if (res != VK_SUCCESS)
++ {
++ break;
++ }
++ }
++ }
++
++ if (res != VK_SUCCESS)
++ {
++ // Free all already created allocations.
++ while (allocIndex--)
++ Free(pAllocations[allocIndex]);
++ memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
++ }
++
++ return res;
++}
++
++VkResult VmaBlockVector::AllocatePage(
++ VkDeviceSize size,
++ VkDeviceSize alignment,
++ const VmaAllocationCreateInfo& createInfo,
++ VmaSuballocationType suballocType,
++ VmaAllocation* pAllocation)
++{
++ const bool isUpperAddress = (createInfo.flags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0;
++
++ VkDeviceSize freeMemory;
++ {
++ const uint32_t heapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex);
++ VmaBudget heapBudget = {};
++ m_hAllocator->GetHeapBudgets(&heapBudget, heapIndex, 1);
++ freeMemory = (heapBudget.usage < heapBudget.budget) ? (heapBudget.budget - heapBudget.usage) : 0;
++ }
++
++ const bool canFallbackToDedicated = !HasExplicitBlockSize() &&
++ (createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0;
++ const bool canCreateNewBlock =
++ ((createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0) &&
++ (m_Blocks.size() < m_MaxBlockCount) &&
++ (freeMemory >= size || !canFallbackToDedicated);
++ uint32_t strategy = createInfo.flags & VMA_ALLOCATION_CREATE_STRATEGY_MASK;
++
++ // Upper address can only be used with linear allocator and within single memory block.
++ if (isUpperAddress &&
++ (m_Algorithm != VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT || m_MaxBlockCount > 1))
++ {
++ return VK_ERROR_FEATURE_NOT_PRESENT;
++ }
++
++ // Early reject: requested allocation size is larger that maximum block size for this block vector.
++ if (size + VMA_DEBUG_MARGIN > m_PreferredBlockSize)
++ {
++ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
++ }
++
++ // 1. Search existing allocations. Try to allocate.
++ if (m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT)
++ {
++ // Use only last block.
++ if (!m_Blocks.empty())
++ {
++ VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks.back();
++ VMA_ASSERT(pCurrBlock);
++ VkResult res = AllocateFromBlock(
++ pCurrBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation);
++ if (res == VK_SUCCESS)
++ {
++ VMA_DEBUG_LOG(" Returned from last block #%u", pCurrBlock->GetId());
++ IncrementallySortBlocks();
++ return VK_SUCCESS;
++ }
++ }
++ }
++ else
++ {
++ if (strategy != VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT) // MIN_MEMORY or default
++ {
++ const bool isHostVisible =
++ (m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0;
++ if(isHostVisible)
++ {
++ const bool isMappingAllowed = (createInfo.flags &
++ (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0;
++ /*
++ For non-mappable allocations, check blocks that are not mapped first.
++ For mappable allocations, check blocks that are already mapped first.
++ This way, having many blocks, we will separate mappable and non-mappable allocations,
++ hopefully limiting the number of blocks that are mapped, which will help tools like RenderDoc.
++ */
++ for(size_t mappingI = 0; mappingI < 2; ++mappingI)
++ {
++ // Forward order in m_Blocks - prefer blocks with smallest amount of free space.
++ for (size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex)
++ {
++ VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex];
++ VMA_ASSERT(pCurrBlock);
++ const bool isBlockMapped = pCurrBlock->GetMappedData() != VMA_NULL;
++ if((mappingI == 0) == (isMappingAllowed == isBlockMapped))
++ {
++ VkResult res = AllocateFromBlock(
++ pCurrBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation);
++ if (res == VK_SUCCESS)
++ {
++ VMA_DEBUG_LOG(" Returned from existing block #%u", pCurrBlock->GetId());
++ IncrementallySortBlocks();
++ return VK_SUCCESS;
++ }
++ }
++ }
++ }
++ }
++ else
++ {
++ // Forward order in m_Blocks - prefer blocks with smallest amount of free space.
++ for (size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex)
++ {
++ VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex];
++ VMA_ASSERT(pCurrBlock);
++ VkResult res = AllocateFromBlock(
++ pCurrBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation);
++ if (res == VK_SUCCESS)
++ {
++ VMA_DEBUG_LOG(" Returned from existing block #%u", pCurrBlock->GetId());
++ IncrementallySortBlocks();
++ return VK_SUCCESS;
++ }
++ }
++ }
++ }
++ else // VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT
++ {
++ // Backward order in m_Blocks - prefer blocks with largest amount of free space.
++ for (size_t blockIndex = m_Blocks.size(); blockIndex--; )
++ {
++ VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex];
++ VMA_ASSERT(pCurrBlock);
++ VkResult res = AllocateFromBlock(pCurrBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation);
++ if (res == VK_SUCCESS)
++ {
++ VMA_DEBUG_LOG(" Returned from existing block #%u", pCurrBlock->GetId());
++ IncrementallySortBlocks();
++ return VK_SUCCESS;
++ }
++ }
++ }
++ }
++
++ // 2. Try to create new block.
++ if (canCreateNewBlock)
++ {
++ // Calculate optimal size for new block.
++ VkDeviceSize newBlockSize = m_PreferredBlockSize;
++ uint32_t newBlockSizeShift = 0;
++ const uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3;
++
++ if (!m_ExplicitBlockSize)
++ {
++ // Allocate 1/8, 1/4, 1/2 as first blocks.
++ const VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize();
++ for (uint32_t i = 0; i < NEW_BLOCK_SIZE_SHIFT_MAX; ++i)
++ {
++ const VkDeviceSize smallerNewBlockSize = newBlockSize / 2;
++ if (smallerNewBlockSize > maxExistingBlockSize && smallerNewBlockSize >= size * 2)
++ {
++ newBlockSize = smallerNewBlockSize;
++ ++newBlockSizeShift;
++ }
++ else
++ {
++ break;
++ }
++ }
++ }
++
++ size_t newBlockIndex = 0;
++ VkResult res = (newBlockSize <= freeMemory || !canFallbackToDedicated) ?
++ CreateBlock(newBlockSize, &newBlockIndex) : VK_ERROR_OUT_OF_DEVICE_MEMORY;
++ // Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize.
++ if (!m_ExplicitBlockSize)
++ {
++ while (res < 0 && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX)
++ {
++ const VkDeviceSize smallerNewBlockSize = newBlockSize / 2;
++ if (smallerNewBlockSize >= size)
++ {
++ newBlockSize = smallerNewBlockSize;
++ ++newBlockSizeShift;
++ res = (newBlockSize <= freeMemory || !canFallbackToDedicated) ?
++ CreateBlock(newBlockSize, &newBlockIndex) : VK_ERROR_OUT_OF_DEVICE_MEMORY;
++ }
++ else
++ {
++ break;
++ }
++ }
++ }
++
++ if (res == VK_SUCCESS)
++ {
++ VmaDeviceMemoryBlock* const pBlock = m_Blocks[newBlockIndex];
++ VMA_ASSERT(pBlock->m_pMetadata->GetSize() >= size);
++
++ res = AllocateFromBlock(
++ pBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation);
++ if (res == VK_SUCCESS)
++ {
++ VMA_DEBUG_LOG(" Created new block #%u Size=%llu", pBlock->GetId(), newBlockSize);
++ IncrementallySortBlocks();
++ return VK_SUCCESS;
++ }
++ else
++ {
++ // Allocation from new block failed, possibly due to VMA_DEBUG_MARGIN or alignment.
++ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
++ }
++ }
++ }
++
++ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
++}
++
++void VmaBlockVector::Free(const VmaAllocation hAllocation)
++{
++ VmaDeviceMemoryBlock* pBlockToDelete = VMA_NULL;
++
++ bool budgetExceeded = false;
++ {
++ const uint32_t heapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex);
++ VmaBudget heapBudget = {};
++ m_hAllocator->GetHeapBudgets(&heapBudget, heapIndex, 1);
++ budgetExceeded = heapBudget.usage >= heapBudget.budget;
++ }
++
++ // Scope for lock.
++ {
++ VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex);
++
++ VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock();
++
++ if (IsCorruptionDetectionEnabled())
++ {
++ VkResult res = pBlock->ValidateMagicValueAfterAllocation(m_hAllocator, hAllocation->GetOffset(), hAllocation->GetSize());
++ VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to validate magic value.");
++ }
++
++ if (hAllocation->IsPersistentMap())
++ {
++ pBlock->Unmap(m_hAllocator, 1);
++ }
++
++ const bool hadEmptyBlockBeforeFree = HasEmptyBlock();
++ pBlock->m_pMetadata->Free(hAllocation->GetAllocHandle());
++ pBlock->PostFree(m_hAllocator);
++ VMA_HEAVY_ASSERT(pBlock->Validate());
++
++ VMA_DEBUG_LOG(" Freed from MemoryTypeIndex=%u", m_MemoryTypeIndex);
++
++ const bool canDeleteBlock = m_Blocks.size() > m_MinBlockCount;
++ // pBlock became empty after this deallocation.
++ if (pBlock->m_pMetadata->IsEmpty())
++ {
++ // Already had empty block. We don't want to have two, so delete this one.
++ if ((hadEmptyBlockBeforeFree || budgetExceeded) && canDeleteBlock)
++ {
++ pBlockToDelete = pBlock;
++ Remove(pBlock);
++ }
++ // else: We now have one empty block - leave it. A hysteresis to avoid allocating whole block back and forth.
++ }
++ // pBlock didn't become empty, but we have another empty block - find and free that one.
++ // (This is optional, heuristics.)
++ else if (hadEmptyBlockBeforeFree && canDeleteBlock)
++ {
++ VmaDeviceMemoryBlock* pLastBlock = m_Blocks.back();
++ if (pLastBlock->m_pMetadata->IsEmpty())
++ {
++ pBlockToDelete = pLastBlock;
++ m_Blocks.pop_back();
++ }
++ }
++
++ IncrementallySortBlocks();
++ }
++
++ // Destruction of a free block. Deferred until this point, outside of mutex
++ // lock, for performance reason.
++ if (pBlockToDelete != VMA_NULL)
++ {
++ VMA_DEBUG_LOG(" Deleted empty block #%u", pBlockToDelete->GetId());
++ pBlockToDelete->Destroy(m_hAllocator);
++ vma_delete(m_hAllocator, pBlockToDelete);
++ }
++
++ m_hAllocator->m_Budget.RemoveAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), hAllocation->GetSize());
++ m_hAllocator->m_AllocationObjectAllocator.Free(hAllocation);
++}
++
++VkDeviceSize VmaBlockVector::CalcMaxBlockSize() const
++{
++ VkDeviceSize result = 0;
++ for (size_t i = m_Blocks.size(); i--; )
++ {
++ result = VMA_MAX(result, m_Blocks[i]->m_pMetadata->GetSize());
++ if (result >= m_PreferredBlockSize)
++ {
++ break;
++ }
++ }
++ return result;
++}
++
++void VmaBlockVector::Remove(VmaDeviceMemoryBlock* pBlock)
++{
++ for (uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex)
++ {
++ if (m_Blocks[blockIndex] == pBlock)
++ {
++ VmaVectorRemove(m_Blocks, blockIndex);
++ return;
++ }
++ }
++ VMA_ASSERT(0);
++}
++
++void VmaBlockVector::IncrementallySortBlocks()
++{
++ if (!m_IncrementalSort)
++ return;
++ if (m_Algorithm != VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT)
++ {
++ // Bubble sort only until first swap.
++ for (size_t i = 1; i < m_Blocks.size(); ++i)
++ {
++ if (m_Blocks[i - 1]->m_pMetadata->GetSumFreeSize() > m_Blocks[i]->m_pMetadata->GetSumFreeSize())
++ {
++ VMA_SWAP(m_Blocks[i - 1], m_Blocks[i]);
++ return;
++ }
++ }
++ }
++}
++
++void VmaBlockVector::SortByFreeSize()
++{
++ VMA_SORT(m_Blocks.begin(), m_Blocks.end(),
++ [](auto* b1, auto* b2)
++ {
++ return b1->m_pMetadata->GetSumFreeSize() < b2->m_pMetadata->GetSumFreeSize();
++ });
++}
++
++VkResult VmaBlockVector::AllocateFromBlock(
++ VmaDeviceMemoryBlock* pBlock,
++ VkDeviceSize size,
++ VkDeviceSize alignment,
++ VmaAllocationCreateFlags allocFlags,
++ void* pUserData,
++ VmaSuballocationType suballocType,
++ uint32_t strategy,
++ VmaAllocation* pAllocation)
++{
++ const bool isUpperAddress = (allocFlags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0;
++
++ VmaAllocationRequest currRequest = {};
++ if (pBlock->m_pMetadata->CreateAllocationRequest(
++ size,
++ alignment,
++ isUpperAddress,
++ suballocType,
++ strategy,
++ &currRequest))
++ {
++ return CommitAllocationRequest(currRequest, pBlock, alignment, allocFlags, pUserData, suballocType, pAllocation);
++ }
++ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
++}
++
++VkResult VmaBlockVector::CommitAllocationRequest(
++ VmaAllocationRequest& allocRequest,
++ VmaDeviceMemoryBlock* pBlock,
++ VkDeviceSize alignment,
++ VmaAllocationCreateFlags allocFlags,
++ void* pUserData,
++ VmaSuballocationType suballocType,
++ VmaAllocation* pAllocation)
++{
++ const bool mapped = (allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0;
++ const bool isUserDataString = (allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0;
++ const bool isMappingAllowed = (allocFlags &
++ (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0;
++
++ pBlock->PostAlloc();
++ // Allocate from pCurrBlock.
++ if (mapped)
++ {
++ VkResult res = pBlock->Map(m_hAllocator, 1, VMA_NULL);
++ if (res != VK_SUCCESS)
++ {
++ return res;
++ }
++ }
++
++ *pAllocation = m_hAllocator->m_AllocationObjectAllocator.Allocate(isMappingAllowed);
++ pBlock->m_pMetadata->Alloc(allocRequest, suballocType, *pAllocation);
++ (*pAllocation)->InitBlockAllocation(
++ pBlock,
++ allocRequest.allocHandle,
++ alignment,
++ allocRequest.size, // Not size, as actual allocation size may be larger than requested!
++ m_MemoryTypeIndex,
++ suballocType,
++ mapped);
++ VMA_HEAVY_ASSERT(pBlock->Validate());
++ if (isUserDataString)
++ (*pAllocation)->SetName(m_hAllocator, (const char*)pUserData);
++ else
++ (*pAllocation)->SetUserData(m_hAllocator, pUserData);
++ m_hAllocator->m_Budget.AddAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), allocRequest.size);
++ if (VMA_DEBUG_INITIALIZE_ALLOCATIONS)
++ {
++ m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
++ }
++ if (IsCorruptionDetectionEnabled())
++ {
++ VkResult res = pBlock->WriteMagicValueAfterAllocation(m_hAllocator, (*pAllocation)->GetOffset(), allocRequest.size);
++ VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value.");
++ }
++ return VK_SUCCESS;
++}
++
++VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex)
++{
++ VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
++ allocInfo.pNext = m_pMemoryAllocateNext;
++ allocInfo.memoryTypeIndex = m_MemoryTypeIndex;
++ allocInfo.allocationSize = blockSize;
++
++#if VMA_BUFFER_DEVICE_ADDRESS
++ // Every standalone block can potentially contain a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - always enable the feature.
++ VkMemoryAllocateFlagsInfoKHR allocFlagsInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR };
++ if (m_hAllocator->m_UseKhrBufferDeviceAddress)
++ {
++ allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
++ VmaPnextChainPushFront(&allocInfo, &allocFlagsInfo);
++ }
++#endif // VMA_BUFFER_DEVICE_ADDRESS
++
++#if VMA_MEMORY_PRIORITY
++ VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT };
++ if (m_hAllocator->m_UseExtMemoryPriority)
++ {
++ VMA_ASSERT(m_Priority >= 0.f && m_Priority <= 1.f);
++ priorityInfo.priority = m_Priority;
++ VmaPnextChainPushFront(&allocInfo, &priorityInfo);
++ }
++#endif // VMA_MEMORY_PRIORITY
++
++#if VMA_EXTERNAL_MEMORY
++ // Attach VkExportMemoryAllocateInfoKHR if necessary.
++ VkExportMemoryAllocateInfoKHR exportMemoryAllocInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR };
++ exportMemoryAllocInfo.handleTypes = m_hAllocator->GetExternalMemoryHandleTypeFlags(m_MemoryTypeIndex);
++ if (exportMemoryAllocInfo.handleTypes != 0)
++ {
++ VmaPnextChainPushFront(&allocInfo, &exportMemoryAllocInfo);
++ }
++#endif // VMA_EXTERNAL_MEMORY
++
++ VkDeviceMemory mem = VK_NULL_HANDLE;
++ VkResult res = m_hAllocator->AllocateVulkanMemory(&allocInfo, &mem);
++ if (res < 0)
++ {
++ return res;
++ }
++
++ // New VkDeviceMemory successfully created.
++
++ // Create new Allocation for it.
++ VmaDeviceMemoryBlock* const pBlock = vma_new(m_hAllocator, VmaDeviceMemoryBlock)(m_hAllocator);
++ pBlock->Init(
++ m_hAllocator,
++ m_hParentPool,
++ m_MemoryTypeIndex,
++ mem,
++ allocInfo.allocationSize,
++ m_NextBlockId++,
++ m_Algorithm,
++ m_BufferImageGranularity);
++
++ m_Blocks.push_back(pBlock);
++ if (pNewBlockIndex != VMA_NULL)
++ {
++ *pNewBlockIndex = m_Blocks.size() - 1;
++ }
++
++ return VK_SUCCESS;
++}
++
++bool VmaBlockVector::HasEmptyBlock()
++{
++ for (size_t index = 0, count = m_Blocks.size(); index < count; ++index)
++ {
++ VmaDeviceMemoryBlock* const pBlock = m_Blocks[index];
++ if (pBlock->m_pMetadata->IsEmpty())
++ {
++ return true;
++ }
++ }
++ return false;
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json)
++{
++ VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex);
++
++
++ json.BeginObject();
++ for (size_t i = 0; i < m_Blocks.size(); ++i)
++ {
++ json.BeginString();
++ json.ContinueString(m_Blocks[i]->GetId());
++ json.EndString();
++
++ json.BeginObject();
++ json.WriteString("MapRefCount");
++ json.WriteNumber(m_Blocks[i]->GetMapRefCount());
++
++ m_Blocks[i]->m_pMetadata->PrintDetailedMap(json);
++ json.EndObject();
++ }
++ json.EndObject();
++}
++#endif // VMA_STATS_STRING_ENABLED
++
++VkResult VmaBlockVector::CheckCorruption()
++{
++ if (!IsCorruptionDetectionEnabled())
++ {
++ return VK_ERROR_FEATURE_NOT_PRESENT;
++ }
++
++ VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex);
++ for (uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex)
++ {
++ VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex];
++ VMA_ASSERT(pBlock);
++ VkResult res = pBlock->CheckCorruption(m_hAllocator);
++ if (res != VK_SUCCESS)
++ {
++ return res;
++ }
++ }
++ return VK_SUCCESS;
++}
++
++#endif // _VMA_BLOCK_VECTOR_FUNCTIONS
++
++#ifndef _VMA_DEFRAGMENTATION_CONTEXT_FUNCTIONS
++VmaDefragmentationContext_T::VmaDefragmentationContext_T(
++ VmaAllocator hAllocator,
++ const VmaDefragmentationInfo& info)
++ : m_MaxPassBytes(info.maxBytesPerPass == 0 ? VK_WHOLE_SIZE : info.maxBytesPerPass),
++ m_MaxPassAllocations(info.maxAllocationsPerPass == 0 ? UINT32_MAX : info.maxAllocationsPerPass),
++ m_MoveAllocator(hAllocator->GetAllocationCallbacks()),
++ m_Moves(m_MoveAllocator)
++{
++ m_Algorithm = info.flags & VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK;
++
++ if (info.pool != VMA_NULL)
++ {
++ m_BlockVectorCount = 1;
++ m_PoolBlockVector = &info.pool->m_BlockVector;
++ m_pBlockVectors = &m_PoolBlockVector;
++ m_PoolBlockVector->SetIncrementalSort(false);
++ m_PoolBlockVector->SortByFreeSize();
++ }
++ else
++ {
++ m_BlockVectorCount = hAllocator->GetMemoryTypeCount();
++ m_PoolBlockVector = VMA_NULL;
++ m_pBlockVectors = hAllocator->m_pBlockVectors;
++ for (uint32_t i = 0; i < m_BlockVectorCount; ++i)
++ {
++ VmaBlockVector* vector = m_pBlockVectors[i];
++ if (vector != VMA_NULL)
++ {
++ vector->SetIncrementalSort(false);
++ vector->SortByFreeSize();
++ }
++ }
++ }
++
++ switch (m_Algorithm)
++ {
++ case 0: // Default algorithm
++ m_Algorithm = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT;
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT:
++ {
++ m_AlgorithmState = vma_new_array(hAllocator, StateBalanced, m_BlockVectorCount);
++ break;
++ }
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
++ {
++ if (hAllocator->GetBufferImageGranularity() > 1)
++ {
++ m_AlgorithmState = vma_new_array(hAllocator, StateExtensive, m_BlockVectorCount);
++ }
++ break;
++ }
++ }
++}
++
++VmaDefragmentationContext_T::~VmaDefragmentationContext_T()
++{
++ if (m_PoolBlockVector != VMA_NULL)
++ {
++ m_PoolBlockVector->SetIncrementalSort(true);
++ }
++ else
++ {
++ for (uint32_t i = 0; i < m_BlockVectorCount; ++i)
++ {
++ VmaBlockVector* vector = m_pBlockVectors[i];
++ if (vector != VMA_NULL)
++ vector->SetIncrementalSort(true);
++ }
++ }
++
++ if (m_AlgorithmState)
++ {
++ switch (m_Algorithm)
++ {
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT:
++ vma_delete_array(m_MoveAllocator.m_pCallbacks, reinterpret_cast<StateBalanced*>(m_AlgorithmState), m_BlockVectorCount);
++ break;
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
++ vma_delete_array(m_MoveAllocator.m_pCallbacks, reinterpret_cast<StateExtensive*>(m_AlgorithmState), m_BlockVectorCount);
++ break;
++ default:
++ VMA_ASSERT(0);
++ }
++ }
++}
++
++VkResult VmaDefragmentationContext_T::DefragmentPassBegin(VmaDefragmentationPassMoveInfo& moveInfo)
++{
++ if (m_PoolBlockVector != VMA_NULL)
++ {
++ VmaMutexLockWrite lock(m_PoolBlockVector->GetMutex(), m_PoolBlockVector->GetAllocator()->m_UseMutex);
++
++ if (m_PoolBlockVector->GetBlockCount() > 1)
++ ComputeDefragmentation(*m_PoolBlockVector, 0);
++ else if (m_PoolBlockVector->GetBlockCount() == 1)
++ ReallocWithinBlock(*m_PoolBlockVector, m_PoolBlockVector->GetBlock(0));
++ }
++ else
++ {
++ for (uint32_t i = 0; i < m_BlockVectorCount; ++i)
++ {
++ if (m_pBlockVectors[i] != VMA_NULL)
++ {
++ VmaMutexLockWrite lock(m_pBlockVectors[i]->GetMutex(), m_pBlockVectors[i]->GetAllocator()->m_UseMutex);
++
++ if (m_pBlockVectors[i]->GetBlockCount() > 1)
++ {
++ if (ComputeDefragmentation(*m_pBlockVectors[i], i))
++ break;
++ }
++ else if (m_pBlockVectors[i]->GetBlockCount() == 1)
++ {
++ if (ReallocWithinBlock(*m_pBlockVectors[i], m_pBlockVectors[i]->GetBlock(0)))
++ break;
++ }
++ }
++ }
++ }
++
++ moveInfo.moveCount = static_cast<uint32_t>(m_Moves.size());
++ if (moveInfo.moveCount > 0)
++ {
++ moveInfo.pMoves = m_Moves.data();
++ return VK_INCOMPLETE;
++ }
++
++ moveInfo.pMoves = VMA_NULL;
++ return VK_SUCCESS;
++}
++
++VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMoveInfo& moveInfo)
++{
++ VMA_ASSERT(moveInfo.moveCount > 0 ? moveInfo.pMoves != VMA_NULL : true);
++
++ VkResult result = VK_SUCCESS;
++ VmaStlAllocator<FragmentedBlock> blockAllocator(m_MoveAllocator.m_pCallbacks);
++ VmaVector<FragmentedBlock, VmaStlAllocator<FragmentedBlock>> immovableBlocks(blockAllocator);
++ VmaVector<FragmentedBlock, VmaStlAllocator<FragmentedBlock>> mappedBlocks(blockAllocator);
++
++ VmaAllocator allocator = VMA_NULL;
++ for (uint32_t i = 0; i < moveInfo.moveCount; ++i)
++ {
++ VmaDefragmentationMove& move = moveInfo.pMoves[i];
++ size_t prevCount = 0, currentCount = 0;
++ VkDeviceSize freedBlockSize = 0;
++
++ uint32_t vectorIndex;
++ VmaBlockVector* vector;
++ if (m_PoolBlockVector != VMA_NULL)
++ {
++ vectorIndex = 0;
++ vector = m_PoolBlockVector;
++ }
++ else
++ {
++ vectorIndex = move.srcAllocation->GetMemoryTypeIndex();
++ vector = m_pBlockVectors[vectorIndex];
++ VMA_ASSERT(vector != VMA_NULL);
++ }
++
++ switch (move.operation)
++ {
++ case VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY:
++ {
++ uint8_t mapCount = move.srcAllocation->SwapBlockAllocation(vector->m_hAllocator, move.dstTmpAllocation);
++ if (mapCount > 0)
++ {
++ allocator = vector->m_hAllocator;
++ VmaDeviceMemoryBlock* newMapBlock = move.srcAllocation->GetBlock();
++ bool notPresent = true;
++ for (FragmentedBlock& block : mappedBlocks)
++ {
++ if (block.block == newMapBlock)
++ {
++ notPresent = false;
++ block.data += mapCount;
++ break;
++ }
++ }
++ if (notPresent)
++ mappedBlocks.push_back({ mapCount, newMapBlock });
++ }
++
++ // Scope for locks, Free have it's own lock
++ {
++ VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
++ prevCount = vector->GetBlockCount();
++ freedBlockSize = move.dstTmpAllocation->GetBlock()->m_pMetadata->GetSize();
++ }
++ vector->Free(move.dstTmpAllocation);
++ {
++ VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
++ currentCount = vector->GetBlockCount();
++ }
++
++ result = VK_INCOMPLETE;
++ break;
++ }
++ case VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE:
++ {
++ m_PassStats.bytesMoved -= move.srcAllocation->GetSize();
++ --m_PassStats.allocationsMoved;
++ vector->Free(move.dstTmpAllocation);
++
++ VmaDeviceMemoryBlock* newBlock = move.srcAllocation->GetBlock();
++ bool notPresent = true;
++ for (const FragmentedBlock& block : immovableBlocks)
++ {
++ if (block.block == newBlock)
++ {
++ notPresent = false;
++ break;
++ }
++ }
++ if (notPresent)
++ immovableBlocks.push_back({ vectorIndex, newBlock });
++ break;
++ }
++ case VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY:
++ {
++ m_PassStats.bytesMoved -= move.srcAllocation->GetSize();
++ --m_PassStats.allocationsMoved;
++ // Scope for locks, Free have it's own lock
++ {
++ VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
++ prevCount = vector->GetBlockCount();
++ freedBlockSize = move.srcAllocation->GetBlock()->m_pMetadata->GetSize();
++ }
++ vector->Free(move.srcAllocation);
++ {
++ VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
++ currentCount = vector->GetBlockCount();
++ }
++ freedBlockSize *= prevCount - currentCount;
++
++ VkDeviceSize dstBlockSize;
++ {
++ VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
++ dstBlockSize = move.dstTmpAllocation->GetBlock()->m_pMetadata->GetSize();
++ }
++ vector->Free(move.dstTmpAllocation);
++ {
++ VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
++ freedBlockSize += dstBlockSize * (currentCount - vector->GetBlockCount());
++ currentCount = vector->GetBlockCount();
++ }
++
++ result = VK_INCOMPLETE;
++ break;
++ }
++ default:
++ VMA_ASSERT(0);
++ }
++
++ if (prevCount > currentCount)
++ {
++ size_t freedBlocks = prevCount - currentCount;
++ m_PassStats.deviceMemoryBlocksFreed += static_cast<uint32_t>(freedBlocks);
++ m_PassStats.bytesFreed += freedBlockSize;
++ }
++
++ switch (m_Algorithm)
++ {
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
++ {
++ if (m_AlgorithmState != VMA_NULL)
++ {
++ // Avoid unnecessary tries to allocate when new free block is avaiable
++ StateExtensive& state = reinterpret_cast<StateExtensive*>(m_AlgorithmState)[vectorIndex];
++ if (state.firstFreeBlock != SIZE_MAX)
++ {
++ const size_t diff = prevCount - currentCount;
++ if (state.firstFreeBlock >= diff)
++ {
++ state.firstFreeBlock -= diff;
++ if (state.firstFreeBlock != 0)
++ state.firstFreeBlock -= vector->GetBlock(state.firstFreeBlock - 1)->m_pMetadata->IsEmpty();
++ }
++ else
++ state.firstFreeBlock = 0;
++ }
++ }
++ }
++ }
++ }
++ moveInfo.moveCount = 0;
++ moveInfo.pMoves = VMA_NULL;
++ m_Moves.clear();
++
++ // Update stats
++ m_GlobalStats.allocationsMoved += m_PassStats.allocationsMoved;
++ m_GlobalStats.bytesFreed += m_PassStats.bytesFreed;
++ m_GlobalStats.bytesMoved += m_PassStats.bytesMoved;
++ m_GlobalStats.deviceMemoryBlocksFreed += m_PassStats.deviceMemoryBlocksFreed;
++ m_PassStats = { 0 };
++
++ // Move blocks with immovable allocations according to algorithm
++ if (immovableBlocks.size() > 0)
++ {
++ switch (m_Algorithm)
++ {
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
++ {
++ if (m_AlgorithmState != VMA_NULL)
++ {
++ bool swapped = false;
++ // Move to the start of free blocks range
++ for (const FragmentedBlock& block : immovableBlocks)
++ {
++ StateExtensive& state = reinterpret_cast<StateExtensive*>(m_AlgorithmState)[block.data];
++ if (state.operation != StateExtensive::Operation::Cleanup)
++ {
++ VmaBlockVector* vector = m_pBlockVectors[block.data];
++ VmaMutexLockWrite lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
++
++ for (size_t i = 0, count = vector->GetBlockCount() - m_ImmovableBlockCount; i < count; ++i)
++ {
++ if (vector->GetBlock(i) == block.block)
++ {
++ VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[vector->GetBlockCount() - ++m_ImmovableBlockCount]);
++ if (state.firstFreeBlock != SIZE_MAX)
++ {
++ if (i + 1 < state.firstFreeBlock)
++ {
++ if (state.firstFreeBlock > 1)
++ VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[--state.firstFreeBlock]);
++ else
++ --state.firstFreeBlock;
++ }
++ }
++ swapped = true;
++ break;
++ }
++ }
++ }
++ }
++ if (swapped)
++ result = VK_INCOMPLETE;
++ break;
++ }
++ }
++ default:
++ {
++ // Move to the begining
++ for (const FragmentedBlock& block : immovableBlocks)
++ {
++ VmaBlockVector* vector = m_pBlockVectors[block.data];
++ VmaMutexLockWrite lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
++
++ for (size_t i = m_ImmovableBlockCount; i < vector->GetBlockCount(); ++i)
++ {
++ if (vector->GetBlock(i) == block.block)
++ {
++ VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[m_ImmovableBlockCount++]);
++ break;
++ }
++ }
++ }
++ break;
++ }
++ }
++ }
++
++ // Bulk-map destination blocks
++ for (const FragmentedBlock& block : mappedBlocks)
++ {
++ VkResult res = block.block->Map(allocator, block.data, VMA_NULL);
++ VMA_ASSERT(res == VK_SUCCESS);
++ }
++ return result;
++}
++
++bool VmaDefragmentationContext_T::ComputeDefragmentation(VmaBlockVector& vector, size_t index)
++{
++ switch (m_Algorithm)
++ {
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT:
++ return ComputeDefragmentation_Fast(vector);
++ default:
++ VMA_ASSERT(0);
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT:
++ return ComputeDefragmentation_Balanced(vector, index, true);
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT:
++ return ComputeDefragmentation_Full(vector);
++ case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT:
++ return ComputeDefragmentation_Extensive(vector, index);
++ }
++}
++
++VmaDefragmentationContext_T::MoveAllocationData VmaDefragmentationContext_T::GetMoveData(
++ VmaAllocHandle handle, VmaBlockMetadata* metadata)
++{
++ MoveAllocationData moveData;
++ moveData.move.srcAllocation = (VmaAllocation)metadata->GetAllocationUserData(handle);
++ moveData.size = moveData.move.srcAllocation->GetSize();
++ moveData.alignment = moveData.move.srcAllocation->GetAlignment();
++ moveData.type = moveData.move.srcAllocation->GetSuballocationType();
++ moveData.flags = 0;
++
++ if (moveData.move.srcAllocation->IsPersistentMap())
++ moveData.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT;
++ if (moveData.move.srcAllocation->IsMappingAllowed())
++ moveData.flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
++
++ return moveData;
++}
++
++VmaDefragmentationContext_T::CounterStatus VmaDefragmentationContext_T::CheckCounters(VkDeviceSize bytes)
++{
++ // Ignore allocation if will exceed max size for copy
++ if (m_PassStats.bytesMoved + bytes > m_MaxPassBytes)
++ {
++ if (++m_IgnoredAllocs < MAX_ALLOCS_TO_IGNORE)
++ return CounterStatus::Ignore;
++ else
++ return CounterStatus::End;
++ }
++ return CounterStatus::Pass;
++}
++
++bool VmaDefragmentationContext_T::IncrementCounters(VkDeviceSize bytes)
++{
++ m_PassStats.bytesMoved += bytes;
++ // Early return when max found
++ if (++m_PassStats.allocationsMoved >= m_MaxPassAllocations || m_PassStats.bytesMoved >= m_MaxPassBytes)
++ {
++ VMA_ASSERT(m_PassStats.allocationsMoved == m_MaxPassAllocations ||
++ m_PassStats.bytesMoved == m_MaxPassBytes && "Exceeded maximal pass threshold!");
++ return true;
++ }
++ return false;
++}
++
++bool VmaDefragmentationContext_T::ReallocWithinBlock(VmaBlockVector& vector, VmaDeviceMemoryBlock* block)
++{
++ VmaBlockMetadata* metadata = block->m_pMetadata;
++
++ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
++ handle != VK_NULL_HANDLE;
++ handle = metadata->GetNextAllocation(handle))
++ {
++ MoveAllocationData moveData = GetMoveData(handle, metadata);
++ // Ignore newly created allocations by defragmentation algorithm
++ if (moveData.move.srcAllocation->GetUserData() == this)
++ continue;
++ switch (CheckCounters(moveData.move.srcAllocation->GetSize()))
++ {
++ case CounterStatus::Ignore:
++ continue;
++ case CounterStatus::End:
++ return true;
++ default:
++ VMA_ASSERT(0);
++ case CounterStatus::Pass:
++ break;
++ }
++
++ VkDeviceSize offset = moveData.move.srcAllocation->GetOffset();
++ if (offset != 0 && metadata->GetSumFreeSize() >= moveData.size)
++ {
++ VmaAllocationRequest request = {};
++ if (metadata->CreateAllocationRequest(
++ moveData.size,
++ moveData.alignment,
++ false,
++ moveData.type,
++ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
++ &request))
++ {
++ if (metadata->GetAllocationOffset(request.allocHandle) < offset)
++ {
++ if (vector.CommitAllocationRequest(
++ request,
++ block,
++ moveData.alignment,
++ moveData.flags,
++ this,
++ moveData.type,
++ &moveData.move.dstTmpAllocation) == VK_SUCCESS)
++ {
++ m_Moves.push_back(moveData.move);
++ if (IncrementCounters(moveData.size))
++ return true;
++ }
++ }
++ }
++ }
++ }
++ return false;
++}
++
++bool VmaDefragmentationContext_T::AllocInOtherBlock(size_t start, size_t end, MoveAllocationData& data, VmaBlockVector& vector)
++{
++ for (; start < end; ++start)
++ {
++ VmaDeviceMemoryBlock* dstBlock = vector.GetBlock(start);
++ if (dstBlock->m_pMetadata->GetSumFreeSize() >= data.size)
++ {
++ if (vector.AllocateFromBlock(dstBlock,
++ data.size,
++ data.alignment,
++ data.flags,
++ this,
++ data.type,
++ 0,
++ &data.move.dstTmpAllocation) == VK_SUCCESS)
++ {
++ m_Moves.push_back(data.move);
++ if (IncrementCounters(data.size))
++ return true;
++ break;
++ }
++ }
++ }
++ return false;
++}
++
++bool VmaDefragmentationContext_T::ComputeDefragmentation_Fast(VmaBlockVector& vector)
++{
++ // Move only between blocks
++
++ // Go through allocations in last blocks and try to fit them inside first ones
++ for (size_t i = vector.GetBlockCount() - 1; i > m_ImmovableBlockCount; --i)
++ {
++ VmaBlockMetadata* metadata = vector.GetBlock(i)->m_pMetadata;
++
++ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
++ handle != VK_NULL_HANDLE;
++ handle = metadata->GetNextAllocation(handle))
++ {
++ MoveAllocationData moveData = GetMoveData(handle, metadata);
++ // Ignore newly created allocations by defragmentation algorithm
++ if (moveData.move.srcAllocation->GetUserData() == this)
++ continue;
++ switch (CheckCounters(moveData.move.srcAllocation->GetSize()))
++ {
++ case CounterStatus::Ignore:
++ continue;
++ case CounterStatus::End:
++ return true;
++ default:
++ VMA_ASSERT(0);
++ case CounterStatus::Pass:
++ break;
++ }
++
++ // Check all previous blocks for free space
++ if (AllocInOtherBlock(0, i, moveData, vector))
++ return true;
++ }
++ }
++ return false;
++}
++
++bool VmaDefragmentationContext_T::ComputeDefragmentation_Balanced(VmaBlockVector& vector, size_t index, bool update)
++{
++ // Go over every allocation and try to fit it in previous blocks at lowest offsets,
++ // if not possible: realloc within single block to minimize offset (exclude offset == 0),
++ // but only if there are noticable gaps between them (some heuristic, ex. average size of allocation in block)
++ VMA_ASSERT(m_AlgorithmState != VMA_NULL);
++
++ StateBalanced& vectorState = reinterpret_cast<StateBalanced*>(m_AlgorithmState)[index];
++ if (update && vectorState.avgAllocSize == UINT64_MAX)
++ UpdateVectorStatistics(vector, vectorState);
++
++ const size_t startMoveCount = m_Moves.size();
++ VkDeviceSize minimalFreeRegion = vectorState.avgFreeSize / 2;
++ for (size_t i = vector.GetBlockCount() - 1; i > m_ImmovableBlockCount; --i)
++ {
++ VmaDeviceMemoryBlock* block = vector.GetBlock(i);
++ VmaBlockMetadata* metadata = block->m_pMetadata;
++ VkDeviceSize prevFreeRegionSize = 0;
++
++ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
++ handle != VK_NULL_HANDLE;
++ handle = metadata->GetNextAllocation(handle))
++ {
++ MoveAllocationData moveData = GetMoveData(handle, metadata);
++ // Ignore newly created allocations by defragmentation algorithm
++ if (moveData.move.srcAllocation->GetUserData() == this)
++ continue;
++ switch (CheckCounters(moveData.move.srcAllocation->GetSize()))
++ {
++ case CounterStatus::Ignore:
++ continue;
++ case CounterStatus::End:
++ return true;
++ default:
++ VMA_ASSERT(0);
++ case CounterStatus::Pass:
++ break;
++ }
++
++ // Check all previous blocks for free space
++ const size_t prevMoveCount = m_Moves.size();
++ if (AllocInOtherBlock(0, i, moveData, vector))
++ return true;
++
++ VkDeviceSize nextFreeRegionSize = metadata->GetNextFreeRegionSize(handle);
++ // If no room found then realloc within block for lower offset
++ VkDeviceSize offset = moveData.move.srcAllocation->GetOffset();
++ if (prevMoveCount == m_Moves.size() && offset != 0 && metadata->GetSumFreeSize() >= moveData.size)
++ {
++ // Check if realloc will make sense
++ if (prevFreeRegionSize >= minimalFreeRegion ||
++ nextFreeRegionSize >= minimalFreeRegion ||
++ moveData.size <= vectorState.avgFreeSize ||
++ moveData.size <= vectorState.avgAllocSize)
++ {
++ VmaAllocationRequest request = {};
++ if (metadata->CreateAllocationRequest(
++ moveData.size,
++ moveData.alignment,
++ false,
++ moveData.type,
++ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
++ &request))
++ {
++ if (metadata->GetAllocationOffset(request.allocHandle) < offset)
++ {
++ if (vector.CommitAllocationRequest(
++ request,
++ block,
++ moveData.alignment,
++ moveData.flags,
++ this,
++ moveData.type,
++ &moveData.move.dstTmpAllocation) == VK_SUCCESS)
++ {
++ m_Moves.push_back(moveData.move);
++ if (IncrementCounters(moveData.size))
++ return true;
++ }
++ }
++ }
++ }
++ }
++ prevFreeRegionSize = nextFreeRegionSize;
++ }
++ }
++
++ // No moves perfomed, update statistics to current vector state
++ if (startMoveCount == m_Moves.size() && !update)
++ {
++ vectorState.avgAllocSize = UINT64_MAX;
++ return ComputeDefragmentation_Balanced(vector, index, false);
++ }
++ return false;
++}
++
++bool VmaDefragmentationContext_T::ComputeDefragmentation_Full(VmaBlockVector& vector)
++{
++ // Go over every allocation and try to fit it in previous blocks at lowest offsets,
++ // if not possible: realloc within single block to minimize offset (exclude offset == 0)
++
++ for (size_t i = vector.GetBlockCount() - 1; i > m_ImmovableBlockCount; --i)
++ {
++ VmaDeviceMemoryBlock* block = vector.GetBlock(i);
++ VmaBlockMetadata* metadata = block->m_pMetadata;
++
++ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
++ handle != VK_NULL_HANDLE;
++ handle = metadata->GetNextAllocation(handle))
++ {
++ MoveAllocationData moveData = GetMoveData(handle, metadata);
++ // Ignore newly created allocations by defragmentation algorithm
++ if (moveData.move.srcAllocation->GetUserData() == this)
++ continue;
++ switch (CheckCounters(moveData.move.srcAllocation->GetSize()))
++ {
++ case CounterStatus::Ignore:
++ continue;
++ case CounterStatus::End:
++ return true;
++ default:
++ VMA_ASSERT(0);
++ case CounterStatus::Pass:
++ break;
++ }
++
++ // Check all previous blocks for free space
++ const size_t prevMoveCount = m_Moves.size();
++ if (AllocInOtherBlock(0, i, moveData, vector))
++ return true;
++
++ // If no room found then realloc within block for lower offset
++ VkDeviceSize offset = moveData.move.srcAllocation->GetOffset();
++ if (prevMoveCount == m_Moves.size() && offset != 0 && metadata->GetSumFreeSize() >= moveData.size)
++ {
++ VmaAllocationRequest request = {};
++ if (metadata->CreateAllocationRequest(
++ moveData.size,
++ moveData.alignment,
++ false,
++ moveData.type,
++ VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
++ &request))
++ {
++ if (metadata->GetAllocationOffset(request.allocHandle) < offset)
++ {
++ if (vector.CommitAllocationRequest(
++ request,
++ block,
++ moveData.alignment,
++ moveData.flags,
++ this,
++ moveData.type,
++ &moveData.move.dstTmpAllocation) == VK_SUCCESS)
++ {
++ m_Moves.push_back(moveData.move);
++ if (IncrementCounters(moveData.size))
++ return true;
++ }
++ }
++ }
++ }
++ }
++ }
++ return false;
++}
++
++bool VmaDefragmentationContext_T::ComputeDefragmentation_Extensive(VmaBlockVector& vector, size_t index)
++{
++ // First free single block, then populate it to the brim, then free another block, and so on
++
++ // Fallback to previous algorithm since without granularity conflicts it can achieve max packing
++ if (vector.m_BufferImageGranularity == 1)
++ return ComputeDefragmentation_Full(vector);
++
++ VMA_ASSERT(m_AlgorithmState != VMA_NULL);
++
++ StateExtensive& vectorState = reinterpret_cast<StateExtensive*>(m_AlgorithmState)[index];
++
++ bool texturePresent = false, bufferPresent = false, otherPresent = false;
++ switch (vectorState.operation)
++ {
++ case StateExtensive::Operation::Done: // Vector defragmented
++ return false;
++ case StateExtensive::Operation::FindFreeBlockBuffer:
++ case StateExtensive::Operation::FindFreeBlockTexture:
++ case StateExtensive::Operation::FindFreeBlockAll:
++ {
++ // No more blocks to free, just perform fast realloc and move to cleanup
++ if (vectorState.firstFreeBlock == 0)
++ {
++ vectorState.operation = StateExtensive::Operation::Cleanup;
++ return ComputeDefragmentation_Fast(vector);
++ }
++
++ // No free blocks, have to clear last one
++ size_t last = (vectorState.firstFreeBlock == SIZE_MAX ? vector.GetBlockCount() : vectorState.firstFreeBlock) - 1;
++ VmaBlockMetadata* freeMetadata = vector.GetBlock(last)->m_pMetadata;
++
++ const size_t prevMoveCount = m_Moves.size();
++ for (VmaAllocHandle handle = freeMetadata->GetAllocationListBegin();
++ handle != VK_NULL_HANDLE;
++ handle = freeMetadata->GetNextAllocation(handle))
++ {
++ MoveAllocationData moveData = GetMoveData(handle, freeMetadata);
++ switch (CheckCounters(moveData.move.srcAllocation->GetSize()))
++ {
++ case CounterStatus::Ignore:
++ continue;
++ case CounterStatus::End:
++ return true;
++ default:
++ VMA_ASSERT(0);
++ case CounterStatus::Pass:
++ break;
++ }
++
++ // Check all previous blocks for free space
++ if (AllocInOtherBlock(0, last, moveData, vector))
++ {
++ // Full clear performed already
++ if (prevMoveCount != m_Moves.size() && freeMetadata->GetNextAllocation(handle) == VK_NULL_HANDLE)
++ reinterpret_cast<size_t*>(m_AlgorithmState)[index] = last;
++ return true;
++ }
++ }
++
++ if (prevMoveCount == m_Moves.size())
++ {
++ // Cannot perform full clear, have to move data in other blocks around
++ if (last != 0)
++ {
++ for (size_t i = last - 1; i; --i)
++ {
++ if (ReallocWithinBlock(vector, vector.GetBlock(i)))
++ return true;
++ }
++ }
++
++ if (prevMoveCount == m_Moves.size())
++ {
++ // No possible reallocs within blocks, try to move them around fast
++ return ComputeDefragmentation_Fast(vector);
++ }
++ }
++ else
++ {
++ switch (vectorState.operation)
++ {
++ case StateExtensive::Operation::FindFreeBlockBuffer:
++ vectorState.operation = StateExtensive::Operation::MoveBuffers;
++ break;
++ default:
++ VMA_ASSERT(0);
++ case StateExtensive::Operation::FindFreeBlockTexture:
++ vectorState.operation = StateExtensive::Operation::MoveTextures;
++ break;
++ case StateExtensive::Operation::FindFreeBlockAll:
++ vectorState.operation = StateExtensive::Operation::MoveAll;
++ break;
++ }
++ vectorState.firstFreeBlock = last;
++ // Nothing done, block found without reallocations, can perform another reallocs in same pass
++ return ComputeDefragmentation_Extensive(vector, index);
++ }
++ break;
++ }
++ case StateExtensive::Operation::MoveTextures:
++ {
++ if (MoveDataToFreeBlocks(VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL, vector,
++ vectorState.firstFreeBlock, texturePresent, bufferPresent, otherPresent))
++ {
++ if (texturePresent)
++ {
++ vectorState.operation = StateExtensive::Operation::FindFreeBlockTexture;
++ return ComputeDefragmentation_Extensive(vector, index);
++ }
++
++ if (!bufferPresent && !otherPresent)
++ {
++ vectorState.operation = StateExtensive::Operation::Cleanup;
++ break;
++ }
++
++ // No more textures to move, check buffers
++ vectorState.operation = StateExtensive::Operation::MoveBuffers;
++ bufferPresent = false;
++ otherPresent = false;
++ }
++ else
++ break;
++ }
++ case StateExtensive::Operation::MoveBuffers:
++ {
++ if (MoveDataToFreeBlocks(VMA_SUBALLOCATION_TYPE_BUFFER, vector,
++ vectorState.firstFreeBlock, texturePresent, bufferPresent, otherPresent))
++ {
++ if (bufferPresent)
++ {
++ vectorState.operation = StateExtensive::Operation::FindFreeBlockBuffer;
++ return ComputeDefragmentation_Extensive(vector, index);
++ }
++
++ if (!otherPresent)
++ {
++ vectorState.operation = StateExtensive::Operation::Cleanup;
++ break;
++ }
++
++ // No more buffers to move, check all others
++ vectorState.operation = StateExtensive::Operation::MoveAll;
++ otherPresent = false;
++ }
++ else
++ break;
++ }
++ case StateExtensive::Operation::MoveAll:
++ {
++ if (MoveDataToFreeBlocks(VMA_SUBALLOCATION_TYPE_FREE, vector,
++ vectorState.firstFreeBlock, texturePresent, bufferPresent, otherPresent))
++ {
++ if (otherPresent)
++ {
++ vectorState.operation = StateExtensive::Operation::FindFreeBlockBuffer;
++ return ComputeDefragmentation_Extensive(vector, index);
++ }
++ // Everything moved
++ vectorState.operation = StateExtensive::Operation::Cleanup;
++ }
++ break;
++ }
++ case StateExtensive::Operation::Cleanup:
++ // Cleanup is handled below so that other operations may reuse the cleanup code. This case is here to prevent the unhandled enum value warning (C4062).
++ break;
++ }
++
++ if (vectorState.operation == StateExtensive::Operation::Cleanup)
++ {
++ // All other work done, pack data in blocks even tighter if possible
++ const size_t prevMoveCount = m_Moves.size();
++ for (size_t i = 0; i < vector.GetBlockCount(); ++i)
++ {
++ if (ReallocWithinBlock(vector, vector.GetBlock(i)))
++ return true;
++ }
++
++ if (prevMoveCount == m_Moves.size())
++ vectorState.operation = StateExtensive::Operation::Done;
++ }
++ return false;
++}
++
++void VmaDefragmentationContext_T::UpdateVectorStatistics(VmaBlockVector& vector, StateBalanced& state)
++{
++ size_t allocCount = 0;
++ size_t freeCount = 0;
++ state.avgFreeSize = 0;
++ state.avgAllocSize = 0;
++
++ for (size_t i = 0; i < vector.GetBlockCount(); ++i)
++ {
++ VmaBlockMetadata* metadata = vector.GetBlock(i)->m_pMetadata;
++
++ allocCount += metadata->GetAllocationCount();
++ freeCount += metadata->GetFreeRegionsCount();
++ state.avgFreeSize += metadata->GetSumFreeSize();
++ state.avgAllocSize += metadata->GetSize();
++ }
++
++ state.avgAllocSize = (state.avgAllocSize - state.avgFreeSize) / allocCount;
++ state.avgFreeSize /= freeCount;
++}
++
++bool VmaDefragmentationContext_T::MoveDataToFreeBlocks(VmaSuballocationType currentType,
++ VmaBlockVector& vector, size_t firstFreeBlock,
++ bool& texturePresent, bool& bufferPresent, bool& otherPresent)
++{
++ const size_t prevMoveCount = m_Moves.size();
++ for (size_t i = firstFreeBlock ; i;)
++ {
++ VmaDeviceMemoryBlock* block = vector.GetBlock(--i);
++ VmaBlockMetadata* metadata = block->m_pMetadata;
++
++ for (VmaAllocHandle handle = metadata->GetAllocationListBegin();
++ handle != VK_NULL_HANDLE;
++ handle = metadata->GetNextAllocation(handle))
++ {
++ MoveAllocationData moveData = GetMoveData(handle, metadata);
++ // Ignore newly created allocations by defragmentation algorithm
++ if (moveData.move.srcAllocation->GetUserData() == this)
++ continue;
++ switch (CheckCounters(moveData.move.srcAllocation->GetSize()))
++ {
++ case CounterStatus::Ignore:
++ continue;
++ case CounterStatus::End:
++ return true;
++ default:
++ VMA_ASSERT(0);
++ case CounterStatus::Pass:
++ break;
++ }
++
++ // Move only single type of resources at once
++ if (!VmaIsBufferImageGranularityConflict(moveData.type, currentType))
++ {
++ // Try to fit allocation into free blocks
++ if (AllocInOtherBlock(firstFreeBlock, vector.GetBlockCount(), moveData, vector))
++ return false;
++ }
++
++ if (!VmaIsBufferImageGranularityConflict(moveData.type, VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL))
++ texturePresent = true;
++ else if (!VmaIsBufferImageGranularityConflict(moveData.type, VMA_SUBALLOCATION_TYPE_BUFFER))
++ bufferPresent = true;
++ else
++ otherPresent = true;
++ }
++ }
++ return prevMoveCount == m_Moves.size();
++}
++#endif // _VMA_DEFRAGMENTATION_CONTEXT_FUNCTIONS
++
++#ifndef _VMA_POOL_T_FUNCTIONS
++VmaPool_T::VmaPool_T(
++ VmaAllocator hAllocator,
++ const VmaPoolCreateInfo& createInfo,
++ VkDeviceSize preferredBlockSize)
++ : m_BlockVector(
++ hAllocator,
++ this, // hParentPool
++ createInfo.memoryTypeIndex,
++ createInfo.blockSize != 0 ? createInfo.blockSize : preferredBlockSize,
++ createInfo.minBlockCount,
++ createInfo.maxBlockCount,
++ (createInfo.flags& VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT) != 0 ? 1 : hAllocator->GetBufferImageGranularity(),
++ createInfo.blockSize != 0, // explicitBlockSize
++ createInfo.flags & VMA_POOL_CREATE_ALGORITHM_MASK, // algorithm
++ createInfo.priority,
++ VMA_MAX(hAllocator->GetMemoryTypeMinAlignment(createInfo.memoryTypeIndex), createInfo.minAllocationAlignment),
++ createInfo.pMemoryAllocateNext),
++ m_Id(0),
++ m_Name(VMA_NULL) {}
++
++VmaPool_T::~VmaPool_T()
++{
++ VMA_ASSERT(m_PrevPool == VMA_NULL && m_NextPool == VMA_NULL);
++}
++
++void VmaPool_T::SetName(const char* pName)
++{
++ const VkAllocationCallbacks* allocs = m_BlockVector.GetAllocator()->GetAllocationCallbacks();
++ VmaFreeString(allocs, m_Name);
++
++ if (pName != VMA_NULL)
++ {
++ m_Name = VmaCreateStringCopy(allocs, pName);
++ }
++ else
++ {
++ m_Name = VMA_NULL;
++ }
++}
++#endif // _VMA_POOL_T_FUNCTIONS
++
++#ifndef _VMA_ALLOCATOR_T_FUNCTIONS
++VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
++ m_UseMutex((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT) == 0),
++ m_VulkanApiVersion(pCreateInfo->vulkanApiVersion != 0 ? pCreateInfo->vulkanApiVersion : VK_API_VERSION_1_0),
++ m_UseKhrDedicatedAllocation((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT) != 0),
++ m_UseKhrBindMemory2((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT) != 0),
++ m_UseExtMemoryBudget((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT) != 0),
++ m_UseAmdDeviceCoherentMemory((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT) != 0),
++ m_UseKhrBufferDeviceAddress((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT) != 0),
++ m_UseExtMemoryPriority((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT) != 0),
++ m_hDevice(pCreateInfo->device),
++ m_hInstance(pCreateInfo->instance),
++ m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
++ m_AllocationCallbacks(pCreateInfo->pAllocationCallbacks ?
++ *pCreateInfo->pAllocationCallbacks : VmaEmptyAllocationCallbacks),
++ m_AllocationObjectAllocator(&m_AllocationCallbacks),
++ m_HeapSizeLimitMask(0),
++ m_DeviceMemoryCount(0),
++ m_PreferredLargeHeapBlockSize(0),
++ m_PhysicalDevice(pCreateInfo->physicalDevice),
++ m_GpuDefragmentationMemoryTypeBits(UINT32_MAX),
++ m_NextPoolId(0),
++ m_GlobalMemoryTypeBits(UINT32_MAX)
++{
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
++ {
++ m_UseKhrDedicatedAllocation = false;
++ m_UseKhrBindMemory2 = false;
++ }
++
++ if(VMA_DEBUG_DETECT_CORRUPTION)
++ {
++ // Needs to be multiply of uint32_t size because we are going to write VMA_CORRUPTION_DETECTION_MAGIC_VALUE to it.
++ VMA_ASSERT(VMA_DEBUG_MARGIN % sizeof(uint32_t) == 0);
++ }
++
++ VMA_ASSERT(pCreateInfo->physicalDevice && pCreateInfo->device && pCreateInfo->instance);
++
++ if(m_VulkanApiVersion < VK_MAKE_VERSION(1, 1, 0))
++ {
++#if !(VMA_DEDICATED_ALLOCATION)
++ if((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT) != 0)
++ {
++ VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT set but required extensions are disabled by preprocessor macros.");
++ }
++#endif
++#if !(VMA_BIND_MEMORY2)
++ if((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT) != 0)
++ {
++ VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT set but required extension is disabled by preprocessor macros.");
++ }
++#endif
++ }
++#if !(VMA_MEMORY_BUDGET)
++ if((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT) != 0)
++ {
++ VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT set but required extension is disabled by preprocessor macros.");
++ }
++#endif
++#if !(VMA_BUFFER_DEVICE_ADDRESS)
++ if(m_UseKhrBufferDeviceAddress)
++ {
++ VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT is set but required extension or Vulkan 1.2 is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
++ }
++#endif
++#if VMA_VULKAN_VERSION < 1002000
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 2, 0))
++ {
++ VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_2 but required Vulkan version is disabled by preprocessor macros.");
++ }
++#endif
++#if VMA_VULKAN_VERSION < 1001000
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
++ {
++ VMA_ASSERT(0 && "vulkanApiVersion >= VK_API_VERSION_1_1 but required Vulkan version is disabled by preprocessor macros.");
++ }
++#endif
++#if !(VMA_MEMORY_PRIORITY)
++ if(m_UseExtMemoryPriority)
++ {
++ VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
++ }
++#endif
++
++ memset(&m_DeviceMemoryCallbacks, 0 ,sizeof(m_DeviceMemoryCallbacks));
++ memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties));
++ memset(&m_MemProps, 0, sizeof(m_MemProps));
++
++ memset(&m_pBlockVectors, 0, sizeof(m_pBlockVectors));
++ memset(&m_VulkanFunctions, 0, sizeof(m_VulkanFunctions));
++
++#if VMA_EXTERNAL_MEMORY
++ memset(&m_TypeExternalMemoryHandleTypes, 0, sizeof(m_TypeExternalMemoryHandleTypes));
++#endif // #if VMA_EXTERNAL_MEMORY
++
++ if(pCreateInfo->pDeviceMemoryCallbacks != VMA_NULL)
++ {
++ m_DeviceMemoryCallbacks.pUserData = pCreateInfo->pDeviceMemoryCallbacks->pUserData;
++ m_DeviceMemoryCallbacks.pfnAllocate = pCreateInfo->pDeviceMemoryCallbacks->pfnAllocate;
++ m_DeviceMemoryCallbacks.pfnFree = pCreateInfo->pDeviceMemoryCallbacks->pfnFree;
++ }
++
++ ImportVulkanFunctions(pCreateInfo->pVulkanFunctions);
++
++ (*m_VulkanFunctions.vkGetPhysicalDeviceProperties)(m_PhysicalDevice, &m_PhysicalDeviceProperties);
++ (*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties)(m_PhysicalDevice, &m_MemProps);
++
++ VMA_ASSERT(VmaIsPow2(VMA_MIN_ALIGNMENT));
++ VMA_ASSERT(VmaIsPow2(VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY));
++ VMA_ASSERT(VmaIsPow2(m_PhysicalDeviceProperties.limits.bufferImageGranularity));
++ VMA_ASSERT(VmaIsPow2(m_PhysicalDeviceProperties.limits.nonCoherentAtomSize));
++
++ m_PreferredLargeHeapBlockSize = (pCreateInfo->preferredLargeHeapBlockSize != 0) ?
++ pCreateInfo->preferredLargeHeapBlockSize : static_cast<VkDeviceSize>(VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE);
++
++ m_GlobalMemoryTypeBits = CalculateGlobalMemoryTypeBits();
++
++#if VMA_EXTERNAL_MEMORY
++ if(pCreateInfo->pTypeExternalMemoryHandleTypes != VMA_NULL)
++ {
++ memcpy(m_TypeExternalMemoryHandleTypes, pCreateInfo->pTypeExternalMemoryHandleTypes,
++ sizeof(VkExternalMemoryHandleTypeFlagsKHR) * GetMemoryTypeCount());
++ }
++#endif // #if VMA_EXTERNAL_MEMORY
++
++ if(pCreateInfo->pHeapSizeLimit != VMA_NULL)
++ {
++ for(uint32_t heapIndex = 0; heapIndex < GetMemoryHeapCount(); ++heapIndex)
++ {
++ const VkDeviceSize limit = pCreateInfo->pHeapSizeLimit[heapIndex];
++ if(limit != VK_WHOLE_SIZE)
++ {
++ m_HeapSizeLimitMask |= 1u << heapIndex;
++ if(limit < m_MemProps.memoryHeaps[heapIndex].size)
++ {
++ m_MemProps.memoryHeaps[heapIndex].size = limit;
++ }
++ }
++ }
++ }
++
++ for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
++ {
++ // Create only supported types
++ if((m_GlobalMemoryTypeBits & (1u << memTypeIndex)) != 0)
++ {
++ const VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(memTypeIndex);
++ m_pBlockVectors[memTypeIndex] = vma_new(this, VmaBlockVector)(
++ this,
++ VK_NULL_HANDLE, // hParentPool
++ memTypeIndex,
++ preferredBlockSize,
++ 0,
++ SIZE_MAX,
++ GetBufferImageGranularity(),
++ false, // explicitBlockSize
++ 0, // algorithm
++ 0.5f, // priority (0.5 is the default per Vulkan spec)
++ GetMemoryTypeMinAlignment(memTypeIndex), // minAllocationAlignment
++ VMA_NULL); // // pMemoryAllocateNext
++ // No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here,
++ // becase minBlockCount is 0.
++ }
++ }
++}
++
++VkResult VmaAllocator_T::Init(const VmaAllocatorCreateInfo* pCreateInfo)
++{
++ VkResult res = VK_SUCCESS;
++
++#if VMA_MEMORY_BUDGET
++ if(m_UseExtMemoryBudget)
++ {
++ UpdateVulkanBudget();
++ }
++#endif // #if VMA_MEMORY_BUDGET
++
++ return res;
++}
++
++VmaAllocator_T::~VmaAllocator_T()
++{
++ VMA_ASSERT(m_Pools.IsEmpty());
++
++ for(size_t memTypeIndex = GetMemoryTypeCount(); memTypeIndex--; )
++ {
++ vma_delete(this, m_pBlockVectors[memTypeIndex]);
++ }
++}
++
++void VmaAllocator_T::ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunctions)
++{
++#if VMA_STATIC_VULKAN_FUNCTIONS == 1
++ ImportVulkanFunctions_Static();
++#endif
++
++ if(pVulkanFunctions != VMA_NULL)
++ {
++ ImportVulkanFunctions_Custom(pVulkanFunctions);
++ }
++
++#if VMA_DYNAMIC_VULKAN_FUNCTIONS == 1
++ ImportVulkanFunctions_Dynamic();
++#endif
++
++ ValidateVulkanFunctions();
++}
++
++#if VMA_STATIC_VULKAN_FUNCTIONS == 1
++
++void VmaAllocator_T::ImportVulkanFunctions_Static()
++{
++ // Vulkan 1.0
++ m_VulkanFunctions.vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)vkGetInstanceProcAddr;
++ m_VulkanFunctions.vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)vkGetDeviceProcAddr;
++ m_VulkanFunctions.vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)vkGetPhysicalDeviceProperties;
++ m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)vkGetPhysicalDeviceMemoryProperties;
++ m_VulkanFunctions.vkAllocateMemory = (PFN_vkAllocateMemory)vkAllocateMemory;
++ m_VulkanFunctions.vkFreeMemory = (PFN_vkFreeMemory)vkFreeMemory;
++ m_VulkanFunctions.vkMapMemory = (PFN_vkMapMemory)vkMapMemory;
++ m_VulkanFunctions.vkUnmapMemory = (PFN_vkUnmapMemory)vkUnmapMemory;
++ m_VulkanFunctions.vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)vkFlushMappedMemoryRanges;
++ m_VulkanFunctions.vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges)vkInvalidateMappedMemoryRanges;
++ m_VulkanFunctions.vkBindBufferMemory = (PFN_vkBindBufferMemory)vkBindBufferMemory;
++ m_VulkanFunctions.vkBindImageMemory = (PFN_vkBindImageMemory)vkBindImageMemory;
++ m_VulkanFunctions.vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)vkGetBufferMemoryRequirements;
++ m_VulkanFunctions.vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)vkGetImageMemoryRequirements;
++ m_VulkanFunctions.vkCreateBuffer = (PFN_vkCreateBuffer)vkCreateBuffer;
++ m_VulkanFunctions.vkDestroyBuffer = (PFN_vkDestroyBuffer)vkDestroyBuffer;
++ m_VulkanFunctions.vkCreateImage = (PFN_vkCreateImage)vkCreateImage;
++ m_VulkanFunctions.vkDestroyImage = (PFN_vkDestroyImage)vkDestroyImage;
++ m_VulkanFunctions.vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer)vkCmdCopyBuffer;
++
++ // Vulkan 1.1
++#if VMA_VULKAN_VERSION >= 1001000
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
++ {
++ m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR = (PFN_vkGetBufferMemoryRequirements2)vkGetBufferMemoryRequirements2;
++ m_VulkanFunctions.vkGetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2)vkGetImageMemoryRequirements2;
++ m_VulkanFunctions.vkBindBufferMemory2KHR = (PFN_vkBindBufferMemory2)vkBindBufferMemory2;
++ m_VulkanFunctions.vkBindImageMemory2KHR = (PFN_vkBindImageMemory2)vkBindImageMemory2;
++ m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2)vkGetPhysicalDeviceMemoryProperties2;
++ }
++#endif
++
++#if VMA_VULKAN_VERSION >= 1003000
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0))
++ {
++ m_VulkanFunctions.vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements)vkGetDeviceBufferMemoryRequirements;
++ m_VulkanFunctions.vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements)vkGetDeviceImageMemoryRequirements;
++ }
++#endif
++}
++
++#endif // VMA_STATIC_VULKAN_FUNCTIONS == 1
++
++void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVulkanFunctions)
++{
++ VMA_ASSERT(pVulkanFunctions != VMA_NULL);
++
++#define VMA_COPY_IF_NOT_NULL(funcName) \
++ if(pVulkanFunctions->funcName != VMA_NULL) m_VulkanFunctions.funcName = pVulkanFunctions->funcName;
++
++ VMA_COPY_IF_NOT_NULL(vkGetInstanceProcAddr);
++ VMA_COPY_IF_NOT_NULL(vkGetDeviceProcAddr);
++ VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceProperties);
++ VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties);
++ VMA_COPY_IF_NOT_NULL(vkAllocateMemory);
++ VMA_COPY_IF_NOT_NULL(vkFreeMemory);
++ VMA_COPY_IF_NOT_NULL(vkMapMemory);
++ VMA_COPY_IF_NOT_NULL(vkUnmapMemory);
++ VMA_COPY_IF_NOT_NULL(vkFlushMappedMemoryRanges);
++ VMA_COPY_IF_NOT_NULL(vkInvalidateMappedMemoryRanges);
++ VMA_COPY_IF_NOT_NULL(vkBindBufferMemory);
++ VMA_COPY_IF_NOT_NULL(vkBindImageMemory);
++ VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements);
++ VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements);
++ VMA_COPY_IF_NOT_NULL(vkCreateBuffer);
++ VMA_COPY_IF_NOT_NULL(vkDestroyBuffer);
++ VMA_COPY_IF_NOT_NULL(vkCreateImage);
++ VMA_COPY_IF_NOT_NULL(vkDestroyImage);
++ VMA_COPY_IF_NOT_NULL(vkCmdCopyBuffer);
++
++#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
++ VMA_COPY_IF_NOT_NULL(vkGetBufferMemoryRequirements2KHR);
++ VMA_COPY_IF_NOT_NULL(vkGetImageMemoryRequirements2KHR);
++#endif
++
++#if VMA_BIND_MEMORY2 || VMA_VULKAN_VERSION >= 1001000
++ VMA_COPY_IF_NOT_NULL(vkBindBufferMemory2KHR);
++ VMA_COPY_IF_NOT_NULL(vkBindImageMemory2KHR);
++#endif
++
++#if VMA_MEMORY_BUDGET
++ VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties2KHR);
++#endif
++
++#if VMA_VULKAN_VERSION >= 1003000
++ VMA_COPY_IF_NOT_NULL(vkGetDeviceBufferMemoryRequirements);
++ VMA_COPY_IF_NOT_NULL(vkGetDeviceImageMemoryRequirements);
++#endif
++
++#undef VMA_COPY_IF_NOT_NULL
++}
++
++#if VMA_DYNAMIC_VULKAN_FUNCTIONS == 1
++
++void VmaAllocator_T::ImportVulkanFunctions_Dynamic()
++{
++ VMA_ASSERT(m_VulkanFunctions.vkGetInstanceProcAddr && m_VulkanFunctions.vkGetDeviceProcAddr &&
++ "To use VMA_DYNAMIC_VULKAN_FUNCTIONS in new versions of VMA you now have to pass "
++ "VmaVulkanFunctions::vkGetInstanceProcAddr and vkGetDeviceProcAddr as VmaAllocatorCreateInfo::pVulkanFunctions. "
++ "Other members can be null.");
++
++#define VMA_FETCH_INSTANCE_FUNC(memberName, functionPointerType, functionNameString) \
++ if(m_VulkanFunctions.memberName == VMA_NULL) \
++ m_VulkanFunctions.memberName = \
++ (functionPointerType)m_VulkanFunctions.vkGetInstanceProcAddr(m_hInstance, functionNameString);
++#define VMA_FETCH_DEVICE_FUNC(memberName, functionPointerType, functionNameString) \
++ if(m_VulkanFunctions.memberName == VMA_NULL) \
++ m_VulkanFunctions.memberName = \
++ (functionPointerType)m_VulkanFunctions.vkGetDeviceProcAddr(m_hDevice, functionNameString);
++
++ VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceProperties, PFN_vkGetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties");
++ VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties, PFN_vkGetPhysicalDeviceMemoryProperties, "vkGetPhysicalDeviceMemoryProperties");
++ VMA_FETCH_DEVICE_FUNC(vkAllocateMemory, PFN_vkAllocateMemory, "vkAllocateMemory");
++ VMA_FETCH_DEVICE_FUNC(vkFreeMemory, PFN_vkFreeMemory, "vkFreeMemory");
++ VMA_FETCH_DEVICE_FUNC(vkMapMemory, PFN_vkMapMemory, "vkMapMemory");
++ VMA_FETCH_DEVICE_FUNC(vkUnmapMemory, PFN_vkUnmapMemory, "vkUnmapMemory");
++ VMA_FETCH_DEVICE_FUNC(vkFlushMappedMemoryRanges, PFN_vkFlushMappedMemoryRanges, "vkFlushMappedMemoryRanges");
++ VMA_FETCH_DEVICE_FUNC(vkInvalidateMappedMemoryRanges, PFN_vkInvalidateMappedMemoryRanges, "vkInvalidateMappedMemoryRanges");
++ VMA_FETCH_DEVICE_FUNC(vkBindBufferMemory, PFN_vkBindBufferMemory, "vkBindBufferMemory");
++ VMA_FETCH_DEVICE_FUNC(vkBindImageMemory, PFN_vkBindImageMemory, "vkBindImageMemory");
++ VMA_FETCH_DEVICE_FUNC(vkGetBufferMemoryRequirements, PFN_vkGetBufferMemoryRequirements, "vkGetBufferMemoryRequirements");
++ VMA_FETCH_DEVICE_FUNC(vkGetImageMemoryRequirements, PFN_vkGetImageMemoryRequirements, "vkGetImageMemoryRequirements");
++ VMA_FETCH_DEVICE_FUNC(vkCreateBuffer, PFN_vkCreateBuffer, "vkCreateBuffer");
++ VMA_FETCH_DEVICE_FUNC(vkDestroyBuffer, PFN_vkDestroyBuffer, "vkDestroyBuffer");
++ VMA_FETCH_DEVICE_FUNC(vkCreateImage, PFN_vkCreateImage, "vkCreateImage");
++ VMA_FETCH_DEVICE_FUNC(vkDestroyImage, PFN_vkDestroyImage, "vkDestroyImage");
++ VMA_FETCH_DEVICE_FUNC(vkCmdCopyBuffer, PFN_vkCmdCopyBuffer, "vkCmdCopyBuffer");
++
++#if VMA_VULKAN_VERSION >= 1001000
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
++ {
++ VMA_FETCH_DEVICE_FUNC(vkGetBufferMemoryRequirements2KHR, PFN_vkGetBufferMemoryRequirements2, "vkGetBufferMemoryRequirements2");
++ VMA_FETCH_DEVICE_FUNC(vkGetImageMemoryRequirements2KHR, PFN_vkGetImageMemoryRequirements2, "vkGetImageMemoryRequirements2");
++ VMA_FETCH_DEVICE_FUNC(vkBindBufferMemory2KHR, PFN_vkBindBufferMemory2, "vkBindBufferMemory2");
++ VMA_FETCH_DEVICE_FUNC(vkBindImageMemory2KHR, PFN_vkBindImageMemory2, "vkBindImageMemory2");
++ VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2, "vkGetPhysicalDeviceMemoryProperties2");
++ }
++#endif
++
++#if VMA_DEDICATED_ALLOCATION
++ if(m_UseKhrDedicatedAllocation)
++ {
++ VMA_FETCH_DEVICE_FUNC(vkGetBufferMemoryRequirements2KHR, PFN_vkGetBufferMemoryRequirements2KHR, "vkGetBufferMemoryRequirements2KHR");
++ VMA_FETCH_DEVICE_FUNC(vkGetImageMemoryRequirements2KHR, PFN_vkGetImageMemoryRequirements2KHR, "vkGetImageMemoryRequirements2KHR");
++ }
++#endif
++
++#if VMA_BIND_MEMORY2
++ if(m_UseKhrBindMemory2)
++ {
++ VMA_FETCH_DEVICE_FUNC(vkBindBufferMemory2KHR, PFN_vkBindBufferMemory2KHR, "vkBindBufferMemory2KHR");
++ VMA_FETCH_DEVICE_FUNC(vkBindImageMemory2KHR, PFN_vkBindImageMemory2KHR, "vkBindImageMemory2KHR");
++ }
++#endif // #if VMA_BIND_MEMORY2
++
++#if VMA_MEMORY_BUDGET
++ if(m_UseExtMemoryBudget)
++ {
++ VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2KHR");
++ }
++#endif // #if VMA_MEMORY_BUDGET
++
++#if VMA_VULKAN_VERSION >= 1003000
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0))
++ {
++ VMA_FETCH_DEVICE_FUNC(vkGetDeviceBufferMemoryRequirements, PFN_vkGetDeviceBufferMemoryRequirements, "vkGetDeviceBufferMemoryRequirements");
++ VMA_FETCH_DEVICE_FUNC(vkGetDeviceImageMemoryRequirements, PFN_vkGetDeviceImageMemoryRequirements, "vkGetDeviceImageMemoryRequirements");
++ }
++#endif
++
++#undef VMA_FETCH_DEVICE_FUNC
++#undef VMA_FETCH_INSTANCE_FUNC
++}
++
++#endif // VMA_DYNAMIC_VULKAN_FUNCTIONS == 1
++
++void VmaAllocator_T::ValidateVulkanFunctions()
++{
++ VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceProperties != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkAllocateMemory != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkFreeMemory != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkMapMemory != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkUnmapMemory != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkFlushMappedMemoryRanges != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkInvalidateMappedMemoryRanges != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkBindBufferMemory != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkBindImageMemory != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkGetImageMemoryRequirements != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkCreateBuffer != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkDestroyBuffer != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkCreateImage != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkDestroyImage != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkCmdCopyBuffer != VMA_NULL);
++
++#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0) || m_UseKhrDedicatedAllocation)
++ {
++ VMA_ASSERT(m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkGetImageMemoryRequirements2KHR != VMA_NULL);
++ }
++#endif
++
++#if VMA_BIND_MEMORY2 || VMA_VULKAN_VERSION >= 1001000
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0) || m_UseKhrBindMemory2)
++ {
++ VMA_ASSERT(m_VulkanFunctions.vkBindBufferMemory2KHR != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkBindImageMemory2KHR != VMA_NULL);
++ }
++#endif
++
++#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000
++ if(m_UseExtMemoryBudget || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
++ {
++ VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR != VMA_NULL);
++ }
++#endif
++
++#if VMA_VULKAN_VERSION >= 1003000
++ if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0))
++ {
++ VMA_ASSERT(m_VulkanFunctions.vkGetDeviceBufferMemoryRequirements != VMA_NULL);
++ VMA_ASSERT(m_VulkanFunctions.vkGetDeviceImageMemoryRequirements != VMA_NULL);
++ }
++#endif
++}
++
++VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex)
++{
++ const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex);
++ const VkDeviceSize heapSize = m_MemProps.memoryHeaps[heapIndex].size;
++ const bool isSmallHeap = heapSize <= VMA_SMALL_HEAP_MAX_SIZE;
++ return VmaAlignUp(isSmallHeap ? (heapSize / 8) : m_PreferredLargeHeapBlockSize, (VkDeviceSize)32);
++}
++
++VkResult VmaAllocator_T::AllocateMemoryOfType(
++ VmaPool pool,
++ VkDeviceSize size,
++ VkDeviceSize alignment,
++ bool dedicatedPreferred,
++ VkBuffer dedicatedBuffer,
++ VkImage dedicatedImage,
++ VkFlags dedicatedBufferImageUsage,
++ const VmaAllocationCreateInfo& createInfo,
++ uint32_t memTypeIndex,
++ VmaSuballocationType suballocType,
++ VmaDedicatedAllocationList& dedicatedAllocations,
++ VmaBlockVector& blockVector,
++ size_t allocationCount,
++ VmaAllocation* pAllocations)
++{
++ VMA_ASSERT(pAllocations != VMA_NULL);
++ VMA_DEBUG_LOG(" AllocateMemory: MemoryTypeIndex=%u, AllocationCount=%zu, Size=%llu", memTypeIndex, allocationCount, size);
++
++ VmaAllocationCreateInfo finalCreateInfo = createInfo;
++ VkResult res = CalcMemTypeParams(
++ finalCreateInfo,
++ memTypeIndex,
++ size,
++ allocationCount);
++ if(res != VK_SUCCESS)
++ return res;
++
++ if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0)
++ {
++ return AllocateDedicatedMemory(
++ pool,
++ size,
++ suballocType,
++ dedicatedAllocations,
++ memTypeIndex,
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0,
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0,
++ (finalCreateInfo.flags &
++ (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0,
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT) != 0,
++ finalCreateInfo.pUserData,
++ finalCreateInfo.priority,
++ dedicatedBuffer,
++ dedicatedImage,
++ dedicatedBufferImageUsage,
++ allocationCount,
++ pAllocations,
++ blockVector.GetAllocationNextPtr());
++ }
++ else
++ {
++ const bool canAllocateDedicated =
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0 &&
++ (pool == VK_NULL_HANDLE || !blockVector.HasExplicitBlockSize());
++
++ if(canAllocateDedicated)
++ {
++ // Heuristics: Allocate dedicated memory if requested size if greater than half of preferred block size.
++ if(size > blockVector.GetPreferredBlockSize() / 2)
++ {
++ dedicatedPreferred = true;
++ }
++ // Protection against creating each allocation as dedicated when we reach or exceed heap size/budget,
++ // which can quickly deplete maxMemoryAllocationCount: Don't prefer dedicated allocations when above
++ // 3/4 of the maximum allocation count.
++ if(m_DeviceMemoryCount.load() > m_PhysicalDeviceProperties.limits.maxMemoryAllocationCount * 3 / 4)
++ {
++ dedicatedPreferred = false;
++ }
++
++ if(dedicatedPreferred)
++ {
++ res = AllocateDedicatedMemory(
++ pool,
++ size,
++ suballocType,
++ dedicatedAllocations,
++ memTypeIndex,
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0,
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0,
++ (finalCreateInfo.flags &
++ (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0,
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT) != 0,
++ finalCreateInfo.pUserData,
++ finalCreateInfo.priority,
++ dedicatedBuffer,
++ dedicatedImage,
++ dedicatedBufferImageUsage,
++ allocationCount,
++ pAllocations,
++ blockVector.GetAllocationNextPtr());
++ if(res == VK_SUCCESS)
++ {
++ // Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here.
++ VMA_DEBUG_LOG(" Allocated as DedicatedMemory");
++ return VK_SUCCESS;
++ }
++ }
++ }
++
++ res = blockVector.Allocate(
++ size,
++ alignment,
++ finalCreateInfo,
++ suballocType,
++ allocationCount,
++ pAllocations);
++ if(res == VK_SUCCESS)
++ return VK_SUCCESS;
++
++ // Try dedicated memory.
++ if(canAllocateDedicated && !dedicatedPreferred)
++ {
++ res = AllocateDedicatedMemory(
++ pool,
++ size,
++ suballocType,
++ dedicatedAllocations,
++ memTypeIndex,
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0,
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0,
++ (finalCreateInfo.flags &
++ (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0,
++ (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT) != 0,
++ finalCreateInfo.pUserData,
++ finalCreateInfo.priority,
++ dedicatedBuffer,
++ dedicatedImage,
++ dedicatedBufferImageUsage,
++ allocationCount,
++ pAllocations,
++ blockVector.GetAllocationNextPtr());
++ if(res == VK_SUCCESS)
++ {
++ // Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here.
++ VMA_DEBUG_LOG(" Allocated as DedicatedMemory");
++ return VK_SUCCESS;
++ }
++ }
++ // Everything failed: Return error code.
++ VMA_DEBUG_LOG(" vkAllocateMemory FAILED");
++ return res;
++ }
++}
++
++VkResult VmaAllocator_T::AllocateDedicatedMemory(
++ VmaPool pool,
++ VkDeviceSize size,
++ VmaSuballocationType suballocType,
++ VmaDedicatedAllocationList& dedicatedAllocations,
++ uint32_t memTypeIndex,
++ bool map,
++ bool isUserDataString,
++ bool isMappingAllowed,
++ bool canAliasMemory,
++ void* pUserData,
++ float priority,
++ VkBuffer dedicatedBuffer,
++ VkImage dedicatedImage,
++ VkFlags dedicatedBufferImageUsage,
++ size_t allocationCount,
++ VmaAllocation* pAllocations,
++ const void* pNextChain)
++{
++ VMA_ASSERT(allocationCount > 0 && pAllocations);
++
++ VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
++ allocInfo.memoryTypeIndex = memTypeIndex;
++ allocInfo.allocationSize = size;
++ allocInfo.pNext = pNextChain;
++
++#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
++ VkMemoryDedicatedAllocateInfoKHR dedicatedAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR };
++ if(!canAliasMemory)
++ {
++ if(m_UseKhrDedicatedAllocation || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
++ {
++ if(dedicatedBuffer != VK_NULL_HANDLE)
++ {
++ VMA_ASSERT(dedicatedImage == VK_NULL_HANDLE);
++ dedicatedAllocInfo.buffer = dedicatedBuffer;
++ VmaPnextChainPushFront(&allocInfo, &dedicatedAllocInfo);
++ }
++ else if(dedicatedImage != VK_NULL_HANDLE)
++ {
++ dedicatedAllocInfo.image = dedicatedImage;
++ VmaPnextChainPushFront(&allocInfo, &dedicatedAllocInfo);
++ }
++ }
++ }
++#endif // #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
++
++#if VMA_BUFFER_DEVICE_ADDRESS
++ VkMemoryAllocateFlagsInfoKHR allocFlagsInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR };
++ if(m_UseKhrBufferDeviceAddress)
++ {
++ bool canContainBufferWithDeviceAddress = true;
++ if(dedicatedBuffer != VK_NULL_HANDLE)
++ {
++ canContainBufferWithDeviceAddress = dedicatedBufferImageUsage == UINT32_MAX || // Usage flags unknown
++ (dedicatedBufferImageUsage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT) != 0;
++ }
++ else if(dedicatedImage != VK_NULL_HANDLE)
++ {
++ canContainBufferWithDeviceAddress = false;
++ }
++ if(canContainBufferWithDeviceAddress)
++ {
++ allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
++ VmaPnextChainPushFront(&allocInfo, &allocFlagsInfo);
++ }
++ }
++#endif // #if VMA_BUFFER_DEVICE_ADDRESS
++
++#if VMA_MEMORY_PRIORITY
++ VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT };
++ if(m_UseExtMemoryPriority)
++ {
++ VMA_ASSERT(priority >= 0.f && priority <= 1.f);
++ priorityInfo.priority = priority;
++ VmaPnextChainPushFront(&allocInfo, &priorityInfo);
++ }
++#endif // #if VMA_MEMORY_PRIORITY
++
++#if VMA_EXTERNAL_MEMORY
++ // Attach VkExportMemoryAllocateInfoKHR if necessary.
++ VkExportMemoryAllocateInfoKHR exportMemoryAllocInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR };
++ exportMemoryAllocInfo.handleTypes = GetExternalMemoryHandleTypeFlags(memTypeIndex);
++ if(exportMemoryAllocInfo.handleTypes != 0)
++ {
++ VmaPnextChainPushFront(&allocInfo, &exportMemoryAllocInfo);
++ }
++#endif // #if VMA_EXTERNAL_MEMORY
++
++ size_t allocIndex;
++ VkResult res = VK_SUCCESS;
++ for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
++ {
++ res = AllocateDedicatedMemoryPage(
++ pool,
++ size,
++ suballocType,
++ memTypeIndex,
++ allocInfo,
++ map,
++ isUserDataString,
++ isMappingAllowed,
++ pUserData,
++ pAllocations + allocIndex);
++ if(res != VK_SUCCESS)
++ {
++ break;
++ }
++ }
++
++ if(res == VK_SUCCESS)
++ {
++ for (allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
++ {
++ dedicatedAllocations.Register(pAllocations[allocIndex]);
++ }
++ VMA_DEBUG_LOG(" Allocated DedicatedMemory Count=%zu, MemoryTypeIndex=#%u", allocationCount, memTypeIndex);
++ }
++ else
++ {
++ // Free all already created allocations.
++ while(allocIndex--)
++ {
++ VmaAllocation currAlloc = pAllocations[allocIndex];
++ VkDeviceMemory hMemory = currAlloc->GetMemory();
++
++ /*
++ There is no need to call this, because Vulkan spec allows to skip vkUnmapMemory
++ before vkFreeMemory.
++
++ if(currAlloc->GetMappedData() != VMA_NULL)
++ {
++ (*m_VulkanFunctions.vkUnmapMemory)(m_hDevice, hMemory);
++ }
++ */
++
++ FreeVulkanMemory(memTypeIndex, currAlloc->GetSize(), hMemory);
++ m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(memTypeIndex), currAlloc->GetSize());
++ m_AllocationObjectAllocator.Free(currAlloc);
++ }
++
++ memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
++ }
++
++ return res;
++}
++
++VkResult VmaAllocator_T::AllocateDedicatedMemoryPage(
++ VmaPool pool,
++ VkDeviceSize size,
++ VmaSuballocationType suballocType,
++ uint32_t memTypeIndex,
++ const VkMemoryAllocateInfo& allocInfo,
++ bool map,
++ bool isUserDataString,
++ bool isMappingAllowed,
++ void* pUserData,
++ VmaAllocation* pAllocation)
++{
++ VkDeviceMemory hMemory = VK_NULL_HANDLE;
++ VkResult res = AllocateVulkanMemory(&allocInfo, &hMemory);
++ if(res < 0)
++ {
++ VMA_DEBUG_LOG(" vkAllocateMemory FAILED");
++ return res;
++ }
++
++ void* pMappedData = VMA_NULL;
++ if(map)
++ {
++ res = (*m_VulkanFunctions.vkMapMemory)(
++ m_hDevice,
++ hMemory,
++ 0,
++ VK_WHOLE_SIZE,
++ 0,
++ &pMappedData);
++ if(res < 0)
++ {
++ VMA_DEBUG_LOG(" vkMapMemory FAILED");
++ FreeVulkanMemory(memTypeIndex, size, hMemory);
++ return res;
++ }
++ }
++
++ *pAllocation = m_AllocationObjectAllocator.Allocate(isMappingAllowed);
++ (*pAllocation)->InitDedicatedAllocation(pool, memTypeIndex, hMemory, suballocType, pMappedData, size);
++ if (isUserDataString)
++ (*pAllocation)->SetName(this, (const char*)pUserData);
++ else
++ (*pAllocation)->SetUserData(this, pUserData);
++ m_Budget.AddAllocation(MemoryTypeIndexToHeapIndex(memTypeIndex), size);
++ if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)
++ {
++ FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
++ }
++
++ return VK_SUCCESS;
++}
++
++void VmaAllocator_T::GetBufferMemoryRequirements(
++ VkBuffer hBuffer,
++ VkMemoryRequirements& memReq,
++ bool& requiresDedicatedAllocation,
++ bool& prefersDedicatedAllocation) const
++{
++#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
++ if(m_UseKhrDedicatedAllocation || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
++ {
++ VkBufferMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR };
++ memReqInfo.buffer = hBuffer;
++
++ VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR };
++
++ VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR };
++ VmaPnextChainPushFront(&memReq2, &memDedicatedReq);
++
++ (*m_VulkanFunctions.vkGetBufferMemoryRequirements2KHR)(m_hDevice, &memReqInfo, &memReq2);
++
++ memReq = memReq2.memoryRequirements;
++ requiresDedicatedAllocation = (memDedicatedReq.requiresDedicatedAllocation != VK_FALSE);
++ prefersDedicatedAllocation = (memDedicatedReq.prefersDedicatedAllocation != VK_FALSE);
++ }
++ else
++#endif // #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
++ {
++ (*m_VulkanFunctions.vkGetBufferMemoryRequirements)(m_hDevice, hBuffer, &memReq);
++ requiresDedicatedAllocation = false;
++ prefersDedicatedAllocation = false;
++ }
++}
++
++void VmaAllocator_T::GetImageMemoryRequirements(
++ VkImage hImage,
++ VkMemoryRequirements& memReq,
++ bool& requiresDedicatedAllocation,
++ bool& prefersDedicatedAllocation) const
++{
++#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
++ if(m_UseKhrDedicatedAllocation || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
++ {
++ VkImageMemoryRequirementsInfo2KHR memReqInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR };
++ memReqInfo.image = hImage;
++
++ VkMemoryDedicatedRequirementsKHR memDedicatedReq = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR };
++
++ VkMemoryRequirements2KHR memReq2 = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR };
++ VmaPnextChainPushFront(&memReq2, &memDedicatedReq);
++
++ (*m_VulkanFunctions.vkGetImageMemoryRequirements2KHR)(m_hDevice, &memReqInfo, &memReq2);
++
++ memReq = memReq2.memoryRequirements;
++ requiresDedicatedAllocation = (memDedicatedReq.requiresDedicatedAllocation != VK_FALSE);
++ prefersDedicatedAllocation = (memDedicatedReq.prefersDedicatedAllocation != VK_FALSE);
++ }
++ else
++#endif // #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
++ {
++ (*m_VulkanFunctions.vkGetImageMemoryRequirements)(m_hDevice, hImage, &memReq);
++ requiresDedicatedAllocation = false;
++ prefersDedicatedAllocation = false;
++ }
++}
++
++VkResult VmaAllocator_T::FindMemoryTypeIndex(
++ uint32_t memoryTypeBits,
++ const VmaAllocationCreateInfo* pAllocationCreateInfo,
++ VkFlags bufImgUsage,
++ uint32_t* pMemoryTypeIndex) const
++{
++ memoryTypeBits &= GetGlobalMemoryTypeBits();
++
++ if(pAllocationCreateInfo->memoryTypeBits != 0)
++ {
++ memoryTypeBits &= pAllocationCreateInfo->memoryTypeBits;
++ }
++
++ VkMemoryPropertyFlags requiredFlags = 0, preferredFlags = 0, notPreferredFlags = 0;
++ if(!FindMemoryPreferences(
++ IsIntegratedGpu(),
++ *pAllocationCreateInfo,
++ bufImgUsage,
++ requiredFlags, preferredFlags, notPreferredFlags))
++ {
++ return VK_ERROR_FEATURE_NOT_PRESENT;
++ }
++
++ *pMemoryTypeIndex = UINT32_MAX;
++ uint32_t minCost = UINT32_MAX;
++ for(uint32_t memTypeIndex = 0, memTypeBit = 1;
++ memTypeIndex < GetMemoryTypeCount();
++ ++memTypeIndex, memTypeBit <<= 1)
++ {
++ // This memory type is acceptable according to memoryTypeBits bitmask.
++ if((memTypeBit & memoryTypeBits) != 0)
++ {
++ const VkMemoryPropertyFlags currFlags =
++ m_MemProps.memoryTypes[memTypeIndex].propertyFlags;
++ // This memory type contains requiredFlags.
++ if((requiredFlags & ~currFlags) == 0)
++ {
++ // Calculate cost as number of bits from preferredFlags not present in this memory type.
++ uint32_t currCost = VMA_COUNT_BITS_SET(preferredFlags & ~currFlags) +
++ VMA_COUNT_BITS_SET(currFlags & notPreferredFlags);
++ // Remember memory type with lowest cost.
++ if(currCost < minCost)
++ {
++ *pMemoryTypeIndex = memTypeIndex;
++ if(currCost == 0)
++ {
++ return VK_SUCCESS;
++ }
++ minCost = currCost;
++ }
++ }
++ }
++ }
++ return (*pMemoryTypeIndex != UINT32_MAX) ? VK_SUCCESS : VK_ERROR_FEATURE_NOT_PRESENT;
++}
++
++VkResult VmaAllocator_T::CalcMemTypeParams(
++ VmaAllocationCreateInfo& inoutCreateInfo,
++ uint32_t memTypeIndex,
++ VkDeviceSize size,
++ size_t allocationCount)
++{
++ // If memory type is not HOST_VISIBLE, disable MAPPED.
++ if((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0 &&
++ (m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)
++ {
++ inoutCreateInfo.flags &= ~VMA_ALLOCATION_CREATE_MAPPED_BIT;
++ }
++
++ if((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0 &&
++ (inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT) != 0)
++ {
++ const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex);
++ VmaBudget heapBudget = {};
++ GetHeapBudgets(&heapBudget, heapIndex, 1);
++ if(heapBudget.usage + size * allocationCount > heapBudget.budget)
++ {
++ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
++ }
++ }
++ return VK_SUCCESS;
++}
++
++VkResult VmaAllocator_T::CalcAllocationParams(
++ VmaAllocationCreateInfo& inoutCreateInfo,
++ bool dedicatedRequired,
++ bool dedicatedPreferred)
++{
++ VMA_ASSERT((inoutCreateInfo.flags &
++ (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) !=
++ (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) &&
++ "Specifying both flags VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT and VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT is incorrect.");
++ VMA_ASSERT((((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT) == 0 ||
++ (inoutCreateInfo.flags & (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0)) &&
++ "Specifying VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT requires also VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT.");
++ if(inoutCreateInfo.usage == VMA_MEMORY_USAGE_AUTO || inoutCreateInfo.usage == VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE || inoutCreateInfo.usage == VMA_MEMORY_USAGE_AUTO_PREFER_HOST)
++ {
++ if((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0)
++ {
++ VMA_ASSERT((inoutCreateInfo.flags & (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0 &&
++ "When using VMA_ALLOCATION_CREATE_MAPPED_BIT and usage = VMA_MEMORY_USAGE_AUTO*, you must also specify VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT.");
++ }
++ }
++
++ // If memory is lazily allocated, it should be always dedicated.
++ if(dedicatedRequired ||
++ inoutCreateInfo.usage == VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED)
++ {
++ inoutCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
++ }
++
++ if(inoutCreateInfo.pool != VK_NULL_HANDLE)
++ {
++ if(inoutCreateInfo.pool->m_BlockVector.HasExplicitBlockSize() &&
++ (inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0)
++ {
++ VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT while current custom pool doesn't support dedicated allocations.");
++ return VK_ERROR_FEATURE_NOT_PRESENT;
++ }
++ inoutCreateInfo.priority = inoutCreateInfo.pool->m_BlockVector.GetPriority();
++ }
++
++ if((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0 &&
++ (inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0)
++ {
++ VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT together with VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT makes no sense.");
++ return VK_ERROR_FEATURE_NOT_PRESENT;
++ }
++
++ if(VMA_DEBUG_ALWAYS_DEDICATED_MEMORY &&
++ (inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0)
++ {
++ inoutCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
++ }
++
++ // Non-auto USAGE values imply HOST_ACCESS flags.
++ // And so does VMA_MEMORY_USAGE_UNKNOWN because it is used with custom pools.
++ // Which specific flag is used doesn't matter. They change things only when used with VMA_MEMORY_USAGE_AUTO*.
++ // Otherwise they just protect from assert on mapping.
++ if(inoutCreateInfo.usage != VMA_MEMORY_USAGE_AUTO &&
++ inoutCreateInfo.usage != VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE &&
++ inoutCreateInfo.usage != VMA_MEMORY_USAGE_AUTO_PREFER_HOST)
++ {
++ if((inoutCreateInfo.flags & (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) == 0)
++ {
++ inoutCreateInfo.flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
++ }
++ }
++
++ return VK_SUCCESS;
++}
++
++VkResult VmaAllocator_T::AllocateMemory(
++ const VkMemoryRequirements& vkMemReq,
++ bool requiresDedicatedAllocation,
++ bool prefersDedicatedAllocation,
++ VkBuffer dedicatedBuffer,
++ VkImage dedicatedImage,
++ VkFlags dedicatedBufferImageUsage,
++ const VmaAllocationCreateInfo& createInfo,
++ VmaSuballocationType suballocType,
++ size_t allocationCount,
++ VmaAllocation* pAllocations)
++{
++ memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
++
++ VMA_ASSERT(VmaIsPow2(vkMemReq.alignment));
++
++ if(vkMemReq.size == 0)
++ {
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++
++ VmaAllocationCreateInfo createInfoFinal = createInfo;
++ VkResult res = CalcAllocationParams(createInfoFinal, requiresDedicatedAllocation, prefersDedicatedAllocation);
++ if(res != VK_SUCCESS)
++ return res;
++
++ if(createInfoFinal.pool != VK_NULL_HANDLE)
++ {
++ VmaBlockVector& blockVector = createInfoFinal.pool->m_BlockVector;
++ return AllocateMemoryOfType(
++ createInfoFinal.pool,
++ vkMemReq.size,
++ vkMemReq.alignment,
++ prefersDedicatedAllocation,
++ dedicatedBuffer,
++ dedicatedImage,
++ dedicatedBufferImageUsage,
++ createInfoFinal,
++ blockVector.GetMemoryTypeIndex(),
++ suballocType,
++ createInfoFinal.pool->m_DedicatedAllocations,
++ blockVector,
++ allocationCount,
++ pAllocations);
++ }
++ else
++ {
++ // Bit mask of memory Vulkan types acceptable for this allocation.
++ uint32_t memoryTypeBits = vkMemReq.memoryTypeBits;
++ uint32_t memTypeIndex = UINT32_MAX;
++ res = FindMemoryTypeIndex(memoryTypeBits, &createInfoFinal, dedicatedBufferImageUsage, &memTypeIndex);
++ // Can't find any single memory type matching requirements. res is VK_ERROR_FEATURE_NOT_PRESENT.
++ if(res != VK_SUCCESS)
++ return res;
++ do
++ {
++ VmaBlockVector* blockVector = m_pBlockVectors[memTypeIndex];
++ VMA_ASSERT(blockVector && "Trying to use unsupported memory type!");
++ res = AllocateMemoryOfType(
++ VK_NULL_HANDLE,
++ vkMemReq.size,
++ vkMemReq.alignment,
++ requiresDedicatedAllocation || prefersDedicatedAllocation,
++ dedicatedBuffer,
++ dedicatedImage,
++ dedicatedBufferImageUsage,
++ createInfoFinal,
++ memTypeIndex,
++ suballocType,
++ m_DedicatedAllocations[memTypeIndex],
++ *blockVector,
++ allocationCount,
++ pAllocations);
++ // Allocation succeeded
++ if(res == VK_SUCCESS)
++ return VK_SUCCESS;
++
++ // Remove old memTypeIndex from list of possibilities.
++ memoryTypeBits &= ~(1u << memTypeIndex);
++ // Find alternative memTypeIndex.
++ res = FindMemoryTypeIndex(memoryTypeBits, &createInfoFinal, dedicatedBufferImageUsage, &memTypeIndex);
++ } while(res == VK_SUCCESS);
++
++ // No other matching memory type index could be found.
++ // Not returning res, which is VK_ERROR_FEATURE_NOT_PRESENT, because we already failed to allocate once.
++ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
++ }
++}
++
++void VmaAllocator_T::FreeMemory(
++ size_t allocationCount,
++ const VmaAllocation* pAllocations)
++{
++ VMA_ASSERT(pAllocations);
++
++ for(size_t allocIndex = allocationCount; allocIndex--; )
++ {
++ VmaAllocation allocation = pAllocations[allocIndex];
++
++ if(allocation != VK_NULL_HANDLE)
++ {
++ if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)
++ {
++ FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
++ }
++
++ allocation->FreeName(this);
++
++ switch(allocation->GetType())
++ {
++ case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
++ {
++ VmaBlockVector* pBlockVector = VMA_NULL;
++ VmaPool hPool = allocation->GetParentPool();
++ if(hPool != VK_NULL_HANDLE)
++ {
++ pBlockVector = &hPool->m_BlockVector;
++ }
++ else
++ {
++ const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
++ pBlockVector = m_pBlockVectors[memTypeIndex];
++ VMA_ASSERT(pBlockVector && "Trying to free memory of unsupported type!");
++ }
++ pBlockVector->Free(allocation);
++ }
++ break;
++ case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
++ FreeDedicatedMemory(allocation);
++ break;
++ default:
++ VMA_ASSERT(0);
++ }
++ }
++ }
++}
++
++void VmaAllocator_T::CalculateStatistics(VmaTotalStatistics* pStats)
++{
++ // Initialize.
++ VmaClearDetailedStatistics(pStats->total);
++ for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i)
++ VmaClearDetailedStatistics(pStats->memoryType[i]);
++ for(uint32_t i = 0; i < VK_MAX_MEMORY_HEAPS; ++i)
++ VmaClearDetailedStatistics(pStats->memoryHeap[i]);
++
++ // Process default pools.
++ for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
++ {
++ VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex];
++ if (pBlockVector != VMA_NULL)
++ pBlockVector->AddDetailedStatistics(pStats->memoryType[memTypeIndex]);
++ }
++
++ // Process custom pools.
++ {
++ VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex);
++ for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool))
++ {
++ VmaBlockVector& blockVector = pool->m_BlockVector;
++ const uint32_t memTypeIndex = blockVector.GetMemoryTypeIndex();
++ blockVector.AddDetailedStatistics(pStats->memoryType[memTypeIndex]);
++ pool->m_DedicatedAllocations.AddDetailedStatistics(pStats->memoryType[memTypeIndex]);
++ }
++ }
++
++ // Process dedicated allocations.
++ for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
++ {
++ m_DedicatedAllocations[memTypeIndex].AddDetailedStatistics(pStats->memoryType[memTypeIndex]);
++ }
++
++ // Sum from memory types to memory heaps.
++ for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
++ {
++ const uint32_t memHeapIndex = m_MemProps.memoryTypes[memTypeIndex].heapIndex;
++ VmaAddDetailedStatistics(pStats->memoryHeap[memHeapIndex], pStats->memoryType[memTypeIndex]);
++ }
++
++ // Sum from memory heaps to total.
++ for(uint32_t memHeapIndex = 0; memHeapIndex < GetMemoryHeapCount(); ++memHeapIndex)
++ VmaAddDetailedStatistics(pStats->total, pStats->memoryHeap[memHeapIndex]);
++
++ VMA_ASSERT(pStats->total.statistics.allocationCount == 0 ||
++ pStats->total.allocationSizeMax >= pStats->total.allocationSizeMin);
++ VMA_ASSERT(pStats->total.unusedRangeCount == 0 ||
++ pStats->total.unusedRangeSizeMax >= pStats->total.unusedRangeSizeMin);
++}
++
++void VmaAllocator_T::GetHeapBudgets(VmaBudget* outBudgets, uint32_t firstHeap, uint32_t heapCount)
++{
++#if VMA_MEMORY_BUDGET
++ if(m_UseExtMemoryBudget)
++ {
++ if(m_Budget.m_OperationsSinceBudgetFetch < 30)
++ {
++ VmaMutexLockRead lockRead(m_Budget.m_BudgetMutex, m_UseMutex);
++ for(uint32_t i = 0; i < heapCount; ++i, ++outBudgets)
++ {
++ const uint32_t heapIndex = firstHeap + i;
++
++ outBudgets->statistics.blockCount = m_Budget.m_BlockCount[heapIndex];
++ outBudgets->statistics.allocationCount = m_Budget.m_AllocationCount[heapIndex];
++ outBudgets->statistics.blockBytes = m_Budget.m_BlockBytes[heapIndex];
++ outBudgets->statistics.allocationBytes = m_Budget.m_AllocationBytes[heapIndex];
++
++ if(m_Budget.m_VulkanUsage[heapIndex] + outBudgets->statistics.blockBytes > m_Budget.m_BlockBytesAtBudgetFetch[heapIndex])
++ {
++ outBudgets->usage = m_Budget.m_VulkanUsage[heapIndex] +
++ outBudgets->statistics.blockBytes - m_Budget.m_BlockBytesAtBudgetFetch[heapIndex];
++ }
++ else
++ {
++ outBudgets->usage = 0;
++ }
++
++ // Have to take MIN with heap size because explicit HeapSizeLimit is included in it.
++ outBudgets->budget = VMA_MIN(
++ m_Budget.m_VulkanBudget[heapIndex], m_MemProps.memoryHeaps[heapIndex].size);
++ }
++ }
++ else
++ {
++ UpdateVulkanBudget(); // Outside of mutex lock
++ GetHeapBudgets(outBudgets, firstHeap, heapCount); // Recursion
++ }
++ }
++ else
++#endif
++ {
++ for(uint32_t i = 0; i < heapCount; ++i, ++outBudgets)
++ {
++ const uint32_t heapIndex = firstHeap + i;
++
++ outBudgets->statistics.blockCount = m_Budget.m_BlockCount[heapIndex];
++ outBudgets->statistics.allocationCount = m_Budget.m_AllocationCount[heapIndex];
++ outBudgets->statistics.blockBytes = m_Budget.m_BlockBytes[heapIndex];
++ outBudgets->statistics.allocationBytes = m_Budget.m_AllocationBytes[heapIndex];
++
++ outBudgets->usage = outBudgets->statistics.blockBytes;
++ outBudgets->budget = m_MemProps.memoryHeaps[heapIndex].size * 8 / 10; // 80% heuristics.
++ }
++ }
++}
++
++void VmaAllocator_T::GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationInfo* pAllocationInfo)
++{
++ pAllocationInfo->memoryType = hAllocation->GetMemoryTypeIndex();
++ pAllocationInfo->deviceMemory = hAllocation->GetMemory();
++ pAllocationInfo->offset = hAllocation->GetOffset();
++ pAllocationInfo->size = hAllocation->GetSize();
++ pAllocationInfo->pMappedData = hAllocation->GetMappedData();
++ pAllocationInfo->pUserData = hAllocation->GetUserData();
++ pAllocationInfo->pName = hAllocation->GetName();
++}
++
++VkResult VmaAllocator_T::CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPool* pPool)
++{
++ VMA_DEBUG_LOG(" CreatePool: MemoryTypeIndex=%u, flags=%u", pCreateInfo->memoryTypeIndex, pCreateInfo->flags);
++
++ VmaPoolCreateInfo newCreateInfo = *pCreateInfo;
++
++ // Protection against uninitialized new structure member. If garbage data are left there, this pointer dereference would crash.
++ if(pCreateInfo->pMemoryAllocateNext)
++ {
++ VMA_ASSERT(((const VkBaseInStructure*)pCreateInfo->pMemoryAllocateNext)->sType != 0);
++ }
++
++ if(newCreateInfo.maxBlockCount == 0)
++ {
++ newCreateInfo.maxBlockCount = SIZE_MAX;
++ }
++ if(newCreateInfo.minBlockCount > newCreateInfo.maxBlockCount)
++ {
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++ // Memory type index out of range or forbidden.
++ if(pCreateInfo->memoryTypeIndex >= GetMemoryTypeCount() ||
++ ((1u << pCreateInfo->memoryTypeIndex) & m_GlobalMemoryTypeBits) == 0)
++ {
++ return VK_ERROR_FEATURE_NOT_PRESENT;
++ }
++ if(newCreateInfo.minAllocationAlignment > 0)
++ {
++ VMA_ASSERT(VmaIsPow2(newCreateInfo.minAllocationAlignment));
++ }
++
++ const VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(newCreateInfo.memoryTypeIndex);
++
++ *pPool = vma_new(this, VmaPool_T)(this, newCreateInfo, preferredBlockSize);
++
++ VkResult res = (*pPool)->m_BlockVector.CreateMinBlocks();
++ if(res != VK_SUCCESS)
++ {
++ vma_delete(this, *pPool);
++ *pPool = VMA_NULL;
++ return res;
++ }
++
++ // Add to m_Pools.
++ {
++ VmaMutexLockWrite lock(m_PoolsMutex, m_UseMutex);
++ (*pPool)->SetId(m_NextPoolId++);
++ m_Pools.PushBack(*pPool);
++ }
++
++ return VK_SUCCESS;
++}
++
++void VmaAllocator_T::DestroyPool(VmaPool pool)
++{
++ // Remove from m_Pools.
++ {
++ VmaMutexLockWrite lock(m_PoolsMutex, m_UseMutex);
++ m_Pools.Remove(pool);
++ }
++
++ vma_delete(this, pool);
++}
++
++void VmaAllocator_T::GetPoolStatistics(VmaPool pool, VmaStatistics* pPoolStats)
++{
++ VmaClearStatistics(*pPoolStats);
++ pool->m_BlockVector.AddStatistics(*pPoolStats);
++ pool->m_DedicatedAllocations.AddStatistics(*pPoolStats);
++}
++
++void VmaAllocator_T::CalculatePoolStatistics(VmaPool pool, VmaDetailedStatistics* pPoolStats)
++{
++ VmaClearDetailedStatistics(*pPoolStats);
++ pool->m_BlockVector.AddDetailedStatistics(*pPoolStats);
++ pool->m_DedicatedAllocations.AddDetailedStatistics(*pPoolStats);
++}
++
++void VmaAllocator_T::SetCurrentFrameIndex(uint32_t frameIndex)
++{
++ m_CurrentFrameIndex.store(frameIndex);
++
++#if VMA_MEMORY_BUDGET
++ if(m_UseExtMemoryBudget)
++ {
++ UpdateVulkanBudget();
++ }
++#endif // #if VMA_MEMORY_BUDGET
++}
++
++VkResult VmaAllocator_T::CheckPoolCorruption(VmaPool hPool)
++{
++ return hPool->m_BlockVector.CheckCorruption();
++}
++
++VkResult VmaAllocator_T::CheckCorruption(uint32_t memoryTypeBits)
++{
++ VkResult finalRes = VK_ERROR_FEATURE_NOT_PRESENT;
++
++ // Process default pools.
++ for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
++ {
++ VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex];
++ if(pBlockVector != VMA_NULL)
++ {
++ VkResult localRes = pBlockVector->CheckCorruption();
++ switch(localRes)
++ {
++ case VK_ERROR_FEATURE_NOT_PRESENT:
++ break;
++ case VK_SUCCESS:
++ finalRes = VK_SUCCESS;
++ break;
++ default:
++ return localRes;
++ }
++ }
++ }
++
++ // Process custom pools.
++ {
++ VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex);
++ for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool))
++ {
++ if(((1u << pool->m_BlockVector.GetMemoryTypeIndex()) & memoryTypeBits) != 0)
++ {
++ VkResult localRes = pool->m_BlockVector.CheckCorruption();
++ switch(localRes)
++ {
++ case VK_ERROR_FEATURE_NOT_PRESENT:
++ break;
++ case VK_SUCCESS:
++ finalRes = VK_SUCCESS;
++ break;
++ default:
++ return localRes;
++ }
++ }
++ }
++ }
++
++ return finalRes;
++}
++
++VkResult VmaAllocator_T::AllocateVulkanMemory(const VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory)
++{
++ AtomicTransactionalIncrement<uint32_t> deviceMemoryCountIncrement;
++ const uint64_t prevDeviceMemoryCount = deviceMemoryCountIncrement.Increment(&m_DeviceMemoryCount);
++#if VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT
++ if(prevDeviceMemoryCount >= m_PhysicalDeviceProperties.limits.maxMemoryAllocationCount)
++ {
++ return VK_ERROR_TOO_MANY_OBJECTS;
++ }
++#endif
++
++ const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(pAllocateInfo->memoryTypeIndex);
++
++ // HeapSizeLimit is in effect for this heap.
++ if((m_HeapSizeLimitMask & (1u << heapIndex)) != 0)
++ {
++ const VkDeviceSize heapSize = m_MemProps.memoryHeaps[heapIndex].size;
++ VkDeviceSize blockBytes = m_Budget.m_BlockBytes[heapIndex];
++ for(;;)
++ {
++ const VkDeviceSize blockBytesAfterAllocation = blockBytes + pAllocateInfo->allocationSize;
++ if(blockBytesAfterAllocation > heapSize)
++ {
++ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
++ }
++ if(m_Budget.m_BlockBytes[heapIndex].compare_exchange_strong(blockBytes, blockBytesAfterAllocation))
++ {
++ break;
++ }
++ }
++ }
++ else
++ {
++ m_Budget.m_BlockBytes[heapIndex] += pAllocateInfo->allocationSize;
++ }
++ ++m_Budget.m_BlockCount[heapIndex];
++
++ // VULKAN CALL vkAllocateMemory.
++ VkResult res = (*m_VulkanFunctions.vkAllocateMemory)(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory);
++
++ if(res == VK_SUCCESS)
++ {
++#if VMA_MEMORY_BUDGET
++ ++m_Budget.m_OperationsSinceBudgetFetch;
++#endif
++
++ // Informative callback.
++ if(m_DeviceMemoryCallbacks.pfnAllocate != VMA_NULL)
++ {
++ (*m_DeviceMemoryCallbacks.pfnAllocate)(this, pAllocateInfo->memoryTypeIndex, *pMemory, pAllocateInfo->allocationSize, m_DeviceMemoryCallbacks.pUserData);
++ }
++
++ deviceMemoryCountIncrement.Commit();
++ }
++ else
++ {
++ --m_Budget.m_BlockCount[heapIndex];
++ m_Budget.m_BlockBytes[heapIndex] -= pAllocateInfo->allocationSize;
++ }
++
++ return res;
++}
++
++void VmaAllocator_T::FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, VkDeviceMemory hMemory)
++{
++ // Informative callback.
++ if(m_DeviceMemoryCallbacks.pfnFree != VMA_NULL)
++ {
++ (*m_DeviceMemoryCallbacks.pfnFree)(this, memoryType, hMemory, size, m_DeviceMemoryCallbacks.pUserData);
++ }
++
++ // VULKAN CALL vkFreeMemory.
++ (*m_VulkanFunctions.vkFreeMemory)(m_hDevice, hMemory, GetAllocationCallbacks());
++
++ const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memoryType);
++ --m_Budget.m_BlockCount[heapIndex];
++ m_Budget.m_BlockBytes[heapIndex] -= size;
++
++ --m_DeviceMemoryCount;
++}
++
++VkResult VmaAllocator_T::BindVulkanBuffer(
++ VkDeviceMemory memory,
++ VkDeviceSize memoryOffset,
++ VkBuffer buffer,
++ const void* pNext)
++{
++ if(pNext != VMA_NULL)
++ {
++#if VMA_VULKAN_VERSION >= 1001000 || VMA_BIND_MEMORY2
++ if((m_UseKhrBindMemory2 || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) &&
++ m_VulkanFunctions.vkBindBufferMemory2KHR != VMA_NULL)
++ {
++ VkBindBufferMemoryInfoKHR bindBufferMemoryInfo = { VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR };
++ bindBufferMemoryInfo.pNext = pNext;
++ bindBufferMemoryInfo.buffer = buffer;
++ bindBufferMemoryInfo.memory = memory;
++ bindBufferMemoryInfo.memoryOffset = memoryOffset;
++ return (*m_VulkanFunctions.vkBindBufferMemory2KHR)(m_hDevice, 1, &bindBufferMemoryInfo);
++ }
++ else
++#endif // #if VMA_VULKAN_VERSION >= 1001000 || VMA_BIND_MEMORY2
++ {
++ return VK_ERROR_EXTENSION_NOT_PRESENT;
++ }
++ }
++ else
++ {
++ return (*m_VulkanFunctions.vkBindBufferMemory)(m_hDevice, buffer, memory, memoryOffset);
++ }
++}
++
++VkResult VmaAllocator_T::BindVulkanImage(
++ VkDeviceMemory memory,
++ VkDeviceSize memoryOffset,
++ VkImage image,
++ const void* pNext)
++{
++ if(pNext != VMA_NULL)
++ {
++#if VMA_VULKAN_VERSION >= 1001000 || VMA_BIND_MEMORY2
++ if((m_UseKhrBindMemory2 || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) &&
++ m_VulkanFunctions.vkBindImageMemory2KHR != VMA_NULL)
++ {
++ VkBindImageMemoryInfoKHR bindBufferMemoryInfo = { VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR };
++ bindBufferMemoryInfo.pNext = pNext;
++ bindBufferMemoryInfo.image = image;
++ bindBufferMemoryInfo.memory = memory;
++ bindBufferMemoryInfo.memoryOffset = memoryOffset;
++ return (*m_VulkanFunctions.vkBindImageMemory2KHR)(m_hDevice, 1, &bindBufferMemoryInfo);
++ }
++ else
++#endif // #if VMA_BIND_MEMORY2
++ {
++ return VK_ERROR_EXTENSION_NOT_PRESENT;
++ }
++ }
++ else
++ {
++ return (*m_VulkanFunctions.vkBindImageMemory)(m_hDevice, image, memory, memoryOffset);
++ }
++}
++
++VkResult VmaAllocator_T::Map(VmaAllocation hAllocation, void** ppData)
++{
++ switch(hAllocation->GetType())
++ {
++ case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
++ {
++ VmaDeviceMemoryBlock* const pBlock = hAllocation->GetBlock();
++ char *pBytes = VMA_NULL;
++ VkResult res = pBlock->Map(this, 1, (void**)&pBytes);
++ if(res == VK_SUCCESS)
++ {
++ *ppData = pBytes + (ptrdiff_t)hAllocation->GetOffset();
++ hAllocation->BlockAllocMap();
++ }
++ return res;
++ }
++ case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
++ return hAllocation->DedicatedAllocMap(this, ppData);
++ default:
++ VMA_ASSERT(0);
++ return VK_ERROR_MEMORY_MAP_FAILED;
++ }
++}
++
++void VmaAllocator_T::Unmap(VmaAllocation hAllocation)
++{
++ switch(hAllocation->GetType())
++ {
++ case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
++ {
++ VmaDeviceMemoryBlock* const pBlock = hAllocation->GetBlock();
++ hAllocation->BlockAllocUnmap();
++ pBlock->Unmap(this, 1);
++ }
++ break;
++ case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
++ hAllocation->DedicatedAllocUnmap(this);
++ break;
++ default:
++ VMA_ASSERT(0);
++ }
++}
++
++VkResult VmaAllocator_T::BindBufferMemory(
++ VmaAllocation hAllocation,
++ VkDeviceSize allocationLocalOffset,
++ VkBuffer hBuffer,
++ const void* pNext)
++{
++ VkResult res = VK_SUCCESS;
++ switch(hAllocation->GetType())
++ {
++ case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
++ res = BindVulkanBuffer(hAllocation->GetMemory(), allocationLocalOffset, hBuffer, pNext);
++ break;
++ case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
++ {
++ VmaDeviceMemoryBlock* const pBlock = hAllocation->GetBlock();
++ VMA_ASSERT(pBlock && "Binding buffer to allocation that doesn't belong to any block.");
++ res = pBlock->BindBufferMemory(this, hAllocation, allocationLocalOffset, hBuffer, pNext);
++ break;
++ }
++ default:
++ VMA_ASSERT(0);
++ }
++ return res;
++}
++
++VkResult VmaAllocator_T::BindImageMemory(
++ VmaAllocation hAllocation,
++ VkDeviceSize allocationLocalOffset,
++ VkImage hImage,
++ const void* pNext)
++{
++ VkResult res = VK_SUCCESS;
++ switch(hAllocation->GetType())
++ {
++ case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
++ res = BindVulkanImage(hAllocation->GetMemory(), allocationLocalOffset, hImage, pNext);
++ break;
++ case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
++ {
++ VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock();
++ VMA_ASSERT(pBlock && "Binding image to allocation that doesn't belong to any block.");
++ res = pBlock->BindImageMemory(this, hAllocation, allocationLocalOffset, hImage, pNext);
++ break;
++ }
++ default:
++ VMA_ASSERT(0);
++ }
++ return res;
++}
++
++VkResult VmaAllocator_T::FlushOrInvalidateAllocation(
++ VmaAllocation hAllocation,
++ VkDeviceSize offset, VkDeviceSize size,
++ VMA_CACHE_OPERATION op)
++{
++ VkResult res = VK_SUCCESS;
++
++ VkMappedMemoryRange memRange = {};
++ if(GetFlushOrInvalidateRange(hAllocation, offset, size, memRange))
++ {
++ switch(op)
++ {
++ case VMA_CACHE_FLUSH:
++ res = (*GetVulkanFunctions().vkFlushMappedMemoryRanges)(m_hDevice, 1, &memRange);
++ break;
++ case VMA_CACHE_INVALIDATE:
++ res = (*GetVulkanFunctions().vkInvalidateMappedMemoryRanges)(m_hDevice, 1, &memRange);
++ break;
++ default:
++ VMA_ASSERT(0);
++ }
++ }
++ // else: Just ignore this call.
++ return res;
++}
++
++VkResult VmaAllocator_T::FlushOrInvalidateAllocations(
++ uint32_t allocationCount,
++ const VmaAllocation* allocations,
++ const VkDeviceSize* offsets, const VkDeviceSize* sizes,
++ VMA_CACHE_OPERATION op)
++{
++ typedef VmaStlAllocator<VkMappedMemoryRange> RangeAllocator;
++ typedef VmaSmallVector<VkMappedMemoryRange, RangeAllocator, 16> RangeVector;
++ RangeVector ranges = RangeVector(RangeAllocator(GetAllocationCallbacks()));
++
++ for(uint32_t allocIndex = 0; allocIndex < allocationCount; ++allocIndex)
++ {
++ const VmaAllocation alloc = allocations[allocIndex];
++ const VkDeviceSize offset = offsets != VMA_NULL ? offsets[allocIndex] : 0;
++ const VkDeviceSize size = sizes != VMA_NULL ? sizes[allocIndex] : VK_WHOLE_SIZE;
++ VkMappedMemoryRange newRange;
++ if(GetFlushOrInvalidateRange(alloc, offset, size, newRange))
++ {
++ ranges.push_back(newRange);
++ }
++ }
++
++ VkResult res = VK_SUCCESS;
++ if(!ranges.empty())
++ {
++ switch(op)
++ {
++ case VMA_CACHE_FLUSH:
++ res = (*GetVulkanFunctions().vkFlushMappedMemoryRanges)(m_hDevice, (uint32_t)ranges.size(), ranges.data());
++ break;
++ case VMA_CACHE_INVALIDATE:
++ res = (*GetVulkanFunctions().vkInvalidateMappedMemoryRanges)(m_hDevice, (uint32_t)ranges.size(), ranges.data());
++ break;
++ default:
++ VMA_ASSERT(0);
++ }
++ }
++ // else: Just ignore this call.
++ return res;
++}
++
++void VmaAllocator_T::FreeDedicatedMemory(const VmaAllocation allocation)
++{
++ VMA_ASSERT(allocation && allocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED);
++
++ const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
++ VmaPool parentPool = allocation->GetParentPool();
++ if(parentPool == VK_NULL_HANDLE)
++ {
++ // Default pool
++ m_DedicatedAllocations[memTypeIndex].Unregister(allocation);
++ }
++ else
++ {
++ // Custom pool
++ parentPool->m_DedicatedAllocations.Unregister(allocation);
++ }
++
++ VkDeviceMemory hMemory = allocation->GetMemory();
++
++ /*
++ There is no need to call this, because Vulkan spec allows to skip vkUnmapMemory
++ before vkFreeMemory.
++
++ if(allocation->GetMappedData() != VMA_NULL)
++ {
++ (*m_VulkanFunctions.vkUnmapMemory)(m_hDevice, hMemory);
++ }
++ */
++
++ FreeVulkanMemory(memTypeIndex, allocation->GetSize(), hMemory);
++
++ m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(allocation->GetMemoryTypeIndex()), allocation->GetSize());
++ m_AllocationObjectAllocator.Free(allocation);
++
++ VMA_DEBUG_LOG(" Freed DedicatedMemory MemoryTypeIndex=%u", memTypeIndex);
++}
++
++uint32_t VmaAllocator_T::CalculateGpuDefragmentationMemoryTypeBits() const
++{
++ VkBufferCreateInfo dummyBufCreateInfo;
++ VmaFillGpuDefragmentationBufferCreateInfo(dummyBufCreateInfo);
++
++ uint32_t memoryTypeBits = 0;
++
++ // Create buffer.
++ VkBuffer buf = VK_NULL_HANDLE;
++ VkResult res = (*GetVulkanFunctions().vkCreateBuffer)(
++ m_hDevice, &dummyBufCreateInfo, GetAllocationCallbacks(), &buf);
++ if(res == VK_SUCCESS)
++ {
++ // Query for supported memory types.
++ VkMemoryRequirements memReq;
++ (*GetVulkanFunctions().vkGetBufferMemoryRequirements)(m_hDevice, buf, &memReq);
++ memoryTypeBits = memReq.memoryTypeBits;
++
++ // Destroy buffer.
++ (*GetVulkanFunctions().vkDestroyBuffer)(m_hDevice, buf, GetAllocationCallbacks());
++ }
++
++ return memoryTypeBits;
++}
++
++uint32_t VmaAllocator_T::CalculateGlobalMemoryTypeBits() const
++{
++ // Make sure memory information is already fetched.
++ VMA_ASSERT(GetMemoryTypeCount() > 0);
++
++ uint32_t memoryTypeBits = UINT32_MAX;
++
++ if(!m_UseAmdDeviceCoherentMemory)
++ {
++ // Exclude memory types that have VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD.
++ for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
++ {
++ if((m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY) != 0)
++ {
++ memoryTypeBits &= ~(1u << memTypeIndex);
++ }
++ }
++ }
++
++ return memoryTypeBits;
++}
++
++bool VmaAllocator_T::GetFlushOrInvalidateRange(
++ VmaAllocation allocation,
++ VkDeviceSize offset, VkDeviceSize size,
++ VkMappedMemoryRange& outRange) const
++{
++ const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
++ if(size > 0 && IsMemoryTypeNonCoherent(memTypeIndex))
++ {
++ const VkDeviceSize nonCoherentAtomSize = m_PhysicalDeviceProperties.limits.nonCoherentAtomSize;
++ const VkDeviceSize allocationSize = allocation->GetSize();
++ VMA_ASSERT(offset <= allocationSize);
++
++ outRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
++ outRange.pNext = VMA_NULL;
++ outRange.memory = allocation->GetMemory();
++
++ switch(allocation->GetType())
++ {
++ case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED:
++ outRange.offset = VmaAlignDown(offset, nonCoherentAtomSize);
++ if(size == VK_WHOLE_SIZE)
++ {
++ outRange.size = allocationSize - outRange.offset;
++ }
++ else
++ {
++ VMA_ASSERT(offset + size <= allocationSize);
++ outRange.size = VMA_MIN(
++ VmaAlignUp(size + (offset - outRange.offset), nonCoherentAtomSize),
++ allocationSize - outRange.offset);
++ }
++ break;
++ case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:
++ {
++ // 1. Still within this allocation.
++ outRange.offset = VmaAlignDown(offset, nonCoherentAtomSize);
++ if(size == VK_WHOLE_SIZE)
++ {
++ size = allocationSize - offset;
++ }
++ else
++ {
++ VMA_ASSERT(offset + size <= allocationSize);
++ }
++ outRange.size = VmaAlignUp(size + (offset - outRange.offset), nonCoherentAtomSize);
++
++ // 2. Adjust to whole block.
++ const VkDeviceSize allocationOffset = allocation->GetOffset();
++ VMA_ASSERT(allocationOffset % nonCoherentAtomSize == 0);
++ const VkDeviceSize blockSize = allocation->GetBlock()->m_pMetadata->GetSize();
++ outRange.offset += allocationOffset;
++ outRange.size = VMA_MIN(outRange.size, blockSize - outRange.offset);
++
++ break;
++ }
++ default:
++ VMA_ASSERT(0);
++ }
++ return true;
++ }
++ return false;
++}
++
++#if VMA_MEMORY_BUDGET
++void VmaAllocator_T::UpdateVulkanBudget()
++{
++ VMA_ASSERT(m_UseExtMemoryBudget);
++
++ VkPhysicalDeviceMemoryProperties2KHR memProps = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR };
++
++ VkPhysicalDeviceMemoryBudgetPropertiesEXT budgetProps = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT };
++ VmaPnextChainPushFront(&memProps, &budgetProps);
++
++ GetVulkanFunctions().vkGetPhysicalDeviceMemoryProperties2KHR(m_PhysicalDevice, &memProps);
++
++ {
++ VmaMutexLockWrite lockWrite(m_Budget.m_BudgetMutex, m_UseMutex);
++
++ for(uint32_t heapIndex = 0; heapIndex < GetMemoryHeapCount(); ++heapIndex)
++ {
++ m_Budget.m_VulkanUsage[heapIndex] = budgetProps.heapUsage[heapIndex];
++ m_Budget.m_VulkanBudget[heapIndex] = budgetProps.heapBudget[heapIndex];
++ m_Budget.m_BlockBytesAtBudgetFetch[heapIndex] = m_Budget.m_BlockBytes[heapIndex].load();
++
++ // Some bugged drivers return the budget incorrectly, e.g. 0 or much bigger than heap size.
++ if(m_Budget.m_VulkanBudget[heapIndex] == 0)
++ {
++ m_Budget.m_VulkanBudget[heapIndex] = m_MemProps.memoryHeaps[heapIndex].size * 8 / 10; // 80% heuristics.
++ }
++ else if(m_Budget.m_VulkanBudget[heapIndex] > m_MemProps.memoryHeaps[heapIndex].size)
++ {
++ m_Budget.m_VulkanBudget[heapIndex] = m_MemProps.memoryHeaps[heapIndex].size;
++ }
++ if(m_Budget.m_VulkanUsage[heapIndex] == 0 && m_Budget.m_BlockBytesAtBudgetFetch[heapIndex] > 0)
++ {
++ m_Budget.m_VulkanUsage[heapIndex] = m_Budget.m_BlockBytesAtBudgetFetch[heapIndex];
++ }
++ }
++ m_Budget.m_OperationsSinceBudgetFetch = 0;
++ }
++}
++#endif // VMA_MEMORY_BUDGET
++
++void VmaAllocator_T::FillAllocation(const VmaAllocation hAllocation, uint8_t pattern)
++{
++ if(VMA_DEBUG_INITIALIZE_ALLOCATIONS &&
++ (m_MemProps.memoryTypes[hAllocation->GetMemoryTypeIndex()].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
++ {
++ void* pData = VMA_NULL;
++ VkResult res = Map(hAllocation, &pData);
++ if(res == VK_SUCCESS)
++ {
++ memset(pData, (int)pattern, (size_t)hAllocation->GetSize());
++ FlushOrInvalidateAllocation(hAllocation, 0, VK_WHOLE_SIZE, VMA_CACHE_FLUSH);
++ Unmap(hAllocation);
++ }
++ else
++ {
++ VMA_ASSERT(0 && "VMA_DEBUG_INITIALIZE_ALLOCATIONS is enabled, but couldn't map memory to fill allocation.");
++ }
++ }
++}
++
++uint32_t VmaAllocator_T::GetGpuDefragmentationMemoryTypeBits()
++{
++ uint32_t memoryTypeBits = m_GpuDefragmentationMemoryTypeBits.load();
++ if(memoryTypeBits == UINT32_MAX)
++ {
++ memoryTypeBits = CalculateGpuDefragmentationMemoryTypeBits();
++ m_GpuDefragmentationMemoryTypeBits.store(memoryTypeBits);
++ }
++ return memoryTypeBits;
++}
++
++#if VMA_STATS_STRING_ENABLED
++void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json)
++{
++ json.WriteString("DefaultPools");
++ json.BeginObject();
++ {
++ for (uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
++ {
++ VmaBlockVector* pBlockVector = m_pBlockVectors[memTypeIndex];
++ VmaDedicatedAllocationList& dedicatedAllocList = m_DedicatedAllocations[memTypeIndex];
++ if (pBlockVector != VMA_NULL)
++ {
++ json.BeginString("Type ");
++ json.ContinueString(memTypeIndex);
++ json.EndString();
++ json.BeginObject();
++ {
++ json.WriteString("PreferredBlockSize");
++ json.WriteNumber(pBlockVector->GetPreferredBlockSize());
++
++ json.WriteString("Blocks");
++ pBlockVector->PrintDetailedMap(json);
++
++ json.WriteString("DedicatedAllocations");
++ dedicatedAllocList.BuildStatsString(json);
++ }
++ json.EndObject();
++ }
++ }
++ }
++ json.EndObject();
++
++ json.WriteString("CustomPools");
++ json.BeginObject();
++ {
++ VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex);
++ if (!m_Pools.IsEmpty())
++ {
++ for (uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)
++ {
++ bool displayType = true;
++ size_t index = 0;
++ for (VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool))
++ {
++ VmaBlockVector& blockVector = pool->m_BlockVector;
++ if (blockVector.GetMemoryTypeIndex() == memTypeIndex)
++ {
++ if (displayType)
++ {
++ json.BeginString("Type ");
++ json.ContinueString(memTypeIndex);
++ json.EndString();
++ json.BeginArray();
++ displayType = false;
++ }
++
++ json.BeginObject();
++ {
++ json.WriteString("Name");
++ json.BeginString();
++ json.ContinueString_Size(index++);
++ if (pool->GetName())
++ {
++ json.ContinueString(" - ");
++ json.ContinueString(pool->GetName());
++ }
++ json.EndString();
++
++ json.WriteString("PreferredBlockSize");
++ json.WriteNumber(blockVector.GetPreferredBlockSize());
++
++ json.WriteString("Blocks");
++ blockVector.PrintDetailedMap(json);
++
++ json.WriteString("DedicatedAllocations");
++ pool->m_DedicatedAllocations.BuildStatsString(json);
++ }
++ json.EndObject();
++ }
++ }
++
++ if (!displayType)
++ json.EndArray();
++ }
++ }
++ }
++ json.EndObject();
++}
++#endif // VMA_STATS_STRING_ENABLED
++#endif // _VMA_ALLOCATOR_T_FUNCTIONS
++
++
++#ifndef _VMA_PUBLIC_INTERFACE
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator(
++ const VmaAllocatorCreateInfo* pCreateInfo,
++ VmaAllocator* pAllocator)
++{
++ VMA_ASSERT(pCreateInfo && pAllocator);
++ VMA_ASSERT(pCreateInfo->vulkanApiVersion == 0 ||
++ (VK_VERSION_MAJOR(pCreateInfo->vulkanApiVersion) == 1 && VK_VERSION_MINOR(pCreateInfo->vulkanApiVersion) <= 3));
++ VMA_DEBUG_LOG("vmaCreateAllocator");
++ *pAllocator = vma_new(pCreateInfo->pAllocationCallbacks, VmaAllocator_T)(pCreateInfo);
++ VkResult result = (*pAllocator)->Init(pCreateInfo);
++ if(result < 0)
++ {
++ vma_delete(pCreateInfo->pAllocationCallbacks, *pAllocator);
++ *pAllocator = VK_NULL_HANDLE;
++ }
++ return result;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyAllocator(
++ VmaAllocator allocator)
++{
++ if(allocator != VK_NULL_HANDLE)
++ {
++ VMA_DEBUG_LOG("vmaDestroyAllocator");
++ VkAllocationCallbacks allocationCallbacks = allocator->m_AllocationCallbacks; // Have to copy the callbacks when destroying.
++ vma_delete(&allocationCallbacks, allocator);
++ }
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocatorInfo(VmaAllocator allocator, VmaAllocatorInfo* pAllocatorInfo)
++{
++ VMA_ASSERT(allocator && pAllocatorInfo);
++ pAllocatorInfo->instance = allocator->m_hInstance;
++ pAllocatorInfo->physicalDevice = allocator->GetPhysicalDevice();
++ pAllocatorInfo->device = allocator->m_hDevice;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetPhysicalDeviceProperties(
++ VmaAllocator allocator,
++ const VkPhysicalDeviceProperties **ppPhysicalDeviceProperties)
++{
++ VMA_ASSERT(allocator && ppPhysicalDeviceProperties);
++ *ppPhysicalDeviceProperties = &allocator->m_PhysicalDeviceProperties;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryProperties(
++ VmaAllocator allocator,
++ const VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties)
++{
++ VMA_ASSERT(allocator && ppPhysicalDeviceMemoryProperties);
++ *ppPhysicalDeviceMemoryProperties = &allocator->m_MemProps;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryTypeProperties(
++ VmaAllocator allocator,
++ uint32_t memoryTypeIndex,
++ VkMemoryPropertyFlags* pFlags)
++{
++ VMA_ASSERT(allocator && pFlags);
++ VMA_ASSERT(memoryTypeIndex < allocator->GetMemoryTypeCount());
++ *pFlags = allocator->m_MemProps.memoryTypes[memoryTypeIndex].propertyFlags;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaSetCurrentFrameIndex(
++ VmaAllocator allocator,
++ uint32_t frameIndex)
++{
++ VMA_ASSERT(allocator);
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ allocator->SetCurrentFrameIndex(frameIndex);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStatistics(
++ VmaAllocator allocator,
++ VmaTotalStatistics* pStats)
++{
++ VMA_ASSERT(allocator && pStats);
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++ allocator->CalculateStatistics(pStats);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetHeapBudgets(
++ VmaAllocator allocator,
++ VmaBudget* pBudgets)
++{
++ VMA_ASSERT(allocator && pBudgets);
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++ allocator->GetHeapBudgets(pBudgets, 0, allocator->GetMemoryHeapCount());
++}
++
++#if VMA_STATS_STRING_ENABLED
++
++VMA_CALL_PRE void VMA_CALL_POST vmaBuildStatsString(
++ VmaAllocator allocator,
++ char** ppStatsString,
++ VkBool32 detailedMap)
++{
++ VMA_ASSERT(allocator && ppStatsString);
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ VmaStringBuilder sb(allocator->GetAllocationCallbacks());
++ {
++ VmaBudget budgets[VK_MAX_MEMORY_HEAPS];
++ allocator->GetHeapBudgets(budgets, 0, allocator->GetMemoryHeapCount());
++
++ VmaTotalStatistics stats;
++ allocator->CalculateStatistics(&stats);
++
++ VmaJsonWriter json(allocator->GetAllocationCallbacks(), sb);
++ json.BeginObject();
++ {
++ json.WriteString("General");
++ json.BeginObject();
++ {
++ const VkPhysicalDeviceProperties& deviceProperties = allocator->m_PhysicalDeviceProperties;
++ const VkPhysicalDeviceMemoryProperties& memoryProperties = allocator->m_MemProps;
++
++ json.WriteString("API");
++ json.WriteString("Vulkan");
++
++ json.WriteString("apiVersion");
++ json.BeginString();
++ json.ContinueString(VK_API_VERSION_MAJOR(deviceProperties.apiVersion));
++ json.ContinueString(".");
++ json.ContinueString(VK_API_VERSION_MINOR(deviceProperties.apiVersion));
++ json.ContinueString(".");
++ json.ContinueString(VK_API_VERSION_PATCH(deviceProperties.apiVersion));
++ json.EndString();
++
++ json.WriteString("GPU");
++ json.WriteString(deviceProperties.deviceName);
++ json.WriteString("deviceType");
++ json.WriteNumber(static_cast<uint32_t>(deviceProperties.deviceType));
++
++ json.WriteString("maxMemoryAllocationCount");
++ json.WriteNumber(deviceProperties.limits.maxMemoryAllocationCount);
++ json.WriteString("bufferImageGranularity");
++ json.WriteNumber(deviceProperties.limits.bufferImageGranularity);
++ json.WriteString("nonCoherentAtomSize");
++ json.WriteNumber(deviceProperties.limits.nonCoherentAtomSize);
++
++ json.WriteString("memoryHeapCount");
++ json.WriteNumber(memoryProperties.memoryHeapCount);
++ json.WriteString("memoryTypeCount");
++ json.WriteNumber(memoryProperties.memoryTypeCount);
++ }
++ json.EndObject();
++ }
++ {
++ json.WriteString("Total");
++ VmaPrintDetailedStatistics(json, stats.total);
++ }
++ {
++ json.WriteString("MemoryInfo");
++ json.BeginObject();
++ {
++ for (uint32_t heapIndex = 0; heapIndex < allocator->GetMemoryHeapCount(); ++heapIndex)
++ {
++ json.BeginString("Heap ");
++ json.ContinueString(heapIndex);
++ json.EndString();
++ json.BeginObject();
++ {
++ const VkMemoryHeap& heapInfo = allocator->m_MemProps.memoryHeaps[heapIndex];
++ json.WriteString("Flags");
++ json.BeginArray(true);
++ {
++ if (heapInfo.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
++ json.WriteString("DEVICE_LOCAL");
++ #if VMA_VULKAN_VERSION >= 1001000
++ if (heapInfo.flags & VK_MEMORY_HEAP_MULTI_INSTANCE_BIT)
++ json.WriteString("MULTI_INSTANCE");
++ #endif
++
++ VkMemoryHeapFlags flags = heapInfo.flags &
++ ~(VK_MEMORY_HEAP_DEVICE_LOCAL_BIT
++ #if VMA_VULKAN_VERSION >= 1001000
++ | VK_MEMORY_HEAP_MULTI_INSTANCE_BIT
++ #endif
++ );
++ if (flags != 0)
++ json.WriteNumber(flags);
++ }
++ json.EndArray();
++
++ json.WriteString("Size");
++ json.WriteNumber(heapInfo.size);
++
++ json.WriteString("Budget");
++ json.BeginObject();
++ {
++ json.WriteString("BudgetBytes");
++ json.WriteNumber(budgets[heapIndex].budget);
++ json.WriteString("UsageBytes");
++ json.WriteNumber(budgets[heapIndex].usage);
++ }
++ json.EndObject();
++
++ json.WriteString("Stats");
++ VmaPrintDetailedStatistics(json, stats.memoryHeap[heapIndex]);
++
++ json.WriteString("MemoryPools");
++ json.BeginObject();
++ {
++ for (uint32_t typeIndex = 0; typeIndex < allocator->GetMemoryTypeCount(); ++typeIndex)
++ {
++ if (allocator->MemoryTypeIndexToHeapIndex(typeIndex) == heapIndex)
++ {
++ json.BeginString("Type ");
++ json.ContinueString(typeIndex);
++ json.EndString();
++ json.BeginObject();
++ {
++ json.WriteString("Flags");
++ json.BeginArray(true);
++ {
++ VkMemoryPropertyFlags flags = allocator->m_MemProps.memoryTypes[typeIndex].propertyFlags;
++ if (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
++ json.WriteString("DEVICE_LOCAL");
++ if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
++ json.WriteString("HOST_VISIBLE");
++ if (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
++ json.WriteString("HOST_COHERENT");
++ if (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
++ json.WriteString("HOST_CACHED");
++ if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
++ json.WriteString("LAZILY_ALLOCATED");
++ #if VMA_VULKAN_VERSION >= 1001000
++ if (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT)
++ json.WriteString("PROTECTED");
++ #endif
++ #if VK_AMD_device_coherent_memory
++ if (flags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY)
++ json.WriteString("DEVICE_COHERENT_AMD");
++ if (flags & VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY)
++ json.WriteString("DEVICE_UNCACHED_AMD");
++ #endif
++
++ flags &= ~(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
++ #if VMA_VULKAN_VERSION >= 1001000
++ | VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
++ #endif
++ #if VK_AMD_device_coherent_memory
++ | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY
++ | VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY
++ #endif
++ | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
++ | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
++ | VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
++ if (flags != 0)
++ json.WriteNumber(flags);
++ }
++ json.EndArray();
++
++ json.WriteString("Stats");
++ VmaPrintDetailedStatistics(json, stats.memoryType[typeIndex]);
++ }
++ json.EndObject();
++ }
++ }
++
++ }
++ json.EndObject();
++ }
++ json.EndObject();
++ }
++ }
++ json.EndObject();
++ }
++
++ if (detailedMap == VK_TRUE)
++ allocator->PrintDetailedMap(json);
++
++ json.EndObject();
++ }
++
++ *ppStatsString = VmaCreateStringCopy(allocator->GetAllocationCallbacks(), sb.GetData(), sb.GetLength());
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString(
++ VmaAllocator allocator,
++ char* pStatsString)
++{
++ if(pStatsString != VMA_NULL)
++ {
++ VMA_ASSERT(allocator);
++ VmaFreeString(allocator->GetAllocationCallbacks(), pStatsString);
++ }
++}
++
++#endif // VMA_STATS_STRING_ENABLED
++
++/*
++This function is not protected by any mutex because it just reads immutable data.
++*/
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndex(
++ VmaAllocator allocator,
++ uint32_t memoryTypeBits,
++ const VmaAllocationCreateInfo* pAllocationCreateInfo,
++ uint32_t* pMemoryTypeIndex)
++{
++ VMA_ASSERT(allocator != VK_NULL_HANDLE);
++ VMA_ASSERT(pAllocationCreateInfo != VMA_NULL);
++ VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);
++
++ return allocator->FindMemoryTypeIndex(memoryTypeBits, pAllocationCreateInfo, UINT32_MAX, pMemoryTypeIndex);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo(
++ VmaAllocator allocator,
++ const VkBufferCreateInfo* pBufferCreateInfo,
++ const VmaAllocationCreateInfo* pAllocationCreateInfo,
++ uint32_t* pMemoryTypeIndex)
++{
++ VMA_ASSERT(allocator != VK_NULL_HANDLE);
++ VMA_ASSERT(pBufferCreateInfo != VMA_NULL);
++ VMA_ASSERT(pAllocationCreateInfo != VMA_NULL);
++ VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);
++
++ const VkDevice hDev = allocator->m_hDevice;
++ const VmaVulkanFunctions* funcs = &allocator->GetVulkanFunctions();
++ VkResult res;
++
++#if VMA_VULKAN_VERSION >= 1003000
++ if(funcs->vkGetDeviceBufferMemoryRequirements)
++ {
++ // Can query straight from VkBufferCreateInfo :)
++ VkDeviceBufferMemoryRequirements devBufMemReq = {VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS};
++ devBufMemReq.pCreateInfo = pBufferCreateInfo;
++
++ VkMemoryRequirements2 memReq = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
++ (*funcs->vkGetDeviceBufferMemoryRequirements)(hDev, &devBufMemReq, &memReq);
++
++ res = allocator->FindMemoryTypeIndex(
++ memReq.memoryRequirements.memoryTypeBits, pAllocationCreateInfo, pBufferCreateInfo->usage, pMemoryTypeIndex);
++ }
++ else
++#endif // #if VMA_VULKAN_VERSION >= 1003000
++ {
++ // Must create a dummy buffer to query :(
++ VkBuffer hBuffer = VK_NULL_HANDLE;
++ res = funcs->vkCreateBuffer(
++ hDev, pBufferCreateInfo, allocator->GetAllocationCallbacks(), &hBuffer);
++ if(res == VK_SUCCESS)
++ {
++ VkMemoryRequirements memReq = {};
++ funcs->vkGetBufferMemoryRequirements(hDev, hBuffer, &memReq);
++
++ res = allocator->FindMemoryTypeIndex(
++ memReq.memoryTypeBits, pAllocationCreateInfo, pBufferCreateInfo->usage, pMemoryTypeIndex);
++
++ funcs->vkDestroyBuffer(
++ hDev, hBuffer, allocator->GetAllocationCallbacks());
++ }
++ }
++ return res;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo(
++ VmaAllocator allocator,
++ const VkImageCreateInfo* pImageCreateInfo,
++ const VmaAllocationCreateInfo* pAllocationCreateInfo,
++ uint32_t* pMemoryTypeIndex)
++{
++ VMA_ASSERT(allocator != VK_NULL_HANDLE);
++ VMA_ASSERT(pImageCreateInfo != VMA_NULL);
++ VMA_ASSERT(pAllocationCreateInfo != VMA_NULL);
++ VMA_ASSERT(pMemoryTypeIndex != VMA_NULL);
++
++ const VkDevice hDev = allocator->m_hDevice;
++ const VmaVulkanFunctions* funcs = &allocator->GetVulkanFunctions();
++ VkResult res;
++
++#if VMA_VULKAN_VERSION >= 1003000
++ if(funcs->vkGetDeviceImageMemoryRequirements)
++ {
++ // Can query straight from VkImageCreateInfo :)
++ VkDeviceImageMemoryRequirements devImgMemReq = {VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS};
++ devImgMemReq.pCreateInfo = pImageCreateInfo;
++ VMA_ASSERT(pImageCreateInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT_COPY && (pImageCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT_COPY) == 0 &&
++ "Cannot use this VkImageCreateInfo with vmaFindMemoryTypeIndexForImageInfo as I don't know what to pass as VkDeviceImageMemoryRequirements::planeAspect.");
++
++ VkMemoryRequirements2 memReq = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
++ (*funcs->vkGetDeviceImageMemoryRequirements)(hDev, &devImgMemReq, &memReq);
++
++ res = allocator->FindMemoryTypeIndex(
++ memReq.memoryRequirements.memoryTypeBits, pAllocationCreateInfo, pImageCreateInfo->usage, pMemoryTypeIndex);
++ }
++ else
++#endif // #if VMA_VULKAN_VERSION >= 1003000
++ {
++ // Must create a dummy image to query :(
++ VkImage hImage = VK_NULL_HANDLE;
++ res = funcs->vkCreateImage(
++ hDev, pImageCreateInfo, allocator->GetAllocationCallbacks(), &hImage);
++ if(res == VK_SUCCESS)
++ {
++ VkMemoryRequirements memReq = {};
++ funcs->vkGetImageMemoryRequirements(hDev, hImage, &memReq);
++
++ res = allocator->FindMemoryTypeIndex(
++ memReq.memoryTypeBits, pAllocationCreateInfo, pImageCreateInfo->usage, pMemoryTypeIndex);
++
++ funcs->vkDestroyImage(
++ hDev, hImage, allocator->GetAllocationCallbacks());
++ }
++ }
++ return res;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreatePool(
++ VmaAllocator allocator,
++ const VmaPoolCreateInfo* pCreateInfo,
++ VmaPool* pPool)
++{
++ VMA_ASSERT(allocator && pCreateInfo && pPool);
++
++ VMA_DEBUG_LOG("vmaCreatePool");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ return allocator->CreatePool(pCreateInfo, pPool);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyPool(
++ VmaAllocator allocator,
++ VmaPool pool)
++{
++ VMA_ASSERT(allocator);
++
++ if(pool == VK_NULL_HANDLE)
++ {
++ return;
++ }
++
++ VMA_DEBUG_LOG("vmaDestroyPool");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ allocator->DestroyPool(pool);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStatistics(
++ VmaAllocator allocator,
++ VmaPool pool,
++ VmaStatistics* pPoolStats)
++{
++ VMA_ASSERT(allocator && pool && pPoolStats);
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ allocator->GetPoolStatistics(pool, pPoolStats);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaCalculatePoolStatistics(
++ VmaAllocator allocator,
++ VmaPool pool,
++ VmaDetailedStatistics* pPoolStats)
++{
++ VMA_ASSERT(allocator && pool && pPoolStats);
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ allocator->CalculatePoolStatistics(pool, pPoolStats);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckPoolCorruption(VmaAllocator allocator, VmaPool pool)
++{
++ VMA_ASSERT(allocator && pool);
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ VMA_DEBUG_LOG("vmaCheckPoolCorruption");
++
++ return allocator->CheckPoolCorruption(pool);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolName(
++ VmaAllocator allocator,
++ VmaPool pool,
++ const char** ppName)
++{
++ VMA_ASSERT(allocator && pool && ppName);
++
++ VMA_DEBUG_LOG("vmaGetPoolName");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ *ppName = pool->GetName();
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName(
++ VmaAllocator allocator,
++ VmaPool pool,
++ const char* pName)
++{
++ VMA_ASSERT(allocator && pool);
++
++ VMA_DEBUG_LOG("vmaSetPoolName");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ pool->SetName(pName);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory(
++ VmaAllocator allocator,
++ const VkMemoryRequirements* pVkMemoryRequirements,
++ const VmaAllocationCreateInfo* pCreateInfo,
++ VmaAllocation* pAllocation,
++ VmaAllocationInfo* pAllocationInfo)
++{
++ VMA_ASSERT(allocator && pVkMemoryRequirements && pCreateInfo && pAllocation);
++
++ VMA_DEBUG_LOG("vmaAllocateMemory");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ VkResult result = allocator->AllocateMemory(
++ *pVkMemoryRequirements,
++ false, // requiresDedicatedAllocation
++ false, // prefersDedicatedAllocation
++ VK_NULL_HANDLE, // dedicatedBuffer
++ VK_NULL_HANDLE, // dedicatedImage
++ UINT32_MAX, // dedicatedBufferImageUsage
++ *pCreateInfo,
++ VMA_SUBALLOCATION_TYPE_UNKNOWN,
++ 1, // allocationCount
++ pAllocation);
++
++ if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS)
++ {
++ allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
++ }
++
++ return result;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryPages(
++ VmaAllocator allocator,
++ const VkMemoryRequirements* pVkMemoryRequirements,
++ const VmaAllocationCreateInfo* pCreateInfo,
++ size_t allocationCount,
++ VmaAllocation* pAllocations,
++ VmaAllocationInfo* pAllocationInfo)
++{
++ if(allocationCount == 0)
++ {
++ return VK_SUCCESS;
++ }
++
++ VMA_ASSERT(allocator && pVkMemoryRequirements && pCreateInfo && pAllocations);
++
++ VMA_DEBUG_LOG("vmaAllocateMemoryPages");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ VkResult result = allocator->AllocateMemory(
++ *pVkMemoryRequirements,
++ false, // requiresDedicatedAllocation
++ false, // prefersDedicatedAllocation
++ VK_NULL_HANDLE, // dedicatedBuffer
++ VK_NULL_HANDLE, // dedicatedImage
++ UINT32_MAX, // dedicatedBufferImageUsage
++ *pCreateInfo,
++ VMA_SUBALLOCATION_TYPE_UNKNOWN,
++ allocationCount,
++ pAllocations);
++
++ if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS)
++ {
++ for(size_t i = 0; i < allocationCount; ++i)
++ {
++ allocator->GetAllocationInfo(pAllocations[i], pAllocationInfo + i);
++ }
++ }
++
++ return result;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForBuffer(
++ VmaAllocator allocator,
++ VkBuffer buffer,
++ const VmaAllocationCreateInfo* pCreateInfo,
++ VmaAllocation* pAllocation,
++ VmaAllocationInfo* pAllocationInfo)
++{
++ VMA_ASSERT(allocator && buffer != VK_NULL_HANDLE && pCreateInfo && pAllocation);
++
++ VMA_DEBUG_LOG("vmaAllocateMemoryForBuffer");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ VkMemoryRequirements vkMemReq = {};
++ bool requiresDedicatedAllocation = false;
++ bool prefersDedicatedAllocation = false;
++ allocator->GetBufferMemoryRequirements(buffer, vkMemReq,
++ requiresDedicatedAllocation,
++ prefersDedicatedAllocation);
++
++ VkResult result = allocator->AllocateMemory(
++ vkMemReq,
++ requiresDedicatedAllocation,
++ prefersDedicatedAllocation,
++ buffer, // dedicatedBuffer
++ VK_NULL_HANDLE, // dedicatedImage
++ UINT32_MAX, // dedicatedBufferImageUsage
++ *pCreateInfo,
++ VMA_SUBALLOCATION_TYPE_BUFFER,
++ 1, // allocationCount
++ pAllocation);
++
++ if(pAllocationInfo && result == VK_SUCCESS)
++ {
++ allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
++ }
++
++ return result;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForImage(
++ VmaAllocator allocator,
++ VkImage image,
++ const VmaAllocationCreateInfo* pCreateInfo,
++ VmaAllocation* pAllocation,
++ VmaAllocationInfo* pAllocationInfo)
++{
++ VMA_ASSERT(allocator && image != VK_NULL_HANDLE && pCreateInfo && pAllocation);
++
++ VMA_DEBUG_LOG("vmaAllocateMemoryForImage");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ VkMemoryRequirements vkMemReq = {};
++ bool requiresDedicatedAllocation = false;
++ bool prefersDedicatedAllocation = false;
++ allocator->GetImageMemoryRequirements(image, vkMemReq,
++ requiresDedicatedAllocation, prefersDedicatedAllocation);
++
++ VkResult result = allocator->AllocateMemory(
++ vkMemReq,
++ requiresDedicatedAllocation,
++ prefersDedicatedAllocation,
++ VK_NULL_HANDLE, // dedicatedBuffer
++ image, // dedicatedImage
++ UINT32_MAX, // dedicatedBufferImageUsage
++ *pCreateInfo,
++ VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN,
++ 1, // allocationCount
++ pAllocation);
++
++ if(pAllocationInfo && result == VK_SUCCESS)
++ {
++ allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
++ }
++
++ return result;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemory(
++ VmaAllocator allocator,
++ VmaAllocation allocation)
++{
++ VMA_ASSERT(allocator);
++
++ if(allocation == VK_NULL_HANDLE)
++ {
++ return;
++ }
++
++ VMA_DEBUG_LOG("vmaFreeMemory");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ allocator->FreeMemory(
++ 1, // allocationCount
++ &allocation);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemoryPages(
++ VmaAllocator allocator,
++ size_t allocationCount,
++ const VmaAllocation* pAllocations)
++{
++ if(allocationCount == 0)
++ {
++ return;
++ }
++
++ VMA_ASSERT(allocator);
++
++ VMA_DEBUG_LOG("vmaFreeMemoryPages");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ allocator->FreeMemory(allocationCount, pAllocations);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationInfo(
++ VmaAllocator allocator,
++ VmaAllocation allocation,
++ VmaAllocationInfo* pAllocationInfo)
++{
++ VMA_ASSERT(allocator && allocation && pAllocationInfo);
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ allocator->GetAllocationInfo(allocation, pAllocationInfo);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationUserData(
++ VmaAllocator allocator,
++ VmaAllocation allocation,
++ void* pUserData)
++{
++ VMA_ASSERT(allocator && allocation);
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ allocation->SetUserData(allocator, pUserData);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationName(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ const char* VMA_NULLABLE pName)
++{
++ allocation->SetName(allocator, pName);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationMemoryProperties(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ VkMemoryPropertyFlags* VMA_NOT_NULL pFlags)
++{
++ VMA_ASSERT(allocator && allocation && pFlags);
++ const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();
++ *pFlags = allocator->m_MemProps.memoryTypes[memTypeIndex].propertyFlags;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaMapMemory(
++ VmaAllocator allocator,
++ VmaAllocation allocation,
++ void** ppData)
++{
++ VMA_ASSERT(allocator && allocation && ppData);
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ return allocator->Map(allocation, ppData);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaUnmapMemory(
++ VmaAllocator allocator,
++ VmaAllocation allocation)
++{
++ VMA_ASSERT(allocator && allocation);
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ allocator->Unmap(allocation);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocation(
++ VmaAllocator allocator,
++ VmaAllocation allocation,
++ VkDeviceSize offset,
++ VkDeviceSize size)
++{
++ VMA_ASSERT(allocator && allocation);
++
++ VMA_DEBUG_LOG("vmaFlushAllocation");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ const VkResult res = allocator->FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_FLUSH);
++
++ return res;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocation(
++ VmaAllocator allocator,
++ VmaAllocation allocation,
++ VkDeviceSize offset,
++ VkDeviceSize size)
++{
++ VMA_ASSERT(allocator && allocation);
++
++ VMA_DEBUG_LOG("vmaInvalidateAllocation");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ const VkResult res = allocator->FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_INVALIDATE);
++
++ return res;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocations(
++ VmaAllocator allocator,
++ uint32_t allocationCount,
++ const VmaAllocation* allocations,
++ const VkDeviceSize* offsets,
++ const VkDeviceSize* sizes)
++{
++ VMA_ASSERT(allocator);
++
++ if(allocationCount == 0)
++ {
++ return VK_SUCCESS;
++ }
++
++ VMA_ASSERT(allocations);
++
++ VMA_DEBUG_LOG("vmaFlushAllocations");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ const VkResult res = allocator->FlushOrInvalidateAllocations(allocationCount, allocations, offsets, sizes, VMA_CACHE_FLUSH);
++
++ return res;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocations(
++ VmaAllocator allocator,
++ uint32_t allocationCount,
++ const VmaAllocation* allocations,
++ const VkDeviceSize* offsets,
++ const VkDeviceSize* sizes)
++{
++ VMA_ASSERT(allocator);
++
++ if(allocationCount == 0)
++ {
++ return VK_SUCCESS;
++ }
++
++ VMA_ASSERT(allocations);
++
++ VMA_DEBUG_LOG("vmaInvalidateAllocations");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ const VkResult res = allocator->FlushOrInvalidateAllocations(allocationCount, allocations, offsets, sizes, VMA_CACHE_INVALIDATE);
++
++ return res;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption(
++ VmaAllocator allocator,
++ uint32_t memoryTypeBits)
++{
++ VMA_ASSERT(allocator);
++
++ VMA_DEBUG_LOG("vmaCheckCorruption");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ return allocator->CheckCorruption(memoryTypeBits);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentation(
++ VmaAllocator allocator,
++ const VmaDefragmentationInfo* pInfo,
++ VmaDefragmentationContext* pContext)
++{
++ VMA_ASSERT(allocator && pInfo && pContext);
++
++ VMA_DEBUG_LOG("vmaBeginDefragmentation");
++
++ if (pInfo->pool != VMA_NULL)
++ {
++ // Check if run on supported algorithms
++ if (pInfo->pool->m_BlockVector.GetAlgorithm() & VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT)
++ return VK_ERROR_FEATURE_NOT_PRESENT;
++ }
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ *pContext = vma_new(allocator, VmaDefragmentationContext_T)(allocator, *pInfo);
++ return VK_SUCCESS;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaEndDefragmentation(
++ VmaAllocator allocator,
++ VmaDefragmentationContext context,
++ VmaDefragmentationStats* pStats)
++{
++ VMA_ASSERT(allocator && context);
++
++ VMA_DEBUG_LOG("vmaEndDefragmentation");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ if (pStats)
++ context->GetStats(*pStats);
++ vma_delete(allocator, context);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentationPass(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaDefragmentationContext VMA_NOT_NULL context,
++ VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo)
++{
++ VMA_ASSERT(context && pPassInfo);
++
++ VMA_DEBUG_LOG("vmaBeginDefragmentationPass");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ return context->DefragmentPassBegin(*pPassInfo);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentationPass(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaDefragmentationContext VMA_NOT_NULL context,
++ VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo)
++{
++ VMA_ASSERT(context && pPassInfo);
++
++ VMA_DEBUG_LOG("vmaEndDefragmentationPass");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ return context->DefragmentPassEnd(*pPassInfo);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory(
++ VmaAllocator allocator,
++ VmaAllocation allocation,
++ VkBuffer buffer)
++{
++ VMA_ASSERT(allocator && allocation && buffer);
++
++ VMA_DEBUG_LOG("vmaBindBufferMemory");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ return allocator->BindBufferMemory(allocation, 0, buffer, VMA_NULL);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory2(
++ VmaAllocator allocator,
++ VmaAllocation allocation,
++ VkDeviceSize allocationLocalOffset,
++ VkBuffer buffer,
++ const void* pNext)
++{
++ VMA_ASSERT(allocator && allocation && buffer);
++
++ VMA_DEBUG_LOG("vmaBindBufferMemory2");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ return allocator->BindBufferMemory(allocation, allocationLocalOffset, buffer, pNext);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory(
++ VmaAllocator allocator,
++ VmaAllocation allocation,
++ VkImage image)
++{
++ VMA_ASSERT(allocator && allocation && image);
++
++ VMA_DEBUG_LOG("vmaBindImageMemory");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ return allocator->BindImageMemory(allocation, 0, image, VMA_NULL);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory2(
++ VmaAllocator allocator,
++ VmaAllocation allocation,
++ VkDeviceSize allocationLocalOffset,
++ VkImage image,
++ const void* pNext)
++{
++ VMA_ASSERT(allocator && allocation && image);
++
++ VMA_DEBUG_LOG("vmaBindImageMemory2");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ return allocator->BindImageMemory(allocation, allocationLocalOffset, image, pNext);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBuffer(
++ VmaAllocator allocator,
++ const VkBufferCreateInfo* pBufferCreateInfo,
++ const VmaAllocationCreateInfo* pAllocationCreateInfo,
++ VkBuffer* pBuffer,
++ VmaAllocation* pAllocation,
++ VmaAllocationInfo* pAllocationInfo)
++{
++ VMA_ASSERT(allocator && pBufferCreateInfo && pAllocationCreateInfo && pBuffer && pAllocation);
++
++ if(pBufferCreateInfo->size == 0)
++ {
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++ if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 &&
++ !allocator->m_UseKhrBufferDeviceAddress)
++ {
++ VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used.");
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++
++ VMA_DEBUG_LOG("vmaCreateBuffer");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ *pBuffer = VK_NULL_HANDLE;
++ *pAllocation = VK_NULL_HANDLE;
++
++ // 1. Create VkBuffer.
++ VkResult res = (*allocator->GetVulkanFunctions().vkCreateBuffer)(
++ allocator->m_hDevice,
++ pBufferCreateInfo,
++ allocator->GetAllocationCallbacks(),
++ pBuffer);
++ if(res >= 0)
++ {
++ // 2. vkGetBufferMemoryRequirements.
++ VkMemoryRequirements vkMemReq = {};
++ bool requiresDedicatedAllocation = false;
++ bool prefersDedicatedAllocation = false;
++ allocator->GetBufferMemoryRequirements(*pBuffer, vkMemReq,
++ requiresDedicatedAllocation, prefersDedicatedAllocation);
++
++ // 3. Allocate memory using allocator.
++ res = allocator->AllocateMemory(
++ vkMemReq,
++ requiresDedicatedAllocation,
++ prefersDedicatedAllocation,
++ *pBuffer, // dedicatedBuffer
++ VK_NULL_HANDLE, // dedicatedImage
++ pBufferCreateInfo->usage, // dedicatedBufferImageUsage
++ *pAllocationCreateInfo,
++ VMA_SUBALLOCATION_TYPE_BUFFER,
++ 1, // allocationCount
++ pAllocation);
++
++ if(res >= 0)
++ {
++ // 3. Bind buffer with memory.
++ if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
++ {
++ res = allocator->BindBufferMemory(*pAllocation, 0, *pBuffer, VMA_NULL);
++ }
++ if(res >= 0)
++ {
++ // All steps succeeded.
++ #if VMA_STATS_STRING_ENABLED
++ (*pAllocation)->InitBufferImageUsage(pBufferCreateInfo->usage);
++ #endif
++ if(pAllocationInfo != VMA_NULL)
++ {
++ allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
++ }
++
++ return VK_SUCCESS;
++ }
++ allocator->FreeMemory(
++ 1, // allocationCount
++ pAllocation);
++ *pAllocation = VK_NULL_HANDLE;
++ (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
++ *pBuffer = VK_NULL_HANDLE;
++ return res;
++ }
++ (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
++ *pBuffer = VK_NULL_HANDLE;
++ return res;
++ }
++ return res;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment(
++ VmaAllocator allocator,
++ const VkBufferCreateInfo* pBufferCreateInfo,
++ const VmaAllocationCreateInfo* pAllocationCreateInfo,
++ VkDeviceSize minAlignment,
++ VkBuffer* pBuffer,
++ VmaAllocation* pAllocation,
++ VmaAllocationInfo* pAllocationInfo)
++{
++ VMA_ASSERT(allocator && pBufferCreateInfo && pAllocationCreateInfo && VmaIsPow2(minAlignment) && pBuffer && pAllocation);
++
++ if(pBufferCreateInfo->size == 0)
++ {
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++ if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 &&
++ !allocator->m_UseKhrBufferDeviceAddress)
++ {
++ VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used.");
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++
++ VMA_DEBUG_LOG("vmaCreateBufferWithAlignment");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ *pBuffer = VK_NULL_HANDLE;
++ *pAllocation = VK_NULL_HANDLE;
++
++ // 1. Create VkBuffer.
++ VkResult res = (*allocator->GetVulkanFunctions().vkCreateBuffer)(
++ allocator->m_hDevice,
++ pBufferCreateInfo,
++ allocator->GetAllocationCallbacks(),
++ pBuffer);
++ if(res >= 0)
++ {
++ // 2. vkGetBufferMemoryRequirements.
++ VkMemoryRequirements vkMemReq = {};
++ bool requiresDedicatedAllocation = false;
++ bool prefersDedicatedAllocation = false;
++ allocator->GetBufferMemoryRequirements(*pBuffer, vkMemReq,
++ requiresDedicatedAllocation, prefersDedicatedAllocation);
++
++ // 2a. Include minAlignment
++ vkMemReq.alignment = VMA_MAX(vkMemReq.alignment, minAlignment);
++
++ // 3. Allocate memory using allocator.
++ res = allocator->AllocateMemory(
++ vkMemReq,
++ requiresDedicatedAllocation,
++ prefersDedicatedAllocation,
++ *pBuffer, // dedicatedBuffer
++ VK_NULL_HANDLE, // dedicatedImage
++ pBufferCreateInfo->usage, // dedicatedBufferImageUsage
++ *pAllocationCreateInfo,
++ VMA_SUBALLOCATION_TYPE_BUFFER,
++ 1, // allocationCount
++ pAllocation);
++
++ if(res >= 0)
++ {
++ // 3. Bind buffer with memory.
++ if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
++ {
++ res = allocator->BindBufferMemory(*pAllocation, 0, *pBuffer, VMA_NULL);
++ }
++ if(res >= 0)
++ {
++ // All steps succeeded.
++ #if VMA_STATS_STRING_ENABLED
++ (*pAllocation)->InitBufferImageUsage(pBufferCreateInfo->usage);
++ #endif
++ if(pAllocationInfo != VMA_NULL)
++ {
++ allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
++ }
++
++ return VK_SUCCESS;
++ }
++ allocator->FreeMemory(
++ 1, // allocationCount
++ pAllocation);
++ *pAllocation = VK_NULL_HANDLE;
++ (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
++ *pBuffer = VK_NULL_HANDLE;
++ return res;
++ }
++ (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
++ *pBuffer = VK_NULL_HANDLE;
++ return res;
++ }
++ return res;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingBuffer(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo,
++ VkBuffer VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pBuffer)
++{
++ VMA_ASSERT(allocator && pBufferCreateInfo && pBuffer && allocation);
++
++ VMA_DEBUG_LOG("vmaCreateAliasingBuffer");
++
++ *pBuffer = VK_NULL_HANDLE;
++
++ if (pBufferCreateInfo->size == 0)
++ {
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++ if ((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 &&
++ !allocator->m_UseKhrBufferDeviceAddress)
++ {
++ VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used.");
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ // 1. Create VkBuffer.
++ VkResult res = (*allocator->GetVulkanFunctions().vkCreateBuffer)(
++ allocator->m_hDevice,
++ pBufferCreateInfo,
++ allocator->GetAllocationCallbacks(),
++ pBuffer);
++ if (res >= 0)
++ {
++ // 2. Bind buffer with memory.
++ res = allocator->BindBufferMemory(allocation, 0, *pBuffer, VMA_NULL);
++ if (res >= 0)
++ {
++ return VK_SUCCESS;
++ }
++ (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
++ }
++ return res;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyBuffer(
++ VmaAllocator allocator,
++ VkBuffer buffer,
++ VmaAllocation allocation)
++{
++ VMA_ASSERT(allocator);
++
++ if(buffer == VK_NULL_HANDLE && allocation == VK_NULL_HANDLE)
++ {
++ return;
++ }
++
++ VMA_DEBUG_LOG("vmaDestroyBuffer");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ if(buffer != VK_NULL_HANDLE)
++ {
++ (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, buffer, allocator->GetAllocationCallbacks());
++ }
++
++ if(allocation != VK_NULL_HANDLE)
++ {
++ allocator->FreeMemory(
++ 1, // allocationCount
++ &allocation);
++ }
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage(
++ VmaAllocator allocator,
++ const VkImageCreateInfo* pImageCreateInfo,
++ const VmaAllocationCreateInfo* pAllocationCreateInfo,
++ VkImage* pImage,
++ VmaAllocation* pAllocation,
++ VmaAllocationInfo* pAllocationInfo)
++{
++ VMA_ASSERT(allocator && pImageCreateInfo && pAllocationCreateInfo && pImage && pAllocation);
++
++ if(pImageCreateInfo->extent.width == 0 ||
++ pImageCreateInfo->extent.height == 0 ||
++ pImageCreateInfo->extent.depth == 0 ||
++ pImageCreateInfo->mipLevels == 0 ||
++ pImageCreateInfo->arrayLayers == 0)
++ {
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++
++ VMA_DEBUG_LOG("vmaCreateImage");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ *pImage = VK_NULL_HANDLE;
++ *pAllocation = VK_NULL_HANDLE;
++
++ // 1. Create VkImage.
++ VkResult res = (*allocator->GetVulkanFunctions().vkCreateImage)(
++ allocator->m_hDevice,
++ pImageCreateInfo,
++ allocator->GetAllocationCallbacks(),
++ pImage);
++ if(res >= 0)
++ {
++ VmaSuballocationType suballocType = pImageCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL ?
++ VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL :
++ VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR;
++
++ // 2. Allocate memory using allocator.
++ VkMemoryRequirements vkMemReq = {};
++ bool requiresDedicatedAllocation = false;
++ bool prefersDedicatedAllocation = false;
++ allocator->GetImageMemoryRequirements(*pImage, vkMemReq,
++ requiresDedicatedAllocation, prefersDedicatedAllocation);
++
++ res = allocator->AllocateMemory(
++ vkMemReq,
++ requiresDedicatedAllocation,
++ prefersDedicatedAllocation,
++ VK_NULL_HANDLE, // dedicatedBuffer
++ *pImage, // dedicatedImage
++ pImageCreateInfo->usage, // dedicatedBufferImageUsage
++ *pAllocationCreateInfo,
++ suballocType,
++ 1, // allocationCount
++ pAllocation);
++
++ if(res >= 0)
++ {
++ // 3. Bind image with memory.
++ if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
++ {
++ res = allocator->BindImageMemory(*pAllocation, 0, *pImage, VMA_NULL);
++ }
++ if(res >= 0)
++ {
++ // All steps succeeded.
++ #if VMA_STATS_STRING_ENABLED
++ (*pAllocation)->InitBufferImageUsage(pImageCreateInfo->usage);
++ #endif
++ if(pAllocationInfo != VMA_NULL)
++ {
++ allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
++ }
++
++ return VK_SUCCESS;
++ }
++ allocator->FreeMemory(
++ 1, // allocationCount
++ pAllocation);
++ *pAllocation = VK_NULL_HANDLE;
++ (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks());
++ *pImage = VK_NULL_HANDLE;
++ return res;
++ }
++ (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks());
++ *pImage = VK_NULL_HANDLE;
++ return res;
++ }
++ return res;
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingImage(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VmaAllocation VMA_NOT_NULL allocation,
++ const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo,
++ VkImage VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pImage)
++{
++ VMA_ASSERT(allocator && pImageCreateInfo && pImage && allocation);
++
++ *pImage = VK_NULL_HANDLE;
++
++ VMA_DEBUG_LOG("vmaCreateImage");
++
++ if (pImageCreateInfo->extent.width == 0 ||
++ pImageCreateInfo->extent.height == 0 ||
++ pImageCreateInfo->extent.depth == 0 ||
++ pImageCreateInfo->mipLevels == 0 ||
++ pImageCreateInfo->arrayLayers == 0)
++ {
++ return VK_ERROR_INITIALIZATION_FAILED;
++ }
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ // 1. Create VkImage.
++ VkResult res = (*allocator->GetVulkanFunctions().vkCreateImage)(
++ allocator->m_hDevice,
++ pImageCreateInfo,
++ allocator->GetAllocationCallbacks(),
++ pImage);
++ if (res >= 0)
++ {
++ // 2. Bind image with memory.
++ res = allocator->BindImageMemory(allocation, 0, *pImage, VMA_NULL);
++ if (res >= 0)
++ {
++ return VK_SUCCESS;
++ }
++ (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks());
++ }
++ return res;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyImage(
++ VmaAllocator VMA_NOT_NULL allocator,
++ VkImage VMA_NULLABLE_NON_DISPATCHABLE image,
++ VmaAllocation VMA_NULLABLE allocation)
++{
++ VMA_ASSERT(allocator);
++
++ if(image == VK_NULL_HANDLE && allocation == VK_NULL_HANDLE)
++ {
++ return;
++ }
++
++ VMA_DEBUG_LOG("vmaDestroyImage");
++
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK
++
++ if(image != VK_NULL_HANDLE)
++ {
++ (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, image, allocator->GetAllocationCallbacks());
++ }
++ if(allocation != VK_NULL_HANDLE)
++ {
++ allocator->FreeMemory(
++ 1, // allocationCount
++ &allocation);
++ }
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateVirtualBlock(
++ const VmaVirtualBlockCreateInfo* VMA_NOT_NULL pCreateInfo,
++ VmaVirtualBlock VMA_NULLABLE * VMA_NOT_NULL pVirtualBlock)
++{
++ VMA_ASSERT(pCreateInfo && pVirtualBlock);
++ VMA_ASSERT(pCreateInfo->size > 0);
++ VMA_DEBUG_LOG("vmaCreateVirtualBlock");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ *pVirtualBlock = vma_new(pCreateInfo->pAllocationCallbacks, VmaVirtualBlock_T)(*pCreateInfo);
++ VkResult res = (*pVirtualBlock)->Init();
++ if(res < 0)
++ {
++ vma_delete(pCreateInfo->pAllocationCallbacks, *pVirtualBlock);
++ *pVirtualBlock = VK_NULL_HANDLE;
++ }
++ return res;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaDestroyVirtualBlock(VmaVirtualBlock VMA_NULLABLE virtualBlock)
++{
++ if(virtualBlock != VK_NULL_HANDLE)
++ {
++ VMA_DEBUG_LOG("vmaDestroyVirtualBlock");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ VkAllocationCallbacks allocationCallbacks = virtualBlock->m_AllocationCallbacks; // Have to copy the callbacks when destroying.
++ vma_delete(&allocationCallbacks, virtualBlock);
++ }
++}
++
++VMA_CALL_PRE VkBool32 VMA_CALL_POST vmaIsVirtualBlockEmpty(VmaVirtualBlock VMA_NOT_NULL virtualBlock)
++{
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE);
++ VMA_DEBUG_LOG("vmaIsVirtualBlockEmpty");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ return virtualBlock->IsEmpty() ? VK_TRUE : VK_FALSE;
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetVirtualAllocationInfo(VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ VmaVirtualAllocation VMA_NOT_NULL_NON_DISPATCHABLE allocation, VmaVirtualAllocationInfo* VMA_NOT_NULL pVirtualAllocInfo)
++{
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && pVirtualAllocInfo != VMA_NULL);
++ VMA_DEBUG_LOG("vmaGetVirtualAllocationInfo");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ virtualBlock->GetAllocationInfo(allocation, *pVirtualAllocInfo);
++}
++
++VMA_CALL_PRE VkResult VMA_CALL_POST vmaVirtualAllocate(VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ const VmaVirtualAllocationCreateInfo* VMA_NOT_NULL pCreateInfo, VmaVirtualAllocation VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pAllocation,
++ VkDeviceSize* VMA_NULLABLE pOffset)
++{
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && pCreateInfo != VMA_NULL && pAllocation != VMA_NULL);
++ VMA_DEBUG_LOG("vmaVirtualAllocate");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ return virtualBlock->Allocate(*pCreateInfo, *pAllocation, pOffset);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaVirtualFree(VmaVirtualBlock VMA_NOT_NULL virtualBlock, VmaVirtualAllocation VMA_NULLABLE_NON_DISPATCHABLE allocation)
++{
++ if(allocation != VK_NULL_HANDLE)
++ {
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE);
++ VMA_DEBUG_LOG("vmaVirtualFree");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ virtualBlock->Free(allocation);
++ }
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaClearVirtualBlock(VmaVirtualBlock VMA_NOT_NULL virtualBlock)
++{
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE);
++ VMA_DEBUG_LOG("vmaClearVirtualBlock");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ virtualBlock->Clear();
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaSetVirtualAllocationUserData(VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ VmaVirtualAllocation VMA_NOT_NULL_NON_DISPATCHABLE allocation, void* VMA_NULLABLE pUserData)
++{
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE);
++ VMA_DEBUG_LOG("vmaSetVirtualAllocationUserData");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ virtualBlock->SetAllocationUserData(allocation, pUserData);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaGetVirtualBlockStatistics(VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ VmaStatistics* VMA_NOT_NULL pStats)
++{
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && pStats != VMA_NULL);
++ VMA_DEBUG_LOG("vmaGetVirtualBlockStatistics");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ virtualBlock->GetStatistics(*pStats);
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaCalculateVirtualBlockStatistics(VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ VmaDetailedStatistics* VMA_NOT_NULL pStats)
++{
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && pStats != VMA_NULL);
++ VMA_DEBUG_LOG("vmaCalculateVirtualBlockStatistics");
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ virtualBlock->CalculateDetailedStatistics(*pStats);
++}
++
++#if VMA_STATS_STRING_ENABLED
++
++VMA_CALL_PRE void VMA_CALL_POST vmaBuildVirtualBlockStatsString(VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ char* VMA_NULLABLE * VMA_NOT_NULL ppStatsString, VkBool32 detailedMap)
++{
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && ppStatsString != VMA_NULL);
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ const VkAllocationCallbacks* allocationCallbacks = virtualBlock->GetAllocationCallbacks();
++ VmaStringBuilder sb(allocationCallbacks);
++ virtualBlock->BuildStatsString(detailedMap != VK_FALSE, sb);
++ *ppStatsString = VmaCreateStringCopy(allocationCallbacks, sb.GetData(), sb.GetLength());
++}
++
++VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString(VmaVirtualBlock VMA_NOT_NULL virtualBlock,
++ char* VMA_NULLABLE pStatsString)
++{
++ if(pStatsString != VMA_NULL)
++ {
++ VMA_ASSERT(virtualBlock != VK_NULL_HANDLE);
++ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
++ VmaFreeString(virtualBlock->GetAllocationCallbacks(), pStatsString);
++ }
++}
++#endif // VMA_STATS_STRING_ENABLED
++#endif // _VMA_PUBLIC_INTERFACE
++#endif // VMA_IMPLEMENTATION
++
++/**
++\page quick_start Quick start
++
++\section quick_start_project_setup Project setup
++
++Vulkan Memory Allocator comes in form of a "stb-style" single header file.
++You don't need to build it as a separate library project.
++You can add this file directly to your project and submit it to code repository next to your other source files.
++
++"Single header" doesn't mean that everything is contained in C/C++ declarations,
++like it tends to be in case of inline functions or C++ templates.
++It means that implementation is bundled with interface in a single file and needs to be extracted using preprocessor macro.
++If you don't do it properly, you will get linker errors.
++
++To do it properly:
++
++-# Include "vk_mem_alloc.h" file in each CPP file where you want to use the library.
++ This includes declarations of all members of the library.
++-# In exactly one CPP file define following macro before this include.
++ It enables also internal definitions.
++
++\code
++#define VMA_IMPLEMENTATION
++#include "vk_mem_alloc.h"
++\endcode
++
++It may be a good idea to create dedicated CPP file just for this purpose.
++
++This library includes header `<vulkan/vulkan.h>`, which in turn
++includes `<windows.h>` on Windows. If you need some specific macros defined
++before including these headers (like `WIN32_LEAN_AND_MEAN` or
++`WINVER` for Windows, `VK_USE_PLATFORM_WIN32_KHR` for Vulkan), you must define
++them before every `#include` of this library.
++
++This library is written in C++, but has C-compatible interface.
++Thus you can include and use vk_mem_alloc.h in C or C++ code, but full
++implementation with `VMA_IMPLEMENTATION` macro must be compiled as C++, NOT as C.
++Some features of C++14 used. STL containers, RTTI, or C++ exceptions are not used.
++
++
++\section quick_start_initialization Initialization
++
++At program startup:
++
++-# Initialize Vulkan to have `VkPhysicalDevice`, `VkDevice` and `VkInstance` object.
++-# Fill VmaAllocatorCreateInfo structure and create #VmaAllocator object by
++ calling vmaCreateAllocator().
++
++Only members `physicalDevice`, `device`, `instance` are required.
++However, you should inform the library which Vulkan version do you use by setting
++VmaAllocatorCreateInfo::vulkanApiVersion and which extensions did you enable
++by setting VmaAllocatorCreateInfo::flags (like #VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT for VK_KHR_buffer_device_address).
++Otherwise, VMA would use only features of Vulkan 1.0 core with no extensions.
++
++You may need to configure importing Vulkan functions. There are 3 ways to do this:
++
++-# **If you link with Vulkan static library** (e.g. "vulkan-1.lib" on Windows):
++ - You don't need to do anything.
++ - VMA will use these, as macro `VMA_STATIC_VULKAN_FUNCTIONS` is defined to 1 by default.
++-# **If you want VMA to fetch pointers to Vulkan functions dynamically** using `vkGetInstanceProcAddr`,
++ `vkGetDeviceProcAddr` (this is the option presented in the example below):
++ - Define `VMA_STATIC_VULKAN_FUNCTIONS` to 0, `VMA_DYNAMIC_VULKAN_FUNCTIONS` to 1.
++ - Provide pointers to these two functions via VmaVulkanFunctions::vkGetInstanceProcAddr,
++ VmaVulkanFunctions::vkGetDeviceProcAddr.
++ - The library will fetch pointers to all other functions it needs internally.
++-# **If you fetch pointers to all Vulkan functions in a custom way**, e.g. using some loader like
++ [Volk](https://github.com/zeux/volk):
++ - Define `VMA_STATIC_VULKAN_FUNCTIONS` and `VMA_DYNAMIC_VULKAN_FUNCTIONS` to 0.
++ - Pass these pointers via structure #VmaVulkanFunctions.
++
++\code
++VmaVulkanFunctions vulkanFunctions = {};
++vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr;
++vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
++
++VmaAllocatorCreateInfo allocatorCreateInfo = {};
++allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
++allocatorCreateInfo.physicalDevice = physicalDevice;
++allocatorCreateInfo.device = device;
++allocatorCreateInfo.instance = instance;
++allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions;
++
++VmaAllocator allocator;
++vmaCreateAllocator(&allocatorCreateInfo, &allocator);
++\endcode
++
++
++\section quick_start_resource_allocation Resource allocation
++
++When you want to create a buffer or image:
++
++-# Fill `VkBufferCreateInfo` / `VkImageCreateInfo` structure.
++-# Fill VmaAllocationCreateInfo structure.
++-# Call vmaCreateBuffer() / vmaCreateImage() to get `VkBuffer`/`VkImage` with memory
++ already allocated and bound to it, plus #VmaAllocation objects that represents its underlying memory.
++
++\code
++VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++bufferInfo.size = 65536;
++bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
++
++VmaAllocationCreateInfo allocInfo = {};
++allocInfo.usage = VMA_MEMORY_USAGE_AUTO;
++
++VkBuffer buffer;
++VmaAllocation allocation;
++vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
++\endcode
++
++Don't forget to destroy your objects when no longer needed:
++
++\code
++vmaDestroyBuffer(allocator, buffer, allocation);
++vmaDestroyAllocator(allocator);
++\endcode
++
++
++\page choosing_memory_type Choosing memory type
++
++Physical devices in Vulkan support various combinations of memory heaps and
++types. Help with choosing correct and optimal memory type for your specific
++resource is one of the key features of this library. You can use it by filling
++appropriate members of VmaAllocationCreateInfo structure, as described below.
++You can also combine multiple methods.
++
++-# If you just want to find memory type index that meets your requirements, you
++ can use function: vmaFindMemoryTypeIndexForBufferInfo(),
++ vmaFindMemoryTypeIndexForImageInfo(), vmaFindMemoryTypeIndex().
++-# If you want to allocate a region of device memory without association with any
++ specific image or buffer, you can use function vmaAllocateMemory(). Usage of
++ this function is not recommended and usually not needed.
++ vmaAllocateMemoryPages() function is also provided for creating multiple allocations at once,
++ which may be useful for sparse binding.
++-# If you already have a buffer or an image created, you want to allocate memory
++ for it and then you will bind it yourself, you can use function
++ vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage().
++ For binding you should use functions: vmaBindBufferMemory(), vmaBindImageMemory()
++ or their extended versions: vmaBindBufferMemory2(), vmaBindImageMemory2().
++-# **This is the easiest and recommended way to use this library:**
++ If you want to create a buffer or an image, allocate memory for it and bind
++ them together, all in one call, you can use function vmaCreateBuffer(),
++ vmaCreateImage().
++
++When using 3. or 4., the library internally queries Vulkan for memory types
++supported for that buffer or image (function `vkGetBufferMemoryRequirements()`)
++and uses only one of these types.
++
++If no memory type can be found that meets all the requirements, these functions
++return `VK_ERROR_FEATURE_NOT_PRESENT`.
++
++You can leave VmaAllocationCreateInfo structure completely filled with zeros.
++It means no requirements are specified for memory type.
++It is valid, although not very useful.
++
++\section choosing_memory_type_usage Usage
++
++The easiest way to specify memory requirements is to fill member
++VmaAllocationCreateInfo::usage using one of the values of enum #VmaMemoryUsage.
++It defines high level, common usage types.
++Since version 3 of the library, it is recommended to use #VMA_MEMORY_USAGE_AUTO to let it select best memory type for your resource automatically.
++
++For example, if you want to create a uniform buffer that will be filled using
++transfer only once or infrequently and then used for rendering every frame as a uniform buffer, you can
++do it using following code. The buffer will most likely end up in a memory type with
++`VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT` to be fast to access by the GPU device.
++
++\code
++VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++bufferInfo.size = 65536;
++bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
++
++VmaAllocationCreateInfo allocInfo = {};
++allocInfo.usage = VMA_MEMORY_USAGE_AUTO;
++
++VkBuffer buffer;
++VmaAllocation allocation;
++vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
++\endcode
++
++If you have a preference for putting the resource in GPU (device) memory or CPU (host) memory
++on systems with discrete graphics card that have the memories separate, you can use
++#VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE or #VMA_MEMORY_USAGE_AUTO_PREFER_HOST.
++
++When using `VMA_MEMORY_USAGE_AUTO*` while you want to map the allocated memory,
++you also need to specify one of the host access flags:
++#VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT.
++This will help the library decide about preferred memory type to ensure it has `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`
++so you can map it.
++
++For example, a staging buffer that will be filled via mapped pointer and then
++used as a source of transfer to the buffer decribed previously can be created like this.
++It will likely and up in a memory type that is `HOST_VISIBLE` and `HOST_COHERENT`
++but not `HOST_CACHED` (meaning uncached, write-combined) and not `DEVICE_LOCAL` (meaning system RAM).
++
++\code
++VkBufferCreateInfo stagingBufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++stagingBufferInfo.size = 65536;
++stagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
++
++VmaAllocationCreateInfo stagingAllocInfo = {};
++stagingAllocInfo.usage = VMA_MEMORY_USAGE_AUTO;
++stagingAllocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
++
++VkBuffer stagingBuffer;
++VmaAllocation stagingAllocation;
++vmaCreateBuffer(allocator, &stagingBufferInfo, &stagingAllocInfo, &stagingBuffer, &stagingAllocation, nullptr);
++\endcode
++
++For more examples of creating different kinds of resources, see chapter \ref usage_patterns.
++
++Usage values `VMA_MEMORY_USAGE_AUTO*` are legal to use only when the library knows
++about the resource being created by having `VkBufferCreateInfo` / `VkImageCreateInfo` passed,
++so they work with functions like: vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo() etc.
++If you allocate raw memory using function vmaAllocateMemory(), you have to use other means of selecting
++memory type, as decribed below.
++
++\note
++Old usage values (`VMA_MEMORY_USAGE_GPU_ONLY`, `VMA_MEMORY_USAGE_CPU_ONLY`,
++`VMA_MEMORY_USAGE_CPU_TO_GPU`, `VMA_MEMORY_USAGE_GPU_TO_CPU`, `VMA_MEMORY_USAGE_CPU_COPY`)
++are still available and work same way as in previous versions of the library
++for backward compatibility, but they are not recommended.
++
++\section choosing_memory_type_required_preferred_flags Required and preferred flags
++
++You can specify more detailed requirements by filling members
++VmaAllocationCreateInfo::requiredFlags and VmaAllocationCreateInfo::preferredFlags
++with a combination of bits from enum `VkMemoryPropertyFlags`. For example,
++if you want to create a buffer that will be persistently mapped on host (so it
++must be `HOST_VISIBLE`) and preferably will also be `HOST_COHERENT` and `HOST_CACHED`,
++use following code:
++
++\code
++VmaAllocationCreateInfo allocInfo = {};
++allocInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
++allocInfo.preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
++allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
++
++VkBuffer buffer;
++VmaAllocation allocation;
++vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
++\endcode
++
++A memory type is chosen that has all the required flags and as many preferred
++flags set as possible.
++
++Value passed in VmaAllocationCreateInfo::usage is internally converted to a set of required and preferred flags,
++plus some extra "magic" (heuristics).
++
++\section choosing_memory_type_explicit_memory_types Explicit memory types
++
++If you inspected memory types available on the physical device and you have
++a preference for memory types that you want to use, you can fill member
++VmaAllocationCreateInfo::memoryTypeBits. It is a bit mask, where each bit set
++means that a memory type with that index is allowed to be used for the
++allocation. Special value 0, just like `UINT32_MAX`, means there are no
++restrictions to memory type index.
++
++Please note that this member is NOT just a memory type index.
++Still you can use it to choose just one, specific memory type.
++For example, if you already determined that your buffer should be created in
++memory type 2, use following code:
++
++\code
++uint32_t memoryTypeIndex = 2;
++
++VmaAllocationCreateInfo allocInfo = {};
++allocInfo.memoryTypeBits = 1u << memoryTypeIndex;
++
++VkBuffer buffer;
++VmaAllocation allocation;
++vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);
++\endcode
++
++
++\section choosing_memory_type_custom_memory_pools Custom memory pools
++
++If you allocate from custom memory pool, all the ways of specifying memory
++requirements described above are not applicable and the aforementioned members
++of VmaAllocationCreateInfo structure are ignored. Memory type is selected
++explicitly when creating the pool and then used to make all the allocations from
++that pool. For further details, see \ref custom_memory_pools.
++
++\section choosing_memory_type_dedicated_allocations Dedicated allocations
++
++Memory for allocations is reserved out of larger block of `VkDeviceMemory`
++allocated from Vulkan internally. That is the main feature of this whole library.
++You can still request a separate memory block to be created for an allocation,
++just like you would do in a trivial solution without using any allocator.
++In that case, a buffer or image is always bound to that memory at offset 0.
++This is called a "dedicated allocation".
++You can explicitly request it by using flag #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
++The library can also internally decide to use dedicated allocation in some cases, e.g.:
++
++- When the size of the allocation is large.
++- When [VK_KHR_dedicated_allocation](@ref vk_khr_dedicated_allocation) extension is enabled
++ and it reports that dedicated allocation is required or recommended for the resource.
++- When allocation of next big memory block fails due to not enough device memory,
++ but allocation with the exact requested size succeeds.
++
++
++\page memory_mapping Memory mapping
++
++To "map memory" in Vulkan means to obtain a CPU pointer to `VkDeviceMemory`,
++to be able to read from it or write to it in CPU code.
++Mapping is possible only of memory allocated from a memory type that has
++`VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag.
++Functions `vkMapMemory()`, `vkUnmapMemory()` are designed for this purpose.
++You can use them directly with memory allocated by this library,
++but it is not recommended because of following issue:
++Mapping the same `VkDeviceMemory` block multiple times is illegal - only one mapping at a time is allowed.
++This includes mapping disjoint regions. Mapping is not reference-counted internally by Vulkan.
++Because of this, Vulkan Memory Allocator provides following facilities:
++
++\note If you want to be able to map an allocation, you need to specify one of the flags
++#VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT
++in VmaAllocationCreateInfo::flags. These flags are required for an allocation to be mappable
++when using #VMA_MEMORY_USAGE_AUTO or other `VMA_MEMORY_USAGE_AUTO*` enum values.
++For other usage values they are ignored and every such allocation made in `HOST_VISIBLE` memory type is mappable,
++but they can still be used for consistency.
++
++\section memory_mapping_mapping_functions Mapping functions
++
++The library provides following functions for mapping of a specific #VmaAllocation: vmaMapMemory(), vmaUnmapMemory().
++They are safer and more convenient to use than standard Vulkan functions.
++You can map an allocation multiple times simultaneously - mapping is reference-counted internally.
++You can also map different allocations simultaneously regardless of whether they use the same `VkDeviceMemory` block.
++The way it is implemented is that the library always maps entire memory block, not just region of the allocation.
++For further details, see description of vmaMapMemory() function.
++Example:
++
++\code
++// Having these objects initialized:
++struct ConstantBuffer
++{
++ ...
++};
++ConstantBuffer constantBufferData = ...
++
++VmaAllocator allocator = ...
++VkBuffer constantBuffer = ...
++VmaAllocation constantBufferAllocation = ...
++
++// You can map and fill your buffer using following code:
++
++void* mappedData;
++vmaMapMemory(allocator, constantBufferAllocation, &mappedData);
++memcpy(mappedData, &constantBufferData, sizeof(constantBufferData));
++vmaUnmapMemory(allocator, constantBufferAllocation);
++\endcode
++
++When mapping, you may see a warning from Vulkan validation layer similar to this one:
++
++<i>Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used.</i>
++
++It happens because the library maps entire `VkDeviceMemory` block, where different
++types of images and buffers may end up together, especially on GPUs with unified memory like Intel.
++You can safely ignore it if you are sure you access only memory of the intended
++object that you wanted to map.
++
++
++\section memory_mapping_persistently_mapped_memory Persistently mapped memory
++
++Kepping your memory persistently mapped is generally OK in Vulkan.
++You don't need to unmap it before using its data on the GPU.
++The library provides a special feature designed for that:
++Allocations made with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag set in
++VmaAllocationCreateInfo::flags stay mapped all the time,
++so you can just access CPU pointer to it any time
++without a need to call any "map" or "unmap" function.
++Example:
++
++\code
++VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++bufCreateInfo.size = sizeof(ConstantBuffer);
++bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
++ VMA_ALLOCATION_CREATE_MAPPED_BIT;
++
++VkBuffer buf;
++VmaAllocation alloc;
++VmaAllocationInfo allocInfo;
++vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
++
++// Buffer is already mapped. You can access its memory.
++memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData));
++\endcode
++
++\note #VMA_ALLOCATION_CREATE_MAPPED_BIT by itself doesn't guarantee that the allocation will end up
++in a mappable memory type.
++For this, you need to also specify #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or
++#VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT.
++#VMA_ALLOCATION_CREATE_MAPPED_BIT only guarantees that if the memory is `HOST_VISIBLE`, the allocation will be mapped on creation.
++For an example of how to make use of this fact, see section \ref usage_patterns_advanced_data_uploading.
++
++\section memory_mapping_cache_control Cache flush and invalidate
++
++Memory in Vulkan doesn't need to be unmapped before using it on GPU,
++but unless a memory types has `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` flag set,
++you need to manually **invalidate** cache before reading of mapped pointer
++and **flush** cache after writing to mapped pointer.
++Map/unmap operations don't do that automatically.
++Vulkan provides following functions for this purpose `vkFlushMappedMemoryRanges()`,
++`vkInvalidateMappedMemoryRanges()`, but this library provides more convenient
++functions that refer to given allocation object: vmaFlushAllocation(),
++vmaInvalidateAllocation(),
++or multiple objects at once: vmaFlushAllocations(), vmaInvalidateAllocations().
++
++Regions of memory specified for flush/invalidate must be aligned to
++`VkPhysicalDeviceLimits::nonCoherentAtomSize`. This is automatically ensured by the library.
++In any memory type that is `HOST_VISIBLE` but not `HOST_COHERENT`, all allocations
++within blocks are aligned to this value, so their offsets are always multiply of
++`nonCoherentAtomSize` and two different allocations never share same "line" of this size.
++
++Also, Windows drivers from all 3 PC GPU vendors (AMD, Intel, NVIDIA)
++currently provide `HOST_COHERENT` flag on all memory types that are
++`HOST_VISIBLE`, so on PC you may not need to bother.
++
++
++\page staying_within_budget Staying within budget
++
++When developing a graphics-intensive game or program, it is important to avoid allocating
++more GPU memory than it is physically available. When the memory is over-committed,
++various bad things can happen, depending on the specific GPU, graphics driver, and
++operating system:
++
++- It may just work without any problems.
++- The application may slow down because some memory blocks are moved to system RAM
++ and the GPU has to access them through PCI Express bus.
++- A new allocation may take very long time to complete, even few seconds, and possibly
++ freeze entire system.
++- The new allocation may fail with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
++- It may even result in GPU crash (TDR), observed as `VK_ERROR_DEVICE_LOST`
++ returned somewhere later.
++
++\section staying_within_budget_querying_for_budget Querying for budget
++
++To query for current memory usage and available budget, use function vmaGetHeapBudgets().
++Returned structure #VmaBudget contains quantities expressed in bytes, per Vulkan memory heap.
++
++Please note that this function returns different information and works faster than
++vmaCalculateStatistics(). vmaGetHeapBudgets() can be called every frame or even before every
++allocation, while vmaCalculateStatistics() is intended to be used rarely,
++only to obtain statistical information, e.g. for debugging purposes.
++
++It is recommended to use <b>VK_EXT_memory_budget</b> device extension to obtain information
++about the budget from Vulkan device. VMA is able to use this extension automatically.
++When not enabled, the allocator behaves same way, but then it estimates current usage
++and available budget based on its internal information and Vulkan memory heap sizes,
++which may be less precise. In order to use this extension:
++
++1. Make sure extensions VK_EXT_memory_budget and VK_KHR_get_physical_device_properties2
++ required by it are available and enable them. Please note that the first is a device
++ extension and the second is instance extension!
++2. Use flag #VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT when creating #VmaAllocator object.
++3. Make sure to call vmaSetCurrentFrameIndex() every frame. Budget is queried from
++ Vulkan inside of it to avoid overhead of querying it with every allocation.
++
++\section staying_within_budget_controlling_memory_usage Controlling memory usage
++
++There are many ways in which you can try to stay within the budget.
++
++First, when making new allocation requires allocating a new memory block, the library
++tries not to exceed the budget automatically. If a block with default recommended size
++(e.g. 256 MB) would go over budget, a smaller block is allocated, possibly even
++dedicated memory for just this resource.
++
++If the size of the requested resource plus current memory usage is more than the
++budget, by default the library still tries to create it, leaving it to the Vulkan
++implementation whether the allocation succeeds or fails. You can change this behavior
++by using #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag. With it, the allocation is
++not made if it would exceed the budget or if the budget is already exceeded.
++VMA then tries to make the allocation from the next eligible Vulkan memory type.
++The all of them fail, the call then fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
++Example usage pattern may be to pass the #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag
++when creating resources that are not essential for the application (e.g. the texture
++of a specific object) and not to pass it when creating critically important resources
++(e.g. render targets).
++
++On AMD graphics cards there is a custom vendor extension available: <b>VK_AMD_memory_overallocation_behavior</b>
++that allows to control the behavior of the Vulkan implementation in out-of-memory cases -
++whether it should fail with an error code or still allow the allocation.
++Usage of this extension involves only passing extra structure on Vulkan device creation,
++so it is out of scope of this library.
++
++Finally, you can also use #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT flag to make sure
++a new allocation is created only when it fits inside one of the existing memory blocks.
++If it would require to allocate a new block, if fails instead with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
++This also ensures that the function call is very fast because it never goes to Vulkan
++to obtain a new block.
++
++\note Creating \ref custom_memory_pools with VmaPoolCreateInfo::minBlockCount
++set to more than 0 will currently try to allocate memory blocks without checking whether they
++fit within budget.
++
++
++\page resource_aliasing Resource aliasing (overlap)
++
++New explicit graphics APIs (Vulkan and Direct3D 12), thanks to manual memory
++management, give an opportunity to alias (overlap) multiple resources in the
++same region of memory - a feature not available in the old APIs (Direct3D 11, OpenGL).
++It can be useful to save video memory, but it must be used with caution.
++
++For example, if you know the flow of your whole render frame in advance, you
++are going to use some intermediate textures or buffers only during a small range of render passes,
++and you know these ranges don't overlap in time, you can bind these resources to
++the same place in memory, even if they have completely different parameters (width, height, format etc.).
++
++![Resource aliasing (overlap)](../gfx/Aliasing.png)
++
++Such scenario is possible using VMA, but you need to create your images manually.
++Then you need to calculate parameters of an allocation to be made using formula:
++
++- allocation size = max(size of each image)
++- allocation alignment = max(alignment of each image)
++- allocation memoryTypeBits = bitwise AND(memoryTypeBits of each image)
++
++Following example shows two different images bound to the same place in memory,
++allocated to fit largest of them.
++
++\code
++// A 512x512 texture to be sampled.
++VkImageCreateInfo img1CreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
++img1CreateInfo.imageType = VK_IMAGE_TYPE_2D;
++img1CreateInfo.extent.width = 512;
++img1CreateInfo.extent.height = 512;
++img1CreateInfo.extent.depth = 1;
++img1CreateInfo.mipLevels = 10;
++img1CreateInfo.arrayLayers = 1;
++img1CreateInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
++img1CreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
++img1CreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
++img1CreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
++img1CreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
++
++// A full screen texture to be used as color attachment.
++VkImageCreateInfo img2CreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
++img2CreateInfo.imageType = VK_IMAGE_TYPE_2D;
++img2CreateInfo.extent.width = 1920;
++img2CreateInfo.extent.height = 1080;
++img2CreateInfo.extent.depth = 1;
++img2CreateInfo.mipLevels = 1;
++img2CreateInfo.arrayLayers = 1;
++img2CreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
++img2CreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
++img2CreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
++img2CreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
++img2CreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
++
++VkImage img1;
++res = vkCreateImage(device, &img1CreateInfo, nullptr, &img1);
++VkImage img2;
++res = vkCreateImage(device, &img2CreateInfo, nullptr, &img2);
++
++VkMemoryRequirements img1MemReq;
++vkGetImageMemoryRequirements(device, img1, &img1MemReq);
++VkMemoryRequirements img2MemReq;
++vkGetImageMemoryRequirements(device, img2, &img2MemReq);
++
++VkMemoryRequirements finalMemReq = {};
++finalMemReq.size = std::max(img1MemReq.size, img2MemReq.size);
++finalMemReq.alignment = std::max(img1MemReq.alignment, img2MemReq.alignment);
++finalMemReq.memoryTypeBits = img1MemReq.memoryTypeBits & img2MemReq.memoryTypeBits;
++// Validate if(finalMemReq.memoryTypeBits != 0)
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
++
++VmaAllocation alloc;
++res = vmaAllocateMemory(allocator, &finalMemReq, &allocCreateInfo, &alloc, nullptr);
++
++res = vmaBindImageMemory(allocator, alloc, img1);
++res = vmaBindImageMemory(allocator, alloc, img2);
++
++// You can use img1, img2 here, but not at the same time!
++
++vmaFreeMemory(allocator, alloc);
++vkDestroyImage(allocator, img2, nullptr);
++vkDestroyImage(allocator, img1, nullptr);
++\endcode
++
++Remember that using resources that alias in memory requires proper synchronization.
++You need to issue a memory barrier to make sure commands that use `img1` and `img2`
++don't overlap on GPU timeline.
++You also need to treat a resource after aliasing as uninitialized - containing garbage data.
++For example, if you use `img1` and then want to use `img2`, you need to issue
++an image memory barrier for `img2` with `oldLayout` = `VK_IMAGE_LAYOUT_UNDEFINED`.
++
++Additional considerations:
++
++- Vulkan also allows to interpret contents of memory between aliasing resources consistently in some cases.
++See chapter 11.8. "Memory Aliasing" of Vulkan specification or `VK_IMAGE_CREATE_ALIAS_BIT` flag.
++- You can create more complex layout where different images and buffers are bound
++at different offsets inside one large allocation. For example, one can imagine
++a big texture used in some render passes, aliasing with a set of many small buffers
++used between in some further passes. To bind a resource at non-zero offset in an allocation,
++use vmaBindBufferMemory2() / vmaBindImageMemory2().
++- Before allocating memory for the resources you want to alias, check `memoryTypeBits`
++returned in memory requirements of each resource to make sure the bits overlap.
++Some GPUs may expose multiple memory types suitable e.g. only for buffers or
++images with `COLOR_ATTACHMENT` usage, so the sets of memory types supported by your
++resources may be disjoint. Aliasing them is not possible in that case.
++
++
++\page custom_memory_pools Custom memory pools
++
++A memory pool contains a number of `VkDeviceMemory` blocks.
++The library automatically creates and manages default pool for each memory type available on the device.
++Default memory pool automatically grows in size.
++Size of allocated blocks is also variable and managed automatically.
++
++You can create custom pool and allocate memory out of it.
++It can be useful if you want to:
++
++- Keep certain kind of allocations separate from others.
++- Enforce particular, fixed size of Vulkan memory blocks.
++- Limit maximum amount of Vulkan memory allocated for that pool.
++- Reserve minimum or fixed amount of Vulkan memory always preallocated for that pool.
++- Use extra parameters for a set of your allocations that are available in #VmaPoolCreateInfo but not in
++ #VmaAllocationCreateInfo - e.g., custom minimum alignment, custom `pNext` chain.
++- Perform defragmentation on a specific subset of your allocations.
++
++To use custom memory pools:
++
++-# Fill VmaPoolCreateInfo structure.
++-# Call vmaCreatePool() to obtain #VmaPool handle.
++-# When making an allocation, set VmaAllocationCreateInfo::pool to this handle.
++ You don't need to specify any other parameters of this structure, like `usage`.
++
++Example:
++
++\code
++// Find memoryTypeIndex for the pool.
++VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++sampleBufCreateInfo.size = 0x10000; // Doesn't matter.
++sampleBufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
++
++VmaAllocationCreateInfo sampleAllocCreateInfo = {};
++sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++
++uint32_t memTypeIndex;
++VkResult res = vmaFindMemoryTypeIndexForBufferInfo(allocator,
++ &sampleBufCreateInfo, &sampleAllocCreateInfo, &memTypeIndex);
++// Check res...
++
++// Create a pool that can have at most 2 blocks, 128 MiB each.
++VmaPoolCreateInfo poolCreateInfo = {};
++poolCreateInfo.memoryTypeIndex = memTypeIndex;
++poolCreateInfo.blockSize = 128ull * 1024 * 1024;
++poolCreateInfo.maxBlockCount = 2;
++
++VmaPool pool;
++res = vmaCreatePool(allocator, &poolCreateInfo, &pool);
++// Check res...
++
++// Allocate a buffer out of it.
++VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++bufCreateInfo.size = 1024;
++bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.pool = pool;
++
++VkBuffer buf;
++VmaAllocation alloc;
++res = vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, nullptr);
++// Check res...
++\endcode
++
++You have to free all allocations made from this pool before destroying it.
++
++\code
++vmaDestroyBuffer(allocator, buf, alloc);
++vmaDestroyPool(allocator, pool);
++\endcode
++
++New versions of this library support creating dedicated allocations in custom pools.
++It is supported only when VmaPoolCreateInfo::blockSize = 0.
++To use this feature, set VmaAllocationCreateInfo::pool to the pointer to your custom pool and
++VmaAllocationCreateInfo::flags to #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
++
++\note Excessive use of custom pools is a common mistake when using this library.
++Custom pools may be useful for special purposes - when you want to
++keep certain type of resources separate e.g. to reserve minimum amount of memory
++for them or limit maximum amount of memory they can occupy. For most
++resources this is not needed and so it is not recommended to create #VmaPool
++objects and allocations out of them. Allocating from the default pool is sufficient.
++
++
++\section custom_memory_pools_MemTypeIndex Choosing memory type index
++
++When creating a pool, you must explicitly specify memory type index.
++To find the one suitable for your buffers or images, you can use helper functions
++vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo().
++You need to provide structures with example parameters of buffers or images
++that you are going to create in that pool.
++
++\code
++VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++exampleBufCreateInfo.size = 1024; // Doesn't matter
++exampleBufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++
++uint32_t memTypeIndex;
++vmaFindMemoryTypeIndexForBufferInfo(allocator, &exampleBufCreateInfo, &allocCreateInfo, &memTypeIndex);
++
++VmaPoolCreateInfo poolCreateInfo = {};
++poolCreateInfo.memoryTypeIndex = memTypeIndex;
++// ...
++\endcode
++
++When creating buffers/images allocated in that pool, provide following parameters:
++
++- `VkBufferCreateInfo`: Prefer to pass same parameters as above.
++ Otherwise you risk creating resources in a memory type that is not suitable for them, which may result in undefined behavior.
++ Using different `VK_BUFFER_USAGE_` flags may work, but you shouldn't create images in a pool intended for buffers
++ or the other way around.
++- VmaAllocationCreateInfo: You don't need to pass same parameters. Fill only `pool` member.
++ Other members are ignored anyway.
++
++\section linear_algorithm Linear allocation algorithm
++
++Each Vulkan memory block managed by this library has accompanying metadata that
++keeps track of used and unused regions. By default, the metadata structure and
++algorithm tries to find best place for new allocations among free regions to
++optimize memory usage. This way you can allocate and free objects in any order.
++
++![Default allocation algorithm](../gfx/Linear_allocator_1_algo_default.png)
++
++Sometimes there is a need to use simpler, linear allocation algorithm. You can
++create custom pool that uses such algorithm by adding flag
++#VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT to VmaPoolCreateInfo::flags while creating
++#VmaPool object. Then an alternative metadata management is used. It always
++creates new allocations after last one and doesn't reuse free regions after
++allocations freed in the middle. It results in better allocation performance and
++less memory consumed by metadata.
++
++![Linear allocation algorithm](../gfx/Linear_allocator_2_algo_linear.png)
++
++With this one flag, you can create a custom pool that can be used in many ways:
++free-at-once, stack, double stack, and ring buffer. See below for details.
++You don't need to specify explicitly which of these options you are going to use - it is detected automatically.
++
++\subsection linear_algorithm_free_at_once Free-at-once
++
++In a pool that uses linear algorithm, you still need to free all the allocations
++individually, e.g. by using vmaFreeMemory() or vmaDestroyBuffer(). You can free
++them in any order. New allocations are always made after last one - free space
++in the middle is not reused. However, when you release all the allocation and
++the pool becomes empty, allocation starts from the beginning again. This way you
++can use linear algorithm to speed up creation of allocations that you are going
++to release all at once.
++
++![Free-at-once](../gfx/Linear_allocator_3_free_at_once.png)
++
++This mode is also available for pools created with VmaPoolCreateInfo::maxBlockCount
++value that allows multiple memory blocks.
++
++\subsection linear_algorithm_stack Stack
++
++When you free an allocation that was created last, its space can be reused.
++Thanks to this, if you always release allocations in the order opposite to their
++creation (LIFO - Last In First Out), you can achieve behavior of a stack.
++
++![Stack](../gfx/Linear_allocator_4_stack.png)
++
++This mode is also available for pools created with VmaPoolCreateInfo::maxBlockCount
++value that allows multiple memory blocks.
++
++\subsection linear_algorithm_double_stack Double stack
++
++The space reserved by a custom pool with linear algorithm may be used by two
++stacks:
++
++- First, default one, growing up from offset 0.
++- Second, "upper" one, growing down from the end towards lower offsets.
++
++To make allocation from the upper stack, add flag #VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT
++to VmaAllocationCreateInfo::flags.
++
++![Double stack](../gfx/Linear_allocator_7_double_stack.png)
++
++Double stack is available only in pools with one memory block -
++VmaPoolCreateInfo::maxBlockCount must be 1. Otherwise behavior is undefined.
++
++When the two stacks' ends meet so there is not enough space between them for a
++new allocation, such allocation fails with usual
++`VK_ERROR_OUT_OF_DEVICE_MEMORY` error.
++
++\subsection linear_algorithm_ring_buffer Ring buffer
++
++When you free some allocations from the beginning and there is not enough free space
++for a new one at the end of a pool, allocator's "cursor" wraps around to the
++beginning and starts allocation there. Thanks to this, if you always release
++allocations in the same order as you created them (FIFO - First In First Out),
++you can achieve behavior of a ring buffer / queue.
++
++![Ring buffer](../gfx/Linear_allocator_5_ring_buffer.png)
++
++Ring buffer is available only in pools with one memory block -
++VmaPoolCreateInfo::maxBlockCount must be 1. Otherwise behavior is undefined.
++
++\note \ref defragmentation is not supported in custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT.
++
++
++\page defragmentation Defragmentation
++
++Interleaved allocations and deallocations of many objects of varying size can
++cause fragmentation over time, which can lead to a situation where the library is unable
++to find a continuous range of free memory for a new allocation despite there is
++enough free space, just scattered across many small free ranges between existing
++allocations.
++
++To mitigate this problem, you can use defragmentation feature.
++It doesn't happen automatically though and needs your cooperation,
++because VMA is a low level library that only allocates memory.
++It cannot recreate buffers and images in a new place as it doesn't remember the contents of `VkBufferCreateInfo` / `VkImageCreateInfo` structures.
++It cannot copy their contents as it doesn't record any commands to a command buffer.
++
++Example:
++
++\code
++VmaDefragmentationInfo defragInfo = {};
++defragInfo.pool = myPool;
++defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT;
++
++VmaDefragmentationContext defragCtx;
++VkResult res = vmaBeginDefragmentation(allocator, &defragInfo, &defragCtx);
++// Check res...
++
++for(;;)
++{
++ VmaDefragmentationPassMoveInfo pass;
++ res = vmaBeginDefragmentationPass(allocator, defragCtx, &pass);
++ if(res == VK_SUCCESS)
++ break;
++ else if(res != VK_INCOMPLETE)
++ // Handle error...
++
++ for(uint32_t i = 0; i < pass.moveCount; ++i)
++ {
++ // Inspect pass.pMoves[i].srcAllocation, identify what buffer/image it represents.
++ VmaAllocationInfo allocInfo;
++ vmaGetAllocationInfo(allocator, pMoves[i].srcAllocation, &allocInfo);
++ MyEngineResourceData* resData = (MyEngineResourceData*)allocInfo.pUserData;
++
++ // Recreate and bind this buffer/image at: pass.pMoves[i].dstMemory, pass.pMoves[i].dstOffset.
++ VkImageCreateInfo imgCreateInfo = ...
++ VkImage newImg;
++ res = vkCreateImage(device, &imgCreateInfo, nullptr, &newImg);
++ // Check res...
++ res = vmaBindImageMemory(allocator, pMoves[i].dstTmpAllocation, newImg);
++ // Check res...
++
++ // Issue a vkCmdCopyBuffer/vkCmdCopyImage to copy its content to the new place.
++ vkCmdCopyImage(cmdBuf, resData->img, ..., newImg, ...);
++ }
++
++ // Make sure the copy commands finished executing.
++ vkWaitForFences(...);
++
++ // Destroy old buffers/images bound with pass.pMoves[i].srcAllocation.
++ for(uint32_t i = 0; i < pass.moveCount; ++i)
++ {
++ // ...
++ vkDestroyImage(device, resData->img, nullptr);
++ }
++
++ // Update appropriate descriptors to point to the new places...
++
++ res = vmaEndDefragmentationPass(allocator, defragCtx, &pass);
++ if(res == VK_SUCCESS)
++ break;
++ else if(res != VK_INCOMPLETE)
++ // Handle error...
++}
++
++vmaEndDefragmentation(allocator, defragCtx, nullptr);
++\endcode
++
++Although functions like vmaCreateBuffer(), vmaCreateImage(), vmaDestroyBuffer(), vmaDestroyImage()
++create/destroy an allocation and a buffer/image at once, these are just a shortcut for
++creating the resource, allocating memory, and binding them together.
++Defragmentation works on memory allocations only. You must handle the rest manually.
++Defragmentation is an iterative process that should repreat "passes" as long as related functions
++return `VK_INCOMPLETE` not `VK_SUCCESS`.
++In each pass:
++
++1. vmaBeginDefragmentationPass() function call:
++ - Calculates and returns the list of allocations to be moved in this pass.
++ Note this can be a time-consuming process.
++ - Reserves destination memory for them by creating temporary destination allocations
++ that you can query for their `VkDeviceMemory` + offset using vmaGetAllocationInfo().
++2. Inside the pass, **you should**:
++ - Inspect the returned list of allocations to be moved.
++ - Create new buffers/images and bind them at the returned destination temporary allocations.
++ - Copy data from source to destination resources if necessary.
++ - Destroy the source buffers/images, but NOT their allocations.
++3. vmaEndDefragmentationPass() function call:
++ - Frees the source memory reserved for the allocations that are moved.
++ - Modifies source #VmaAllocation objects that are moved to point to the destination reserved memory.
++ - Frees `VkDeviceMemory` blocks that became empty.
++
++Unlike in previous iterations of the defragmentation API, there is no list of "movable" allocations passed as a parameter.
++Defragmentation algorithm tries to move all suitable allocations.
++You can, however, refuse to move some of them inside a defragmentation pass, by setting
++`pass.pMoves[i].operation` to #VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE.
++This is not recommended and may result in suboptimal packing of the allocations after defragmentation.
++If you cannot ensure any allocation can be moved, it is better to keep movable allocations separate in a custom pool.
++
++Inside a pass, for each allocation that should be moved:
++
++- You should copy its data from the source to the destination place by calling e.g. `vkCmdCopyBuffer()`, `vkCmdCopyImage()`.
++ - You need to make sure these commands finished executing before destroying the source buffers/images and before calling vmaEndDefragmentationPass().
++- If a resource doesn't contain any meaningful data, e.g. it is a transient color attachment image to be cleared,
++ filled, and used temporarily in each rendering frame, you can just recreate this image
++ without copying its data.
++- If the resource is in `HOST_VISIBLE` and `HOST_CACHED` memory, you can copy its data on the CPU
++ using `memcpy()`.
++- If you cannot move the allocation, you can set `pass.pMoves[i].operation` to #VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE.
++ This will cancel the move.
++ - vmaEndDefragmentationPass() will then free the destination memory
++ not the source memory of the allocation, leaving it unchanged.
++- If you decide the allocation is unimportant and can be destroyed instead of moved (e.g. it wasn't used for long time),
++ you can set `pass.pMoves[i].operation` to #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY.
++ - vmaEndDefragmentationPass() will then free both source and destination memory, and will destroy the source #VmaAllocation object.
++
++You can defragment a specific custom pool by setting VmaDefragmentationInfo::pool
++(like in the example above) or all the default pools by setting this member to null.
++
++Defragmentation is always performed in each pool separately.
++Allocations are never moved between different Vulkan memory types.
++The size of the destination memory reserved for a moved allocation is the same as the original one.
++Alignment of an allocation as it was determined using `vkGetBufferMemoryRequirements()` etc. is also respected after defragmentation.
++Buffers/images should be recreated with the same `VkBufferCreateInfo` / `VkImageCreateInfo` parameters as the original ones.
++
++You can perform the defragmentation incrementally to limit the number of allocations and bytes to be moved
++in each pass, e.g. to call it in sync with render frames and not to experience too big hitches.
++See members: VmaDefragmentationInfo::maxBytesPerPass, VmaDefragmentationInfo::maxAllocationsPerPass.
++
++It is also safe to perform the defragmentation asynchronously to render frames and other Vulkan and VMA
++usage, possibly from multiple threads, with the exception that allocations
++returned in VmaDefragmentationPassMoveInfo::pMoves shouldn't be destroyed until the defragmentation pass is ended.
++
++<b>Mapping</b> is preserved on allocations that are moved during defragmentation.
++Whether through #VMA_ALLOCATION_CREATE_MAPPED_BIT or vmaMapMemory(), the allocations
++are mapped at their new place. Of course, pointer to the mapped data changes, so it needs to be queried
++using VmaAllocationInfo::pMappedData.
++
++\note Defragmentation is not supported in custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT.
++
++
++\page statistics Statistics
++
++This library contains several functions that return information about its internal state,
++especially the amount of memory allocated from Vulkan.
++
++\section statistics_numeric_statistics Numeric statistics
++
++If you need to obtain basic statistics about memory usage per heap, together with current budget,
++you can call function vmaGetHeapBudgets() and inspect structure #VmaBudget.
++This is useful to keep track of memory usage and stay withing budget
++(see also \ref staying_within_budget).
++Example:
++
++\code
++uint32_t heapIndex = ...
++
++VmaBudget budgets[VK_MAX_MEMORY_HEAPS];
++vmaGetHeapBudgets(allocator, budgets);
++
++printf("My heap currently has %u allocations taking %llu B,\n",
++ budgets[heapIndex].statistics.allocationCount,
++ budgets[heapIndex].statistics.allocationBytes);
++printf("allocated out of %u Vulkan device memory blocks taking %llu B,\n",
++ budgets[heapIndex].statistics.blockCount,
++ budgets[heapIndex].statistics.blockBytes);
++printf("Vulkan reports total usage %llu B with budget %llu B.\n",
++ budgets[heapIndex].usage,
++ budgets[heapIndex].budget);
++\endcode
++
++You can query for more detailed statistics per memory heap, type, and totals,
++including minimum and maximum allocation size and unused range size,
++by calling function vmaCalculateStatistics() and inspecting structure #VmaTotalStatistics.
++This function is slower though, as it has to traverse all the internal data structures,
++so it should be used only for debugging purposes.
++
++You can query for statistics of a custom pool using function vmaGetPoolStatistics()
++or vmaCalculatePoolStatistics().
++
++You can query for information about a specific allocation using function vmaGetAllocationInfo().
++It fill structure #VmaAllocationInfo.
++
++\section statistics_json_dump JSON dump
++
++You can dump internal state of the allocator to a string in JSON format using function vmaBuildStatsString().
++The result is guaranteed to be correct JSON.
++It uses ANSI encoding.
++Any strings provided by user (see [Allocation names](@ref allocation_names))
++are copied as-is and properly escaped for JSON, so if they use UTF-8, ISO-8859-2 or any other encoding,
++this JSON string can be treated as using this encoding.
++It must be freed using function vmaFreeStatsString().
++
++The format of this JSON string is not part of official documentation of the library,
++but it will not change in backward-incompatible way without increasing library major version number
++and appropriate mention in changelog.
++
++The JSON string contains all the data that can be obtained using vmaCalculateStatistics().
++It can also contain detailed map of allocated memory blocks and their regions -
++free and occupied by allocations.
++This allows e.g. to visualize the memory or assess fragmentation.
++
++
++\page allocation_annotation Allocation names and user data
++
++\section allocation_user_data Allocation user data
++
++You can annotate allocations with your own information, e.g. for debugging purposes.
++To do that, fill VmaAllocationCreateInfo::pUserData field when creating
++an allocation. It is an opaque `void*` pointer. You can use it e.g. as a pointer,
++some handle, index, key, ordinal number or any other value that would associate
++the allocation with your custom metadata.
++It it useful to identify appropriate data structures in your engine given #VmaAllocation,
++e.g. when doing \ref defragmentation.
++
++\code
++VkBufferCreateInfo bufCreateInfo = ...
++
++MyBufferMetadata* pMetadata = CreateBufferMetadata();
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++allocCreateInfo.pUserData = pMetadata;
++
++VkBuffer buffer;
++VmaAllocation allocation;
++vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buffer, &allocation, nullptr);
++\endcode
++
++The pointer may be later retrieved as VmaAllocationInfo::pUserData:
++
++\code
++VmaAllocationInfo allocInfo;
++vmaGetAllocationInfo(allocator, allocation, &allocInfo);
++MyBufferMetadata* pMetadata = (MyBufferMetadata*)allocInfo.pUserData;
++\endcode
++
++It can also be changed using function vmaSetAllocationUserData().
++
++Values of (non-zero) allocations' `pUserData` are printed in JSON report created by
++vmaBuildStatsString() in hexadecimal form.
++
++\section allocation_names Allocation names
++
++An allocation can also carry a null-terminated string, giving a name to the allocation.
++To set it, call vmaSetAllocationName().
++The library creates internal copy of the string, so the pointer you pass doesn't need
++to be valid for whole lifetime of the allocation. You can free it after the call.
++
++\code
++std::string imageName = "Texture: ";
++imageName += fileName;
++vmaSetAllocationName(allocator, allocation, imageName.c_str());
++\endcode
++
++The string can be later retrieved by inspecting VmaAllocationInfo::pName.
++It is also printed in JSON report created by vmaBuildStatsString().
++
++\note Setting string name to VMA allocation doesn't automatically set it to the Vulkan buffer or image created with it.
++You must do it manually using an extension like VK_EXT_debug_utils, which is independent of this library.
++
++
++\page virtual_allocator Virtual allocator
++
++As an extra feature, the core allocation algorithm of the library is exposed through a simple and convenient API of "virtual allocator".
++It doesn't allocate any real GPU memory. It just keeps track of used and free regions of a "virtual block".
++You can use it to allocate your own memory or other objects, even completely unrelated to Vulkan.
++A common use case is sub-allocation of pieces of one large GPU buffer.
++
++\section virtual_allocator_creating_virtual_block Creating virtual block
++
++To use this functionality, there is no main "allocator" object.
++You don't need to have #VmaAllocator object created.
++All you need to do is to create a separate #VmaVirtualBlock object for each block of memory you want to be managed by the allocator:
++
++-# Fill in #VmaVirtualBlockCreateInfo structure.
++-# Call vmaCreateVirtualBlock(). Get new #VmaVirtualBlock object.
++
++Example:
++
++\code
++VmaVirtualBlockCreateInfo blockCreateInfo = {};
++blockCreateInfo.size = 1048576; // 1 MB
++
++VmaVirtualBlock block;
++VkResult res = vmaCreateVirtualBlock(&blockCreateInfo, &block);
++\endcode
++
++\section virtual_allocator_making_virtual_allocations Making virtual allocations
++
++#VmaVirtualBlock object contains internal data structure that keeps track of free and occupied regions
++using the same code as the main Vulkan memory allocator.
++Similarly to #VmaAllocation for standard GPU allocations, there is #VmaVirtualAllocation type
++that represents an opaque handle to an allocation withing the virtual block.
++
++In order to make such allocation:
++
++-# Fill in #VmaVirtualAllocationCreateInfo structure.
++-# Call vmaVirtualAllocate(). Get new #VmaVirtualAllocation object that represents the allocation.
++ You can also receive `VkDeviceSize offset` that was assigned to the allocation.
++
++Example:
++
++\code
++VmaVirtualAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.size = 4096; // 4 KB
++
++VmaVirtualAllocation alloc;
++VkDeviceSize offset;
++res = vmaVirtualAllocate(block, &allocCreateInfo, &alloc, &offset);
++if(res == VK_SUCCESS)
++{
++ // Use the 4 KB of your memory starting at offset.
++}
++else
++{
++ // Allocation failed - no space for it could be found. Handle this error!
++}
++\endcode
++
++\section virtual_allocator_deallocation Deallocation
++
++When no longer needed, an allocation can be freed by calling vmaVirtualFree().
++You can only pass to this function an allocation that was previously returned by vmaVirtualAllocate()
++called for the same #VmaVirtualBlock.
++
++When whole block is no longer needed, the block object can be released by calling vmaDestroyVirtualBlock().
++All allocations must be freed before the block is destroyed, which is checked internally by an assert.
++However, if you don't want to call vmaVirtualFree() for each allocation, you can use vmaClearVirtualBlock() to free them all at once -
++a feature not available in normal Vulkan memory allocator. Example:
++
++\code
++vmaVirtualFree(block, alloc);
++vmaDestroyVirtualBlock(block);
++\endcode
++
++\section virtual_allocator_allocation_parameters Allocation parameters
++
++You can attach a custom pointer to each allocation by using vmaSetVirtualAllocationUserData().
++Its default value is null.
++It can be used to store any data that needs to be associated with that allocation - e.g. an index, a handle, or a pointer to some
++larger data structure containing more information. Example:
++
++\code
++struct CustomAllocData
++{
++ std::string m_AllocName;
++};
++CustomAllocData* allocData = new CustomAllocData();
++allocData->m_AllocName = "My allocation 1";
++vmaSetVirtualAllocationUserData(block, alloc, allocData);
++\endcode
++
++The pointer can later be fetched, along with allocation offset and size, by passing the allocation handle to function
++vmaGetVirtualAllocationInfo() and inspecting returned structure #VmaVirtualAllocationInfo.
++If you allocated a new object to be used as the custom pointer, don't forget to delete that object before freeing the allocation!
++Example:
++
++\code
++VmaVirtualAllocationInfo allocInfo;
++vmaGetVirtualAllocationInfo(block, alloc, &allocInfo);
++delete (CustomAllocData*)allocInfo.pUserData;
++
++vmaVirtualFree(block, alloc);
++\endcode
++
++\section virtual_allocator_alignment_and_units Alignment and units
++
++It feels natural to express sizes and offsets in bytes.
++If an offset of an allocation needs to be aligned to a multiply of some number (e.g. 4 bytes), you can fill optional member
++VmaVirtualAllocationCreateInfo::alignment to request it. Example:
++
++\code
++VmaVirtualAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.size = 4096; // 4 KB
++allocCreateInfo.alignment = 4; // Returned offset must be a multiply of 4 B
++
++VmaVirtualAllocation alloc;
++res = vmaVirtualAllocate(block, &allocCreateInfo, &alloc, nullptr);
++\endcode
++
++Alignments of different allocations made from one block may vary.
++However, if all alignments and sizes are always multiply of some size e.g. 4 B or `sizeof(MyDataStruct)`,
++you can express all sizes, alignments, and offsets in multiples of that size instead of individual bytes.
++It might be more convenient, but you need to make sure to use this new unit consistently in all the places:
++
++- VmaVirtualBlockCreateInfo::size
++- VmaVirtualAllocationCreateInfo::size and VmaVirtualAllocationCreateInfo::alignment
++- Using offset returned by vmaVirtualAllocate() or in VmaVirtualAllocationInfo::offset
++
++\section virtual_allocator_statistics Statistics
++
++You can obtain statistics of a virtual block using vmaGetVirtualBlockStatistics()
++(to get brief statistics that are fast to calculate)
++or vmaCalculateVirtualBlockStatistics() (to get more detailed statistics, slower to calculate).
++The functions fill structures #VmaStatistics, #VmaDetailedStatistics respectively - same as used by the normal Vulkan memory allocator.
++Example:
++
++\code
++VmaStatistics stats;
++vmaGetVirtualBlockStatistics(block, &stats);
++printf("My virtual block has %llu bytes used by %u virtual allocations\n",
++ stats.allocationBytes, stats.allocationCount);
++\endcode
++
++You can also request a full list of allocations and free regions as a string in JSON format by calling
++vmaBuildVirtualBlockStatsString().
++Returned string must be later freed using vmaFreeVirtualBlockStatsString().
++The format of this string differs from the one returned by the main Vulkan allocator, but it is similar.
++
++\section virtual_allocator_additional_considerations Additional considerations
++
++The "virtual allocator" functionality is implemented on a level of individual memory blocks.
++Keeping track of a whole collection of blocks, allocating new ones when out of free space,
++deleting empty ones, and deciding which one to try first for a new allocation must be implemented by the user.
++
++Alternative allocation algorithms are supported, just like in custom pools of the real GPU memory.
++See enum #VmaVirtualBlockCreateFlagBits to learn how to specify them (e.g. #VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT).
++You can find their description in chapter \ref custom_memory_pools.
++Allocation strategies are also supported.
++See enum #VmaVirtualAllocationCreateFlagBits to learn how to specify them (e.g. #VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT).
++
++Following features are supported only by the allocator of the real GPU memory and not by virtual allocations:
++buffer-image granularity, `VMA_DEBUG_MARGIN`, `VMA_MIN_ALIGNMENT`.
++
++
++\page debugging_memory_usage Debugging incorrect memory usage
++
++If you suspect a bug with memory usage, like usage of uninitialized memory or
++memory being overwritten out of bounds of an allocation,
++you can use debug features of this library to verify this.
++
++\section debugging_memory_usage_initialization Memory initialization
++
++If you experience a bug with incorrect and nondeterministic data in your program and you suspect uninitialized memory to be used,
++you can enable automatic memory initialization to verify this.
++To do it, define macro `VMA_DEBUG_INITIALIZE_ALLOCATIONS` to 1.
++
++\code
++#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1
++#include "vk_mem_alloc.h"
++\endcode
++
++It makes memory of all new allocations initialized to bit pattern `0xDCDCDCDC`.
++Before an allocation is destroyed, its memory is filled with bit pattern `0xEFEFEFEF`.
++Memory is automatically mapped and unmapped if necessary.
++
++If you find these values while debugging your program, good chances are that you incorrectly
++read Vulkan memory that is allocated but not initialized, or already freed, respectively.
++
++Memory initialization works only with memory types that are `HOST_VISIBLE`.
++It works also with dedicated allocations.
++
++\section debugging_memory_usage_margins Margins
++
++By default, allocations are laid out in memory blocks next to each other if possible
++(considering required alignment, `bufferImageGranularity`, and `nonCoherentAtomSize`).
++
++![Allocations without margin](../gfx/Margins_1.png)
++
++Define macro `VMA_DEBUG_MARGIN` to some non-zero value (e.g. 16) to enforce specified
++number of bytes as a margin after every allocation.
++
++\code
++#define VMA_DEBUG_MARGIN 16
++#include "vk_mem_alloc.h"
++\endcode
++
++![Allocations with margin](../gfx/Margins_2.png)
++
++If your bug goes away after enabling margins, it means it may be caused by memory
++being overwritten outside of allocation boundaries. It is not 100% certain though.
++Change in application behavior may also be caused by different order and distribution
++of allocations across memory blocks after margins are applied.
++
++Margins work with all types of memory.
++
++Margin is applied only to allocations made out of memory blocks and not to dedicated
++allocations, which have their own memory block of specific size.
++It is thus not applied to allocations made using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag
++or those automatically decided to put into dedicated allocations, e.g. due to its
++large size or recommended by VK_KHR_dedicated_allocation extension.
++
++Margins appear in [JSON dump](@ref statistics_json_dump) as part of free space.
++
++Note that enabling margins increases memory usage and fragmentation.
++
++Margins do not apply to \ref virtual_allocator.
++
++\section debugging_memory_usage_corruption_detection Corruption detection
++
++You can additionally define macro `VMA_DEBUG_DETECT_CORRUPTION` to 1 to enable validation
++of contents of the margins.
++
++\code
++#define VMA_DEBUG_MARGIN 16
++#define VMA_DEBUG_DETECT_CORRUPTION 1
++#include "vk_mem_alloc.h"
++\endcode
++
++When this feature is enabled, number of bytes specified as `VMA_DEBUG_MARGIN`
++(it must be multiply of 4) after every allocation is filled with a magic number.
++This idea is also know as "canary".
++Memory is automatically mapped and unmapped if necessary.
++
++This number is validated automatically when the allocation is destroyed.
++If it is not equal to the expected value, `VMA_ASSERT()` is executed.
++It clearly means that either CPU or GPU overwritten the memory outside of boundaries of the allocation,
++which indicates a serious bug.
++
++You can also explicitly request checking margins of all allocations in all memory blocks
++that belong to specified memory types by using function vmaCheckCorruption(),
++or in memory blocks that belong to specified custom pool, by using function
++vmaCheckPoolCorruption().
++
++Margin validation (corruption detection) works only for memory types that are
++`HOST_VISIBLE` and `HOST_COHERENT`.
++
++
++\page opengl_interop OpenGL Interop
++
++VMA provides some features that help with interoperability with OpenGL.
++
++\section opengl_interop_exporting_memory Exporting memory
++
++If you want to attach `VkExportMemoryAllocateInfoKHR` structure to `pNext` chain of memory allocations made by the library:
++
++It is recommended to create \ref custom_memory_pools for such allocations.
++Define and fill in your `VkExportMemoryAllocateInfoKHR` structure and attach it to VmaPoolCreateInfo::pMemoryAllocateNext
++while creating the custom pool.
++Please note that the structure must remain alive and unchanged for the whole lifetime of the #VmaPool,
++not only while creating it, as no copy of the structure is made,
++but its original pointer is used for each allocation instead.
++
++If you want to export all memory allocated by the library from certain memory types,
++also dedicated allocations or other allocations made from default pools,
++an alternative solution is to fill in VmaAllocatorCreateInfo::pTypeExternalMemoryHandleTypes.
++It should point to an array with `VkExternalMemoryHandleTypeFlagsKHR` to be automatically passed by the library
++through `VkExportMemoryAllocateInfoKHR` on each allocation made from a specific memory type.
++Please note that new versions of the library also support dedicated allocations created in custom pools.
++
++You should not mix these two methods in a way that allows to apply both to the same memory type.
++Otherwise, `VkExportMemoryAllocateInfoKHR` structure would be attached twice to the `pNext` chain of `VkMemoryAllocateInfo`.
++
++
++\section opengl_interop_custom_alignment Custom alignment
++
++Buffers or images exported to a different API like OpenGL may require a different alignment,
++higher than the one used by the library automatically, queried from functions like `vkGetBufferMemoryRequirements`.
++To impose such alignment:
++
++It is recommended to create \ref custom_memory_pools for such allocations.
++Set VmaPoolCreateInfo::minAllocationAlignment member to the minimum alignment required for each allocation
++to be made out of this pool.
++The alignment actually used will be the maximum of this member and the alignment returned for the specific buffer or image
++from a function like `vkGetBufferMemoryRequirements`, which is called by VMA automatically.
++
++If you want to create a buffer with a specific minimum alignment out of default pools,
++use special function vmaCreateBufferWithAlignment(), which takes additional parameter `minAlignment`.
++
++Note the problem of alignment affects only resources placed inside bigger `VkDeviceMemory` blocks and not dedicated
++allocations, as these, by definition, always have alignment = 0 because the resource is bound to the beginning of its dedicated block.
++Contrary to Direct3D 12, Vulkan doesn't have a concept of alignment of the entire memory block passed on its allocation.
++
++
++\page usage_patterns Recommended usage patterns
++
++Vulkan gives great flexibility in memory allocation.
++This chapter shows the most common patterns.
++
++See also slides from talk:
++[Sawicki, Adam. Advanced Graphics Techniques Tutorial: Memory management in Vulkan and DX12. Game Developers Conference, 2018](https://www.gdcvault.com/play/1025458/Advanced-Graphics-Techniques-Tutorial-New)
++
++
++\section usage_patterns_gpu_only GPU-only resource
++
++<b>When:</b>
++Any resources that you frequently write and read on GPU,
++e.g. images used as color attachments (aka "render targets"), depth-stencil attachments,
++images/buffers used as storage image/buffer (aka "Unordered Access View (UAV)").
++
++<b>What to do:</b>
++Let the library select the optimal memory type, which will likely have `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`.
++
++\code
++VkImageCreateInfo imgCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
++imgCreateInfo.imageType = VK_IMAGE_TYPE_2D;
++imgCreateInfo.extent.width = 3840;
++imgCreateInfo.extent.height = 2160;
++imgCreateInfo.extent.depth = 1;
++imgCreateInfo.mipLevels = 1;
++imgCreateInfo.arrayLayers = 1;
++imgCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
++imgCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
++imgCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
++imgCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
++imgCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++allocCreateInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
++allocCreateInfo.priority = 1.0f;
++
++VkImage img;
++VmaAllocation alloc;
++vmaCreateImage(allocator, &imgCreateInfo, &allocCreateInfo, &img, &alloc, nullptr);
++\endcode
++
++<b>Also consider:</b>
++Consider creating them as dedicated allocations using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
++especially if they are large or if you plan to destroy and recreate them with different sizes
++e.g. when display resolution changes.
++Prefer to create such resources first and all other GPU resources (like textures and vertex buffers) later.
++When VK_EXT_memory_priority extension is enabled, it is also worth setting high priority to such allocation
++to decrease chances to be evicted to system memory by the operating system.
++
++\section usage_patterns_staging_copy_upload Staging copy for upload
++
++<b>When:</b>
++A "staging" buffer than you want to map and fill from CPU code, then use as a source od transfer
++to some GPU resource.
++
++<b>What to do:</b>
++Use flag #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT.
++Let the library select the optimal memory type, which will always have `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`.
++
++\code
++VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++bufCreateInfo.size = 65536;
++bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
++ VMA_ALLOCATION_CREATE_MAPPED_BIT;
++
++VkBuffer buf;
++VmaAllocation alloc;
++VmaAllocationInfo allocInfo;
++vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
++
++...
++
++memcpy(allocInfo.pMappedData, myData, myDataSize);
++\endcode
++
++<b>Also consider:</b>
++You can map the allocation using vmaMapMemory() or you can create it as persistenly mapped
++using #VMA_ALLOCATION_CREATE_MAPPED_BIT, as in the example above.
++
++
++\section usage_patterns_readback Readback
++
++<b>When:</b>
++Buffers for data written by or transferred from the GPU that you want to read back on the CPU,
++e.g. results of some computations.
++
++<b>What to do:</b>
++Use flag #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT.
++Let the library select the optimal memory type, which will always have `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`
++and `VK_MEMORY_PROPERTY_HOST_CACHED_BIT`.
++
++\code
++VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++bufCreateInfo.size = 65536;
++bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT |
++ VMA_ALLOCATION_CREATE_MAPPED_BIT;
++
++VkBuffer buf;
++VmaAllocation alloc;
++VmaAllocationInfo allocInfo;
++vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
++
++...
++
++const float* downloadedData = (const float*)allocInfo.pMappedData;
++\endcode
++
++
++\section usage_patterns_advanced_data_uploading Advanced data uploading
++
++For resources that you frequently write on CPU via mapped pointer and
++freqnently read on GPU e.g. as a uniform buffer (also called "dynamic"), multiple options are possible:
++
++-# Easiest solution is to have one copy of the resource in `HOST_VISIBLE` memory,
++ even if it means system RAM (not `DEVICE_LOCAL`) on systems with a discrete graphics card,
++ and make the device reach out to that resource directly.
++ - Reads performed by the device will then go through PCI Express bus.
++ The performace of this access may be limited, but it may be fine depending on the size
++ of this resource (whether it is small enough to quickly end up in GPU cache) and the sparsity
++ of access.
++-# On systems with unified memory (e.g. AMD APU or Intel integrated graphics, mobile chips),
++ a memory type may be available that is both `HOST_VISIBLE` (available for mapping) and `DEVICE_LOCAL`
++ (fast to access from the GPU). Then, it is likely the best choice for such type of resource.
++-# Systems with a discrete graphics card and separate video memory may or may not expose
++ a memory type that is both `HOST_VISIBLE` and `DEVICE_LOCAL`, also known as Base Address Register (BAR).
++ If they do, it represents a piece of VRAM (or entire VRAM, if ReBAR is enabled in the motherboard BIOS)
++ that is available to CPU for mapping.
++ - Writes performed by the host to that memory go through PCI Express bus.
++ The performance of these writes may be limited, but it may be fine, especially on PCIe 4.0,
++ as long as rules of using uncached and write-combined memory are followed - only sequential writes and no reads.
++-# Finally, you may need or prefer to create a separate copy of the resource in `DEVICE_LOCAL` memory,
++ a separate "staging" copy in `HOST_VISIBLE` memory and perform an explicit transfer command between them.
++
++Thankfully, VMA offers an aid to create and use such resources in the the way optimal
++for the current Vulkan device. To help the library make the best choice,
++use flag #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT together with
++#VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT.
++It will then prefer a memory type that is both `DEVICE_LOCAL` and `HOST_VISIBLE` (integrated memory or BAR),
++but if no such memory type is available or allocation from it fails
++(PC graphics cards have only 256 MB of BAR by default, unless ReBAR is supported and enabled in BIOS),
++it will fall back to `DEVICE_LOCAL` memory for fast GPU access.
++It is then up to you to detect that the allocation ended up in a memory type that is not `HOST_VISIBLE`,
++so you need to create another "staging" allocation and perform explicit transfers.
++
++\code
++VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++bufCreateInfo.size = 65536;
++bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
++ VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
++ VMA_ALLOCATION_CREATE_MAPPED_BIT;
++
++VkBuffer buf;
++VmaAllocation alloc;
++VmaAllocationInfo allocInfo;
++vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
++
++VkMemoryPropertyFlags memPropFlags;
++vmaGetAllocationMemoryProperties(allocator, alloc, &memPropFlags);
++
++if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
++{
++ // Allocation ended up in a mappable memory and is already mapped - write to it directly.
++
++ // [Executed in runtime]:
++ memcpy(allocInfo.pMappedData, myData, myDataSize);
++}
++else
++{
++ // Allocation ended up in a non-mappable memory - need to transfer.
++ VkBufferCreateInfo stagingBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
++ stagingBufCreateInfo.size = 65536;
++ stagingBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
++
++ VmaAllocationCreateInfo stagingAllocCreateInfo = {};
++ stagingAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++ stagingAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
++ VMA_ALLOCATION_CREATE_MAPPED_BIT;
++
++ VkBuffer stagingBuf;
++ VmaAllocation stagingAlloc;
++ VmaAllocationInfo stagingAllocInfo;
++ vmaCreateBuffer(allocator, &stagingBufCreateInfo, &stagingAllocCreateInfo,
++ &stagingBuf, &stagingAlloc, stagingAllocInfo);
++
++ // [Executed in runtime]:
++ memcpy(stagingAllocInfo.pMappedData, myData, myDataSize);
++ //vkCmdPipelineBarrier: VK_ACCESS_HOST_WRITE_BIT --> VK_ACCESS_TRANSFER_READ_BIT
++ VkBufferCopy bufCopy = {
++ 0, // srcOffset
++ 0, // dstOffset,
++ myDataSize); // size
++ vkCmdCopyBuffer(cmdBuf, stagingBuf, buf, 1, &bufCopy);
++}
++\endcode
++
++\section usage_patterns_other_use_cases Other use cases
++
++Here are some other, less obvious use cases and their recommended settings:
++
++- An image that is used only as transfer source and destination, but it should stay on the device,
++ as it is used to temporarily store a copy of some texture, e.g. from the current to the next frame,
++ for temporal antialiasing or other temporal effects.
++ - Use `VkImageCreateInfo::usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT`
++ - Use VmaAllocationCreateInfo::usage = #VMA_MEMORY_USAGE_AUTO
++- An image that is used only as transfer source and destination, but it should be placed
++ in the system RAM despite it doesn't need to be mapped, because it serves as a "swap" copy to evict
++ least recently used textures from VRAM.
++ - Use `VkImageCreateInfo::usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT`
++ - Use VmaAllocationCreateInfo::usage = #VMA_MEMORY_USAGE_AUTO_PREFER_HOST,
++ as VMA needs a hint here to differentiate from the previous case.
++- A buffer that you want to map and write from the CPU, directly read from the GPU
++ (e.g. as a uniform or vertex buffer), but you have a clear preference to place it in device or
++ host memory due to its large size.
++ - Use `VkBufferCreateInfo::usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT`
++ - Use VmaAllocationCreateInfo::usage = #VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE or #VMA_MEMORY_USAGE_AUTO_PREFER_HOST
++ - Use VmaAllocationCreateInfo::flags = #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
++
++
++\page configuration Configuration
++
++Please check "CONFIGURATION SECTION" in the code to find macros that you can define
++before each include of this file or change directly in this file to provide
++your own implementation of basic facilities like assert, `min()` and `max()` functions,
++mutex, atomic etc.
++The library uses its own implementation of containers by default, but you can switch to using
++STL containers instead.
++
++For example, define `VMA_ASSERT(expr)` before including the library to provide
++custom implementation of the assertion, compatible with your project.
++By default it is defined to standard C `assert(expr)` in `_DEBUG` configuration
++and empty otherwise.
++
++\section config_Vulkan_functions Pointers to Vulkan functions
++
++There are multiple ways to import pointers to Vulkan functions in the library.
++In the simplest case you don't need to do anything.
++If the compilation or linking of your program or the initialization of the #VmaAllocator
++doesn't work for you, you can try to reconfigure it.
++
++First, the allocator tries to fetch pointers to Vulkan functions linked statically,
++like this:
++
++\code
++m_VulkanFunctions.vkAllocateMemory = (PFN_vkAllocateMemory)vkAllocateMemory;
++\endcode
++
++If you want to disable this feature, set configuration macro: `#define VMA_STATIC_VULKAN_FUNCTIONS 0`.
++
++Second, you can provide the pointers yourself by setting member VmaAllocatorCreateInfo::pVulkanFunctions.
++You can fetch them e.g. using functions `vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` or
++by using a helper library like [volk](https://github.com/zeux/volk).
++
++Third, VMA tries to fetch remaining pointers that are still null by calling
++`vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` on its own.
++You need to only fill in VmaVulkanFunctions::vkGetInstanceProcAddr and VmaVulkanFunctions::vkGetDeviceProcAddr.
++Other pointers will be fetched automatically.
++If you want to disable this feature, set configuration macro: `#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0`.
++
++Finally, all the function pointers required by the library (considering selected
++Vulkan version and enabled extensions) are checked with `VMA_ASSERT` if they are not null.
++
++
++\section custom_memory_allocator Custom host memory allocator
++
++If you use custom allocator for CPU memory rather than default operator `new`
++and `delete` from C++, you can make this library using your allocator as well
++by filling optional member VmaAllocatorCreateInfo::pAllocationCallbacks. These
++functions will be passed to Vulkan, as well as used by the library itself to
++make any CPU-side allocations.
++
++\section allocation_callbacks Device memory allocation callbacks
++
++The library makes calls to `vkAllocateMemory()` and `vkFreeMemory()` internally.
++You can setup callbacks to be informed about these calls, e.g. for the purpose
++of gathering some statistics. To do it, fill optional member
++VmaAllocatorCreateInfo::pDeviceMemoryCallbacks.
++
++\section heap_memory_limit Device heap memory limit
++
++When device memory of certain heap runs out of free space, new allocations may
++fail (returning error code) or they may succeed, silently pushing some existing_
++memory blocks from GPU VRAM to system RAM (which degrades performance). This
++behavior is implementation-dependent - it depends on GPU vendor and graphics
++driver.
++
++On AMD cards it can be controlled while creating Vulkan device object by using
++VK_AMD_memory_overallocation_behavior extension, if available.
++
++Alternatively, if you want to test how your program behaves with limited amount of Vulkan device
++memory available without switching your graphics card to one that really has
++smaller VRAM, you can use a feature of this library intended for this purpose.
++To do it, fill optional member VmaAllocatorCreateInfo::pHeapSizeLimit.
++
++
++
++\page vk_khr_dedicated_allocation VK_KHR_dedicated_allocation
++
++VK_KHR_dedicated_allocation is a Vulkan extension which can be used to improve
++performance on some GPUs. It augments Vulkan API with possibility to query
++driver whether it prefers particular buffer or image to have its own, dedicated
++allocation (separate `VkDeviceMemory` block) for better efficiency - to be able
++to do some internal optimizations. The extension is supported by this library.
++It will be used automatically when enabled.
++
++It has been promoted to core Vulkan 1.1, so if you use eligible Vulkan version
++and inform VMA about it by setting VmaAllocatorCreateInfo::vulkanApiVersion,
++you are all set.
++
++Otherwise, if you want to use it as an extension:
++
++1 . When creating Vulkan device, check if following 2 device extensions are
++supported (call `vkEnumerateDeviceExtensionProperties()`).
++If yes, enable them (fill `VkDeviceCreateInfo::ppEnabledExtensionNames`).
++
++- VK_KHR_get_memory_requirements2
++- VK_KHR_dedicated_allocation
++
++If you enabled these extensions:
++
++2 . Use #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag when creating
++your #VmaAllocator to inform the library that you enabled required extensions
++and you want the library to use them.
++
++\code
++allocatorInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT;
++
++vmaCreateAllocator(&allocatorInfo, &allocator);
++\endcode
++
++That is all. The extension will be automatically used whenever you create a
++buffer using vmaCreateBuffer() or image using vmaCreateImage().
++
++When using the extension together with Vulkan Validation Layer, you will receive
++warnings like this:
++
++_vkBindBufferMemory(): Binding memory to buffer 0x33 but vkGetBufferMemoryRequirements() has not been called on that buffer._
++
++It is OK, you should just ignore it. It happens because you use function
++`vkGetBufferMemoryRequirements2KHR()` instead of standard
++`vkGetBufferMemoryRequirements()`, while the validation layer seems to be
++unaware of it.
++
++To learn more about this extension, see:
++
++- [VK_KHR_dedicated_allocation in Vulkan specification](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/chap50.html#VK_KHR_dedicated_allocation)
++- [VK_KHR_dedicated_allocation unofficial manual](http://asawicki.info/articles/VK_KHR_dedicated_allocation.php5)
++
++
++
++\page vk_ext_memory_priority VK_EXT_memory_priority
++
++VK_EXT_memory_priority is a device extension that allows to pass additional "priority"
++value to Vulkan memory allocations that the implementation may use prefer certain
++buffers and images that are critical for performance to stay in device-local memory
++in cases when the memory is over-subscribed, while some others may be moved to the system memory.
++
++VMA offers convenient usage of this extension.
++If you enable it, you can pass "priority" parameter when creating allocations or custom pools
++and the library automatically passes the value to Vulkan using this extension.
++
++If you want to use this extension in connection with VMA, follow these steps:
++
++\section vk_ext_memory_priority_initialization Initialization
++
++1) Call `vkEnumerateDeviceExtensionProperties` for the physical device.
++Check if the extension is supported - if returned array of `VkExtensionProperties` contains "VK_EXT_memory_priority".
++
++2) Call `vkGetPhysicalDeviceFeatures2` for the physical device instead of old `vkGetPhysicalDeviceFeatures`.
++Attach additional structure `VkPhysicalDeviceMemoryPriorityFeaturesEXT` to `VkPhysicalDeviceFeatures2::pNext` to be returned.
++Check if the device feature is really supported - check if `VkPhysicalDeviceMemoryPriorityFeaturesEXT::memoryPriority` is true.
++
++3) While creating device with `vkCreateDevice`, enable this extension - add "VK_EXT_memory_priority"
++to the list passed as `VkDeviceCreateInfo::ppEnabledExtensionNames`.
++
++4) While creating the device, also don't set `VkDeviceCreateInfo::pEnabledFeatures`.
++Fill in `VkPhysicalDeviceFeatures2` structure instead and pass it as `VkDeviceCreateInfo::pNext`.
++Enable this device feature - attach additional structure `VkPhysicalDeviceMemoryPriorityFeaturesEXT` to
++`VkPhysicalDeviceFeatures2::pNext` chain and set its member `memoryPriority` to `VK_TRUE`.
++
++5) While creating #VmaAllocator with vmaCreateAllocator() inform VMA that you
++have enabled this extension and feature - add #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
++to VmaAllocatorCreateInfo::flags.
++
++\section vk_ext_memory_priority_usage Usage
++
++When using this extension, you should initialize following member:
++
++- VmaAllocationCreateInfo::priority when creating a dedicated allocation with #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
++- VmaPoolCreateInfo::priority when creating a custom pool.
++
++It should be a floating-point value between `0.0f` and `1.0f`, where recommended default is `0.5f`.
++Memory allocated with higher value can be treated by the Vulkan implementation as higher priority
++and so it can have lower chances of being pushed out to system memory, experiencing degraded performance.
++
++It might be a good idea to create performance-critical resources like color-attachment or depth-stencil images
++as dedicated and set high priority to them. For example:
++
++\code
++VkImageCreateInfo imgCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
++imgCreateInfo.imageType = VK_IMAGE_TYPE_2D;
++imgCreateInfo.extent.width = 3840;
++imgCreateInfo.extent.height = 2160;
++imgCreateInfo.extent.depth = 1;
++imgCreateInfo.mipLevels = 1;
++imgCreateInfo.arrayLayers = 1;
++imgCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
++imgCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
++imgCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
++imgCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
++imgCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
++
++VmaAllocationCreateInfo allocCreateInfo = {};
++allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
++allocCreateInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
++allocCreateInfo.priority = 1.0f;
++
++VkImage img;
++VmaAllocation alloc;
++vmaCreateImage(allocator, &imgCreateInfo, &allocCreateInfo, &img, &alloc, nullptr);
++\endcode
++
++`priority` member is ignored in the following situations:
++
++- Allocations created in custom pools: They inherit the priority, along with all other allocation parameters
++ from the parametrs passed in #VmaPoolCreateInfo when the pool was created.
++- Allocations created in default pools: They inherit the priority from the parameters
++ VMA used when creating default pools, which means `priority == 0.5f`.
++
++
++\page vk_amd_device_coherent_memory VK_AMD_device_coherent_memory
++
++VK_AMD_device_coherent_memory is a device extension that enables access to
++additional memory types with `VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD` and
++`VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD` flag. It is useful mostly for
++allocation of buffers intended for writing "breadcrumb markers" in between passes
++or draw calls, which in turn are useful for debugging GPU crash/hang/TDR cases.
++
++When the extension is available but has not been enabled, Vulkan physical device
++still exposes those memory types, but their usage is forbidden. VMA automatically
++takes care of that - it returns `VK_ERROR_FEATURE_NOT_PRESENT` when an attempt
++to allocate memory of such type is made.
++
++If you want to use this extension in connection with VMA, follow these steps:
++
++\section vk_amd_device_coherent_memory_initialization Initialization
++
++1) Call `vkEnumerateDeviceExtensionProperties` for the physical device.
++Check if the extension is supported - if returned array of `VkExtensionProperties` contains "VK_AMD_device_coherent_memory".
++
++2) Call `vkGetPhysicalDeviceFeatures2` for the physical device instead of old `vkGetPhysicalDeviceFeatures`.
++Attach additional structure `VkPhysicalDeviceCoherentMemoryFeaturesAMD` to `VkPhysicalDeviceFeatures2::pNext` to be returned.
++Check if the device feature is really supported - check if `VkPhysicalDeviceCoherentMemoryFeaturesAMD::deviceCoherentMemory` is true.
++
++3) While creating device with `vkCreateDevice`, enable this extension - add "VK_AMD_device_coherent_memory"
++to the list passed as `VkDeviceCreateInfo::ppEnabledExtensionNames`.
++
++4) While creating the device, also don't set `VkDeviceCreateInfo::pEnabledFeatures`.
++Fill in `VkPhysicalDeviceFeatures2` structure instead and pass it as `VkDeviceCreateInfo::pNext`.
++Enable this device feature - attach additional structure `VkPhysicalDeviceCoherentMemoryFeaturesAMD` to
++`VkPhysicalDeviceFeatures2::pNext` and set its member `deviceCoherentMemory` to `VK_TRUE`.
++
++5) While creating #VmaAllocator with vmaCreateAllocator() inform VMA that you
++have enabled this extension and feature - add #VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT
++to VmaAllocatorCreateInfo::flags.
++
++\section vk_amd_device_coherent_memory_usage Usage
++
++After following steps described above, you can create VMA allocations and custom pools
++out of the special `DEVICE_COHERENT` and `DEVICE_UNCACHED` memory types on eligible
++devices. There are multiple ways to do it, for example:
++
++- You can request or prefer to allocate out of such memory types by adding
++ `VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD` to VmaAllocationCreateInfo::requiredFlags
++ or VmaAllocationCreateInfo::preferredFlags. Those flags can be freely mixed with
++ other ways of \ref choosing_memory_type, like setting VmaAllocationCreateInfo::usage.
++- If you manually found memory type index to use for this purpose, force allocation
++ from this specific index by setting VmaAllocationCreateInfo::memoryTypeBits `= 1u << index`.
++
++\section vk_amd_device_coherent_memory_more_information More information
++
++To learn more about this extension, see [VK_AMD_device_coherent_memory in Vulkan specification](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_AMD_device_coherent_memory.html)
++
++Example use of this extension can be found in the code of the sample and test suite
++accompanying this library.
++
++
++\page enabling_buffer_device_address Enabling buffer device address
++
++Device extension VK_KHR_buffer_device_address
++allow to fetch raw GPU pointer to a buffer and pass it for usage in a shader code.
++It has been promoted to core Vulkan 1.2.
++
++If you want to use this feature in connection with VMA, follow these steps:
++
++\section enabling_buffer_device_address_initialization Initialization
++
++1) (For Vulkan version < 1.2) Call `vkEnumerateDeviceExtensionProperties` for the physical device.
++Check if the extension is supported - if returned array of `VkExtensionProperties` contains
++"VK_KHR_buffer_device_address".
++
++2) Call `vkGetPhysicalDeviceFeatures2` for the physical device instead of old `vkGetPhysicalDeviceFeatures`.
++Attach additional structure `VkPhysicalDeviceBufferDeviceAddressFeatures*` to `VkPhysicalDeviceFeatures2::pNext` to be returned.
++Check if the device feature is really supported - check if `VkPhysicalDeviceBufferDeviceAddressFeatures::bufferDeviceAddress` is true.
++
++3) (For Vulkan version < 1.2) While creating device with `vkCreateDevice`, enable this extension - add
++"VK_KHR_buffer_device_address" to the list passed as `VkDeviceCreateInfo::ppEnabledExtensionNames`.
++
++4) While creating the device, also don't set `VkDeviceCreateInfo::pEnabledFeatures`.
++Fill in `VkPhysicalDeviceFeatures2` structure instead and pass it as `VkDeviceCreateInfo::pNext`.
++Enable this device feature - attach additional structure `VkPhysicalDeviceBufferDeviceAddressFeatures*` to
++`VkPhysicalDeviceFeatures2::pNext` and set its member `bufferDeviceAddress` to `VK_TRUE`.
++
++5) While creating #VmaAllocator with vmaCreateAllocator() inform VMA that you
++have enabled this feature - add #VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT
++to VmaAllocatorCreateInfo::flags.
++
++\section enabling_buffer_device_address_usage Usage
++
++After following steps described above, you can create buffers with `VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT*` using VMA.
++The library automatically adds `VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT*` to
++allocated memory blocks wherever it might be needed.
++
++Please note that the library supports only `VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT*`.
++The second part of this functionality related to "capture and replay" is not supported,
++as it is intended for usage in debugging tools like RenderDoc, not in everyday Vulkan usage.
++
++\section enabling_buffer_device_address_more_information More information
++
++To learn more about this extension, see [VK_KHR_buffer_device_address in Vulkan specification](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/chap46.html#VK_KHR_buffer_device_address)
++
++Example use of this extension can be found in the code of the sample and test suite
++accompanying this library.
++
++\page general_considerations General considerations
++
++\section general_considerations_thread_safety Thread safety
++
++- The library has no global state, so separate #VmaAllocator objects can be used
++ independently.
++ There should be no need to create multiple such objects though - one per `VkDevice` is enough.
++- By default, all calls to functions that take #VmaAllocator as first parameter
++ are safe to call from multiple threads simultaneously because they are
++ synchronized internally when needed.
++ This includes allocation and deallocation from default memory pool, as well as custom #VmaPool.
++- When the allocator is created with #VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT
++ flag, calls to functions that take such #VmaAllocator object must be
++ synchronized externally.
++- Access to a #VmaAllocation object must be externally synchronized. For example,
++ you must not call vmaGetAllocationInfo() and vmaMapMemory() from different
++ threads at the same time if you pass the same #VmaAllocation object to these
++ functions.
++- #VmaVirtualBlock is not safe to be used from multiple threads simultaneously.
++
++\section general_considerations_versioning_and_compatibility Versioning and compatibility
++
++The library uses [**Semantic Versioning**](https://semver.org/),
++which means version numbers follow convention: Major.Minor.Patch (e.g. 2.3.0), where:
++
++- Incremented Patch version means a release is backward- and forward-compatible,
++ introducing only some internal improvements, bug fixes, optimizations etc.
++ or changes that are out of scope of the official API described in this documentation.
++- Incremented Minor version means a release is backward-compatible,
++ so existing code that uses the library should continue to work, while some new
++ symbols could have been added: new structures, functions, new values in existing
++ enums and bit flags, new structure members, but not new function parameters.
++- Incrementing Major version means a release could break some backward compatibility.
++
++All changes between official releases are documented in file "CHANGELOG.md".
++
++\warning Backward compatiblity is considered on the level of C++ source code, not binary linkage.
++Adding new members to existing structures is treated as backward compatible if initializing
++the new members to binary zero results in the old behavior.
++You should always fully initialize all library structures to zeros and not rely on their
++exact binary size.
++
++\section general_considerations_validation_layer_warnings Validation layer warnings
++
++When using this library, you can meet following types of warnings issued by
++Vulkan validation layer. They don't necessarily indicate a bug, so you may need
++to just ignore them.
++
++- *vkBindBufferMemory(): Binding memory to buffer 0xeb8e4 but vkGetBufferMemoryRequirements() has not been called on that buffer.*
++ - It happens when VK_KHR_dedicated_allocation extension is enabled.
++ `vkGetBufferMemoryRequirements2KHR` function is used instead, while validation layer seems to be unaware of it.
++- *Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used.*
++ - It happens when you map a buffer or image, because the library maps entire
++ `VkDeviceMemory` block, where different types of images and buffers may end
++ up together, especially on GPUs with unified memory like Intel.
++- *Non-linear image 0xebc91 is aliased with linear buffer 0xeb8e4 which may indicate a bug.*
++ - It may happen when you use [defragmentation](@ref defragmentation).
++
++\section general_considerations_allocation_algorithm Allocation algorithm
++
++The library uses following algorithm for allocation, in order:
++
++-# Try to find free range of memory in existing blocks.
++-# If failed, try to create a new block of `VkDeviceMemory`, with preferred block size.
++-# If failed, try to create such block with size / 2, size / 4, size / 8.
++-# If failed, try to allocate separate `VkDeviceMemory` for this allocation,
++ just like when you use #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
++-# If failed, choose other memory type that meets the requirements specified in
++ VmaAllocationCreateInfo and go to point 1.
++-# If failed, return `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
++
++\section general_considerations_features_not_supported Features not supported
++
++Features deliberately excluded from the scope of this library:
++
++-# **Data transfer.** Uploading (streaming) and downloading data of buffers and images
++ between CPU and GPU memory and related synchronization is responsibility of the user.
++ Defining some "texture" object that would automatically stream its data from a
++ staging copy in CPU memory to GPU memory would rather be a feature of another,
++ higher-level library implemented on top of VMA.
++ VMA doesn't record any commands to a `VkCommandBuffer`. It just allocates memory.
++-# **Recreation of buffers and images.** Although the library has functions for
++ buffer and image creation: vmaCreateBuffer(), vmaCreateImage(), you need to
++ recreate these objects yourself after defragmentation. That is because the big
++ structures `VkBufferCreateInfo`, `VkImageCreateInfo` are not stored in
++ #VmaAllocation object.
++-# **Handling CPU memory allocation failures.** When dynamically creating small C++
++ objects in CPU memory (not Vulkan memory), allocation failures are not checked
++ and handled gracefully, because that would complicate code significantly and
++ is usually not needed in desktop PC applications anyway.
++ Success of an allocation is just checked with an assert.
++-# **Code free of any compiler warnings.** Maintaining the library to compile and
++ work correctly on so many different platforms is hard enough. Being free of
++ any warnings, on any version of any compiler, is simply not feasible.
++ There are many preprocessor macros that make some variables unused, function parameters unreferenced,
++ or conditional expressions constant in some configurations.
++ The code of this library should not be bigger or more complicated just to silence these warnings.
++ It is recommended to disable such warnings instead.
++-# This is a C++ library with C interface. **Bindings or ports to any other programming languages** are welcome as external projects but
++ are not going to be included into this repository.
++*/
diff --git a/external/skia/windows-do-not-modify-logfont.patch.0 b/external/skia/windows-do-not-modify-logfont.patch.0
new file mode 100644
index 000000000..30c5c1e96
--- /dev/null
+++ b/external/skia/windows-do-not-modify-logfont.patch.0
@@ -0,0 +1,29 @@
+--- ./src/ports/SkFontHost_win.cpp
++++ ./src/ports/SkFontHost_win.cpp
+@@ -349,7 +349,7 @@ static bool FindByLogFont(SkTypeface* face, void* ctx) {
+ */
+ SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) {
+ LOGFONT lf = origLF;
+- make_canonical(&lf);
++// make_canonical(&lf);
+ sk_sp<SkTypeface> face = SkTypefaceCache::FindByProcAndRef(FindByLogFont, &lf);
+ if (!face) {
+ face = LogFontTypeface::Make(lf);
+@@ -363,7 +363,7 @@ SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) {
+ */
+ sk_sp<SkTypeface> SkCreateFontMemResourceTypefaceFromLOGFONT(const LOGFONT& origLF, HANDLE fontMemResource) {
+ LOGFONT lf = origLF;
+- make_canonical(&lf);
++// make_canonical(&lf);
+ // We'll never get a cache hit, so no point in putting this in SkTypefaceCache.
+ return FontMemResourceTypeface::Make(lf, fontMemResource);
+ }
+@@ -686,7 +686,7 @@ SkScalerContext_GDI::SkScalerContext_GDI(sk_sp<LogFontTypeface> rawTypeface,
+
+ LOGFONT lf = typeface->fLogFont;
+ lf.lfHeight = -SkScalarTruncToInt(gdiTextSize);
+- lf.lfQuality = compute_quality(fRec);
++// lf.lfQuality = compute_quality(fRec);
+ fFont = CreateFontIndirect(&lf);
+ if (!fFont) {
+ return;
diff --git a/external/skia/windows-force-unicode-api.patch.0 b/external/skia/windows-force-unicode-api.patch.0
new file mode 100644
index 000000000..f73de176d
--- /dev/null
+++ b/external/skia/windows-force-unicode-api.patch.0
@@ -0,0 +1,31 @@
+diff --git a/include/ports/SkTypeface_win.h b/include/ports/SkTypeface_win.h
+index f659adf0e9..34446fc7a1 100644
+--- ./include/ports/SkTypeface_win.h
++++ ./include/ports/SkTypeface_win.h
+@@ -26,7 +26,7 @@ typedef LOGFONTA LOGFONT;
+ * corresponding typeface for the specified logfont. The caller is responsible
+ * for calling unref() when it is finished.
+ */
+-SK_API SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT&);
++SK_API SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONTW&);
+
+ /**
+ * Copy the LOGFONT associated with this typeface into the lf parameter. Note
+@@ -34,7 +34,7 @@ SK_API SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT&);
+ * not track this (the paint does).
+ * typeface may be NULL, in which case we return the logfont for the default font.
+ */
+-SK_API void SkLOGFONTFromTypeface(const SkTypeface* typeface, LOGFONT* lf);
++SK_API void SkLOGFONTFromTypeface(const SkTypeface* typeface, LOGFONTW* lf);
+
+ /**
+ * Set an optional callback to ensure that the data behind a LOGFONT is loaded.
+@@ -42,7 +42,7 @@ SK_API void SkLOGFONTFromTypeface(const SkTypeface* typeface, LOGFONT* lf);
+ * Normally this is null, and is only required if the font data needs to be
+ * remotely (re)loaded.
+ */
+-SK_API void SkTypeface_SetEnsureLOGFONTAccessibleProc(void (*)(const LOGFONT&));
++SK_API void SkTypeface_SetEnsureLOGFONTAccessibleProc(void (*)(const LOGFONTW&));
+
+ // Experimental!
+ //
diff --git a/external/skia/windows-libraries-system32.patch.1 b/external/skia/windows-libraries-system32.patch.1
new file mode 100644
index 000000000..45c0e35d1
--- /dev/null
+++ b/external/skia/windows-libraries-system32.patch.1
@@ -0,0 +1,13 @@
+diff --git a/src/ports/SkOSLibrary_win.cpp b/src/ports/SkOSLibrary_win.cpp
+index d2dcbe0af6..c288bbf177 100644
+--- a/src/ports/SkOSLibrary_win.cpp
++++ b/src/ports/SkOSLibrary_win.cpp
+@@ -11,7 +11,7 @@
+ #include "src/ports/SkOSLibrary.h"
+
+ void* SkLoadDynamicLibrary(const char* libraryName) {
+- return LoadLibraryA(libraryName);
++ return LoadLibraryExA(libraryName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ }
+
+ void* SkGetProcedureAddress(void* library, const char* functionName) {
diff --git a/external/skia/windows-raster-surface-no-copies.patch.1 b/external/skia/windows-raster-surface-no-copies.patch.1
new file mode 100644
index 000000000..0c5804d85
--- /dev/null
+++ b/external/skia/windows-raster-surface-no-copies.patch.1
@@ -0,0 +1,39 @@
+diff --git a/tools/sk_app/win/RasterWindowContext_win.cpp b/tools/sk_app/win/RasterWindowContext_win.cpp
+index 9548220ce6..49f1f9ed17 100644
+--- a/tools/sk_app/win/RasterWindowContext_win.cpp
++++ b/tools/sk_app/win/RasterWindowContext_win.cpp
+@@ -55,7 +55,7 @@ void RasterWindowContext_win::resize(int w, int h) {
+ fWidth = w;
+ fHeight = h;
+ fBackbufferSurface.reset();
+- const size_t bmpSize = sizeof(BITMAPINFOHEADER) + w * h * sizeof(uint32_t);
++ const size_t bmpSize = sizeof(BITMAPINFO);
+ fSurfaceMemory.reset(bmpSize);
+ BITMAPINFO* bmpInfo = reinterpret_cast<BITMAPINFO*>(fSurfaceMemory.get());
+ ZeroMemory(bmpInfo, sizeof(BITMAPINFO));
+@@ -65,11 +65,12 @@ void RasterWindowContext_win::resize(int w, int h) {
+ bmpInfo->bmiHeader.biPlanes = 1;
+ bmpInfo->bmiHeader.biBitCount = 32;
+ bmpInfo->bmiHeader.biCompression = BI_RGB;
+- void* pixels = bmpInfo->bmiColors;
++ // Do not use a packed DIB bitmap, SkSurface_Raster::onNewImageSnapshot() does
++ // a deep copy if it does not own the pixels.
+
+ SkImageInfo info = SkImageInfo::Make(w, h, fDisplayParams.fColorType, kPremul_SkAlphaType,
+ fDisplayParams.fColorSpace);
+- fBackbufferSurface = SkSurface::MakeRasterDirect(info, pixels, sizeof(uint32_t) * w);
++ fBackbufferSurface = SkSurface::MakeRaster(info);
+ }
+
+ sk_sp<SkSurface> RasterWindowContext_win::getBackbufferSurface() { return fBackbufferSurface; }
+@@ -77,7 +78,9 @@ sk_sp<SkSurface> RasterWindowContext_win::getBackbufferSurface() { return fBackb
+ void RasterWindowContext_win::swapBuffers() {
+ BITMAPINFO* bmpInfo = reinterpret_cast<BITMAPINFO*>(fSurfaceMemory.get());
+ HDC dc = GetDC(fWnd);
+- StretchDIBits(dc, 0, 0, fWidth, fHeight, 0, 0, fWidth, fHeight, bmpInfo->bmiColors, bmpInfo,
++ SkPixmap pixmap;
++ fBackbufferSurface->peekPixels(&pixmap);
++ StretchDIBits(dc, 0, 0, fWidth, fHeight, 0, 0, fWidth, fHeight, pixmap.addr(), bmpInfo,
+ DIB_RGB_COLORS, SRCCOPY);
+ ReleaseDC(fWnd, dc);
+ }
diff --git a/external/skia/windows-text-gamma.patch.0 b/external/skia/windows-text-gamma.patch.0
new file mode 100644
index 000000000..624636b7d
--- /dev/null
+++ b/external/skia/windows-text-gamma.patch.0
@@ -0,0 +1,70 @@
+--- ./src/ports/SkFontHost_win.cpp.sav 2020-03-18 10:26:52.470184300 +0100
++++ ./src/ports/SkFontHost_win.cpp 2020-03-18 12:08:04.598406700 +0100
+@@ -1215,17 +1215,23 @@
+ // since the caller may require A8 for maskfilters, we can't check for BW
+ // ... until we have the caller tell us that explicitly
+ const SkGdiRGB* src = (const SkGdiRGB*)bits;
++#if defined(SK_GAMMA_APPLY_TO_A8)
+ if (fPreBlend.isApplicable()) {
+ RGBToA8<true>(src, srcRB, glyph, fPreBlend.fG);
+- } else {
++ } else
++#endif
++ {
+ RGBToA8<false>(src, srcRB, glyph, fPreBlend.fG);
+ }
+ } else { // LCD16
+ const SkGdiRGB* src = (const SkGdiRGB*)bits;
+ SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat);
++#if defined(SK_GAMMA_APPLY_TO_A8)
+ if (fPreBlend.isApplicable()) {
+ RGBToLcd16<true>(src, srcRB, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
+- } else {
++ } else
++#endif
++ {
+ RGBToLcd16<false>(src, srcRB, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
+ }
+ }
+--- ./src/ports/SkScalerContext_win_dw.cpp
++++ ./src/ports/SkScalerContext_win_dw.cpp
+@@ -1132,27 +1132,36 @@ void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
+ BilevelToBW(src, glyph);
+ } else if (!isLCD(fRec)) {
+ if (textureType == DWRITE_TEXTURE_ALIASED_1x1) {
++#if defined(SK_GAMMA_APPLY_TO_A8)
+ if (fPreBlend.isApplicable()) {
+ GrayscaleToA8<true>(src, glyph, fPreBlend.fG);
+- } else {
++ } else
++#endif
++ {
+ GrayscaleToA8<false>(src, glyph, fPreBlend.fG);
+ }
+ } else {
++#if defined(SK_GAMMA_APPLY_TO_A8)
+ if (fPreBlend.isApplicable()) {
+ RGBToA8<true>(src, glyph, fPreBlend.fG);
+- } else {
++ } else
++#endif
++ {
+ RGBToA8<false>(src, glyph, fPreBlend.fG);
+ }
+ }
+ } else {
+ SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat);
++#if defined(SK_GAMMA_APPLY_TO_A8)
+ if (fPreBlend.isApplicable()) {
+ if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) {
+ RGBToLcd16<true, false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
+ } else {
+ RGBToLcd16<true, true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
+ }
+- } else {
++ } else
++#endif
++ {
+ if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) {
+ RGBToLcd16<false, false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
+ } else {
diff --git a/external/skia/windows-typeface-directwrite.patch.0 b/external/skia/windows-typeface-directwrite.patch.0
new file mode 100644
index 000000000..56e8209ce
--- /dev/null
+++ b/external/skia/windows-typeface-directwrite.patch.0
@@ -0,0 +1,48 @@
+--- ./include/ports/SkTypeface_win.h
++++ ./include/ports/SkTypeface_win.h
+@@ -75,5 +75,13 @@ SK_API sk_sp<SkFontMgr> SkFontMgr_New_DirectWriteRenderer(sk_sp<SkRemotableFontM
+ */
+ SK_API sk_sp<SkRemotableFontMgr> SkRemotableFontMgr_New_DirectWrite();
+
++struct IDWriteFontFace;
++struct IDWriteFont;
++struct IDWriteFontFamily;
++SK_API SkTypeface* SkCreateTypefaceDirectWrite(sk_sp<SkFontMgr> fontMgr,
++ IDWriteFontFace* fontFace,
++ IDWriteFont* font,
++ IDWriteFontFamily* fontFamily);
++
+ #endif // SK_BUILD_FOR_WIN
+ #endif // SkTypeface_win_DEFINED
+--- ./src/ports/SkFontMgr_win_dw.cpp
++++ ./src/ports/SkFontMgr_win_dw.cpp
+@@ -320,6 +320,10 @@ private:
+
+ friend class SkFontStyleSet_DirectWrite;
+ friend class FontFallbackRenderer;
++ friend SK_API SkTypeface* SkCreateTypefaceDirectWrite(sk_sp<SkFontMgr> fontMgr,
++ IDWriteFontFace* fontFace,
++ IDWriteFont* font,
++ IDWriteFontFamily* fontFamily);
+ };
+
+ class SkFontStyleSet_DirectWrite : public SkFontStyleSet {
+@@ -1215,6 +1219,18 @@ SK_API sk_sp<SkFontMgr> SkFontMgr_New_DirectWrite(IDWriteFactory* factory,
+ defaultFamilyName, defaultFamilyNameLen);
+ }
+
++SkTypeface* SkCreateTypefaceDirectWrite(sk_sp<SkFontMgr> fontMgr,
++ IDWriteFontFace* fontFace,
++ IDWriteFont* font,
++ IDWriteFontFamily* fontFamily)
++{
++ SkFontMgr_DirectWrite* mgr = dynamic_cast<SkFontMgr_DirectWrite*>(fontMgr.get());
++ if(!mgr)
++ return nullptr;
++ sk_sp<SkTypeface> typeface = mgr->makeTypefaceFromDWriteFont(fontFace, font, fontFamily);
++ return typeface.release();
++}
++
+ #include "include/ports/SkFontMgr_indirect.h"
+ SK_API sk_sp<SkFontMgr> SkFontMgr_New_DirectWriteRenderer(sk_sp<SkRemotableFontMgr> proxy) {
+ sk_sp<SkFontMgr> impl(SkFontMgr_New_DirectWrite());
diff --git a/external/twain_dsm/Module_twain_dsm.mk b/external/twain_dsm/Module_twain_dsm.mk
new file mode 100644
index 000000000..bbaedb77b
--- /dev/null
+++ b/external/twain_dsm/Module_twain_dsm.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,twain_dsm))
+
+ifeq ($(OS),WNT)
+ifeq ($(BUILD_X86),TRUE)
+$(eval $(call gb_Module_add_targets,twain_dsm,\
+ UnpackedTarball_twain_dsm \
+))
+endif
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/twain_dsm/README b/external/twain_dsm/README
new file mode 100644
index 000000000..b12e77001
--- /dev/null
+++ b/external/twain_dsm/README
@@ -0,0 +1 @@
+Windows scanner support. \ No newline at end of file
diff --git a/external/twain_dsm/UnpackedTarball_twain_dsm.mk b/external/twain_dsm/UnpackedTarball_twain_dsm.mk
new file mode 100644
index 000000000..11be31e9e
--- /dev/null
+++ b/external/twain_dsm/UnpackedTarball_twain_dsm.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,twain_dsm))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,twain_dsm,$(TWAIN_DSM_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/ucpp/Executable_ucpp.mk b/external/ucpp/Executable_ucpp.mk
new file mode 100644
index 000000000..a4be71c49
--- /dev/null
+++ b/external/ucpp/Executable_ucpp.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Executable_Executable,ucpp))
+
+$(eval $(call gb_Executable_set_warnings_disabled,ucpp))
+
+$(eval $(call gb_Executable_use_unpacked,ucpp,ucpp))
+
+$(eval $(call gb_Executable_add_defs,ucpp,\
+ -DNO_UCPP_BUF \
+ -DUCPP_CONFIG \
+ -DSTAND_ALONE \
+))
+
+$(eval $(call gb_Executable_add_generated_cobjects,ucpp,\
+ UnpackedTarball/ucpp/assert \
+ UnpackedTarball/ucpp/cpp \
+ UnpackedTarball/ucpp/eval \
+ UnpackedTarball/ucpp/hash \
+ UnpackedTarball/ucpp/lexer \
+ UnpackedTarball/ucpp/macro \
+ UnpackedTarball/ucpp/mem \
+ UnpackedTarball/ucpp/nhash \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/ucpp/Makefile b/external/ucpp/Makefile
new file mode 100644
index 000000000..569ad8a0b
--- /dev/null
+++ b/external/ucpp/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/ucpp/Module_ucpp.mk b/external/ucpp/Module_ucpp.mk
new file mode 100644
index 000000000..dc4c02f53
--- /dev/null
+++ b/external/ucpp/Module_ucpp.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,ucpp))
+
+# if not cross-compiling or we need ucpp for ODK
+ifneq (,$(if $(CROSS_COMPILING),,T)$(filter ODK,$(BUILD_TYPE)))
+$(eval $(call gb_Module_add_targets,ucpp,\
+ Executable_ucpp \
+ UnpackedTarball_ucpp \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/ucpp/README b/external/ucpp/README
new file mode 100644
index 000000000..9246c701a
--- /dev/null
+++ b/external/ucpp/README
@@ -0,0 +1,3 @@
+ucpp is a C99 preprocessor
+
+Used to be hosted at https://code.google.com/p/ucpp/ - not sure where it's gone
diff --git a/external/ucpp/UnpackedTarball_ucpp.mk b/external/ucpp/UnpackedTarball_ucpp.mk
new file mode 100644
index 000000000..04d7113b8
--- /dev/null
+++ b/external/ucpp/UnpackedTarball_ucpp.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,ucpp))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,ucpp,$(UCPP_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,ucpp,0))
+
+$(eval $(call gb_UnpackedTarball_add_patches,ucpp,\
+ external/ucpp/ucpp.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/ucpp/ucpp.patch b/external/ucpp/ucpp.patch
new file mode 100644
index 000000000..c9c4b92b7
--- /dev/null
+++ b/external/ucpp/ucpp.patch
@@ -0,0 +1,11 @@
+--- cpp.c
++++ cpp.c
+@@ -2464,7 +2464,7 @@
+ warning(-1, "unknown option '%s'", argv[i]);
+ } else {
+ if (filename != 0) {
+- error(-1, "spurious filename '%s'", argv[i]);
++ error(-1, "spurious duplicate filename '%s' - vs. '%s' ", argv[i], filename);
+ return 2;
+ }
+ filename = argv[i];
diff --git a/external/unixODBC/README b/external/unixODBC/README
new file mode 100644
index 000000000..5f01f07cc
--- /dev/null
+++ b/external/unixODBC/README
@@ -0,0 +1 @@
+Library and API with which to access Data Sources from [http://www.unixodbc.org/]
diff --git a/external/unixODBC/inc/odbc/sql.h b/external/unixODBC/inc/odbc/sql.h
new file mode 100644
index 000000000..6d1e16083
--- /dev/null
+++ b/external/unixODBC/inc/odbc/sql.h
@@ -0,0 +1,824 @@
+/**************************************************
+ * sql.h
+ *
+ * These should be consistent with the MS version.
+ *
+ **************************************************/
+#ifndef __SQL_H
+#define __SQL_H
+
+
+/****************************
+ * default to 3.51 declare something else before here and you get a whole new ball of wax
+ ***************************/
+#ifndef ODBCVER
+#define ODBCVER 0x0351
+#endif
+
+#ifndef __SQLTYPES_H
+#include "odbc/sqltypes.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************
+ * some ret values
+ ***************************/
+#define SQL_NULL_DATA (-1)
+#define SQL_DATA_AT_EXEC (-2)
+#define SQL_SUCCESS 0
+#define SQL_SUCCESS_WITH_INFO 1
+#if (ODBCVER >= 0x0300)
+#define SQL_NO_DATA 100
+#endif
+#define SQL_ERROR (-1)
+#define SQL_INVALID_HANDLE (-2)
+#define SQL_STILL_EXECUTING 2
+#define SQL_NEED_DATA 99
+#define SQL_SUCCEEDED(rc) (((rc)&(~1))==0)
+
+/****************************
+ * use these to indicate string termination to some function
+ ***************************/
+#define SQL_NTS (-3)
+#define SQL_NTSL (-3L)
+
+/* maximum message length */
+#define SQL_MAX_MESSAGE_LENGTH 512
+
+/* date/time length constants */
+#if (ODBCVER >= 0x0300)
+#define SQL_DATE_LEN 10
+#define SQL_TIME_LEN 8 /* add P+1 if precision is nonzero */
+#define SQL_TIMESTAMP_LEN 19 /* add P+1 if precision is nonzero */
+#endif
+
+/* handle type identifiers */
+#if (ODBCVER >= 0x0300)
+#define SQL_HANDLE_ENV 1
+#define SQL_HANDLE_DBC 2
+#define SQL_HANDLE_STMT 3
+#define SQL_HANDLE_DESC 4
+#endif
+
+/* environment attribute */
+#if (ODBCVER >= 0x0300)
+#define SQL_ATTR_OUTPUT_NTS 10001
+#endif
+
+/* connection attributes */
+#if (ODBCVER >= 0x0300)
+#define SQL_ATTR_AUTO_IPD 10001
+#define SQL_ATTR_METADATA_ID 10014
+#endif /* ODBCVER >= 0x0300 */
+
+/* statement attributes */
+#if (ODBCVER >= 0x0300)
+#define SQL_ATTR_APP_ROW_DESC 10010
+#define SQL_ATTR_APP_PARAM_DESC 10011
+#define SQL_ATTR_IMP_ROW_DESC 10012
+#define SQL_ATTR_IMP_PARAM_DESC 10013
+#define SQL_ATTR_CURSOR_SCROLLABLE (-1)
+#define SQL_ATTR_CURSOR_SENSITIVITY (-2)
+#endif
+
+/* SQL_ATTR_CURSOR_SCROLLABLE values */
+#if (ODBCVER >= 0x0300)
+#define SQL_NONSCROLLABLE 0
+#define SQL_SCROLLABLE 1
+#endif /* ODBCVER >= 0x0300 */
+
+/* identifiers of fields in the SQL descriptor */
+#if (ODBCVER >= 0x0300)
+#define SQL_DESC_COUNT 1001
+#define SQL_DESC_TYPE 1002
+#define SQL_DESC_LENGTH 1003
+#define SQL_DESC_OCTET_LENGTH_PTR 1004
+#define SQL_DESC_PRECISION 1005
+#define SQL_DESC_SCALE 1006
+#define SQL_DESC_DATETIME_INTERVAL_CODE 1007
+#define SQL_DESC_NULLABLE 1008
+#define SQL_DESC_INDICATOR_PTR 1009
+#define SQL_DESC_DATA_PTR 1010
+#define SQL_DESC_NAME 1011
+#define SQL_DESC_UNNAMED 1012
+#define SQL_DESC_OCTET_LENGTH 1013
+#define SQL_DESC_ALLOC_TYPE 1099
+#endif
+
+/* identifiers of fields in the diagnostics area */
+#if (ODBCVER >= 0x0300)
+#define SQL_DIAG_RETURNCODE 1
+#define SQL_DIAG_NUMBER 2
+#define SQL_DIAG_ROW_COUNT 3
+#define SQL_DIAG_SQLSTATE 4
+#define SQL_DIAG_NATIVE 5
+#define SQL_DIAG_MESSAGE_TEXT 6
+#define SQL_DIAG_DYNAMIC_FUNCTION 7
+#define SQL_DIAG_CLASS_ORIGIN 8
+#define SQL_DIAG_SUBCLASS_ORIGIN 9
+#define SQL_DIAG_CONNECTION_NAME 10
+#define SQL_DIAG_SERVER_NAME 11
+#define SQL_DIAG_DYNAMIC_FUNCTION_CODE 12
+#endif
+
+/* dynamic function codes */
+#if (ODBCVER >= 0x0300)
+#define SQL_DIAG_ALTER_DOMAIN 3
+#define SQL_DIAG_ALTER_TABLE 4
+#define SQL_DIAG_CALL 7
+#define SQL_DIAG_CREATE_ASSERTION 6
+#define SQL_DIAG_CREATE_CHARACTER_SET 8
+#define SQL_DIAG_CREATE_COLLATION 10
+#define SQL_DIAG_CREATE_DOMAIN 23
+#define SQL_DIAG_CREATE_INDEX (-1)
+#define SQL_DIAG_CREATE_SCHEMA 64
+#define SQL_DIAG_CREATE_TABLE 77
+#define SQL_DIAG_CREATE_TRANSLATION 79
+#define SQL_DIAG_CREATE_VIEW 84
+#define SQL_DIAG_DELETE_WHERE 19
+#define SQL_DIAG_DROP_ASSERTION 24
+#define SQL_DIAG_DROP_CHARACTER_SET 25
+#define SQL_DIAG_DROP_COLLATION 26
+#define SQL_DIAG_DROP_DOMAIN 27
+#define SQL_DIAG_DROP_INDEX (-2)
+#define SQL_DIAG_DROP_SCHEMA 31
+#define SQL_DIAG_DROP_TABLE 32
+#define SQL_DIAG_DROP_TRANSLATION 33
+#define SQL_DIAG_DROP_VIEW 36
+#define SQL_DIAG_DYNAMIC_DELETE_CURSOR 38
+#define SQL_DIAG_DYNAMIC_UPDATE_CURSOR 81
+#define SQL_DIAG_GRANT 48
+#define SQL_DIAG_INSERT 50
+#define SQL_DIAG_REVOKE 59
+#define SQL_DIAG_SELECT_CURSOR 85
+#define SQL_DIAG_UNKNOWN_STATEMENT 0
+#define SQL_DIAG_UPDATE_WHERE 82
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL data type codes */
+#define SQL_UNKNOWN_TYPE 0
+#define SQL_CHAR 1
+#define SQL_NUMERIC 2
+#define SQL_DECIMAL 3
+#define SQL_INTEGER 4
+#define SQL_SMALLINT 5
+#define SQL_FLOAT 6
+#define SQL_REAL 7
+#define SQL_DOUBLE 8
+#if (ODBCVER >= 0x0300)
+#define SQL_DATETIME 9
+#endif
+#define SQL_VARCHAR 12
+
+/* One-parameter shortcuts for date/time data types */
+#if (ODBCVER >= 0x0300)
+#define SQL_TYPE_DATE 91
+#define SQL_TYPE_TIME 92
+#define SQL_TYPE_TIMESTAMP 93
+#endif
+
+/* Statement attribute values for cursor sensitivity */
+#if (ODBCVER >= 0x0300)
+#define SQL_UNSPECIFIED 0
+#define SQL_INSENSITIVE 1
+#define SQL_SENSITIVE 2
+#endif
+
+/* GetTypeInfo() request for all data types */
+#define SQL_ALL_TYPES 0
+
+/* Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData() */
+#if (ODBCVER >= 0x0300)
+#define SQL_DEFAULT 99
+#endif
+
+/* SQLGetData() code indicating that the application row descriptor
+ * specifies the data type
+ */
+#if (ODBCVER >= 0x0300)
+#define SQL_ARD_TYPE (-99)
+#endif
+
+/* SQL date/time type subcodes */
+#if (ODBCVER >= 0x0300)
+#define SQL_CODE_DATE 1
+#define SQL_CODE_TIME 2
+#define SQL_CODE_TIMESTAMP 3
+#endif
+
+/* CLI option values */
+#if (ODBCVER >= 0x0300)
+#define SQL_FALSE 0
+#define SQL_TRUE 1
+#endif
+
+/* values of NULLABLE field in descriptor */
+#define SQL_NO_NULLS 0
+#define SQL_NULLABLE 1
+
+/* Value returned by SQLGetTypeInfo() to denote that it is
+ * not known whether or not a data type supports null values.
+ */
+#define SQL_NULLABLE_UNKNOWN 2
+
+/* Values returned by SQLGetTypeInfo() to show WHERE clause
+ * supported
+ */
+#if (ODBCVER >= 0x0300)
+#define SQL_PRED_NONE 0
+#define SQL_PRED_CHAR 1
+#define SQL_PRED_BASIC 2
+#endif
+
+/* values of UNNAMED field in descriptor */
+#if (ODBCVER >= 0x0300)
+#define SQL_NAMED 0
+#define SQL_UNNAMED 1
+#endif
+
+/* values of ALLOC_TYPE field in descriptor */
+#if (ODBCVER >= 0x0300)
+#define SQL_DESC_ALLOC_AUTO 1
+#define SQL_DESC_ALLOC_USER 2
+#endif
+
+/* FreeStmt() options */
+#define SQL_CLOSE 0
+#define SQL_DROP 1
+#define SQL_UNBIND 2
+#define SQL_RESET_PARAMS 3
+
+/* Codes used for FetchOrientation in SQLFetchScroll(),
+ and in SQLDataSources()
+*/
+#define SQL_FETCH_NEXT 1
+#define SQL_FETCH_FIRST 2
+
+/* Other codes used for FetchOrientation in SQLFetchScroll() */
+#define SQL_FETCH_LAST 3
+#define SQL_FETCH_PRIOR 4
+#define SQL_FETCH_ABSOLUTE 5
+#define SQL_FETCH_RELATIVE 6
+
+/* SQLEndTran() options */
+#define SQL_COMMIT 0
+#define SQL_ROLLBACK 1
+
+/* null handles returned by SQLAllocHandle() */
+#define SQL_NULL_HENV 0
+#define SQL_NULL_HDBC 0
+#define SQL_NULL_HSTMT 0
+#if (ODBCVER >= 0x0300)
+#define SQL_NULL_HDESC 0
+#define SQL_NULL_DESC 0
+#endif
+
+/* null handle used in place of parent handle when allocating HENV */
+#if (ODBCVER >= 0x0300)
+#define SQL_NULL_HANDLE NULL
+#endif
+
+/* Values that may appear in the result set of SQLSpecialColumns() */
+#define SQL_SCOPE_CURROW 0
+#define SQL_SCOPE_TRANSACTION 1
+#define SQL_SCOPE_SESSION 2
+
+#define SQL_PC_UNKNOWN 0
+#if (ODBCVER >= 0x0300)
+#define SQL_PC_NON_PSEUDO 1
+#endif
+#define SQL_PC_PSEUDO 2
+
+/* Reserved value for the IdentifierType argument of SQLSpecialColumns() */
+#if (ODBCVER >= 0x0300)
+#define SQL_ROW_IDENTIFIER 1
+#endif
+
+/* Reserved values for UNIQUE argument of SQLStatistics() */
+#define SQL_INDEX_UNIQUE 0
+#define SQL_INDEX_ALL 1
+
+/* Values that may appear in the result set of SQLStatistics() */
+#define SQL_INDEX_CLUSTERED 1
+#define SQL_INDEX_HASHED 2
+#define SQL_INDEX_OTHER 3
+
+/* SQLGetFunctions() values to identify ODBC APIs */
+#define SQL_API_SQLALLOCCONNECT 1
+#define SQL_API_SQLALLOCENV 2
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLALLOCHANDLE 1001
+#endif
+#define SQL_API_SQLALLOCSTMT 3
+#define SQL_API_SQLBINDCOL 4
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLBINDPARAM 1002
+#endif
+#define SQL_API_SQLCANCEL 5
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLCLOSECURSOR 1003
+#define SQL_API_SQLCOLATTRIBUTE 6
+#endif
+#define SQL_API_SQLCOLUMNS 40
+#define SQL_API_SQLCONNECT 7
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLCOPYDESC 1004
+#endif
+#define SQL_API_SQLDATASOURCES 57
+#define SQL_API_SQLDESCRIBECOL 8
+#define SQL_API_SQLDISCONNECT 9
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLENDTRAN 1005
+#endif
+#define SQL_API_SQLERROR 10
+#define SQL_API_SQLEXECDIRECT 11
+#define SQL_API_SQLEXECUTE 12
+#define SQL_API_SQLFETCH 13
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLFETCHSCROLL 1021
+#endif
+#define SQL_API_SQLFREECONNECT 14
+#define SQL_API_SQLFREEENV 15
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLFREEHANDLE 1006
+#endif
+#define SQL_API_SQLFREESTMT 16
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLGETCONNECTATTR 1007
+#endif
+#define SQL_API_SQLGETCONNECTOPTION 42
+#define SQL_API_SQLGETCURSORNAME 17
+#define SQL_API_SQLGETDATA 43
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLGETDESCFIELD 1008
+#define SQL_API_SQLGETDESCREC 1009
+#define SQL_API_SQLGETDIAGFIELD 1010
+#define SQL_API_SQLGETDIAGREC 1011
+#define SQL_API_SQLGETENVATTR 1012
+#endif
+#define SQL_API_SQLGETFUNCTIONS 44
+#define SQL_API_SQLGETINFO 45
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLGETSTMTATTR 1014
+#endif
+#define SQL_API_SQLGETSTMTOPTION 46
+#define SQL_API_SQLGETTYPEINFO 47
+#define SQL_API_SQLNUMRESULTCOLS 18
+#define SQL_API_SQLPARAMDATA 48
+#define SQL_API_SQLPREPARE 19
+#define SQL_API_SQLPUTDATA 49
+#define SQL_API_SQLROWCOUNT 20
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLSETCONNECTATTR 1016
+#endif
+#define SQL_API_SQLSETCONNECTOPTION 50
+#define SQL_API_SQLSETCURSORNAME 21
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLSETDESCFIELD 1017
+#define SQL_API_SQLSETDESCREC 1018
+#define SQL_API_SQLSETENVATTR 1019
+#endif
+#define SQL_API_SQLSETPARAM 22
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLSETSTMTATTR 1020
+#endif
+#define SQL_API_SQLSETSTMTOPTION 51
+#define SQL_API_SQLSPECIALCOLUMNS 52
+#define SQL_API_SQLSTATISTICS 53
+#define SQL_API_SQLTABLES 54
+#define SQL_API_SQLTRANSACT 23
+
+/* Information requested by SQLGetInfo() */
+#if (ODBCVER >= 0x0300)
+#define SQL_MAX_DRIVER_CONNECTIONS 0
+#define SQL_MAXIMUM_DRIVER_CONNECTIONS SQL_MAX_DRIVER_CONNECTIONS
+#define SQL_MAX_CONCURRENT_ACTIVITIES 1
+#define SQL_MAXIMUM_CONCURRENT_ACTIVITIES SQL_MAX_CONCURRENT_ACTIVITIES
+#endif
+#define SQL_DATA_SOURCE_NAME 2
+#define SQL_FETCH_DIRECTION 8
+#define SQL_SERVER_NAME 13
+#define SQL_SEARCH_PATTERN_ESCAPE 14
+#define SQL_DBMS_NAME 17
+#define SQL_DBMS_VER 18
+#define SQL_ACCESSIBLE_TABLES 19
+#define SQL_ACCESSIBLE_PROCEDURES 20
+#define SQL_CURSOR_COMMIT_BEHAVIOR 23
+#define SQL_DATA_SOURCE_READ_ONLY 25
+#define SQL_DEFAULT_TXN_ISOLATION 26
+#define SQL_IDENTIFIER_CASE 28
+#define SQL_IDENTIFIER_QUOTE_CHAR 29
+#define SQL_MAX_COLUMN_NAME_LEN 30
+#define SQL_MAXIMUM_COLUMN_NAME_LENGTH SQL_MAX_COLUMN_NAME_LEN
+#define SQL_MAX_CURSOR_NAME_LEN 31
+#define SQL_MAXIMUM_CURSOR_NAME_LENGTH SQL_MAX_CURSOR_NAME_LEN
+#define SQL_MAX_SCHEMA_NAME_LEN 32
+#define SQL_MAXIMUM_SCHEMA_NAME_LENGTH SQL_MAX_SCHEMA_NAME_LEN
+#define SQL_MAX_CATALOG_NAME_LEN 34
+#define SQL_MAXIMUM_CATALOG_NAME_LENGTH SQL_MAX_CATALOG_NAME_LEN
+#define SQL_MAX_TABLE_NAME_LEN 35
+#define SQL_SCROLL_CONCURRENCY 43
+#define SQL_TXN_CAPABLE 46
+#define SQL_TRANSACTION_CAPABLE SQL_TXN_CAPABLE
+#define SQL_USER_NAME 47
+#define SQL_TXN_ISOLATION_OPTION 72
+#define SQL_TRANSACTION_ISOLATION_OPTION SQL_TXN_ISOLATION_OPTION
+#define SQL_INTEGRITY 73
+#define SQL_GETDATA_EXTENSIONS 81
+#define SQL_NULL_COLLATION 85
+#define SQL_ALTER_TABLE 86
+#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90
+#define SQL_SPECIAL_CHARACTERS 94
+#define SQL_MAX_COLUMNS_IN_GROUP_BY 97
+#define SQL_MAXIMUM_COLUMNS_IN_GROUP_BY SQL_MAX_COLUMNS_IN_GROUP_BY
+#define SQL_MAX_COLUMNS_IN_INDEX 98
+#define SQL_MAXIMUM_COLUMNS_IN_INDEX SQL_MAX_COLUMNS_IN_INDEX
+#define SQL_MAX_COLUMNS_IN_ORDER_BY 99
+#define SQL_MAXIMUM_COLUMNS_IN_ORDER_BY SQL_MAX_COLUMNS_IN_ORDER_BY
+#define SQL_MAX_COLUMNS_IN_SELECT 100
+#define SQL_MAXIMUM_COLUMNS_IN_SELECT SQL_MAX_COLUMNS_IN_SELECT
+#define SQL_MAX_COLUMNS_IN_TABLE 101
+#define SQL_MAX_INDEX_SIZE 102
+#define SQL_MAXIMUM_INDEX_SIZE SQL_MAX_INDEX_SIZE
+#define SQL_MAX_ROW_SIZE 104
+#define SQL_MAXIMUM_ROW_SIZE SQL_MAX_ROW_SIZE
+#define SQL_MAX_STATEMENT_LEN 105
+#define SQL_MAXIMUM_STATEMENT_LENGTH SQL_MAX_STATEMENT_LEN
+#define SQL_MAX_TABLES_IN_SELECT 106
+#define SQL_MAXIMUM_TABLES_IN_SELECT SQL_MAX_TABLES_IN_SELECT
+#define SQL_MAX_USER_NAME_LEN 107
+#define SQL_MAXIMUM_USER_NAME_LENGTH SQL_MAX_USER_NAME_LEN
+#if (ODBCVER >= 0x0300)
+#define SQL_OJ_CAPABILITIES 115
+#define SQL_OUTER_JOIN_CAPABILITIES SQL_OJ_CAPABILITIES
+#endif /* ODBCVER >= 0x0300 */
+
+#if (ODBCVER >= 0x0300)
+#define SQL_XOPEN_CLI_YEAR 10000
+#define SQL_CURSOR_SENSITIVITY 10001
+#define SQL_DESCRIBE_PARAMETER 10002
+#define SQL_CATALOG_NAME 10003
+#define SQL_COLLATION_SEQ 10004
+#define SQL_MAX_IDENTIFIER_LEN 10005
+#define SQL_MAXIMUM_IDENTIFIER_LENGTH SQL_MAX_IDENTIFIER_LEN
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_ALTER_TABLE bitmasks */
+#if (ODBCVER >= 0x0200)
+#define SQL_AT_ADD_COLUMN 0x00000001L
+#define SQL_AT_DROP_COLUMN 0x00000002L
+#endif /* ODBCVER >= 0x0200 */
+
+#if (ODBCVER >= 0x0300)
+#define SQL_AT_ADD_CONSTRAINT 0x00000008L
+
+/* The following bitmasks are ODBC extensions and defined in sqlext.h
+*#define SQL_AT_COLUMN_SINGLE 0x00000020L
+*#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L
+*#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L
+*#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L
+*#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L
+*#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L
+*#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L
+*#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L
+*#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L
+*#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L
+*#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L
+*#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L
+*#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L
+*#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L
+*#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L
+*/
+#endif /* ODBCVER >= 0x0300 */
+
+
+/* SQL_ASYNC_MODE values */
+#if (ODBCVER >= 0x0300)
+#define SQL_AM_NONE 0
+#define SQL_AM_CONNECTION 1
+#define SQL_AM_STATEMENT 2
+#endif
+
+/* SQL_CURSOR_COMMIT_BEHAVIOR values */
+#define SQL_CB_DELETE 0
+#define SQL_CB_CLOSE 1
+#define SQL_CB_PRESERVE 2
+
+/* SQL_FETCH_DIRECTION bitmasks */
+#define SQL_FD_FETCH_NEXT 0x00000001L
+#define SQL_FD_FETCH_FIRST 0x00000002L
+#define SQL_FD_FETCH_LAST 0x00000004L
+#define SQL_FD_FETCH_PRIOR 0x00000008L
+#define SQL_FD_FETCH_ABSOLUTE 0x00000010L
+#define SQL_FD_FETCH_RELATIVE 0x00000020L
+
+/* SQL_GETDATA_EXTENSIONS bitmasks */
+#define SQL_GD_ANY_COLUMN 0x00000001L
+#define SQL_GD_ANY_ORDER 0x00000002L
+
+/* SQL_IDENTIFIER_CASE values */
+#define SQL_IC_UPPER 1
+#define SQL_IC_LOWER 2
+#define SQL_IC_SENSITIVE 3
+#define SQL_IC_MIXED 4
+
+/* SQL_OJ_CAPABILITIES bitmasks */
+/* NB: this means 'outer join', not what you may be thinking */
+
+
+#if (ODBCVER >= 0x0201)
+#define SQL_OJ_LEFT 0x00000001L
+#define SQL_OJ_RIGHT 0x00000002L
+#define SQL_OJ_FULL 0x00000004L
+#define SQL_OJ_NESTED 0x00000008L
+#define SQL_OJ_NOT_ORDERED 0x00000010L
+#define SQL_OJ_INNER 0x00000020L
+#define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L
+#endif
+
+/* SQL_SCROLL_CONCURRENCY bitmasks */
+#define SQL_SCCO_READ_ONLY 0x00000001L
+#define SQL_SCCO_LOCK 0x00000002L
+#define SQL_SCCO_OPT_ROWVER 0x00000004L
+#define SQL_SCCO_OPT_VALUES 0x00000008L
+
+/* SQL_TXN_CAPABLE values */
+#define SQL_TC_NONE 0
+#define SQL_TC_DML 1
+#define SQL_TC_ALL 2
+#define SQL_TC_DDL_COMMIT 3
+#define SQL_TC_DDL_IGNORE 4
+
+/* SQL_TXN_ISOLATION_OPTION bitmasks */
+#define SQL_TXN_READ_UNCOMMITTED 0x00000001L
+#define SQL_TRANSACTION_READ_UNCOMMITTED SQL_TXN_READ_UNCOMMITTED
+#define SQL_TXN_READ_COMMITTED 0x00000002L
+#define SQL_TRANSACTION_READ_COMMITTED SQL_TXN_READ_COMMITTED
+#define SQL_TXN_REPEATABLE_READ 0x00000004L
+#define SQL_TRANSACTION_REPEATABLE_READ SQL_TXN_REPEATABLE_READ
+#define SQL_TXN_SERIALIZABLE 0x00000008L
+#define SQL_TRANSACTION_SERIALIZABLE SQL_TXN_SERIALIZABLE
+
+/* SQL_NULL_COLLATION values */
+#define SQL_NC_HIGH 0
+#define SQL_NC_LOW 1
+
+ SQLRETURN SQL_API SQLAllocConnect(SQLHENV EnvironmentHandle,
+ SQLHDBC *ConnectionHandle);
+
+ SQLRETURN SQL_API SQLAllocEnv(SQLHENV *EnvironmentHandle);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT HandleType,
+ SQLHANDLE InputHandle, SQLHANDLE *OutputHandle);
+#endif
+
+ SQLRETURN SQL_API SQLAllocStmt(SQLHDBC ConnectionHandle,
+ SQLHSTMT *StatementHandle);
+
+ SQLRETURN SQL_API SQLBindCol(SQLHSTMT StatementHandle,
+ SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType,
+ SQLPOINTER TargetValue, SQLLEN BufferLength,
+ SQLLEN *StrLen_or_Ind);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLBindParam(SQLHSTMT StatementHandle,
+ SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
+ SQLSMALLINT ParameterType, SQLULEN LengthPrecision,
+ SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue,
+ SQLLEN *StrLen_or_Ind);
+#endif
+
+ SQLRETURN SQL_API SQLCancel(SQLHSTMT StatementHandle);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT StatementHandle);
+
+ SQLRETURN SQL_API SQLColAttribute(SQLHSTMT StatementHandle,
+ SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier,
+ SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength,
+ SQLSMALLINT *StringLength, SQLLEN *NumericAttribute
+ /* spec says (SQLPOINTER) not (SQLEN*) - PAH */ );
+ /* Ms now say SQLLEN* http://msdn.microsoft.com/library/en-us/odbc/htm/dasdkodbcoverview_64bit.asp - NG */
+
+#endif
+
+
+ SQLRETURN SQL_API SQLColumns(SQLHSTMT StatementHandle,
+ SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
+ SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
+ SQLCHAR *TableName, SQLSMALLINT NameLength3,
+ SQLCHAR *ColumnName, SQLSMALLINT NameLength4);
+
+
+ SQLRETURN SQL_API SQLConnect(SQLHDBC ConnectionHandle,
+ SQLCHAR *ServerName, SQLSMALLINT NameLength1,
+ SQLCHAR *UserName, SQLSMALLINT NameLength2,
+ SQLCHAR *Authentication, SQLSMALLINT NameLength3);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLCopyDesc(SQLHDESC SourceDescHandle,
+ SQLHDESC TargetDescHandle);
+#endif
+
+ SQLRETURN SQL_API SQLDataSources(SQLHENV EnvironmentHandle,
+ SQLUSMALLINT Direction, SQLCHAR *ServerName,
+ SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1,
+ SQLCHAR *Description, SQLSMALLINT BufferLength2,
+ SQLSMALLINT *NameLength2);
+
+ SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT StatementHandle,
+ SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName,
+ SQLSMALLINT BufferLength, SQLSMALLINT *NameLength,
+ SQLSMALLINT *DataType, SQLULEN *ColumnSize,
+ SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable);
+
+ SQLRETURN SQL_API SQLDisconnect(SQLHDBC ConnectionHandle);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle,
+ SQLSMALLINT CompletionType);
+#endif
+
+ SQLRETURN SQL_API SQLError(SQLHENV EnvironmentHandle,
+ SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle,
+ SQLCHAR *Sqlstate, SQLINTEGER *NativeError,
+ SQLCHAR *MessageText, SQLSMALLINT BufferLength,
+ SQLSMALLINT *TextLength);
+
+ SQLRETURN SQL_API SQLExecDirect(SQLHSTMT StatementHandle,
+ SQLCHAR *StatementText, SQLINTEGER TextLength);
+
+ SQLRETURN SQL_API SQLExecute(SQLHSTMT StatementHandle);
+
+ SQLRETURN SQL_API SQLFetch(SQLHSTMT StatementHandle);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT StatementHandle,
+ SQLSMALLINT FetchOrientation, SQLLEN FetchOffset);
+#endif
+
+ SQLRETURN SQL_API SQLFreeConnect(SQLHDBC ConnectionHandle);
+
+ SQLRETURN SQL_API SQLFreeEnv(SQLHENV EnvironmentHandle);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle);
+#endif
+
+ SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT StatementHandle,
+ SQLUSMALLINT Option);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC ConnectionHandle,
+ SQLINTEGER Attribute, SQLPOINTER Value,
+ SQLINTEGER BufferLength, SQLINTEGER *StringLength);
+#endif
+
+ SQLRETURN SQL_API SQLGetConnectOption(SQLHDBC ConnectionHandle,
+ SQLUSMALLINT Option, SQLPOINTER Value);
+
+ SQLRETURN SQL_API SQLGetCursorName(SQLHSTMT StatementHandle,
+ SQLCHAR *CursorName, SQLSMALLINT BufferLength,
+ SQLSMALLINT *NameLength);
+
+ SQLRETURN SQL_API SQLGetData(SQLHSTMT StatementHandle,
+ SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType,
+ SQLPOINTER TargetValue, SQLLEN BufferLength,
+ SQLLEN *StrLen_or_Ind);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQLGetDescField(SQLHDESC DescriptorHandle,
+ SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
+ SQLPOINTER Value, SQLINTEGER BufferLength,
+ SQLINTEGER *StringLength);
+
+ SQLRETURN SQL_API SQLGetDescRec(SQLHDESC DescriptorHandle,
+ SQLSMALLINT RecNumber, SQLCHAR *Name,
+ SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
+ SQLSMALLINT *Type, SQLSMALLINT *SubType,
+ SQLLEN *Length, SQLSMALLINT *Precision,
+ SQLSMALLINT *Scale, SQLSMALLINT *Nullable);
+
+ SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
+ SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
+ SQLPOINTER DiagInfo, SQLSMALLINT BufferLength,
+ SQLSMALLINT *StringLength);
+
+ SQLRETURN SQL_API SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
+ SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
+ SQLINTEGER *NativeError, SQLCHAR *MessageText,
+ SQLSMALLINT BufferLength, SQLSMALLINT *TextLength);
+
+ SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV EnvironmentHandle,
+ SQLINTEGER Attribute, SQLPOINTER Value,
+ SQLINTEGER BufferLength, SQLINTEGER *StringLength);
+#endif /* ODBCVER >= 0x0300 */
+
+ SQLRETURN SQL_API SQLGetFunctions(SQLHDBC ConnectionHandle,
+ SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported);
+
+ SQLRETURN SQL_API SQLGetInfo(SQLHDBC ConnectionHandle,
+ SQLUSMALLINT InfoType, SQLPOINTER InfoValue,
+ SQLSMALLINT BufferLength, SQLSMALLINT *StringLength);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLGetStmtAttr(SQLHSTMT StatementHandle,
+ SQLINTEGER Attribute, SQLPOINTER Value,
+ SQLINTEGER BufferLength, SQLINTEGER *StringLength);
+#endif /* ODBCVER >= 0x0300 */
+
+ SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT StatementHandle,
+ SQLUSMALLINT Option, SQLPOINTER Value);
+
+ SQLRETURN SQL_API SQLGetTypeInfo(SQLHSTMT StatementHandle,
+ SQLSMALLINT DataType);
+
+ SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT StatementHandle,
+ SQLSMALLINT *ColumnCount);
+
+ SQLRETURN SQL_API SQLParamData(SQLHSTMT StatementHandle,
+ SQLPOINTER *Value);
+
+ SQLRETURN SQL_API SQLPrepare(SQLHSTMT StatementHandle,
+ SQLCHAR *StatementText, SQLINTEGER TextLength);
+
+ SQLRETURN SQL_API SQLPutData(SQLHSTMT StatementHandle,
+ SQLPOINTER Data, SQLLEN StrLen_or_Ind);
+
+ SQLRETURN SQL_API SQLRowCount(SQLHSTMT StatementHandle,
+ SQLLEN *RowCount);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC ConnectionHandle,
+ SQLINTEGER Attribute, SQLPOINTER Value,
+ SQLINTEGER StringLength);
+#endif /* ODBCVER >= 0x0300 */
+
+ SQLRETURN SQL_API SQLSetConnectOption(SQLHDBC ConnectionHandle,
+ SQLUSMALLINT Option, SQLULEN Value);
+
+ SQLRETURN SQL_API SQLSetCursorName(SQLHSTMT StatementHandle,
+ SQLCHAR *CursorName, SQLSMALLINT NameLength);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLSetDescField(SQLHDESC DescriptorHandle,
+ SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
+ SQLPOINTER Value, SQLINTEGER BufferLength);
+
+ SQLRETURN SQL_API SQLSetDescRec(SQLHDESC DescriptorHandle,
+ SQLSMALLINT RecNumber, SQLSMALLINT Type,
+ SQLSMALLINT SubType, SQLLEN Length,
+ SQLSMALLINT Precision, SQLSMALLINT Scale,
+ SQLPOINTER Data, SQLLEN *StringLength,
+ SQLLEN *Indicator);
+
+ SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV EnvironmentHandle,
+ SQLINTEGER Attribute, SQLPOINTER Value,
+ SQLINTEGER StringLength);
+#endif /* ODBCVER >= 0x0300 */
+
+ SQLRETURN SQL_API SQLSetParam(SQLHSTMT StatementHandle,
+ SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
+ SQLSMALLINT ParameterType, SQLULEN LengthPrecision,
+ SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue,
+ SQLLEN *StrLen_or_Ind);
+
+#if (ODBCVER >= 0x0300)
+ SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle,
+ SQLINTEGER Attribute, SQLPOINTER Value,
+ SQLINTEGER StringLength);
+#endif
+
+ SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT StatementHandle,
+ SQLUSMALLINT Option, SQLULEN Value);
+
+ SQLRETURN SQL_API SQLSpecialColumns(SQLHSTMT StatementHandle,
+ SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName,
+ SQLSMALLINT NameLength1, SQLCHAR *SchemaName,
+ SQLSMALLINT NameLength2, SQLCHAR *TableName,
+ SQLSMALLINT NameLength3, SQLUSMALLINT Scope,
+ SQLUSMALLINT Nullable);
+
+ SQLRETURN SQL_API SQLStatistics(SQLHSTMT StatementHandle,
+ SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
+ SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
+ SQLCHAR *TableName, SQLSMALLINT NameLength3,
+ SQLUSMALLINT Unique, SQLUSMALLINT Reserved);
+
+ SQLRETURN SQL_API SQLTables(SQLHSTMT StatementHandle,
+ SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
+ SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
+ SQLCHAR *TableName, SQLSMALLINT NameLength3,
+ SQLCHAR *TableType, SQLSMALLINT NameLength4);
+
+ SQLRETURN SQL_API SQLTransact(SQLHENV EnvironmentHandle,
+ SQLHDBC ConnectionHandle, SQLUSMALLINT CompletionType);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/external/unixODBC/inc/odbc/sqlext.h b/external/unixODBC/inc/odbc/sqlext.h
new file mode 100644
index 000000000..5bc9d7d80
--- /dev/null
+++ b/external/unixODBC/inc/odbc/sqlext.h
@@ -0,0 +1,2122 @@
+/*****************************************************
+ * sqlext.h
+ *
+ * These should be consistent with the MS version.
+ *
+ *****************************************************/
+#ifndef __SQLEXT_H
+#define __SQLEXT_H
+
+
+/* BEGIN - unixODBC ONLY (programs like ODBCConfig and DataManager use these) */
+
+/* COLUMNS IN SQLTables() RESULT SET */
+#define SQLTables_TABLE_CATALOG 1
+#define SQLTables_TABLE_SCHEM 2
+#define SQLTables_TABLE_NAME 3
+#define SQLTables_TABLE_TYPE 4
+#define SQLTables_REMARKS 5
+
+/* COLUMNS IN SQLColumns() RESULT SET */
+#define SQLColumns_TABLE_CAT 1
+#define SQLColumns_TABLE_SCHEM 2
+#define SQLColumns_TABLE_NAME 3
+#define SQLColumns_COLUMN_NAME 4
+#define SQLColumns_DATA_TYPE 5
+#define SQLColumns_TYPE_NAME 6
+#define SQLColumns_COLUMN_SIZE 7
+#define SQLColumns_BUFFER_LENGTH 8
+#define SQLColumns_DECIMAL_DIGITS 9
+#define SQLColumns_NUM_PREC_RADIX 10
+#define SQLColumns_NULLABLE 11
+#define SQLColumns_REMARKS 12
+#define SQLColumns_COLUMN_DEF 13
+#define SQLColumns_SQL_DATA_TYPE 14
+#define SQLColumns_SQL_DATETIME_SUB 15
+#define SQLColumns_CHAR_OCTET_LENGTH 16
+#define SQLColumns_ORDINAL_POSITION 17
+#define SQLColumns_IS_NULLABLE 18
+
+/* END - unixODBC ONLY */
+
+#ifndef __SQL_H
+#include "odbc/sql.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" { /* Assume C declarations for C++ */
+#endif
+
+/* generally useful constants */
+#define SQL_SPEC_MAJOR 3 /* Major version of specification */
+#define SQL_SPEC_MINOR 52 /* Minor version of specification */
+#define SQL_SPEC_STRING "03.52" /* String constant for version */
+
+#define SQL_SQLSTATE_SIZE 5 /* size of SQLSTATE */
+#define SQL_MAX_DSN_LENGTH 32 /* maximum data source name size */
+
+#define SQL_MAX_OPTION_STRING_LENGTH 256
+
+/* return code SQL_NO_DATA_FOUND is the same as SQL_NO_DATA */
+#if (ODBCVER < 0x0300)
+#define SQL_NO_DATA_FOUND 100
+#else
+#define SQL_NO_DATA_FOUND SQL_NO_DATA
+#endif
+
+/* an end handle type */
+#if (ODBCVER >= 0x0300)
+#define SQL_HANDLE_SENV 5
+#endif /* ODBCVER >= 0x0300 */
+
+/* env attribute */
+#if (ODBCVER >= 0x0300)
+#define SQL_ATTR_ODBC_VERSION 200
+#define SQL_ATTR_CONNECTION_POOLING 201
+#define SQL_ATTR_CP_MATCH 202
+
+/* unixODBC additions */
+#define SQL_ATTR_UNIXODBC_SYSPATH 65001
+#define SQL_ATTR_UNIXODBC_VERSION 65002
+#define SQL_ATTR_UNIXODBC_ENVATTR 65003
+#endif /* ODBCVER >= 0x0300 */
+
+#if (ODBCVER >= 0x0300)
+/* values for SQL_ATTR_CONNECTION_POOLING */
+#define SQL_CP_OFF 0UL
+#define SQL_CP_ONE_PER_DRIVER 1UL
+#define SQL_CP_ONE_PER_HENV 2UL
+#define SQL_CP_DEFAULT SQL_CP_OFF
+
+/* values for SQL_ATTR_CP_MATCH */
+#define SQL_CP_STRICT_MATCH 0UL
+#define SQL_CP_RELAXED_MATCH 1UL
+#define SQL_CP_MATCH_DEFAULT SQL_CP_STRICT_MATCH
+
+/* values for SQL_ATTR_ODBC_VERSION */
+#define SQL_OV_ODBC2 2UL
+#define SQL_OV_ODBC3 3UL
+#endif /* ODBCVER >= 0x0300 */
+
+/* connection attributes */
+#define SQL_ACCESS_MODE 101
+#define SQL_AUTOCOMMIT 102
+#define SQL_LOGIN_TIMEOUT 103
+#define SQL_OPT_TRACE 104
+#define SQL_OPT_TRACEFILE 105
+#define SQL_TRANSLATE_DLL 106
+#define SQL_TRANSLATE_OPTION 107
+#define SQL_TXN_ISOLATION 108
+#define SQL_CURRENT_QUALIFIER 109
+#define SQL_ODBC_CURSORS 110
+#define SQL_QUIET_MODE 111
+#define SQL_PACKET_SIZE 112
+
+/* connection attributes with new names */
+#if (ODBCVER >= 0x0300)
+#define SQL_ATTR_ACCESS_MODE SQL_ACCESS_MODE
+#define SQL_ATTR_AUTOCOMMIT SQL_AUTOCOMMIT
+#define SQL_ATTR_CONNECTION_TIMEOUT 113
+#define SQL_ATTR_CURRENT_CATALOG SQL_CURRENT_QUALIFIER
+#define SQL_ATTR_DISCONNECT_BEHAVIOR 114
+#define SQL_ATTR_ENLIST_IN_DTC 1207
+#define SQL_ATTR_ENLIST_IN_XA 1208
+#define SQL_ATTR_LOGIN_TIMEOUT SQL_LOGIN_TIMEOUT
+#define SQL_ATTR_ODBC_CURSORS SQL_ODBC_CURSORS
+#define SQL_ATTR_PACKET_SIZE SQL_PACKET_SIZE
+#define SQL_ATTR_QUIET_MODE SQL_QUIET_MODE
+#define SQL_ATTR_TRACE SQL_OPT_TRACE
+#define SQL_ATTR_TRACEFILE SQL_OPT_TRACEFILE
+#define SQL_ATTR_TRANSLATE_LIB SQL_TRANSLATE_DLL
+#define SQL_ATTR_TRANSLATE_OPTION SQL_TRANSLATE_OPTION
+#define SQL_ATTR_TXN_ISOLATION SQL_TXN_ISOLATION
+#endif /* ODBCVER >= 0x0300 */
+
+#define SQL_ATTR_CONNECTION_DEAD 1209 /* GetConnectAttr only */
+
+#define SQL_ATTR_DRIVER_THREADING 1028 /* Driver threading level */
+
+#if (ODBCVER >= 0x0351)
+/* ODBC Driver Manager sets this connection attribute to a unicode driver
+ (which supports SQLConnectW) when the application is an ANSI application
+ (which calls SQLConnect, SQLDriverConnect, or SQLBrowseConnect).
+ This is SetConnectAttr only and application does not set this attribute
+ This attribute was introduced because some unicode driver's some APIs may
+ need to behave differently on ANSI or Unicode applications. A unicode
+ driver, which has same behavior for both ANSI or Unicode applications,
+ should return SQL_ERROR when the driver manager sets this connection
+ attribute. When a unicode driver returns SQL_SUCCESS on this attribute,
+ the driver manager treates ANSI and Unicode connections differently in
+ connection pooling.
+*/
+#define SQL_ATTR_ANSI_APP 115
+#endif
+
+/* SQL_CONNECT_OPT_DRVR_START is not meaningful for 3.0 driver */
+#if (ODBCVER < 0x0300)
+#define SQL_CONNECT_OPT_DRVR_START 1000
+#endif /* ODBCVER < 0x0300 */
+
+#if (ODBCVER < 0x0300)
+#define SQL_CONN_OPT_MAX SQL_PACKET_SIZE
+#define SQL_CONN_OPT_MIN SQL_ACCESS_MODE
+#endif /* ODBCVER < 0x0300 */
+
+/* SQL_ACCESS_MODE options */
+#define SQL_MODE_READ_WRITE 0UL
+#define SQL_MODE_READ_ONLY 1UL
+#define SQL_MODE_DEFAULT SQL_MODE_READ_WRITE
+
+/* SQL_AUTOCOMMIT options */
+#define SQL_AUTOCOMMIT_OFF 0UL
+#define SQL_AUTOCOMMIT_ON 1UL
+#define SQL_AUTOCOMMIT_DEFAULT SQL_AUTOCOMMIT_ON
+
+/* SQL_LOGIN_TIMEOUT options */
+#define SQL_LOGIN_TIMEOUT_DEFAULT 15UL
+
+/* SQL_OPT_TRACE options */
+#define SQL_OPT_TRACE_OFF 0UL
+#define SQL_OPT_TRACE_ON 1UL
+#define SQL_OPT_TRACE_DEFAULT SQL_OPT_TRACE_OFF
+#define SQL_OPT_TRACE_FILE_DEFAULT "/tmp/SQL.LOG"
+
+/* SQL_ODBC_CURSORS options */
+#define SQL_CUR_USE_IF_NEEDED 0UL
+#define SQL_CUR_USE_ODBC 1UL
+#define SQL_CUR_USE_DRIVER 2UL
+#define SQL_CUR_DEFAULT SQL_CUR_USE_DRIVER
+
+#if (ODBCVER >= 0x0300)
+/* values for SQL_ATTR_DISCONNECT_BEHAVIOR */
+#define SQL_DB_RETURN_TO_POOL 0UL
+#define SQL_DB_DISCONNECT 1UL
+#define SQL_DB_DEFAULT SQL_DB_RETURN_TO_POOL
+
+/* values for SQL_ATTR_ENLIST_IN_DTC */
+#define SQL_DTC_DONE 0L
+#endif /* ODBCVER >= 0x0300 */
+
+/* values for SQL_ATTR_CONNECTION_DEAD */
+#define SQL_CD_TRUE 1L /* Connection is closed/dead */
+#define SQL_CD_FALSE 0L /* Connection is open/available */
+
+/* values for SQL_ATTR_ANSI_APP */
+#if (ODBCVER >= 0x0351)
+#define SQL_AA_TRUE 1L /* the application is an ANSI app */
+#define SQL_AA_FALSE 0L /* the application is a Unicode app */
+#endif
+
+/* statement attributes */
+#define SQL_QUERY_TIMEOUT 0
+#define SQL_MAX_ROWS 1
+#define SQL_NOSCAN 2
+#define SQL_MAX_LENGTH 3
+#define SQL_ASYNC_ENABLE 4 /* same as SQL_ATTR_ASYNC_ENABLE */
+#define SQL_BIND_TYPE 5
+#define SQL_CURSOR_TYPE 6
+#define SQL_CONCURRENCY 7
+#define SQL_KEYSET_SIZE 8
+#define SQL_ROWSET_SIZE 9
+#define SQL_SIMULATE_CURSOR 10
+#define SQL_RETRIEVE_DATA 11
+#define SQL_USE_BOOKMARKS 12
+#define SQL_GET_BOOKMARK 13 /* GetStmtOption Only */
+#define SQL_ROW_NUMBER 14 /* GetStmtOption Only */
+
+/* statement attributes for ODBC 3.0 */
+#if (ODBCVER >= 0x0300)
+#define SQL_ATTR_ASYNC_ENABLE 4
+#define SQL_ATTR_CONCURRENCY SQL_CONCURRENCY
+#define SQL_ATTR_CURSOR_TYPE SQL_CURSOR_TYPE
+#define SQL_ATTR_ENABLE_AUTO_IPD 15
+#define SQL_ATTR_FETCH_BOOKMARK_PTR 16
+#define SQL_ATTR_KEYSET_SIZE SQL_KEYSET_SIZE
+#define SQL_ATTR_MAX_LENGTH SQL_MAX_LENGTH
+#define SQL_ATTR_MAX_ROWS SQL_MAX_ROWS
+#define SQL_ATTR_NOSCAN SQL_NOSCAN
+#define SQL_ATTR_PARAM_BIND_OFFSET_PTR 17
+#define SQL_ATTR_PARAM_BIND_TYPE 18
+#define SQL_ATTR_PARAM_OPERATION_PTR 19
+#define SQL_ATTR_PARAM_STATUS_PTR 20
+#define SQL_ATTR_PARAMS_PROCESSED_PTR 21
+#define SQL_ATTR_PARAMSET_SIZE 22
+#define SQL_ATTR_QUERY_TIMEOUT SQL_QUERY_TIMEOUT
+#define SQL_ATTR_RETRIEVE_DATA SQL_RETRIEVE_DATA
+#define SQL_ATTR_ROW_BIND_OFFSET_PTR 23
+#define SQL_ATTR_ROW_BIND_TYPE SQL_BIND_TYPE
+#define SQL_ATTR_ROW_NUMBER SQL_ROW_NUMBER /*GetStmtAttr*/
+#define SQL_ATTR_ROW_OPERATION_PTR 24
+#define SQL_ATTR_ROW_STATUS_PTR 25
+#define SQL_ATTR_ROWS_FETCHED_PTR 26
+#define SQL_ATTR_ROW_ARRAY_SIZE 27
+#define SQL_ATTR_SIMULATE_CURSOR SQL_SIMULATE_CURSOR
+#define SQL_ATTR_USE_BOOKMARKS SQL_USE_BOOKMARKS
+
+#endif /* ODBCVER >= 0x0300 */
+
+#if (ODBCVER < 0x0300)
+#define SQL_STMT_OPT_MAX SQL_ROW_NUMBER
+#define SQL_STMT_OPT_MIN SQL_QUERY_TIMEOUT
+#endif /* ODBCVER < 0x0300 */
+
+/* New defines for SEARCHABLE column in SQLGetTypeInfo */
+
+#if (ODBCVER >= 0x0300)
+#define SQL_COL_PRED_CHAR SQL_LIKE_ONLY
+#define SQL_COL_PRED_BASIC SQL_ALL_EXCEPT_LIKE
+#endif /* ODBCVER >= 0x0300 */
+
+
+
+/* whether an attribute is a pointer or not */
+#if (ODBCVER >= 0x0300)
+#define SQL_IS_POINTER (-4)
+#define SQL_IS_UINTEGER (-5)
+#define SQL_IS_INTEGER (-6)
+#define SQL_IS_USMALLINT (-7)
+#define SQL_IS_SMALLINT (-8)
+#endif /* ODBCVER >= 0x0300 */
+
+/* the value of SQL_ATTR_PARAM_BIND_TYPE */
+#if (ODBCVER >= 0x0300)
+#define SQL_PARAM_BIND_BY_COLUMN 0UL
+#define SQL_PARAM_BIND_TYPE_DEFAULT SQL_PARAM_BIND_BY_COLUMN
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_QUERY_TIMEOUT options */
+#define SQL_QUERY_TIMEOUT_DEFAULT 0UL
+
+/* SQL_MAX_ROWS options */
+#define SQL_MAX_ROWS_DEFAULT 0UL
+
+/* SQL_NOSCAN options */
+#define SQL_NOSCAN_OFF 0UL /* 1.0 FALSE */
+#define SQL_NOSCAN_ON 1UL /* 1.0 TRUE */
+#define SQL_NOSCAN_DEFAULT SQL_NOSCAN_OFF
+
+/* SQL_MAX_LENGTH options */
+#define SQL_MAX_LENGTH_DEFAULT 0UL
+
+/* values for SQL_ATTR_ASYNC_ENABLE */
+#define SQL_ASYNC_ENABLE_OFF 0UL
+#define SQL_ASYNC_ENABLE_ON 1UL
+#define SQL_ASYNC_ENABLE_DEFAULT SQL_ASYNC_ENABLE_OFF
+
+/* SQL_BIND_TYPE options */
+#define SQL_BIND_BY_COLUMN 0UL
+#define SQL_BIND_TYPE_DEFAULT SQL_BIND_BY_COLUMN /* Default value */
+
+/* SQL_CONCURRENCY options */
+#define SQL_CONCUR_READ_ONLY 1
+#define SQL_CONCUR_LOCK 2
+#define SQL_CONCUR_ROWVER 3
+#define SQL_CONCUR_VALUES 4
+#define SQL_CONCUR_DEFAULT SQL_CONCUR_READ_ONLY /* Default value */
+
+/* SQL_CURSOR_TYPE options */
+#define SQL_CURSOR_FORWARD_ONLY 0UL
+#define SQL_CURSOR_KEYSET_DRIVEN 1UL
+#define SQL_CURSOR_DYNAMIC 2UL
+#define SQL_CURSOR_STATIC 3UL
+#define SQL_CURSOR_TYPE_DEFAULT SQL_CURSOR_FORWARD_ONLY /* Default value */
+
+/* SQL_ROWSET_SIZE options */
+#define SQL_ROWSET_SIZE_DEFAULT 1UL
+
+/* SQL_KEYSET_SIZE options */
+#define SQL_KEYSET_SIZE_DEFAULT 0UL
+
+/* SQL_SIMULATE_CURSOR options */
+#define SQL_SC_NON_UNIQUE 0UL
+#define SQL_SC_TRY_UNIQUE 1UL
+#define SQL_SC_UNIQUE 2UL
+
+/* SQL_RETRIEVE_DATA options */
+#define SQL_RD_OFF 0UL
+#define SQL_RD_ON 1UL
+#define SQL_RD_DEFAULT SQL_RD_ON
+
+/* SQL_USE_BOOKMARKS options */
+#define SQL_UB_OFF 0UL
+#define SQL_UB_ON 01UL
+#define SQL_UB_DEFAULT SQL_UB_OFF
+
+/* New values for SQL_USE_BOOKMARKS attribute */
+#if (ODBCVER >= 0x0300)
+#define SQL_UB_FIXED SQL_UB_ON
+#define SQL_UB_VARIABLE 2UL
+#endif /* ODBCVER >= 0x0300 */
+
+/* extended descriptor field */
+#if (ODBCVER >= 0x0300)
+#define SQL_DESC_ARRAY_SIZE 20
+#define SQL_DESC_ARRAY_STATUS_PTR 21
+#define SQL_DESC_AUTO_UNIQUE_VALUE SQL_COLUMN_AUTO_INCREMENT
+#define SQL_DESC_BASE_COLUMN_NAME 22
+#define SQL_DESC_BASE_TABLE_NAME 23
+#define SQL_DESC_BIND_OFFSET_PTR 24
+#define SQL_DESC_BIND_TYPE 25
+#define SQL_DESC_CASE_SENSITIVE SQL_COLUMN_CASE_SENSITIVE
+#define SQL_DESC_CATALOG_NAME SQL_COLUMN_QUALIFIER_NAME
+#define SQL_DESC_CONCISE_TYPE SQL_COLUMN_TYPE
+#define SQL_DESC_DATETIME_INTERVAL_PRECISION 26
+#define SQL_DESC_DISPLAY_SIZE SQL_COLUMN_DISPLAY_SIZE
+#define SQL_DESC_FIXED_PREC_SCALE SQL_COLUMN_MONEY
+#define SQL_DESC_LABEL SQL_COLUMN_LABEL
+#define SQL_DESC_LITERAL_PREFIX 27
+#define SQL_DESC_LITERAL_SUFFIX 28
+#define SQL_DESC_LOCAL_TYPE_NAME 29
+#define SQL_DESC_MAXIMUM_SCALE 30
+#define SQL_DESC_MINIMUM_SCALE 31
+#define SQL_DESC_NUM_PREC_RADIX 32
+#define SQL_DESC_PARAMETER_TYPE 33
+#define SQL_DESC_ROWS_PROCESSED_PTR 34
+#if (ODBCVER >= 0x0350)
+#define SQL_DESC_ROWVER 35
+#endif /* ODBCVER >= 0x0350 */
+#define SQL_DESC_SCHEMA_NAME SQL_COLUMN_OWNER_NAME
+#define SQL_DESC_SEARCHABLE SQL_COLUMN_SEARCHABLE
+#define SQL_DESC_TYPE_NAME SQL_COLUMN_TYPE_NAME
+#define SQL_DESC_TABLE_NAME SQL_COLUMN_TABLE_NAME
+#define SQL_DESC_UNSIGNED SQL_COLUMN_UNSIGNED
+#define SQL_DESC_UPDATABLE SQL_COLUMN_UPDATABLE
+#endif /* ODBCVER >= 0x0300 */
+
+
+/* defines for diagnostics fields */
+#if (ODBCVER >= 0x0300)
+#define SQL_DIAG_CURSOR_ROW_COUNT (-1249)
+#define SQL_DIAG_ROW_NUMBER (-1248)
+#define SQL_DIAG_COLUMN_NUMBER (-1247)
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL extended datatypes */
+#define SQL_DATE 9
+#if (ODBCVER >= 0x0300)
+#define SQL_INTERVAL 10
+#endif /* ODBCVER >= 0x0300 */
+#define SQL_TIME 10
+#define SQL_TIMESTAMP 11
+#define SQL_LONGVARCHAR (-1)
+#define SQL_BINARY (-2)
+#define SQL_VARBINARY (-3)
+#define SQL_LONGVARBINARY (-4)
+#define SQL_BIGINT (-5)
+#define SQL_TINYINT (-6)
+#define SQL_BIT (-7)
+#if (ODBCVER >= 0x0350)
+#define SQL_GUID (-11)
+#endif /* ODBCVER >= 0x0350 */
+
+#if (ODBCVER >= 0x0300)
+/* interval code */
+#define SQL_CODE_YEAR 1
+#define SQL_CODE_MONTH 2
+#define SQL_CODE_DAY 3
+#define SQL_CODE_HOUR 4
+#define SQL_CODE_MINUTE 5
+#define SQL_CODE_SECOND 6
+#define SQL_CODE_YEAR_TO_MONTH 7
+#define SQL_CODE_DAY_TO_HOUR 8
+#define SQL_CODE_DAY_TO_MINUTE 9
+#define SQL_CODE_DAY_TO_SECOND 10
+#define SQL_CODE_HOUR_TO_MINUTE 11
+#define SQL_CODE_HOUR_TO_SECOND 12
+#define SQL_CODE_MINUTE_TO_SECOND 13
+
+#define SQL_INTERVAL_YEAR (100 + SQL_CODE_YEAR)
+#define SQL_INTERVAL_MONTH (100 + SQL_CODE_MONTH)
+#define SQL_INTERVAL_DAY (100 + SQL_CODE_DAY)
+#define SQL_INTERVAL_HOUR (100 + SQL_CODE_HOUR)
+#define SQL_INTERVAL_MINUTE (100 + SQL_CODE_MINUTE)
+#define SQL_INTERVAL_SECOND (100 + SQL_CODE_SECOND)
+#define SQL_INTERVAL_YEAR_TO_MONTH (100 + SQL_CODE_YEAR_TO_MONTH)
+#define SQL_INTERVAL_DAY_TO_HOUR (100 + SQL_CODE_DAY_TO_HOUR)
+#define SQL_INTERVAL_DAY_TO_MINUTE (100 + SQL_CODE_DAY_TO_MINUTE)
+#define SQL_INTERVAL_DAY_TO_SECOND (100 + SQL_CODE_DAY_TO_SECOND)
+#define SQL_INTERVAL_HOUR_TO_MINUTE (100 + SQL_CODE_HOUR_TO_MINUTE)
+#define SQL_INTERVAL_HOUR_TO_SECOND (100 + SQL_CODE_HOUR_TO_SECOND)
+#define SQL_INTERVAL_MINUTE_TO_SECOND (100 + SQL_CODE_MINUTE_TO_SECOND)
+
+#else
+#define SQL_INTERVAL_YEAR (-80)
+#define SQL_INTERVAL_MONTH (-81)
+#define SQL_INTERVAL_YEAR_TO_MONTH (-82)
+#define SQL_INTERVAL_DAY (-83)
+#define SQL_INTERVAL_HOUR (-84)
+#define SQL_INTERVAL_MINUTE (-85)
+#define SQL_INTERVAL_SECOND (-86)
+#define SQL_INTERVAL_DAY_TO_HOUR (-87)
+#define SQL_INTERVAL_DAY_TO_MINUTE (-88)
+#define SQL_INTERVAL_DAY_TO_SECOND (-89)
+#define SQL_INTERVAL_HOUR_TO_MINUTE (-90)
+#define SQL_INTERVAL_HOUR_TO_SECOND (-91)
+#define SQL_INTERVAL_MINUTE_TO_SECOND (-92)
+#endif /* ODBCVER >= 0x0300 */
+
+
+#if (ODBCVER <= 0x0300)
+#define SQL_UNICODE (-95)
+#define SQL_UNICODE_VARCHAR (-96)
+#define SQL_UNICODE_LONGVARCHAR (-97)
+#define SQL_UNICODE_CHAR SQL_UNICODE
+#else
+/* The previous definitions for SQL_UNICODE_ are historical and obsolete */
+
+#define SQL_UNICODE SQL_WCHAR
+#define SQL_UNICODE_VARCHAR SQL_WVARCHAR
+#define SQL_UNICODE_LONGVARCHAR SQL_WLONGVARCHAR
+#define SQL_UNICODE_CHAR SQL_WCHAR
+#endif
+
+#if (ODBCVER < 0x0300)
+#define SQL_TYPE_DRIVER_START SQL_INTERVAL_YEAR
+#define SQL_TYPE_DRIVER_END SQL_UNICODE_LONGVARCHAR
+#endif /* ODBCVER < 0x0300 */
+
+/* C datatype to SQL datatype mapping SQL types
+ ------------------- */
+#define SQL_C_CHAR SQL_CHAR /* CHAR, VARCHAR, DECIMAL, NUMERIC */
+#define SQL_C_LONG SQL_INTEGER /* INTEGER */
+#define SQL_C_SHORT SQL_SMALLINT /* SMALLINT */
+#define SQL_C_FLOAT SQL_REAL /* REAL */
+#define SQL_C_DOUBLE SQL_DOUBLE /* FLOAT, DOUBLE */
+#if (ODBCVER >= 0x0300)
+#define SQL_C_NUMERIC SQL_NUMERIC
+#endif /* ODBCVER >= 0x0300 */
+#define SQL_C_DEFAULT 99
+
+#define SQL_SIGNED_OFFSET (-20)
+#define SQL_UNSIGNED_OFFSET (-22)
+
+/* C datatype to SQL datatype mapping */
+#define SQL_C_DATE SQL_DATE
+#define SQL_C_TIME SQL_TIME
+#define SQL_C_TIMESTAMP SQL_TIMESTAMP
+#if (ODBCVER >= 0x0300)
+#define SQL_C_TYPE_DATE SQL_TYPE_DATE
+#define SQL_C_TYPE_TIME SQL_TYPE_TIME
+#define SQL_C_TYPE_TIMESTAMP SQL_TYPE_TIMESTAMP
+#define SQL_C_INTERVAL_YEAR SQL_INTERVAL_YEAR
+#define SQL_C_INTERVAL_MONTH SQL_INTERVAL_MONTH
+#define SQL_C_INTERVAL_DAY SQL_INTERVAL_DAY
+#define SQL_C_INTERVAL_HOUR SQL_INTERVAL_HOUR
+#define SQL_C_INTERVAL_MINUTE SQL_INTERVAL_MINUTE
+#define SQL_C_INTERVAL_SECOND SQL_INTERVAL_SECOND
+#define SQL_C_INTERVAL_YEAR_TO_MONTH SQL_INTERVAL_YEAR_TO_MONTH
+#define SQL_C_INTERVAL_DAY_TO_HOUR SQL_INTERVAL_DAY_TO_HOUR
+#define SQL_C_INTERVAL_DAY_TO_MINUTE SQL_INTERVAL_DAY_TO_MINUTE
+#define SQL_C_INTERVAL_DAY_TO_SECOND SQL_INTERVAL_DAY_TO_SECOND
+#define SQL_C_INTERVAL_HOUR_TO_MINUTE SQL_INTERVAL_HOUR_TO_MINUTE
+#define SQL_C_INTERVAL_HOUR_TO_SECOND SQL_INTERVAL_HOUR_TO_SECOND
+#define SQL_C_INTERVAL_MINUTE_TO_SECOND SQL_INTERVAL_MINUTE_TO_SECOND
+#endif /* ODBCVER >= 0x0300 */
+#define SQL_C_BINARY SQL_BINARY
+#define SQL_C_BIT SQL_BIT
+#if (ODBCVER >= 0x0300)
+#define SQL_C_SBIGINT (SQL_BIGINT+SQL_SIGNED_OFFSET) /* SIGNED BIGINT */
+#define SQL_C_UBIGINT (SQL_BIGINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED BIGINT */
+#endif /* ODBCVER >= 0x0300 */
+#define SQL_C_TINYINT SQL_TINYINT
+#define SQL_C_SLONG (SQL_C_LONG+SQL_SIGNED_OFFSET) /* SIGNED INTEGER */
+#define SQL_C_SSHORT (SQL_C_SHORT+SQL_SIGNED_OFFSET) /* SIGNED SMALLINT */
+#define SQL_C_STINYINT (SQL_TINYINT+SQL_SIGNED_OFFSET) /* SIGNED TINYINT */
+#define SQL_C_ULONG (SQL_C_LONG+SQL_UNSIGNED_OFFSET) /* UNSIGNED INTEGER*/
+#define SQL_C_USHORT (SQL_C_SHORT+SQL_UNSIGNED_OFFSET) /* UNSIGNED SMALLINT*/
+#define SQL_C_UTINYINT (SQL_TINYINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED TINYINT*/
+
+#if (ODBCVER >= 0x0300) && (SIZEOF_LONG_INT == 8) && !defined(BUILD_LEGACY_64_BIT_MODE)
+#define SQL_C_BOOKMARK SQL_C_UBIGINT /* BOOKMARK */
+#else
+#define SQL_C_BOOKMARK SQL_C_ULONG /* BOOKMARK */
+#endif
+
+#if (ODBCVER >= 0x0350)
+#define SQL_C_GUID SQL_GUID
+#endif /* ODBCVER >= 0x0350 */
+
+#define SQL_TYPE_NULL 0
+#if (ODBCVER < 0x0300)
+#define SQL_TYPE_MIN SQL_BIT
+#define SQL_TYPE_MAX SQL_VARCHAR
+#endif
+
+#if (ODBCVER >= 0x0300)
+#define SQL_C_VARBOOKMARK SQL_C_BINARY
+#endif /* ODBCVER >= 0x0300 */
+
+/* define for SQL_DIAG_ROW_NUMBER and SQL_DIAG_COLUMN_NUMBER */
+#if (ODBCVER >= 0x0300)
+#define SQL_NO_ROW_NUMBER (-1)
+#define SQL_NO_COLUMN_NUMBER (-1)
+#define SQL_ROW_NUMBER_UNKNOWN (-2)
+#define SQL_COLUMN_NUMBER_UNKNOWN (-2)
+#endif
+
+/* SQLBindParameter extensions */
+#define SQL_DEFAULT_PARAM (-5)
+#define SQL_IGNORE (-6)
+#if (ODBCVER >= 0x0300)
+#define SQL_COLUMN_IGNORE SQL_IGNORE
+#endif /* ODBCVER >= 0x0300 */
+#define SQL_LEN_DATA_AT_EXEC_OFFSET (-100)
+#define SQL_LEN_DATA_AT_EXEC(length) (-(length)+SQL_LEN_DATA_AT_EXEC_OFFSET)
+
+/* binary length for driver specific attributes */
+#define SQL_LEN_BINARY_ATTR_OFFSET (-100)
+#define SQL_LEN_BINARY_ATTR(length) (-(length)+SQL_LEN_BINARY_ATTR_OFFSET)
+
+/* Defines used by Driver Manager when mapping SQLSetParam to SQLBindParameter
+*/
+#define SQL_PARAM_TYPE_DEFAULT SQL_PARAM_INPUT_OUTPUT
+#define SQL_SETPARAM_VALUE_MAX (-1L)
+
+/* SQLColAttributes defines */
+#define SQL_COLUMN_COUNT 0
+#define SQL_COLUMN_NAME 1
+#define SQL_COLUMN_TYPE 2
+#define SQL_COLUMN_LENGTH 3
+#define SQL_COLUMN_PRECISION 4
+#define SQL_COLUMN_SCALE 5
+#define SQL_COLUMN_DISPLAY_SIZE 6
+#define SQL_COLUMN_NULLABLE 7
+#define SQL_COLUMN_UNSIGNED 8
+#define SQL_COLUMN_MONEY 9
+#define SQL_COLUMN_UPDATABLE 10
+#define SQL_COLUMN_AUTO_INCREMENT 11
+#define SQL_COLUMN_CASE_SENSITIVE 12
+#define SQL_COLUMN_SEARCHABLE 13
+#define SQL_COLUMN_TYPE_NAME 14
+#define SQL_COLUMN_TABLE_NAME 15
+#define SQL_COLUMN_OWNER_NAME 16
+#define SQL_COLUMN_QUALIFIER_NAME 17
+#define SQL_COLUMN_LABEL 18
+#define SQL_COLATT_OPT_MAX SQL_COLUMN_LABEL
+#if (ODBCVER < 0x0300)
+#define SQL_COLUMN_DRIVER_START 1000
+#endif /* ODBCVER < 0x0300 */
+
+#define SQL_COLATT_OPT_MIN SQL_COLUMN_COUNT
+
+/* SQLColAttributes subdefines for SQL_COLUMN_UPDATABLE */
+#define SQL_ATTR_READONLY 0
+#define SQL_ATTR_WRITE 1
+#define SQL_ATTR_READWRITE_UNKNOWN 2
+
+/* SQLColAttributes subdefines for SQL_COLUMN_SEARCHABLE */
+/* These are also used by SQLGetInfo */
+#define SQL_UNSEARCHABLE 0
+#define SQL_LIKE_ONLY 1
+#define SQL_ALL_EXCEPT_LIKE 2
+#define SQL_SEARCHABLE 3
+#define SQL_PRED_SEARCHABLE SQL_SEARCHABLE
+
+
+/* Special return values for SQLGetData */
+#define SQL_NO_TOTAL (-4)
+
+/********************************************/
+/* SQLGetFunctions: additional values for */
+/* Function to represent functions that */
+/* are not in the X/Open spec. */
+/********************************************/
+
+#if (ODBCVER >= 0x0300)
+#define SQL_API_SQLALLOCHANDLESTD 73
+#define SQL_API_SQLBULKOPERATIONS 24
+#endif /* ODBCVER >= 0x0300 */
+#define SQL_API_SQLBINDPARAMETER 72
+#define SQL_API_SQLBROWSECONNECT 55
+#define SQL_API_SQLCOLATTRIBUTES 6
+#define SQL_API_SQLCOLUMNPRIVILEGES 56
+#define SQL_API_SQLDESCRIBEPARAM 58
+#define SQL_API_SQLDRIVERCONNECT 41
+#define SQL_API_SQLDRIVERS 71
+#define SQL_API_SQLEXTENDEDFETCH 59
+#define SQL_API_SQLFOREIGNKEYS 60
+#define SQL_API_SQLMORERESULTS 61
+#define SQL_API_SQLNATIVESQL 62
+#define SQL_API_SQLNUMPARAMS 63
+#define SQL_API_SQLPARAMOPTIONS 64
+#define SQL_API_SQLPRIMARYKEYS 65
+#define SQL_API_SQLPROCEDURECOLUMNS 66
+#define SQL_API_SQLPROCEDURES 67
+#define SQL_API_SQLSETPOS 68
+#define SQL_API_SQLSETSCROLLOPTIONS 69
+#define SQL_API_SQLTABLEPRIVILEGES 70
+
+/*-------------------------------------------*/
+/* SQL_EXT_API_LAST is not useful with ODBC */
+/* version 3.0 because some of the values */
+/* from X/Open are in the 10000 range. */
+/*-------------------------------------------*/
+
+#if (ODBCVER < 0x0300)
+#define SQL_EXT_API_LAST SQL_API_SQLBINDPARAMETER
+#define SQL_NUM_FUNCTIONS 23
+#define SQL_EXT_API_START 40
+#define SQL_NUM_EXTENSIONS (SQL_EXT_API_LAST-SQL_EXT_API_START+1)
+#endif
+
+/*--------------------------------------------*/
+/* SQL_API_ALL_FUNCTIONS returns an array */
+/* of 'booleans' representing whether a */
+/* function is implemented by the driver. */
+/* */
+/* CAUTION: Only functions defined in ODBC */
+/* version 2.0 and earlier are returned, the */
+/* new high-range function numbers defined by */
+/* X/Open break this scheme. See the new */
+/* method -- SQL_API_ODBC3_ALL_FUNCTIONS */
+/*--------------------------------------------*/
+
+#define SQL_API_ALL_FUNCTIONS 0 /* See CAUTION above */
+
+/*----------------------------------------------*/
+/* 2.X drivers export a dummy function with */
+/* ordinal number SQL_API_LOADBYORDINAL to speed*/
+/* loading under the windows operating system. */
+/* */
+/* CAUTION: Loading by ordinal is not supported */
+/* for 3.0 and above drivers. */
+/*----------------------------------------------*/
+
+#define SQL_API_LOADBYORDINAL 199 /* See CAUTION above */
+
+/*----------------------------------------------*/
+/* SQL_API_ODBC3_ALL_FUNCTIONS */
+/* This returns a bitmap, which allows us to */
+/* handle the higher-valued function numbers. */
+/* Use SQL_FUNC_EXISTS(bitmap,function_number) */
+/* to determine if the function exists. */
+/*----------------------------------------------*/
+
+
+#if (ODBCVER >= 0x0300)
+#define SQL_API_ODBC3_ALL_FUNCTIONS 999
+#define SQL_API_ODBC3_ALL_FUNCTIONS_SIZE 250 /* array of 250 words */
+
+
+#define SQL_FUNC_EXISTS(pfExists, uwAPI) ((*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) & (1 << ((uwAPI) & 0x000F)) ) ? SQL_TRUE : SQL_FALSE )
+
+#endif /* ODBCVER >= 0x0300 */
+
+
+/************************************************/
+/* Extended definitions for SQLGetInfo */
+/************************************************/
+
+/*---------------------------------*/
+/* Values in ODBC 2.0 that are not */
+/* in the X/Open spec */
+/*---------------------------------*/
+
+#define SQL_INFO_FIRST 0
+#define SQL_ACTIVE_CONNECTIONS 0 /* MAX_DRIVER_CONNECTIONS */
+#define SQL_ACTIVE_STATEMENTS 1 /* MAX_CONCURRENT_ACTIVITIES */
+#define SQL_DRIVER_HDBC 3
+#define SQL_DRIVER_HENV 4
+#define SQL_DRIVER_HSTMT 5
+#define SQL_DRIVER_NAME 6
+#define SQL_DRIVER_VER 7
+#define SQL_ODBC_API_CONFORMANCE 9
+#define SQL_ODBC_VER 10
+#define SQL_ROW_UPDATES 11
+#define SQL_ODBC_SAG_CLI_CONFORMANCE 12
+#define SQL_ODBC_SQL_CONFORMANCE 15
+#define SQL_PROCEDURES 21
+#define SQL_CONCAT_NULL_BEHAVIOR 22
+#define SQL_CURSOR_ROLLBACK_BEHAVIOR 24
+#define SQL_EXPRESSIONS_IN_ORDERBY 27
+#define SQL_MAX_OWNER_NAME_LEN 32 /* MAX_SCHEMA_NAME_LEN */
+#define SQL_MAX_PROCEDURE_NAME_LEN 33
+#define SQL_MAX_QUALIFIER_NAME_LEN 34 /* MAX_CATALOG_NAME_LEN */
+#define SQL_MULT_RESULT_SETS 36
+#define SQL_MULTIPLE_ACTIVE_TXN 37
+#define SQL_OUTER_JOINS 38
+#define SQL_OWNER_TERM 39
+#define SQL_PROCEDURE_TERM 40
+#define SQL_QUALIFIER_NAME_SEPARATOR 41
+#define SQL_QUALIFIER_TERM 42
+#define SQL_SCROLL_OPTIONS 44
+#define SQL_TABLE_TERM 45
+#define SQL_CONVERT_FUNCTIONS 48
+#define SQL_NUMERIC_FUNCTIONS 49
+#define SQL_STRING_FUNCTIONS 50
+#define SQL_SYSTEM_FUNCTIONS 51
+#define SQL_TIMEDATE_FUNCTIONS 52
+#define SQL_CONVERT_BIGINT 53
+#define SQL_CONVERT_BINARY 54
+#define SQL_CONVERT_BIT 55
+#define SQL_CONVERT_CHAR 56
+#define SQL_CONVERT_DATE 57
+#define SQL_CONVERT_DECIMAL 58
+#define SQL_CONVERT_DOUBLE 59
+#define SQL_CONVERT_FLOAT 60
+#define SQL_CONVERT_INTEGER 61
+#define SQL_CONVERT_LONGVARCHAR 62
+#define SQL_CONVERT_NUMERIC 63
+#define SQL_CONVERT_REAL 64
+#define SQL_CONVERT_SMALLINT 65
+#define SQL_CONVERT_TIME 66
+#define SQL_CONVERT_TIMESTAMP 67
+#define SQL_CONVERT_TINYINT 68
+#define SQL_CONVERT_VARBINARY 69
+#define SQL_CONVERT_VARCHAR 70
+#define SQL_CONVERT_LONGVARBINARY 71
+#define SQL_CONVERT_GUID 173
+#define SQL_ODBC_SQL_OPT_IEF 73 /* SQL_INTEGRITY */
+#define SQL_CORRELATION_NAME 74
+#define SQL_NON_NULLABLE_COLUMNS 75
+#define SQL_DRIVER_HLIB 76
+#define SQL_DRIVER_ODBC_VER 77
+#define SQL_LOCK_TYPES 78
+#define SQL_POS_OPERATIONS 79
+#define SQL_POSITIONED_STATEMENTS 80
+#define SQL_BOOKMARK_PERSISTENCE 82
+#define SQL_STATIC_SENSITIVITY 83
+#define SQL_FILE_USAGE 84
+#define SQL_COLUMN_ALIAS 87
+#define SQL_GROUP_BY 88
+#define SQL_KEYWORDS 89
+#define SQL_OWNER_USAGE 91
+#define SQL_QUALIFIER_USAGE 92
+#define SQL_QUOTED_IDENTIFIER_CASE 93
+#define SQL_SUBQUERIES 95
+#define SQL_UNION 96
+#define SQL_MAX_ROW_SIZE_INCLUDES_LONG 103
+#define SQL_MAX_CHAR_LITERAL_LEN 108
+#define SQL_TIMEDATE_ADD_INTERVALS 109
+#define SQL_TIMEDATE_DIFF_INTERVALS 110
+#define SQL_NEED_LONG_DATA_LEN 111
+#define SQL_MAX_BINARY_LITERAL_LEN 112
+#define SQL_LIKE_ESCAPE_CLAUSE 113
+#define SQL_QUALIFIER_LOCATION 114
+
+#if (ODBCVER >= 0x0201 && ODBCVER < 0x0300)
+#ifndef SQL_OJ_CAPABILITIES
+#define SQL_OJ_CAPABILITIES 65003 /* Temp value until ODBC 3.0 */
+#endif
+#endif /* ODBCVER >= 0x0201 && ODBCVER < 0x0300 */
+
+/*----------------------------------------------*/
+/* SQL_INFO_LAST and SQL_INFO_DRIVER_START are */
+/* not useful anymore, because X/Open has */
+/* values in the 10000 range. You */
+/* must contact X/Open directly to get a range */
+/* of numbers for driver-specific values. */
+/*----------------------------------------------*/
+
+#if (ODBCVER < 0x0300)
+#define SQL_INFO_LAST SQL_QUALIFIER_LOCATION
+#define SQL_INFO_DRIVER_START 1000
+#endif /* ODBCVER < 0x0300 */
+
+/*-----------------------------------------------*/
+/* ODBC 3.0 SQLGetInfo values that are not part */
+/* of the X/Open standard at this time. X/Open */
+/* standard values are in sql.h. */
+/*-----------------------------------------------*/
+
+#if (ODBCVER >= 0x0300)
+#define SQL_ACTIVE_ENVIRONMENTS 116
+#define SQL_ALTER_DOMAIN 117
+
+#define SQL_SQL_CONFORMANCE 118
+#define SQL_DATETIME_LITERALS 119
+
+#define SQL_ASYNC_MODE 10021 /* new X/Open spec */
+#define SQL_BATCH_ROW_COUNT 120
+#define SQL_BATCH_SUPPORT 121
+#define SQL_CATALOG_LOCATION SQL_QUALIFIER_LOCATION
+#define SQL_CATALOG_NAME_SEPARATOR SQL_QUALIFIER_NAME_SEPARATOR
+#define SQL_CATALOG_TERM SQL_QUALIFIER_TERM
+#define SQL_CATALOG_USAGE SQL_QUALIFIER_USAGE
+#define SQL_CONVERT_WCHAR 122
+#define SQL_CONVERT_INTERVAL_DAY_TIME 123
+#define SQL_CONVERT_INTERVAL_YEAR_MONTH 124
+#define SQL_CONVERT_WLONGVARCHAR 125
+#define SQL_CONVERT_WVARCHAR 126
+#define SQL_CREATE_ASSERTION 127
+#define SQL_CREATE_CHARACTER_SET 128
+#define SQL_CREATE_COLLATION 129
+#define SQL_CREATE_DOMAIN 130
+#define SQL_CREATE_SCHEMA 131
+#define SQL_CREATE_TABLE 132
+#define SQL_CREATE_TRANSLATION 133
+#define SQL_CREATE_VIEW 134
+#define SQL_DRIVER_HDESC 135
+#define SQL_DROP_ASSERTION 136
+#define SQL_DROP_CHARACTER_SET 137
+#define SQL_DROP_COLLATION 138
+#define SQL_DROP_DOMAIN 139
+#define SQL_DROP_SCHEMA 140
+#define SQL_DROP_TABLE 141
+#define SQL_DROP_TRANSLATION 142
+#define SQL_DROP_VIEW 143
+#define SQL_DYNAMIC_CURSOR_ATTRIBUTES1 144
+#define SQL_DYNAMIC_CURSOR_ATTRIBUTES2 145
+#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 146
+#define SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 147
+#define SQL_INDEX_KEYWORDS 148
+#define SQL_INFO_SCHEMA_VIEWS 149
+#define SQL_KEYSET_CURSOR_ATTRIBUTES1 150
+#define SQL_KEYSET_CURSOR_ATTRIBUTES2 151
+#define SQL_MAX_ASYNC_CONCURRENT_STATEMENTS 10022 /* new X/Open spec */
+#define SQL_ODBC_INTERFACE_CONFORMANCE 152
+#define SQL_PARAM_ARRAY_ROW_COUNTS 153
+#define SQL_PARAM_ARRAY_SELECTS 154
+#define SQL_SCHEMA_TERM SQL_OWNER_TERM
+#define SQL_SCHEMA_USAGE SQL_OWNER_USAGE
+#define SQL_SQL92_DATETIME_FUNCTIONS 155
+#define SQL_SQL92_FOREIGN_KEY_DELETE_RULE 156
+#define SQL_SQL92_FOREIGN_KEY_UPDATE_RULE 157
+#define SQL_SQL92_GRANT 158
+#define SQL_SQL92_NUMERIC_VALUE_FUNCTIONS 159
+#define SQL_SQL92_PREDICATES 160
+#define SQL_SQL92_RELATIONAL_JOIN_OPERATORS 161
+#define SQL_SQL92_REVOKE 162
+#define SQL_SQL92_ROW_VALUE_CONSTRUCTOR 163
+#define SQL_SQL92_STRING_FUNCTIONS 164
+#define SQL_SQL92_VALUE_EXPRESSIONS 165
+#define SQL_STANDARD_CLI_CONFORMANCE 166
+#define SQL_STATIC_CURSOR_ATTRIBUTES1 167
+#define SQL_STATIC_CURSOR_ATTRIBUTES2 168
+
+#define SQL_AGGREGATE_FUNCTIONS 169
+#define SQL_DDL_INDEX 170
+#define SQL_DM_VER 171
+#define SQL_INSERT_STATEMENT 172
+#define SQL_UNION_STATEMENT SQL_UNION
+#endif /* ODBCVER >= 0x0300 */
+
+#define SQL_DTC_TRANSITION_COST 1750
+
+/* SQL_ALTER_TABLE bitmasks */
+#if (ODBCVER >= 0x0300)
+/* the following 5 bitmasks are defined in sql.h
+*#define SQL_AT_ADD_COLUMN 0x00000001L
+*#define SQL_AT_DROP_COLUMN 0x00000002L
+*#define SQL_AT_ADD_CONSTRAINT 0x00000008L
+*/
+#define SQL_AT_ADD_COLUMN_SINGLE 0x00000020L
+#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L
+#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L
+#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L
+#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L
+#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L
+#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L
+#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L
+#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L
+#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L
+#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L
+#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L
+#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L
+#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L
+#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_CONVERT_* return value bitmasks */
+
+#define SQL_CVT_CHAR 0x00000001L
+#define SQL_CVT_NUMERIC 0x00000002L
+#define SQL_CVT_DECIMAL 0x00000004L
+#define SQL_CVT_INTEGER 0x00000008L
+#define SQL_CVT_SMALLINT 0x00000010L
+#define SQL_CVT_FLOAT 0x00000020L
+#define SQL_CVT_REAL 0x00000040L
+#define SQL_CVT_DOUBLE 0x00000080L
+#define SQL_CVT_VARCHAR 0x00000100L
+#define SQL_CVT_LONGVARCHAR 0x00000200L
+#define SQL_CVT_BINARY 0x00000400L
+#define SQL_CVT_VARBINARY 0x00000800L
+#define SQL_CVT_BIT 0x00001000L
+#define SQL_CVT_TINYINT 0x00002000L
+#define SQL_CVT_BIGINT 0x00004000L
+#define SQL_CVT_DATE 0x00008000L
+#define SQL_CVT_TIME 0x00010000L
+#define SQL_CVT_TIMESTAMP 0x00020000L
+#define SQL_CVT_LONGVARBINARY 0x00040000L
+#if (ODBCVER >= 0x0300)
+#define SQL_CVT_INTERVAL_YEAR_MONTH 0x00080000L
+#define SQL_CVT_INTERVAL_DAY_TIME 0x00100000L
+#define SQL_CVT_WCHAR 0x00200000L
+#define SQL_CVT_WLONGVARCHAR 0x00400000L
+#define SQL_CVT_WVARCHAR 0x00800000L
+#define SQL_CVT_GUID 0x01000000L
+
+#endif /* ODBCVER >= 0x0300 */
+
+
+/* SQL_CONVERT_FUNCTIONS functions */
+#define SQL_FN_CVT_CONVERT 0x00000001L
+#if (ODBCVER >= 0x0300)
+#define SQL_FN_CVT_CAST 0x00000002L
+#endif /* ODBCVER >= 0x0300 */
+
+
+/* SQL_STRING_FUNCTIONS functions */
+
+#define SQL_FN_STR_CONCAT 0x00000001L
+#define SQL_FN_STR_INSERT 0x00000002L
+#define SQL_FN_STR_LEFT 0x00000004L
+#define SQL_FN_STR_LTRIM 0x00000008L
+#define SQL_FN_STR_LENGTH 0x00000010L
+#define SQL_FN_STR_LOCATE 0x00000020L
+#define SQL_FN_STR_LCASE 0x00000040L
+#define SQL_FN_STR_REPEAT 0x00000080L
+#define SQL_FN_STR_REPLACE 0x00000100L
+#define SQL_FN_STR_RIGHT 0x00000200L
+#define SQL_FN_STR_RTRIM 0x00000400L
+#define SQL_FN_STR_SUBSTRING 0x00000800L
+#define SQL_FN_STR_UCASE 0x00001000L
+#define SQL_FN_STR_ASCII 0x00002000L
+#define SQL_FN_STR_CHAR 0x00004000L
+#define SQL_FN_STR_DIFFERENCE 0x00008000L
+#define SQL_FN_STR_LOCATE_2 0x00010000L
+#define SQL_FN_STR_SOUNDEX 0x00020000L
+#define SQL_FN_STR_SPACE 0x00040000L
+#if (ODBCVER >= 0x0300)
+#define SQL_FN_STR_BIT_LENGTH 0x00080000L
+#define SQL_FN_STR_CHAR_LENGTH 0x00100000L
+#define SQL_FN_STR_CHARACTER_LENGTH 0x00200000L
+#define SQL_FN_STR_OCTET_LENGTH 0x00400000L
+#define SQL_FN_STR_POSITION 0x00800000L
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_SQL92_STRING_FUNCTIONS */
+#if (ODBCVER >= 0x0300)
+#define SQL_SSF_CONVERT 0x00000001L
+#define SQL_SSF_LOWER 0x00000002L
+#define SQL_SSF_UPPER 0x00000004L
+#define SQL_SSF_SUBSTRING 0x00000008L
+#define SQL_SSF_TRANSLATE 0x00000010L
+#define SQL_SSF_TRIM_BOTH 0x00000020L
+#define SQL_SSF_TRIM_LEADING 0x00000040L
+#define SQL_SSF_TRIM_TRAILING 0x00000080L
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_NUMERIC_FUNCTIONS functions */
+
+#define SQL_FN_NUM_ABS 0x00000001L
+#define SQL_FN_NUM_ACOS 0x00000002L
+#define SQL_FN_NUM_ASIN 0x00000004L
+#define SQL_FN_NUM_ATAN 0x00000008L
+#define SQL_FN_NUM_ATAN2 0x00000010L
+#define SQL_FN_NUM_CEILING 0x00000020L
+#define SQL_FN_NUM_COS 0x00000040L
+#define SQL_FN_NUM_COT 0x00000080L
+#define SQL_FN_NUM_EXP 0x00000100L
+#define SQL_FN_NUM_FLOOR 0x00000200L
+#define SQL_FN_NUM_LOG 0x00000400L
+#define SQL_FN_NUM_MOD 0x00000800L
+#define SQL_FN_NUM_SIGN 0x00001000L
+#define SQL_FN_NUM_SIN 0x00002000L
+#define SQL_FN_NUM_SQRT 0x00004000L
+#define SQL_FN_NUM_TAN 0x00008000L
+#define SQL_FN_NUM_PI 0x00010000L
+#define SQL_FN_NUM_RAND 0x00020000L
+#define SQL_FN_NUM_DEGREES 0x00040000L
+#define SQL_FN_NUM_LOG10 0x00080000L
+#define SQL_FN_NUM_POWER 0x00100000L
+#define SQL_FN_NUM_RADIANS 0x00200000L
+#define SQL_FN_NUM_ROUND 0x00400000L
+#define SQL_FN_NUM_TRUNCATE 0x00800000L
+
+/* SQL_SQL92_NUMERIC_VALUE_FUNCTIONS */
+#if (ODBCVER >= 0x0300)
+#define SQL_SNVF_BIT_LENGTH 0x00000001L
+#define SQL_SNVF_CHAR_LENGTH 0x00000002L
+#define SQL_SNVF_CHARACTER_LENGTH 0x00000004L
+#define SQL_SNVF_EXTRACT 0x00000008L
+#define SQL_SNVF_OCTET_LENGTH 0x00000010L
+#define SQL_SNVF_POSITION 0x00000020L
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_TIMEDATE_FUNCTIONS functions */
+
+#define SQL_FN_TD_NOW 0x00000001L
+#define SQL_FN_TD_CURDATE 0x00000002L
+#define SQL_FN_TD_DAYOFMONTH 0x00000004L
+#define SQL_FN_TD_DAYOFWEEK 0x00000008L
+#define SQL_FN_TD_DAYOFYEAR 0x00000010L
+#define SQL_FN_TD_MONTH 0x00000020L
+#define SQL_FN_TD_QUARTER 0x00000040L
+#define SQL_FN_TD_WEEK 0x00000080L
+#define SQL_FN_TD_YEAR 0x00000100L
+#define SQL_FN_TD_CURTIME 0x00000200L
+#define SQL_FN_TD_HOUR 0x00000400L
+#define SQL_FN_TD_MINUTE 0x00000800L
+#define SQL_FN_TD_SECOND 0x00001000L
+#define SQL_FN_TD_TIMESTAMPADD 0x00002000L
+#define SQL_FN_TD_TIMESTAMPDIFF 0x00004000L
+#define SQL_FN_TD_DAYNAME 0x00008000L
+#define SQL_FN_TD_MONTHNAME 0x00010000L
+#if (ODBCVER >= 0x0300)
+#define SQL_FN_TD_CURRENT_DATE 0x00020000L
+#define SQL_FN_TD_CURRENT_TIME 0x00040000L
+#define SQL_FN_TD_CURRENT_TIMESTAMP 0x00080000L
+#define SQL_FN_TD_EXTRACT 0x00100000L
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_SQL92_DATETIME_FUNCTIONS */
+#if (ODBCVER >= 0x0300)
+#define SQL_SDF_CURRENT_DATE 0x00000001L
+#define SQL_SDF_CURRENT_TIME 0x00000002L
+#define SQL_SDF_CURRENT_TIMESTAMP 0x00000004L
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_SYSTEM_FUNCTIONS functions */
+
+#define SQL_FN_SYS_USERNAME 0x00000001L
+#define SQL_FN_SYS_DBNAME 0x00000002L
+#define SQL_FN_SYS_IFNULL 0x00000004L
+
+/* SQL_TIMEDATE_ADD_INTERVALS and SQL_TIMEDATE_DIFF_INTERVALS functions */
+
+#define SQL_FN_TSI_FRAC_SECOND 0x00000001L
+#define SQL_FN_TSI_SECOND 0x00000002L
+#define SQL_FN_TSI_MINUTE 0x00000004L
+#define SQL_FN_TSI_HOUR 0x00000008L
+#define SQL_FN_TSI_DAY 0x00000010L
+#define SQL_FN_TSI_WEEK 0x00000020L
+#define SQL_FN_TSI_MONTH 0x00000040L
+#define SQL_FN_TSI_QUARTER 0x00000080L
+#define SQL_FN_TSI_YEAR 0x00000100L
+
+/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES1,
+ * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1,
+ * SQL_KEYSET_CURSOR_ATTRIBUTES1, and SQL_STATIC_CURSOR_ATTRIBUTES1
+ */
+#if (ODBCVER >= 0x0300)
+/* supported SQLFetchScroll FetchOrientation's */
+#define SQL_CA1_NEXT 0x00000001L
+#define SQL_CA1_ABSOLUTE 0x00000002L
+#define SQL_CA1_RELATIVE 0x00000004L
+#define SQL_CA1_BOOKMARK 0x00000008L
+
+/* supported SQLSetPos LockType's */
+#define SQL_CA1_LOCK_NO_CHANGE 0x00000040L
+#define SQL_CA1_LOCK_EXCLUSIVE 0x00000080L
+#define SQL_CA1_LOCK_UNLOCK 0x00000100L
+
+/* supported SQLSetPos Operations */
+#define SQL_CA1_POS_POSITION 0x00000200L
+#define SQL_CA1_POS_UPDATE 0x00000400L
+#define SQL_CA1_POS_DELETE 0x00000800L
+#define SQL_CA1_POS_REFRESH 0x00001000L
+
+/* positioned updates and deletes */
+#define SQL_CA1_POSITIONED_UPDATE 0x00002000L
+#define SQL_CA1_POSITIONED_DELETE 0x00004000L
+#define SQL_CA1_SELECT_FOR_UPDATE 0x00008000L
+
+/* supported SQLBulkOperations operations */
+#define SQL_CA1_BULK_ADD 0x00010000L
+#define SQL_CA1_BULK_UPDATE_BY_BOOKMARK 0x00020000L
+#define SQL_CA1_BULK_DELETE_BY_BOOKMARK 0x00040000L
+#define SQL_CA1_BULK_FETCH_BY_BOOKMARK 0x00080000L
+#endif /* ODBCVER >= 0x0300 */
+
+/* bitmasks for SQL_DYNAMIC_CURSOR_ATTRIBUTES2,
+ * SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2,
+ * SQL_KEYSET_CURSOR_ATTRIBUTES2, and SQL_STATIC_CURSOR_ATTRIBUTES2
+ */
+#if (ODBCVER >= 0x0300)
+/* supported values for SQL_ATTR_SCROLL_CONCURRENCY */
+#define SQL_CA2_READ_ONLY_CONCURRENCY 0x00000001L
+#define SQL_CA2_LOCK_CONCURRENCY 0x00000002L
+#define SQL_CA2_OPT_ROWVER_CONCURRENCY 0x00000004L
+#define SQL_CA2_OPT_VALUES_CONCURRENCY 0x00000008L
+
+/* sensitivity of the cursor to its own inserts, deletes, and updates */
+#define SQL_CA2_SENSITIVITY_ADDITIONS 0x00000010L
+#define SQL_CA2_SENSITIVITY_DELETIONS 0x00000020L
+#define SQL_CA2_SENSITIVITY_UPDATES 0x00000040L
+
+/* semantics of SQL_ATTR_MAX_ROWS */
+#define SQL_CA2_MAX_ROWS_SELECT 0x00000080L
+#define SQL_CA2_MAX_ROWS_INSERT 0x00000100L
+#define SQL_CA2_MAX_ROWS_DELETE 0x00000200L
+#define SQL_CA2_MAX_ROWS_UPDATE 0x00000400L
+#define SQL_CA2_MAX_ROWS_CATALOG 0x00000800L
+#define SQL_CA2_MAX_ROWS_AFFECTS_ALL (SQL_CA2_MAX_ROWS_SELECT | SQL_CA2_MAX_ROWS_INSERT | SQL_CA2_MAX_ROWS_DELETE | SQL_CA2_MAX_ROWS_UPDATE | SQL_CA2_MAX_ROWS_CATALOG)
+
+/* semantics of SQL_DIAG_CURSOR_ROW_COUNT */
+#define SQL_CA2_CRC_EXACT 0x00001000L
+#define SQL_CA2_CRC_APPROXIMATE 0x00002000L
+
+/* the kinds of positioned statements that can be simulated */
+#define SQL_CA2_SIMULATE_NON_UNIQUE 0x00004000L
+#define SQL_CA2_SIMULATE_TRY_UNIQUE 0x00008000L
+#define SQL_CA2_SIMULATE_UNIQUE 0x00010000L
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_ODBC_API_CONFORMANCE values */
+
+#define SQL_OAC_NONE 0x0000
+#define SQL_OAC_LEVEL1 0x0001
+#define SQL_OAC_LEVEL2 0x0002
+
+/* SQL_ODBC_SAG_CLI_CONFORMANCE values */
+
+#define SQL_OSCC_NOT_COMPLIANT 0x0000
+#define SQL_OSCC_COMPLIANT 0x0001
+
+/* SQL_ODBC_SQL_CONFORMANCE values */
+
+#define SQL_OSC_MINIMUM 0x0000
+#define SQL_OSC_CORE 0x0001
+#define SQL_OSC_EXTENDED 0x0002
+
+
+/* SQL_CONCAT_NULL_BEHAVIOR values */
+
+#define SQL_CB_NULL 0x0000
+#define SQL_CB_NON_NULL 0x0001
+
+/* SQL_SCROLL_OPTIONS masks */
+
+#define SQL_SO_FORWARD_ONLY 0x00000001L
+#define SQL_SO_KEYSET_DRIVEN 0x00000002L
+#define SQL_SO_DYNAMIC 0x00000004L
+#define SQL_SO_MIXED 0x00000008L
+#define SQL_SO_STATIC 0x00000010L
+
+/* SQL_FETCH_DIRECTION masks */
+
+/* SQL_FETCH_RESUME is no longer supported
+#define SQL_FD_FETCH_RESUME 0x00000040L
+*/
+#define SQL_FD_FETCH_BOOKMARK 0x00000080L
+
+/* SQL_TXN_ISOLATION_OPTION masks */
+/* SQL_TXN_VERSIONING is no longer supported
+#define SQL_TXN_VERSIONING 0x00000010L
+*/
+
+/* SQL_CORRELATION_NAME values */
+
+#define SQL_CN_NONE 0x0000
+#define SQL_CN_DIFFERENT 0x0001
+#define SQL_CN_ANY 0x0002
+
+/* SQL_NON_NULLABLE_COLUMNS values */
+
+#define SQL_NNC_NULL 0x0000
+#define SQL_NNC_NON_NULL 0x0001
+
+/* SQL_NULL_COLLATION values */
+
+#define SQL_NC_START 0x0002
+#define SQL_NC_END 0x0004
+
+/* SQL_FILE_USAGE values */
+
+#define SQL_FILE_NOT_SUPPORTED 0x0000
+#define SQL_FILE_TABLE 0x0001
+#define SQL_FILE_QUALIFIER 0x0002
+#define SQL_FILE_CATALOG SQL_FILE_QUALIFIER /* ODBC 3.0 */
+
+
+/* SQL_GETDATA_EXTENSIONS values */
+
+#define SQL_GD_BLOCK 0x00000004L
+#define SQL_GD_BOUND 0x00000008L
+
+/* SQL_POSITIONED_STATEMENTS masks */
+
+#define SQL_PS_POSITIONED_DELETE 0x00000001L
+#define SQL_PS_POSITIONED_UPDATE 0x00000002L
+#define SQL_PS_SELECT_FOR_UPDATE 0x00000004L
+
+/* SQL_GROUP_BY values */
+
+#define SQL_GB_NOT_SUPPORTED 0x0000
+#define SQL_GB_GROUP_BY_EQUALS_SELECT 0x0001
+#define SQL_GB_GROUP_BY_CONTAINS_SELECT 0x0002
+#define SQL_GB_NO_RELATION 0x0003
+#if (ODBCVER >= 0x0300)
+#define SQL_GB_COLLATE 0x0004
+
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_OWNER_USAGE masks */
+
+#define SQL_OU_DML_STATEMENTS 0x00000001L
+#define SQL_OU_PROCEDURE_INVOCATION 0x00000002L
+#define SQL_OU_TABLE_DEFINITION 0x00000004L
+#define SQL_OU_INDEX_DEFINITION 0x00000008L
+#define SQL_OU_PRIVILEGE_DEFINITION 0x00000010L
+
+/* SQL_SCHEMA_USAGE masks */
+#if (ODBCVER >= 0x0300)
+#define SQL_SU_DML_STATEMENTS SQL_OU_DML_STATEMENTS
+#define SQL_SU_PROCEDURE_INVOCATION SQL_OU_PROCEDURE_INVOCATION
+#define SQL_SU_TABLE_DEFINITION SQL_OU_TABLE_DEFINITION
+#define SQL_SU_INDEX_DEFINITION SQL_OU_INDEX_DEFINITION
+#define SQL_SU_PRIVILEGE_DEFINITION SQL_OU_PRIVILEGE_DEFINITION
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_QUALIFIER_USAGE masks */
+
+#define SQL_QU_DML_STATEMENTS 0x00000001L
+#define SQL_QU_PROCEDURE_INVOCATION 0x00000002L
+#define SQL_QU_TABLE_DEFINITION 0x00000004L
+#define SQL_QU_INDEX_DEFINITION 0x00000008L
+#define SQL_QU_PRIVILEGE_DEFINITION 0x00000010L
+
+#if (ODBCVER >= 0x0300)
+/* SQL_CATALOG_USAGE masks */
+#define SQL_CU_DML_STATEMENTS SQL_QU_DML_STATEMENTS
+#define SQL_CU_PROCEDURE_INVOCATION SQL_QU_PROCEDURE_INVOCATION
+#define SQL_CU_TABLE_DEFINITION SQL_QU_TABLE_DEFINITION
+#define SQL_CU_INDEX_DEFINITION SQL_QU_INDEX_DEFINITION
+#define SQL_CU_PRIVILEGE_DEFINITION SQL_QU_PRIVILEGE_DEFINITION
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_SUBQUERIES masks */
+
+#define SQL_SQ_COMPARISON 0x00000001L
+#define SQL_SQ_EXISTS 0x00000002L
+#define SQL_SQ_IN 0x00000004L
+#define SQL_SQ_QUANTIFIED 0x00000008L
+#define SQL_SQ_CORRELATED_SUBQUERIES 0x00000010L
+
+/* SQL_UNION masks */
+
+#define SQL_U_UNION 0x00000001L
+#define SQL_U_UNION_ALL 0x00000002L
+
+/* SQL_BOOKMARK_PERSISTENCE values */
+
+#define SQL_BP_CLOSE 0x00000001L
+#define SQL_BP_DELETE 0x00000002L
+#define SQL_BP_DROP 0x00000004L
+#define SQL_BP_TRANSACTION 0x00000008L
+#define SQL_BP_UPDATE 0x00000010L
+#define SQL_BP_OTHER_HSTMT 0x00000020L
+#define SQL_BP_SCROLL 0x00000040L
+
+/* SQL_STATIC_SENSITIVITY values */
+
+#define SQL_SS_ADDITIONS 0x00000001L
+#define SQL_SS_DELETIONS 0x00000002L
+#define SQL_SS_UPDATES 0x00000004L
+
+/* SQL_VIEW values */
+#define SQL_CV_CREATE_VIEW 0x00000001L
+#define SQL_CV_CHECK_OPTION 0x00000002L
+#define SQL_CV_CASCADED 0x00000004L
+#define SQL_CV_LOCAL 0x00000008L
+
+/* SQL_LOCK_TYPES masks */
+
+#define SQL_LCK_NO_CHANGE 0x00000001L
+#define SQL_LCK_EXCLUSIVE 0x00000002L
+#define SQL_LCK_UNLOCK 0x00000004L
+
+/* SQL_POS_OPERATIONS masks */
+
+#define SQL_POS_POSITION 0x00000001L
+#define SQL_POS_REFRESH 0x00000002L
+#define SQL_POS_UPDATE 0x00000004L
+#define SQL_POS_DELETE 0x00000008L
+#define SQL_POS_ADD 0x00000010L
+
+/* SQL_QUALIFIER_LOCATION values */
+
+#define SQL_QL_START 0x0001
+#define SQL_QL_END 0x0002
+
+/* Here start return values for ODBC 3.0 SQLGetInfo */
+
+#if (ODBCVER >= 0x0300)
+/* SQL_AGGREGATE_FUNCTIONS bitmasks */
+#define SQL_AF_AVG 0x00000001L
+#define SQL_AF_COUNT 0x00000002L
+#define SQL_AF_MAX 0x00000004L
+#define SQL_AF_MIN 0x00000008L
+#define SQL_AF_SUM 0x00000010L
+#define SQL_AF_DISTINCT 0x00000020L
+#define SQL_AF_ALL 0x00000040L
+
+/* SQL_SQL_CONFORMANCE bit masks */
+#define SQL_SC_SQL92_ENTRY 0x00000001L
+#define SQL_SC_FIPS127_2_TRANSITIONAL 0x00000002L
+#define SQL_SC_SQL92_INTERMEDIATE 0x00000004L
+#define SQL_SC_SQL92_FULL 0x00000008L
+
+/* SQL_DATETIME_LITERALS masks */
+#define SQL_DL_SQL92_DATE 0x00000001L
+#define SQL_DL_SQL92_TIME 0x00000002L
+#define SQL_DL_SQL92_TIMESTAMP 0x00000004L
+#define SQL_DL_SQL92_INTERVAL_YEAR 0x00000008L
+#define SQL_DL_SQL92_INTERVAL_MONTH 0x00000010L
+#define SQL_DL_SQL92_INTERVAL_DAY 0x00000020L
+#define SQL_DL_SQL92_INTERVAL_HOUR 0x00000040L
+#define SQL_DL_SQL92_INTERVAL_MINUTE 0x00000080L
+#define SQL_DL_SQL92_INTERVAL_SECOND 0x00000100L
+#define SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH 0x00000200L
+#define SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR 0x00000400L
+#define SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE 0x00000800L
+#define SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND 0x00001000L
+#define SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE 0x00002000L
+#define SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND 0x00004000L
+#define SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND 0x00008000L
+
+/* SQL_CATALOG_LOCATION values */
+#define SQL_CL_START SQL_QL_START
+#define SQL_CL_END SQL_QL_END
+
+/* values for SQL_BATCH_ROW_COUNT */
+#define SQL_BRC_PROCEDURES 0x0000001
+#define SQL_BRC_EXPLICIT 0x0000002
+#define SQL_BRC_ROLLED_UP 0x0000004
+
+/* bitmasks for SQL_BATCH_SUPPORT */
+#define SQL_BS_SELECT_EXPLICIT 0x00000001L
+#define SQL_BS_ROW_COUNT_EXPLICIT 0x00000002L
+#define SQL_BS_SELECT_PROC 0x00000004L
+#define SQL_BS_ROW_COUNT_PROC 0x00000008L
+
+/* Values for SQL_PARAM_ARRAY_ROW_COUNTS getinfo */
+#define SQL_PARC_BATCH 1
+#define SQL_PARC_NO_BATCH 2
+
+/* values for SQL_PARAM_ARRAY_SELECTS */
+#define SQL_PAS_BATCH 1
+#define SQL_PAS_NO_BATCH 2
+#define SQL_PAS_NO_SELECT 3
+
+/* Bitmasks for SQL_INDEX_KEYWORDS */
+#define SQL_IK_NONE 0x00000000L
+#define SQL_IK_ASC 0x00000001L
+#define SQL_IK_DESC 0x00000002L
+#define SQL_IK_ALL (SQL_IK_ASC | SQL_IK_DESC)
+
+/* Bitmasks for SQL_INFO_SCHEMA_VIEWS */
+
+#define SQL_ISV_ASSERTIONS 0x00000001L
+#define SQL_ISV_CHARACTER_SETS 0x00000002L
+#define SQL_ISV_CHECK_CONSTRAINTS 0x00000004L
+#define SQL_ISV_COLLATIONS 0x00000008L
+#define SQL_ISV_COLUMN_DOMAIN_USAGE 0x00000010L
+#define SQL_ISV_COLUMN_PRIVILEGES 0x00000020L
+#define SQL_ISV_COLUMNS 0x00000040L
+#define SQL_ISV_CONSTRAINT_COLUMN_USAGE 0x00000080L
+#define SQL_ISV_CONSTRAINT_TABLE_USAGE 0x00000100L
+#define SQL_ISV_DOMAIN_CONSTRAINTS 0x00000200L
+#define SQL_ISV_DOMAINS 0x00000400L
+#define SQL_ISV_KEY_COLUMN_USAGE 0x00000800L
+#define SQL_ISV_REFERENTIAL_CONSTRAINTS 0x00001000L
+#define SQL_ISV_SCHEMATA 0x00002000L
+#define SQL_ISV_SQL_LANGUAGES 0x00004000L
+#define SQL_ISV_TABLE_CONSTRAINTS 0x00008000L
+#define SQL_ISV_TABLE_PRIVILEGES 0x00010000L
+#define SQL_ISV_TABLES 0x00020000L
+#define SQL_ISV_TRANSLATIONS 0x00040000L
+#define SQL_ISV_USAGE_PRIVILEGES 0x00080000L
+#define SQL_ISV_VIEW_COLUMN_USAGE 0x00100000L
+#define SQL_ISV_VIEW_TABLE_USAGE 0x00200000L
+#define SQL_ISV_VIEWS 0x00400000L
+
+/* Bitmasks for SQL_ASYNC_MODE */
+
+#define SQL_AM_NONE 0
+#define SQL_AM_CONNECTION 1
+#define SQL_AM_STATEMENT 2
+
+/* Bitmasks for SQL_ALTER_DOMAIN */
+#define SQL_AD_CONSTRAINT_NAME_DEFINITION 0x00000001L
+#define SQL_AD_ADD_DOMAIN_CONSTRAINT 0x00000002L
+#define SQL_AD_DROP_DOMAIN_CONSTRAINT 0x00000004L
+#define SQL_AD_ADD_DOMAIN_DEFAULT 0x00000008L
+#define SQL_AD_DROP_DOMAIN_DEFAULT 0x00000010L
+#define SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L
+#define SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L
+#define SQL_AD_ADD_CONSTRAINT_DEFERRABLE 0x00000080L
+#define SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE 0x00000100L
+
+
+/* SQL_CREATE_SCHEMA bitmasks */
+#define SQL_CS_CREATE_SCHEMA 0x00000001L
+#define SQL_CS_AUTHORIZATION 0x00000002L
+#define SQL_CS_DEFAULT_CHARACTER_SET 0x00000004L
+
+/* SQL_CREATE_TRANSLATION bitmasks */
+#define SQL_CTR_CREATE_TRANSLATION 0x00000001L
+
+/* SQL_CREATE_ASSERTION bitmasks */
+#define SQL_CA_CREATE_ASSERTION 0x00000001L
+#define SQL_CA_CONSTRAINT_INITIALLY_DEFERRED 0x00000010L
+#define SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000020L
+#define SQL_CA_CONSTRAINT_DEFERRABLE 0x00000040L
+#define SQL_CA_CONSTRAINT_NON_DEFERRABLE 0x00000080L
+
+/* SQL_CREATE_CHARACTER_SET bitmasks */
+#define SQL_CCS_CREATE_CHARACTER_SET 0x00000001L
+#define SQL_CCS_COLLATE_CLAUSE 0x00000002L
+#define SQL_CCS_LIMITED_COLLATION 0x00000004L
+
+/* SQL_CREATE_COLLATION bitmasks */
+#define SQL_CCOL_CREATE_COLLATION 0x00000001L
+
+/* SQL_CREATE_DOMAIN bitmasks */
+#define SQL_CDO_CREATE_DOMAIN 0x00000001L
+#define SQL_CDO_DEFAULT 0x00000002L
+#define SQL_CDO_CONSTRAINT 0x00000004L
+#define SQL_CDO_COLLATION 0x00000008L
+#define SQL_CDO_CONSTRAINT_NAME_DEFINITION 0x00000010L
+#define SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L
+#define SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L
+#define SQL_CDO_CONSTRAINT_DEFERRABLE 0x00000080L
+#define SQL_CDO_CONSTRAINT_NON_DEFERRABLE 0x00000100L
+
+/* SQL_CREATE_TABLE bitmasks */
+#define SQL_CT_CREATE_TABLE 0x00000001L
+#define SQL_CT_COMMIT_PRESERVE 0x00000002L
+#define SQL_CT_COMMIT_DELETE 0x00000004L
+#define SQL_CT_GLOBAL_TEMPORARY 0x00000008L
+#define SQL_CT_LOCAL_TEMPORARY 0x00000010L
+#define SQL_CT_CONSTRAINT_INITIALLY_DEFERRED 0x00000020L
+#define SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00000040L
+#define SQL_CT_CONSTRAINT_DEFERRABLE 0x00000080L
+#define SQL_CT_CONSTRAINT_NON_DEFERRABLE 0x00000100L
+#define SQL_CT_COLUMN_CONSTRAINT 0x00000200L
+#define SQL_CT_COLUMN_DEFAULT 0x00000400L
+#define SQL_CT_COLUMN_COLLATION 0x00000800L
+#define SQL_CT_TABLE_CONSTRAINT 0x00001000L
+#define SQL_CT_CONSTRAINT_NAME_DEFINITION 0x00002000L
+
+/* SQL_DDL_INDEX bitmasks */
+#define SQL_DI_CREATE_INDEX 0x00000001L
+#define SQL_DI_DROP_INDEX 0x00000002L
+
+/* SQL_DROP_COLLATION bitmasks */
+#define SQL_DC_DROP_COLLATION 0x00000001L
+
+/* SQL_DROP_DOMAIN bitmasks */
+#define SQL_DD_DROP_DOMAIN 0x00000001L
+#define SQL_DD_RESTRICT 0x00000002L
+#define SQL_DD_CASCADE 0x00000004L
+
+/* SQL_DROP_SCHEMA bitmasks */
+#define SQL_DS_DROP_SCHEMA 0x00000001L
+#define SQL_DS_RESTRICT 0x00000002L
+#define SQL_DS_CASCADE 0x00000004L
+
+/* SQL_DROP_CHARACTER_SET bitmasks */
+#define SQL_DCS_DROP_CHARACTER_SET 0x00000001L
+
+/* SQL_DROP_ASSERTION bitmasks */
+#define SQL_DA_DROP_ASSERTION 0x00000001L
+
+/* SQL_DROP_TABLE bitmasks */
+#define SQL_DT_DROP_TABLE 0x00000001L
+#define SQL_DT_RESTRICT 0x00000002L
+#define SQL_DT_CASCADE 0x00000004L
+
+/* SQL_DROP_TRANSLATION bitmasks */
+#define SQL_DTR_DROP_TRANSLATION 0x00000001L
+
+/* SQL_DROP_VIEW bitmasks */
+#define SQL_DV_DROP_VIEW 0x00000001L
+#define SQL_DV_RESTRICT 0x00000002L
+#define SQL_DV_CASCADE 0x00000004L
+
+/* SQL_INSERT_STATEMENT bitmasks */
+#define SQL_IS_INSERT_LITERALS 0x00000001L
+#define SQL_IS_INSERT_SEARCHED 0x00000002L
+#define SQL_IS_SELECT_INTO 0x00000004L
+
+/* SQL_ODBC_INTERFACE_CONFORMANCE values */
+#define SQL_OIC_CORE 1UL
+#define SQL_OIC_LEVEL1 2UL
+#define SQL_OIC_LEVEL2 3UL
+
+/* SQL_SQL92_FOREIGN_KEY_DELETE_RULE bitmasks */
+#define SQL_SFKD_CASCADE 0x00000001L
+#define SQL_SFKD_NO_ACTION 0x00000002L
+#define SQL_SFKD_SET_DEFAULT 0x00000004L
+#define SQL_SFKD_SET_NULL 0x00000008L
+
+/* SQL_SQL92_FOREIGN_KEY_UPDATE_RULE bitmasks */
+#define SQL_SFKU_CASCADE 0x00000001L
+#define SQL_SFKU_NO_ACTION 0x00000002L
+#define SQL_SFKU_SET_DEFAULT 0x00000004L
+#define SQL_SFKU_SET_NULL 0x00000008L
+
+/* SQL_SQL92_GRANT bitmasks */
+#define SQL_SG_USAGE_ON_DOMAIN 0x00000001L
+#define SQL_SG_USAGE_ON_CHARACTER_SET 0x00000002L
+#define SQL_SG_USAGE_ON_COLLATION 0x00000004L
+#define SQL_SG_USAGE_ON_TRANSLATION 0x00000008L
+#define SQL_SG_WITH_GRANT_OPTION 0x00000010L
+#define SQL_SG_DELETE_TABLE 0x00000020L
+#define SQL_SG_INSERT_TABLE 0x00000040L
+#define SQL_SG_INSERT_COLUMN 0x00000080L
+#define SQL_SG_REFERENCES_TABLE 0x00000100L
+#define SQL_SG_REFERENCES_COLUMN 0x00000200L
+#define SQL_SG_SELECT_TABLE 0x00000400L
+#define SQL_SG_UPDATE_TABLE 0x00000800L
+#define SQL_SG_UPDATE_COLUMN 0x00001000L
+
+/* SQL_SQL92_PREDICATES bitmasks */
+#define SQL_SP_EXISTS 0x00000001L
+#define SQL_SP_ISNOTNULL 0x00000002L
+#define SQL_SP_ISNULL 0x00000004L
+#define SQL_SP_MATCH_FULL 0x00000008L
+#define SQL_SP_MATCH_PARTIAL 0x00000010L
+#define SQL_SP_MATCH_UNIQUE_FULL 0x00000020L
+#define SQL_SP_MATCH_UNIQUE_PARTIAL 0x00000040L
+#define SQL_SP_OVERLAPS 0x00000080L
+#define SQL_SP_UNIQUE 0x00000100L
+#define SQL_SP_LIKE 0x00000200L
+#define SQL_SP_IN 0x00000400L
+#define SQL_SP_BETWEEN 0x00000800L
+#define SQL_SP_COMPARISON 0x00001000L
+#define SQL_SP_QUANTIFIED_COMPARISON 0x00002000L
+
+/* SQL_SQL92_RELATIONAL_JOIN_OPERATORS bitmasks */
+#define SQL_SRJO_CORRESPONDING_CLAUSE 0x00000001L
+#define SQL_SRJO_CROSS_JOIN 0x00000002L
+#define SQL_SRJO_EXCEPT_JOIN 0x00000004L
+#define SQL_SRJO_FULL_OUTER_JOIN 0x00000008L
+#define SQL_SRJO_INNER_JOIN 0x00000010L
+#define SQL_SRJO_INTERSECT_JOIN 0x00000020L
+#define SQL_SRJO_LEFT_OUTER_JOIN 0x00000040L
+#define SQL_SRJO_NATURAL_JOIN 0x00000080L
+#define SQL_SRJO_RIGHT_OUTER_JOIN 0x00000100L
+#define SQL_SRJO_UNION_JOIN 0x00000200L
+
+/* SQL_SQL92_REVOKE bitmasks */
+#define SQL_SR_USAGE_ON_DOMAIN 0x00000001L
+#define SQL_SR_USAGE_ON_CHARACTER_SET 0x00000002L
+#define SQL_SR_USAGE_ON_COLLATION 0x00000004L
+#define SQL_SR_USAGE_ON_TRANSLATION 0x00000008L
+#define SQL_SR_GRANT_OPTION_FOR 0x00000010L
+#define SQL_SR_CASCADE 0x00000020L
+#define SQL_SR_RESTRICT 0x00000040L
+#define SQL_SR_DELETE_TABLE 0x00000080L
+#define SQL_SR_INSERT_TABLE 0x00000100L
+#define SQL_SR_INSERT_COLUMN 0x00000200L
+#define SQL_SR_REFERENCES_TABLE 0x00000400L
+#define SQL_SR_REFERENCES_COLUMN 0x00000800L
+#define SQL_SR_SELECT_TABLE 0x00001000L
+#define SQL_SR_UPDATE_TABLE 0x00002000L
+#define SQL_SR_UPDATE_COLUMN 0x00004000L
+
+/* SQL_SQL92_ROW_VALUE_CONSTRUCTOR bitmasks */
+#define SQL_SRVC_VALUE_EXPRESSION 0x00000001L
+#define SQL_SRVC_NULL 0x00000002L
+#define SQL_SRVC_DEFAULT 0x00000004L
+#define SQL_SRVC_ROW_SUBQUERY 0x00000008L
+
+/* SQL_SQL92_VALUE_EXPRESSIONS bitmasks */
+#define SQL_SVE_CASE 0x00000001L
+#define SQL_SVE_CAST 0x00000002L
+#define SQL_SVE_COALESCE 0x00000004L
+#define SQL_SVE_NULLIF 0x00000008L
+
+/* SQL_STANDARD_CLI_CONFORMANCE bitmasks */
+#define SQL_SCC_XOPEN_CLI_VERSION1 0x00000001L
+#define SQL_SCC_ISO92_CLI 0x00000002L
+
+/* SQL_UNION_STATEMENT bitmasks */
+#define SQL_US_UNION SQL_U_UNION
+#define SQL_US_UNION_ALL SQL_U_UNION_ALL
+
+#endif /* ODBCVER >= 0x0300 */
+
+/* SQL_DTC_TRANSITION_COST bitmasks */
+#define SQL_DTC_ENLIST_EXPENSIVE 0x00000001L
+#define SQL_DTC_UNENLIST_EXPENSIVE 0x00000002L
+
+/* additional SQLDataSources fetch directions */
+#if (ODBCVER >= 0x0300)
+#define SQL_FETCH_FIRST_USER 31
+#define SQL_FETCH_FIRST_SYSTEM 32
+#endif /* ODBCVER >= 0x0300 */
+
+
+/* Defines for SQLSetPos */
+#define SQL_ENTIRE_ROWSET 0
+
+/* Operations in SQLSetPos */
+#define SQL_POSITION 0 /* 1.0 FALSE */
+#define SQL_REFRESH 1 /* 1.0 TRUE */
+#define SQL_UPDATE 2
+#define SQL_DELETE 3
+
+/* Operations in SQLBulkOperations */
+#define SQL_ADD 4
+#define SQL_SETPOS_MAX_OPTION_VALUE SQL_ADD
+#if (ODBCVER >= 0x0300)
+#define SQL_UPDATE_BY_BOOKMARK 5
+#define SQL_DELETE_BY_BOOKMARK 6
+#define SQL_FETCH_BY_BOOKMARK 7
+
+#endif /* ODBCVER >= 0x0300 */
+
+/* Lock options in SQLSetPos */
+#define SQL_LOCK_NO_CHANGE 0 /* 1.0 FALSE */
+#define SQL_LOCK_EXCLUSIVE 1 /* 1.0 TRUE */
+#define SQL_LOCK_UNLOCK 2
+
+#define SQL_SETPOS_MAX_LOCK_VALUE SQL_LOCK_UNLOCK
+
+/* Macros for SQLSetPos */
+#define SQL_POSITION_TO(hstmt,irow) SQLSetPos(hstmt,irow,SQL_POSITION,SQL_LOCK_NO_CHANGE)
+#define SQL_LOCK_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_POSITION,fLock)
+#define SQL_REFRESH_RECORD(hstmt,irow,fLock) SQLSetPos(hstmt,irow,SQL_REFRESH,fLock)
+#define SQL_UPDATE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_UPDATE,SQL_LOCK_NO_CHANGE)
+#define SQL_DELETE_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_DELETE,SQL_LOCK_NO_CHANGE)
+#define SQL_ADD_RECORD(hstmt,irow) SQLSetPos(hstmt,irow,SQL_ADD,SQL_LOCK_NO_CHANGE)
+
+/* Column types and scopes in SQLSpecialColumns. */
+#define SQL_BEST_ROWID 1
+#define SQL_ROWVER 2
+
+/* Defines for SQLSpecialColumns (returned in the result set)
+ SQL_PC_UNKNOWN and SQL_PC_PSEUDO are defined in sql.h */
+#define SQL_PC_NOT_PSEUDO 1
+
+/* Defines for SQLStatistics */
+#define SQL_QUICK 0
+#define SQL_ENSURE 1
+
+/* Defines for SQLStatistics (returned in the result set)
+ SQL_INDEX_CLUSTERED, SQL_INDEX_HASHED, and SQL_INDEX_OTHER are
+ defined in sql.h */
+#define SQL_TABLE_STAT 0
+
+
+/* Defines for SQLTables */
+#if (ODBCVER >= 0x0300)
+#define SQL_ALL_CATALOGS "%"
+#define SQL_ALL_SCHEMAS "%"
+#define SQL_ALL_TABLE_TYPES "%"
+#endif /* ODBCVER >= 0x0300 */
+
+/* Options for SQLDriverConnect */
+#define SQL_DRIVER_NOPROMPT 0
+#define SQL_DRIVER_COMPLETE 1
+#define SQL_DRIVER_PROMPT 2
+#define SQL_DRIVER_COMPLETE_REQUIRED 3
+
+SQLRETURN SQL_API SQLDriverConnect(
+ SQLHDBC hdbc,
+ SQLHWND hwnd,
+ SQLCHAR *szConnStrIn,
+ SQLSMALLINT cbConnStrIn,
+ SQLCHAR *szConnStrOut,
+ SQLSMALLINT cbConnStrOutMax,
+ SQLSMALLINT *pcbConnStrOut,
+ SQLUSMALLINT fDriverCompletion);
+
+/* Level 2 Functions */
+
+/* SQLExtendedFetch "fFetchType" values */
+#define SQL_FETCH_BOOKMARK 8
+
+/* SQLExtendedFetch "rgfRowStatus" element values */
+#define SQL_ROW_SUCCESS 0
+#define SQL_ROW_DELETED 1
+#define SQL_ROW_UPDATED 2
+#define SQL_ROW_NOROW 3
+#define SQL_ROW_ADDED 4
+#define SQL_ROW_ERROR 5
+#if (ODBCVER >= 0x0300)
+#define SQL_ROW_SUCCESS_WITH_INFO 6
+#define SQL_ROW_PROCEED 0
+#define SQL_ROW_IGNORE 1
+#endif
+
+/* value for SQL_DESC_ARRAY_STATUS_PTR */
+#if (ODBCVER >= 0x0300)
+#define SQL_PARAM_SUCCESS 0
+#define SQL_PARAM_SUCCESS_WITH_INFO 6
+#define SQL_PARAM_ERROR 5
+#define SQL_PARAM_UNUSED 7
+#define SQL_PARAM_DIAG_UNAVAILABLE 1
+
+#define SQL_PARAM_PROCEED 0
+#define SQL_PARAM_IGNORE 1
+#endif /* ODBCVER >= 0x0300 */
+
+/* Defines for SQLForeignKeys (UPDATE_RULE and DELETE_RULE) */
+#define SQL_CASCADE 0
+#define SQL_RESTRICT 1
+#define SQL_SET_NULL 2
+#if (ODBCVER >= 0x0250)
+#define SQL_NO_ACTION 3
+#define SQL_SET_DEFAULT 4
+#endif /* ODBCVER >= 0x0250 */
+
+#if (ODBCVER >= 0x0300)
+/* Note that the following are in a different column of SQLForeignKeys than */
+/* the previous #defines. These are for DEFERRABILITY. */
+
+#define SQL_INITIALLY_DEFERRED 5
+#define SQL_INITIALLY_IMMEDIATE 6
+#define SQL_NOT_DEFERRABLE 7
+
+#endif /* ODBCVER >= 0x0300 */
+
+/* Defines for SQLBindParameter and
+ SQLProcedureColumns (returned in the result set) */
+#define SQL_PARAM_TYPE_UNKNOWN 0
+#define SQL_PARAM_INPUT 1
+#define SQL_PARAM_INPUT_OUTPUT 2
+#define SQL_RESULT_COL 3
+#define SQL_PARAM_OUTPUT 4
+#define SQL_RETURN_VALUE 5
+
+/* Defines for SQLProcedures (returned in the result set) */
+#define SQL_PT_UNKNOWN 0
+#define SQL_PT_PROCEDURE 1
+#define SQL_PT_FUNCTION 2
+
+/* This define is too large for RC */
+#define SQL_ODBC_KEYWORDS "ABSOLUTE,ACTION,ADA,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,"\
+"ASC,ASSERTION,AT,AUTHORIZATION,AVG,"\
+"BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,"\
+"CHAR,CHAR_LENGTH,CHARACTER,CHARACTER_LENGTH,CHECK,CLOSE,COALESCE,"\
+"COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,"\
+"CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,"\
+"CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,"\
+"DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,"\
+"DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,"\
+"DISTINCT,DOMAIN,DOUBLE,DROP,"\
+"ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,"\
+"EXISTS,EXTERNAL,EXTRACT,"\
+"FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FROM,FULL,"\
+"GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,"\
+"IDENTITY,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALLY,INNER,"\
+"INPUT,INSENSITIVE,INSERT,INT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,"\
+"JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,"\
+"MATCH,MAX,MIN,MINUTE,MODULE,MONTH,"\
+"NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NONE,NOT,NULL,NULLIF,NUMERIC,"\
+"OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,"\
+"PAD,PARTIAL,PASCAL,PLI,POSITION,PRECISION,PREPARE,PRESERVE,"\
+"PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,"\
+"READ,REAL,REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS"\
+"SCHEMA,SCROLL,SECOND,SECTION,SELECT,SESSION,SESSION_USER,SET,SIZE,"\
+"SMALLINT,SOME,SPACE,SQL,SQLCA,SQLCODE,SQLERROR,SQLSTATE,SQLWARNING,"\
+"SUBSTRING,SUM,SYSTEM_USER,"\
+"TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,"\
+"TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,"\
+"UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,"\
+"VALUE,VALUES,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,WRITE,"\
+"YEAR,ZONE"
+
+SQLRETURN SQL_API SQLBrowseConnect(
+ SQLHDBC hdbc,
+ SQLCHAR *szConnStrIn,
+ SQLSMALLINT cbConnStrIn,
+ SQLCHAR *szConnStrOut,
+ SQLSMALLINT cbConnStrOutMax,
+ SQLSMALLINT *pcbConnStrOut);
+
+#if (ODBCVER >= 0x0300)
+SQLRETURN SQL_API SQLBulkOperations(
+ SQLHSTMT StatementHandle,
+ SQLSMALLINT Operation);
+#endif /* ODBCVER >= 0x0300 */
+
+SQLRETURN SQL_API SQLColAttributes(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT icol,
+ SQLUSMALLINT fDescType,
+ SQLPOINTER rgbDesc,
+ SQLSMALLINT cbDescMax,
+ SQLSMALLINT *pcbDesc,
+ SQLLEN *pfDesc);
+
+SQLRETURN SQL_API SQLColumnPrivileges(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLCHAR *szColumnName,
+ SQLSMALLINT cbColumnName);
+
+SQLRETURN SQL_API SQLDescribeParam(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT ipar,
+ SQLSMALLINT *pfSqlType,
+ SQLULEN *pcbParamDef,
+ SQLSMALLINT *pibScale,
+ SQLSMALLINT *pfNullable);
+
+SQLRETURN SQL_API SQLExtendedFetch(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT fFetchType,
+ SQLLEN irow,
+ SQLULEN *pcrow,
+ SQLUSMALLINT *rgfRowStatus);
+
+SQLRETURN SQL_API SQLForeignKeys(
+ SQLHSTMT hstmt,
+ SQLCHAR *szPkCatalogName,
+ SQLSMALLINT cbPkCatalogName,
+ SQLCHAR *szPkSchemaName,
+ SQLSMALLINT cbPkSchemaName,
+ SQLCHAR *szPkTableName,
+ SQLSMALLINT cbPkTableName,
+ SQLCHAR *szFkCatalogName,
+ SQLSMALLINT cbFkCatalogName,
+ SQLCHAR *szFkSchemaName,
+ SQLSMALLINT cbFkSchemaName,
+ SQLCHAR *szFkTableName,
+ SQLSMALLINT cbFkTableName);
+
+SQLRETURN SQL_API SQLMoreResults(
+ SQLHSTMT hstmt);
+
+SQLRETURN SQL_API SQLNativeSql(
+ SQLHDBC hdbc,
+ SQLCHAR *szSqlStrIn,
+ SQLINTEGER cbSqlStrIn,
+ SQLCHAR *szSqlStr,
+ SQLINTEGER cbSqlStrMax,
+ SQLINTEGER *pcbSqlStr);
+
+SQLRETURN SQL_API SQLNumParams(
+ SQLHSTMT hstmt,
+ SQLSMALLINT *pcpar);
+
+SQLRETURN SQL_API SQLParamOptions(
+ SQLHSTMT hstmt,
+ SQLULEN crow,
+ SQLULEN *pirow);
+
+SQLRETURN SQL_API SQLPrimaryKeys(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName);
+
+SQLRETURN SQL_API SQLProcedureColumns(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szProcName,
+ SQLSMALLINT cbProcName,
+ SQLCHAR *szColumnName,
+ SQLSMALLINT cbColumnName);
+
+SQLRETURN SQL_API SQLProcedures(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szProcName,
+ SQLSMALLINT cbProcName);
+
+SQLRETURN SQL_API SQLSetPos(
+ SQLHSTMT hstmt,
+ SQLSETPOSIROW irow,
+ SQLUSMALLINT fOption,
+ SQLUSMALLINT fLock);
+
+SQLRETURN SQL_API SQLTablePrivileges(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName);
+
+SQLRETURN SQL_API SQLDrivers(
+ SQLHENV henv,
+ SQLUSMALLINT fDirection,
+ SQLCHAR *szDriverDesc,
+ SQLSMALLINT cbDriverDescMax,
+ SQLSMALLINT *pcbDriverDesc,
+ SQLCHAR *szDriverAttributes,
+ SQLSMALLINT cbDrvrAttrMax,
+ SQLSMALLINT *pcbDrvrAttr);
+
+SQLRETURN SQL_API SQLBindParameter(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT ipar,
+ SQLSMALLINT fParamType,
+ SQLSMALLINT fCType,
+ SQLSMALLINT fSqlType,
+ SQLULEN cbColDef,
+ SQLSMALLINT ibScale,
+ SQLPOINTER rgbValue,
+ SQLLEN cbValueMax,
+ SQLLEN *pcbValue);
+
+/*---------------------------------------------------------*/
+/* SQLAllocHandleStd is implemented to make SQLAllocHandle */
+/* compatible with X/Open standard. an application should */
+/* not call SQLAllocHandleStd directly */
+/*---------------------------------------------------------*/
+#ifdef ODBC_STD
+#define SQLAllocHandle SQLAllocHandleStd
+#define SQLAllocEnv(phenv) SQLAllocHandleStd(SQL_HANDLE_ENV, SQL_NULL_HANDLE, phenv)
+
+/* Internal type subcodes */
+#define SQL_YEAR SQL_CODE_YEAR
+#define SQL_MONTH SQL_CODE_MONTH
+#define SQL_DAY SQL_CODE_DAY
+#define SQL_HOUR SQL_CODE_HOUR
+#define SQL_MINUTE SQL_CODE_MINUTE
+#define SQL_SECOND SQL_CODE_SECOND
+#define SQL_YEAR_TO_MONTH SQL_CODE_YEAR_TO_MONTH
+#define SQL_DAY_TO_HOUR SQL_CODE_DAY_TO_HOUR
+#define SQL_DAY_TO_MINUTE SQL_CODE_DAY_TO_MINUTE
+#define SQL_DAY_TO_SECOND SQL_CODE_DAY_TO_SECOND
+#define SQL_HOUR_TO_MINUTE SQL_CODE_HOUR_TO_MINUTE
+#define SQL_HOUR_TO_SECOND SQL_CODE_HOUR_TO_SECOND
+#define SQL_MINUTE_TO_SECOND SQL_CODE_MINUTE_TO_SECOND
+#endif /* ODBC_STD */
+
+#if (ODBCVER >= 0x0300)
+SQLRETURN SQL_API SQLAllocHandleStd(
+ SQLSMALLINT fHandleType,
+ SQLHANDLE hInput,
+ SQLHANDLE *phOutput);
+#endif
+
+/* Deprecated defines from prior versions of ODBC */
+#define SQL_DATABASE_NAME 16 /* Use SQLGetConnectOption/SQL_CURRENT_QUALIFIER */
+#define SQL_FD_FETCH_PREV SQL_FD_FETCH_PRIOR
+#define SQL_FETCH_PREV SQL_FETCH_PRIOR
+#define SQL_CONCUR_TIMESTAMP SQL_CONCUR_ROWVER
+#define SQL_SCCO_OPT_TIMESTAMP SQL_SCCO_OPT_ROWVER
+#define SQL_CC_DELETE SQL_CB_DELETE
+#define SQL_CR_DELETE SQL_CB_DELETE
+#define SQL_CC_CLOSE SQL_CB_CLOSE
+#define SQL_CR_CLOSE SQL_CB_CLOSE
+#define SQL_CC_PRESERVE SQL_CB_PRESERVE
+#define SQL_CR_PRESERVE SQL_CB_PRESERVE
+/* SQL_FETCH_RESUME is not supported by 2.0+ drivers
+#define SQL_FETCH_RESUME 7
+*/
+#define SQL_SCROLL_FORWARD_ONLY 0L /*-SQL_CURSOR_FORWARD_ONLY */
+#define SQL_SCROLL_KEYSET_DRIVEN (-1L) /*-SQL_CURSOR_KEYSET_DRIVEN */
+#define SQL_SCROLL_DYNAMIC (-2L) /*-SQL_CURSOR_DYNAMIC */
+#define SQL_SCROLL_STATIC (-3L) /*-SQL_CURSOR_STATIC */
+
+/* Deprecated functions from prior versions of ODBC */
+SQLRETURN SQL_API SQLSetScrollOptions( /* Use SQLSetStmtOptions */
+ SQLHSTMT hstmt,
+ SQLUSMALLINT fConcurrency,
+ SQLLEN crowKeyset,
+ SQLUSMALLINT crowRowset);
+
+/*!
+ * \defgroup Tracing.
+ *
+ * unixODBC implements a slight variation of the tracing mechanism used
+ * on MS platforms. The unixODBC method loses the ability to produce trace
+ * output for invalid handles but gains the following;
+ *
+ * - better concurrency
+ * - allows tracing to be turned on/off and configured at finer granularity
+ * - hopefully; better performance
+ *
+ * unixODBC provides a cross-platform helper library called 'trace' and an
+ * example/default trace plugin called 'odbctrac'. Those writing an ODBC
+ * driver can use the 'trace' helper library (a static library). Those wanting
+ * to create custom trace output can implement a different version of the
+ * 'odbctrac' plugin.
+ *
+ * The text file driver (odbctxt) included with unixODBC is an example of a
+ * driver using the 'trace' helper library.
+ *
+ * The 'trace' library and the example plugin 'odbctrac' are designed to be
+ * portable on all platforms where unixODBC is available and on MS platforms.
+ * This will allow drivers using 'trace' and 'odbctrac' plugin to equilly
+ * portable. On MS platforms - this compliments traditional tracing (mostly
+ * just used by the Driver Manager).
+ *
+ * \sa trace
+ * odbctxt
+ * odbctrac
+ */
+/*@{*/
+#define TRACE_VERSION 1000 /*!< Version of trace API */
+#ifdef UNICODE
+RETCODE TraceOpenLogFile(SQLPOINTER,LPWSTR,LPWSTR,DWORD); /*!< open a trace log file */
+#else
+RETCODE TraceOpenLogFile(SQLPOINTER,LPSTR,LPSTR,DWORD); /*!< open a trace log file */
+#endif
+RETCODE TraceCloseLogFile(SQLPOINTER); /*!< Request to close a trace log */
+SQLRETURN TraceReturn(SQLPOINTER,SQLRETURN); /*!< Call to produce trace output upon function return. */
+#ifdef __cplusplus
+DWORD TraceVersion(); /*!< Returns trace API version */
+#else
+DWORD TraceVersion(VOID); /*!< Returns trace API version */
+#endif
+
+/* Functions for Visual Studio Analyzer*/
+/* to turn on/off tracing or VS events, call TraceVSControl by setting or clearing the following bits */
+#define TRACE_ON 0x00000001L
+#define TRACE_VS_EVENT_ON 0x00000002L
+
+RETCODE TraceVSControl(DWORD);
+
+/* the flags in ODBC_VS_ARGS */
+#define ODBC_VS_FLAG_UNICODE_ARG 0x00000001L /* the argument is unicode */
+#define ODBC_VS_FLAG_UNICODE_COR 0x00000002L /* the correlation is unicode */
+#define ODBC_VS_FLAG_RETCODE 0x00000004L /* RetCode field is set */
+#define ODBC_VS_FLAG_STOP 0x00000008L /* Stop firing visual studio analyzer events */
+
+typedef struct tagODBC_VS_ARGS {
+#ifdef GUID_DEFINED
+ const GUID *pguidEvent; /* the GUID for event */
+#else
+ const void *pguidEvent; /* the GUID for event */
+#endif
+ DWORD dwFlags; /* flags for the call */
+ union {
+ WCHAR *wszArg;
+ CHAR *szArg;
+ }u1;
+ union {
+ WCHAR *wszCorrelation;
+ CHAR *szCorrelation;
+ }u2;
+ RETCODE RetCode;
+} ODBC_VS_ARGS, *PODBC_VS_ARGS;
+
+VOID FireVSDebugEvent(PODBC_VS_ARGS);
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * connection pooling retry times
+ */
+
+int ODBCSetTryWaitValue ( DWORD dwValue );
+#ifdef __cplusplus
+DWORD ODBCGetTryWaitValue ( );
+#else
+DWORD ODBCGetTryWaitValue ( VOID );
+#endif
+
+#ifndef __SQLUCODE_H
+#include "odbc/sqlucode.h"
+#endif
+
+#endif
diff --git a/external/unixODBC/inc/odbc/sqltypes.h b/external/unixODBC/inc/odbc/sqltypes.h
new file mode 100644
index 000000000..939c5d29b
--- /dev/null
+++ b/external/unixODBC/inc/odbc/sqltypes.h
@@ -0,0 +1,470 @@
+/*************************************************************
+ * sqltypes.h
+ *
+ * This is the lowest level include in unixODBC. It defines
+ * the basic types required by unixODBC and is heavily based
+ * upon the MS include of the same name (it has to be for
+ * binary compatibility between drivers developed under different
+ * packages).
+ *
+ * You can include this file directly but it is almost always
+ * included indirectly, by including.. for example sqlext.h
+ *
+ * This include makes no effort to be useful on any platforms other
+ * than Linux (with some exceptions for UNIX in general).
+ *
+ * !!!DO NOT CONTAMINATE THIS FILE WITH NON-Linux CODE!!!
+ *
+ *************************************************************/
+#ifndef __SQLTYPES_H
+#define __SQLTYPES_H
+
+/****************************
+ * default to the 3.51 definitions. should define ODBCVER before here if you want an older set of defines
+ ***************************/
+#ifndef ODBCVER
+#define ODBCVER 0x0351
+#endif
+
+/*
+ * if this is set, then use a 4 byte unicode definition, instead of the 2 bytes that MS uses
+ */
+
+#ifdef SQL_WCHART_CONVERT
+/*
+ * Use this if you want to use the C/C++ portable definition of a wide char, wchar_t
+ * Microsoft hardcoded a definition of unsigned short which may not be compatible with
+ * your platform specific wide char definition.
+ */
+#include <wchar.h>
+#endif
+
+#include <sal/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SIZEOF_LONG_INT
+# define SIZEOF_LONG_INT SAL_TYPES_SIZEOFLONG
+#endif
+#ifndef ODBCINT64
+# define ODBCINT64 sal_Int64
+#endif
+#ifndef UODBCINT64
+# define UODBCINT64 sal_uInt64
+#endif
+
+/*
+ * this is defined by configure, but will not be on a normal application build
+ * the install creates a unixodbc_conf.h file that contains the current build settings
+ */
+
+#ifndef SIZEOF_LONG_INT
+#include <unixodbc_conf.h>
+#endif
+
+#ifndef SIZEOF_LONG_INT
+#error "Needs to know how big a long int is to continue!!!"
+#endif
+
+/****************************
+ * These make up for having no windows.h
+ ***************************/
+#ifndef ALLREADY_HAVE_WINDOWS_TYPE
+
+#define CALLBACK
+#define SQL_API
+#define BOOL int
+typedef void* HWND;
+typedef char CHAR;
+#ifdef UNICODE
+
+/*
+ * NOTE: The Microsoft unicode define is only for apps that want to use TCHARs and
+ * be able to compile for both unicode and non-unicode with the same source.
+ * This is not recommended for linux applications and is not supported
+ * by the standard linux string header files.
+ */
+#ifdef SQL_WCHART_CONVERT
+typedef wchar_t TCHAR;
+#else
+typedef signed short TCHAR;
+#endif
+
+#else
+typedef char TCHAR;
+#endif
+
+#ifndef DONT_TD_VOID
+typedef void VOID;
+#endif
+
+typedef unsigned short WORD;
+#if (SIZEOF_LONG_INT == 4)
+typedef unsigned long DWORD;
+#else
+typedef unsigned int DWORD;
+#endif
+typedef unsigned char BYTE;
+
+#ifdef SQL_WCHART_CONVERT
+typedef wchar_t WCHAR;
+#else
+typedef unsigned short WCHAR;
+#endif
+
+typedef WCHAR* LPWSTR;
+typedef const char* LPCSTR;
+typedef const WCHAR* LPCWSTR;
+typedef TCHAR* LPTSTR;
+typedef char* LPSTR;
+typedef DWORD* LPDWORD;
+
+typedef void* HINSTANCE;
+
+#endif
+
+
+/****************************
+ * standard SQL* data types. use these as much as possible when using ODBC calls/vars
+ ***************************/
+typedef unsigned char SQLCHAR;
+
+#if (ODBCVER >= 0x0300)
+typedef unsigned char SQLDATE;
+typedef unsigned char SQLDECIMAL;
+typedef double SQLDOUBLE;
+typedef double SQLFLOAT;
+#endif
+
+/*
+ * can't use a long it fails on 64 platforms
+ */
+
+/*
+ * Hopefully by now it should be safe to assume most drivers know about SQLLEN now
+ * and the default is now sizeof( SQLLEN ) = 8 on 64 bit platforms
+ *
+ */
+
+#if (SIZEOF_LONG_INT == 8)
+#ifdef BUILD_LEGACY_64_BIT_MODE
+typedef int SQLINTEGER;
+typedef unsigned int SQLUINTEGER;
+#define SQLLEN SQLINTEGER
+#define SQLULEN SQLUINTEGER
+#define SQLSETPOSIROW SQLUSMALLINT
+/*
+ * These are not supported on 64bit ODBC according to MS, removed, so use at your peril
+ *
+ typedef SQLULEN SQLROWCOUNT;
+ typedef SQLULEN SQLROWSETSIZE;
+ typedef SQLULEN SQLTRANSID;
+ typedef SQLLEN SQLROWOFFSET;
+*/
+#else
+typedef int SQLINTEGER;
+typedef unsigned int SQLUINTEGER;
+typedef long SQLLEN;
+typedef unsigned long SQLULEN;
+typedef unsigned long SQLSETPOSIROW;
+/*
+ * These are not supported on 64bit ODBC according to MS, removed, so use at your peril
+ *
+ typedef SQLULEN SQLTRANSID;
+ typedef SQLULEN SQLROWCOUNT;
+ typedef SQLUINTEGER SQLROWSETSIZE;
+ typedef SQLLEN SQLROWOFFSET;
+ */
+typedef SQLULEN SQLROWCOUNT;
+typedef SQLULEN SQLROWSETSIZE;
+typedef SQLULEN SQLTRANSID;
+typedef SQLLEN SQLROWOFFSET;
+#endif
+#else
+typedef long SQLINTEGER;
+typedef unsigned long SQLUINTEGER;
+#define SQLLEN SQLINTEGER
+#define SQLULEN SQLUINTEGER
+#define SQLSETPOSIROW SQLUSMALLINT
+typedef SQLULEN SQLROWCOUNT;
+typedef SQLULEN SQLROWSETSIZE;
+typedef SQLULEN SQLTRANSID;
+typedef SQLLEN SQLROWOFFSET;
+#endif
+
+#if (ODBCVER >= 0x0300)
+typedef unsigned char SQLNUMERIC;
+#endif
+
+typedef void * SQLPOINTER;
+
+#if (ODBCVER >= 0x0300)
+typedef float SQLREAL;
+#endif
+
+typedef signed short int SQLSMALLINT;
+typedef unsigned short SQLUSMALLINT;
+
+#if (ODBCVER >= 0x0300)
+typedef unsigned char SQLTIME;
+typedef unsigned char SQLTIMESTAMP;
+typedef unsigned char SQLVARCHAR;
+#endif
+
+typedef SQLSMALLINT SQLRETURN;
+
+#if (ODBCVER >= 0x0300)
+typedef void * SQLHANDLE;
+typedef SQLHANDLE SQLHENV;
+typedef SQLHANDLE SQLHDBC;
+typedef SQLHANDLE SQLHSTMT;
+typedef SQLHANDLE SQLHDESC;
+#else
+typedef void * SQLHENV;
+typedef void * SQLHDBC;
+typedef void * SQLHSTMT;
+/*
+ * some things like PHP won't build without this
+ */
+typedef void * SQLHANDLE;
+#endif
+
+/****************************
+ * These are cast into the actual struct that is being passed around. The
+ * DriverManager knows what its structs look like and the Driver knows about its
+ * structs... the app knows nothing about them... just void*
+ * These are deprecated in favour of SQLHENV, SQLHDBC, SQLHSTMT
+ ***************************/
+
+#if (ODBCVER >= 0x0300)
+typedef SQLHANDLE HENV;
+typedef SQLHANDLE HDBC;
+typedef SQLHANDLE HSTMT;
+#else
+typedef void * HENV;
+typedef void * HDBC;
+typedef void * HSTMT;
+#endif
+
+
+/****************************
+ * more basic data types to augment what windows.h provides
+ ***************************/
+#ifndef ALLREADY_HAVE_WINDOWS_TYPE
+
+typedef unsigned char UCHAR;
+typedef signed char SCHAR;
+typedef SCHAR SQLSCHAR;
+#if (SIZEOF_LONG_INT == 4)
+typedef long int SDWORD;
+typedef unsigned long int UDWORD;
+#else
+typedef int SDWORD;
+typedef unsigned int UDWORD;
+#endif
+typedef signed short int SWORD;
+typedef unsigned short int UWORD;
+typedef unsigned int UINT;
+typedef signed long SLONG;
+typedef signed short SSHORT;
+typedef unsigned long ULONG;
+typedef unsigned short USHORT;
+typedef double SDOUBLE;
+typedef double LDOUBLE;
+typedef float SFLOAT;
+typedef void* PTR;
+typedef signed short RETCODE;
+typedef void* SQLHWND;
+
+#endif
+
+/****************************
+ * standard structs for working with date/times
+ ***************************/
+#ifndef __SQLDATE
+#define __SQLDATE
+typedef struct tagDATE_STRUCT
+{
+ SQLSMALLINT year;
+ SQLUSMALLINT month;
+ SQLUSMALLINT day;
+} DATE_STRUCT;
+
+#if (ODBCVER >= 0x0300)
+typedef DATE_STRUCT SQL_DATE_STRUCT;
+#endif
+
+typedef struct tagTIME_STRUCT
+{
+ SQLUSMALLINT hour;
+ SQLUSMALLINT minute;
+ SQLUSMALLINT second;
+} TIME_STRUCT;
+
+#if (ODBCVER >= 0x0300)
+typedef TIME_STRUCT SQL_TIME_STRUCT;
+#endif
+
+typedef struct tagTIMESTAMP_STRUCT
+{
+ SQLSMALLINT year;
+ SQLUSMALLINT month;
+ SQLUSMALLINT day;
+ SQLUSMALLINT hour;
+ SQLUSMALLINT minute;
+ SQLUSMALLINT second;
+ SQLUINTEGER fraction;
+} TIMESTAMP_STRUCT;
+
+#if (ODBCVER >= 0x0300)
+typedef TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT;
+#endif
+
+
+#if (ODBCVER >= 0x0300)
+typedef enum
+{
+ SQL_IS_YEAR = 1,
+ SQL_IS_MONTH = 2,
+ SQL_IS_DAY = 3,
+ SQL_IS_HOUR = 4,
+ SQL_IS_MINUTE = 5,
+ SQL_IS_SECOND = 6,
+ SQL_IS_YEAR_TO_MONTH = 7,
+ SQL_IS_DAY_TO_HOUR = 8,
+ SQL_IS_DAY_TO_MINUTE = 9,
+ SQL_IS_DAY_TO_SECOND = 10,
+ SQL_IS_HOUR_TO_MINUTE = 11,
+ SQL_IS_HOUR_TO_SECOND = 12,
+ SQL_IS_MINUTE_TO_SECOND = 13
+} SQLINTERVAL;
+
+#endif
+
+#if (ODBCVER >= 0x0300)
+typedef struct tagSQL_YEAR_MONTH
+{
+ SQLUINTEGER year;
+ SQLUINTEGER month;
+} SQL_YEAR_MONTH_STRUCT;
+
+typedef struct tagSQL_DAY_SECOND
+{
+ SQLUINTEGER day;
+ SQLUINTEGER hour;
+ SQLUINTEGER minute;
+ SQLUINTEGER second;
+ SQLUINTEGER fraction;
+} SQL_DAY_SECOND_STRUCT;
+
+typedef struct tagSQL_INTERVAL_STRUCT
+{
+ SQLINTERVAL interval_type;
+ SQLSMALLINT interval_sign;
+ union {
+ SQL_YEAR_MONTH_STRUCT year_month;
+ SQL_DAY_SECOND_STRUCT day_second;
+ } intval;
+
+} SQL_INTERVAL_STRUCT;
+
+#endif
+
+#endif
+
+#ifndef ODBCINT64
+# if (ODBCVER >= 0x0300)
+# if (SIZEOF_LONG_INT == 8)
+# define ODBCINT64 long
+# define UODBCINT64 unsigned long
+# else
+# ifdef HAVE_LONG_LONG
+# define ODBCINT64 long long
+# define UODBCINT64 unsigned long long
+# else
+/*
+ * may fail in some cases, but what else can we do ?
+ */
+struct __bigint_struct
+{
+ int hiword;
+ unsigned int loword;
+};
+struct __bigint_struct_u
+{
+ unsigned int hiword;
+ unsigned int loword;
+};
+# define ODBCINT64 struct __bigint_struct
+# define UODBCINT64 struct __bigint_struct_u
+# endif
+# endif
+#endif
+#endif
+
+#ifdef ODBCINT64
+typedef ODBCINT64 SQLBIGINT;
+#endif
+#ifdef UODBCINT64
+typedef UODBCINT64 SQLUBIGINT;
+#endif
+
+
+/****************************
+ * cursor and bookmark
+ ***************************/
+#if (ODBCVER >= 0x0300)
+#define SQL_MAX_NUMERIC_LEN 16
+typedef struct tagSQL_NUMERIC_STRUCT
+{
+ SQLCHAR precision;
+ SQLSCHAR scale;
+ SQLCHAR sign; /* 1=pos 0=neg */
+ SQLCHAR val[SQL_MAX_NUMERIC_LEN];
+} SQL_NUMERIC_STRUCT;
+#endif
+
+#if (ODBCVER >= 0x0350)
+#ifdef GUID_DEFINED
+#ifndef ALLREADY_HAVE_WINDOWS_TYPE
+typedef GUID SQLGUID;
+#else
+typedef struct tagSQLGUID
+{
+ DWORD Data1;
+ WORD Data2;
+ WORD Data3;
+ BYTE Data4[ 8 ];
+} SQLGUID;
+#endif
+#else
+typedef struct tagSQLGUID
+{
+ DWORD Data1;
+ WORD Data2;
+ WORD Data3;
+ BYTE Data4[ 8 ];
+} SQLGUID;
+#endif
+#endif
+
+typedef SQLULEN BOOKMARK;
+
+typedef WCHAR SQLWCHAR;
+
+#ifdef UNICODE
+typedef SQLWCHAR SQLTCHAR;
+#else
+typedef SQLCHAR SQLTCHAR;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/external/unixODBC/inc/odbc/sqlucode.h b/external/unixODBC/inc/odbc/sqlucode.h
new file mode 100644
index 000000000..366dab751
--- /dev/null
+++ b/external/unixODBC/inc/odbc/sqlucode.h
@@ -0,0 +1,789 @@
+/**************************************************
+ * sqlucode.h
+ *
+ * These should be consistent with the MS version.
+ *
+ **************************************************/
+#ifndef __SQLUCODE_H
+#define __SQLUCODE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SQL_WCHAR (-8)
+#define SQL_WVARCHAR (-9)
+#define SQL_WLONGVARCHAR (-10)
+#define SQL_C_WCHAR SQL_WCHAR
+
+#ifdef UNICODE
+#define SQL_C_TCHAR SQL_C_WCHAR
+#else
+#define SQL_C_TCHAR SQL_C_CHAR
+#endif
+
+#define SQL_SQLSTATE_SIZEW 10 /* size of SQLSTATE for unicode */
+
+/* UNICODE versions */
+
+SQLRETURN SQL_API SQLColAttributeW(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT iCol,
+ SQLUSMALLINT iField,
+ SQLPOINTER pCharAttr,
+ SQLSMALLINT cbCharAttrMax,
+ SQLSMALLINT *pcbCharAttr,
+ SQLLEN *pNumAttr);
+
+SQLRETURN SQL_API SQLColAttributesW(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT icol,
+ SQLUSMALLINT fDescType,
+ SQLPOINTER rgbDesc,
+ SQLSMALLINT cbDescMax,
+ SQLSMALLINT *pcbDesc,
+ SQLLEN *pfDesc);
+
+SQLRETURN SQL_API SQLConnectW(
+ SQLHDBC hdbc,
+ SQLWCHAR *szDSN,
+ SQLSMALLINT cbDSN,
+ SQLWCHAR *szUID,
+ SQLSMALLINT cbUID,
+ SQLWCHAR *szAuthStr,
+ SQLSMALLINT cbAuthStr);
+
+
+SQLRETURN SQL_API SQLDescribeColW(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT icol,
+ SQLWCHAR *szColName,
+ SQLSMALLINT cbColNameMax,
+ SQLSMALLINT *pcbColName,
+ SQLSMALLINT *pfSqlType,
+ SQLULEN *pcbColDef,
+ SQLSMALLINT *pibScale,
+ SQLSMALLINT *pfNullable);
+
+
+SQLRETURN SQL_API SQLErrorW(
+ SQLHENV henv,
+ SQLHDBC hdbc,
+ SQLHSTMT hstmt,
+ SQLWCHAR *szSqlState,
+ SQLINTEGER *pfNativeError,
+ SQLWCHAR *szErrorMsg,
+ SQLSMALLINT cbErrorMsgMax,
+ SQLSMALLINT *pcbErrorMsg);
+
+SQLRETURN SQL_API SQLExecDirectW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szSqlStr,
+ SQLINTEGER cbSqlStr);
+
+SQLRETURN SQL_API SQLGetConnectAttrW(
+ SQLHDBC hdbc,
+ SQLINTEGER fAttribute,
+ SQLPOINTER rgbValue,
+ SQLINTEGER cbValueMax,
+ SQLINTEGER *pcbValue);
+
+SQLRETURN SQL_API SQLGetCursorNameW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCursor,
+ SQLSMALLINT cbCursorMax,
+ SQLSMALLINT *pcbCursor);
+
+#if (ODBCVER >= 0x0300)
+SQLRETURN SQL_API SQLSetDescFieldW(SQLHDESC DescriptorHandle,
+ SQLSMALLINT RecNumber,
+ SQLSMALLINT FieldIdentifier,
+ SQLPOINTER Value,
+ SQLINTEGER BufferLength);
+
+
+
+SQLRETURN SQL_API SQLGetDescFieldW(
+ SQLHDESC hdesc,
+ SQLSMALLINT iRecord,
+ SQLSMALLINT iField,
+ SQLPOINTER rgbValue,
+ SQLINTEGER cbValueMax,
+ SQLINTEGER *pcbValue);
+
+SQLRETURN SQL_API SQLGetDescRecW(
+ SQLHDESC hdesc,
+ SQLSMALLINT iRecord,
+ SQLWCHAR *szName,
+ SQLSMALLINT cbNameMax,
+ SQLSMALLINT *pcbName,
+ SQLSMALLINT *pfType,
+ SQLSMALLINT *pfSubType,
+ SQLLEN *pLength,
+ SQLSMALLINT *pPrecision,
+ SQLSMALLINT *pScale,
+ SQLSMALLINT *pNullable);
+
+SQLRETURN SQL_API SQLGetDiagFieldW(
+ SQLSMALLINT fHandleType,
+ SQLHANDLE handle,
+ SQLSMALLINT iRecord,
+ SQLSMALLINT fDiagField,
+ SQLPOINTER rgbDiagInfo,
+ SQLSMALLINT cbDiagInfoMax,
+ SQLSMALLINT *pcbDiagInfo);
+
+SQLRETURN SQL_API SQLGetDiagRecW(
+ SQLSMALLINT fHandleType,
+ SQLHANDLE handle,
+ SQLSMALLINT iRecord,
+ SQLWCHAR *szSqlState,
+ SQLINTEGER *pfNativeError,
+ SQLWCHAR *szErrorMsg,
+ SQLSMALLINT cbErrorMsgMax,
+ SQLSMALLINT *pcbErrorMsg);
+
+
+#endif
+
+
+SQLRETURN SQL_API SQLPrepareW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szSqlStr,
+ SQLINTEGER cbSqlStr);
+
+SQLRETURN SQL_API SQLSetConnectAttrW(
+ SQLHDBC hdbc,
+ SQLINTEGER fAttribute,
+ SQLPOINTER rgbValue,
+ SQLINTEGER cbValue);
+
+SQLRETURN SQL_API SQLSetCursorNameW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCursor,
+ SQLSMALLINT cbCursor);
+
+
+
+
+
+
+
+SQLRETURN SQL_API SQLColumnsW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLWCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLWCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLWCHAR *szColumnName,
+ SQLSMALLINT cbColumnName);
+
+SQLRETURN SQL_API SQLGetConnectOptionW(
+ SQLHDBC hdbc,
+ SQLUSMALLINT fOption,
+ SQLPOINTER pvParam);
+
+
+
+SQLRETURN SQL_API SQLGetInfoW(
+ SQLHDBC hdbc,
+ SQLUSMALLINT fInfoType,
+ SQLPOINTER rgbInfoValue,
+ SQLSMALLINT cbInfoValueMax,
+ SQLSMALLINT *pcbInfoValue);
+
+SQLRETURN SQL_API SQLGetTypeInfoW(
+ SQLHSTMT StatementHandle,
+ SQLSMALLINT DataType);
+
+
+SQLRETURN SQL_API SQLSetConnectOptionW(
+ SQLHDBC hdbc,
+ SQLUSMALLINT fOption,
+ SQLULEN vParam);
+
+
+SQLRETURN SQL_API SQLSpecialColumnsW(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT fColType,
+ SQLWCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLWCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLWCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLUSMALLINT fScope,
+ SQLUSMALLINT fNullable);
+
+SQLRETURN SQL_API SQLStatisticsW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLWCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLWCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLUSMALLINT fUnique,
+ SQLUSMALLINT fAccuracy);
+
+SQLRETURN SQL_API SQLTablesW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLWCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLWCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLWCHAR *szTableType,
+ SQLSMALLINT cbTableType);
+
+
+
+SQLRETURN SQL_API SQLDataSourcesW(
+ SQLHENV henv,
+ SQLUSMALLINT fDirection,
+ SQLWCHAR *szDSN,
+ SQLSMALLINT cbDSNMax,
+ SQLSMALLINT *pcbDSN,
+ SQLWCHAR *szDescription,
+ SQLSMALLINT cbDescriptionMax,
+ SQLSMALLINT *pcbDescription);
+
+
+
+
+SQLRETURN SQL_API SQLDriverConnectW(
+ SQLHDBC hdbc,
+ SQLHWND hwnd,
+ SQLWCHAR *szConnStrIn,
+ SQLSMALLINT cbConnStrIn,
+ SQLWCHAR *szConnStrOut,
+ SQLSMALLINT cbConnStrOutMax,
+ SQLSMALLINT *pcbConnStrOut,
+ SQLUSMALLINT fDriverCompletion);
+
+
+SQLRETURN SQL_API SQLBrowseConnectW(
+ SQLHDBC hdbc,
+ SQLWCHAR *szConnStrIn,
+ SQLSMALLINT cbConnStrIn,
+ SQLWCHAR *szConnStrOut,
+ SQLSMALLINT cbConnStrOutMax,
+ SQLSMALLINT *pcbConnStrOut);
+
+SQLRETURN SQL_API SQLColumnPrivilegesW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLWCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLWCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLWCHAR *szColumnName,
+ SQLSMALLINT cbColumnName);
+
+SQLRETURN SQL_API SQLGetStmtAttrW(
+ SQLHSTMT hstmt,
+ SQLINTEGER fAttribute,
+ SQLPOINTER rgbValue,
+ SQLINTEGER cbValueMax,
+ SQLINTEGER *pcbValue);
+
+SQLRETURN SQL_API SQLSetStmtAttrW(
+ SQLHSTMT hstmt,
+ SQLINTEGER fAttribute,
+ SQLPOINTER rgbValue,
+ SQLINTEGER cbValueMax);
+
+SQLRETURN SQL_API SQLForeignKeysW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szPkCatalogName,
+ SQLSMALLINT cbPkCatalogName,
+ SQLWCHAR *szPkSchemaName,
+ SQLSMALLINT cbPkSchemaName,
+ SQLWCHAR *szPkTableName,
+ SQLSMALLINT cbPkTableName,
+ SQLWCHAR *szFkCatalogName,
+ SQLSMALLINT cbFkCatalogName,
+ SQLWCHAR *szFkSchemaName,
+ SQLSMALLINT cbFkSchemaName,
+ SQLWCHAR *szFkTableName,
+ SQLSMALLINT cbFkTableName);
+
+
+SQLRETURN SQL_API SQLNativeSqlW(
+ SQLHDBC hdbc,
+ SQLWCHAR *szSqlStrIn,
+ SQLINTEGER cbSqlStrIn,
+ SQLWCHAR *szSqlStr,
+ SQLINTEGER cbSqlStrMax,
+ SQLINTEGER *pcbSqlStr);
+
+
+SQLRETURN SQL_API SQLPrimaryKeysW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLWCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLWCHAR *szTableName,
+ SQLSMALLINT cbTableName);
+
+SQLRETURN SQL_API SQLProcedureColumnsW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLWCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLWCHAR *szProcName,
+ SQLSMALLINT cbProcName,
+ SQLWCHAR *szColumnName,
+ SQLSMALLINT cbColumnName);
+
+SQLRETURN SQL_API SQLProceduresW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLWCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLWCHAR *szProcName,
+ SQLSMALLINT cbProcName);
+
+
+SQLRETURN SQL_API SQLTablePrivilegesW(
+ SQLHSTMT hstmt,
+ SQLWCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLWCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLWCHAR *szTableName,
+ SQLSMALLINT cbTableName);
+
+SQLRETURN SQL_API SQLDriversW(
+ SQLHENV henv,
+ SQLUSMALLINT fDirection,
+ SQLWCHAR *szDriverDesc,
+ SQLSMALLINT cbDriverDescMax,
+ SQLSMALLINT *pcbDriverDesc,
+ SQLWCHAR *szDriverAttributes,
+ SQLSMALLINT cbDrvrAttrMax,
+ SQLSMALLINT *pcbDrvrAttr);
+
+
+/* ANSI versions */
+
+SQLRETURN SQL_API SQLColAttributeA(
+ SQLHSTMT hstmt,
+ SQLSMALLINT iCol,
+ SQLSMALLINT iField,
+ SQLPOINTER pCharAttr,
+ SQLSMALLINT cbCharAttrMax,
+ SQLSMALLINT *pcbCharAttr,
+ SQLLEN *pNumAttr);
+
+SQLRETURN SQL_API SQLColAttributesA(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT icol,
+ SQLUSMALLINT fDescType,
+ SQLPOINTER rgbDesc,
+ SQLSMALLINT cbDescMax,
+ SQLSMALLINT *pcbDesc,
+ SQLLEN *pfDesc);
+
+SQLRETURN SQL_API SQLConnectA(
+ SQLHDBC hdbc,
+ SQLCHAR *szDSN,
+ SQLSMALLINT cbDSN,
+ SQLCHAR *szUID,
+ SQLSMALLINT cbUID,
+ SQLCHAR *szAuthStr,
+ SQLSMALLINT cbAuthStr);
+
+
+SQLRETURN SQL_API SQLDescribeColA(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT icol,
+ SQLCHAR *szColName,
+ SQLSMALLINT cbColNameMax,
+ SQLSMALLINT *pcbColName,
+ SQLSMALLINT *pfSqlType,
+ SQLULEN *pcbColDef,
+ SQLSMALLINT *pibScale,
+ SQLSMALLINT *pfNullable);
+
+
+SQLRETURN SQL_API SQLErrorA(
+ SQLHENV henv,
+ SQLHDBC hdbc,
+ SQLHSTMT hstmt,
+ SQLCHAR *szSqlState,
+ SQLINTEGER *pfNativeError,
+ SQLCHAR *szErrorMsg,
+ SQLSMALLINT cbErrorMsgMax,
+ SQLSMALLINT *pcbErrorMsg);
+
+SQLRETURN SQL_API SQLExecDirectA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szSqlStr,
+ SQLINTEGER cbSqlStr);
+
+SQLRETURN SQL_API SQLGetConnectAttrA(
+ SQLHDBC hdbc,
+ SQLINTEGER fAttribute,
+ SQLPOINTER rgbValue,
+ SQLINTEGER cbValueMax,
+ SQLINTEGER *pcbValue);
+
+SQLRETURN SQL_API SQLGetCursorNameA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCursor,
+ SQLSMALLINT cbCursorMax,
+ SQLSMALLINT *pcbCursor);
+
+#if (ODBCVER >= 0x0300)
+SQLRETURN SQL_API SQLGetDescFieldA(
+ SQLHDESC hdesc,
+ SQLSMALLINT iRecord,
+ SQLSMALLINT iField,
+ SQLPOINTER rgbValue,
+ SQLINTEGER cbValueMax,
+ SQLINTEGER *pcbValue);
+
+SQLRETURN SQL_API SQLGetDescRecA(
+ SQLHDESC hdesc,
+ SQLSMALLINT iRecord,
+ SQLCHAR *szName,
+ SQLSMALLINT cbNameMax,
+ SQLSMALLINT *pcbName,
+ SQLSMALLINT *pfType,
+ SQLSMALLINT *pfSubType,
+ SQLLEN *pLength,
+ SQLSMALLINT *pPrecision,
+ SQLSMALLINT *pScale,
+ SQLSMALLINT *pNullable);
+
+SQLRETURN SQL_API SQLGetDiagFieldA(
+ SQLSMALLINT fHandleType,
+ SQLHANDLE handle,
+ SQLSMALLINT iRecord,
+ SQLSMALLINT fDiagField,
+ SQLPOINTER rgbDiagInfo,
+ SQLSMALLINT cbDiagInfoMax,
+ SQLSMALLINT *pcbDiagInfo);
+
+SQLRETURN SQL_API SQLGetDiagRecA(
+ SQLSMALLINT fHandleType,
+ SQLHANDLE handle,
+ SQLSMALLINT iRecord,
+ SQLCHAR *szSqlState,
+ SQLINTEGER *pfNativeError,
+ SQLCHAR *szErrorMsg,
+ SQLSMALLINT cbErrorMsgMax,
+ SQLSMALLINT *pcbErrorMsg);
+
+
+SQLRETURN SQL_API SQLGetStmtAttrA(
+ SQLHSTMT hstmt,
+ SQLINTEGER fAttribute,
+ SQLPOINTER rgbValue,
+ SQLINTEGER cbValueMax,
+ SQLINTEGER *pcbValue);
+
+#endif
+
+SQLRETURN SQL_API SQLGetTypeInfoA(
+ SQLHSTMT StatementHandle,
+ SQLSMALLINT DataTyoe);
+
+SQLRETURN SQL_API SQLPrepareA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szSqlStr,
+ SQLINTEGER cbSqlStr);
+
+SQLRETURN SQL_API SQLSetConnectAttrA(
+ SQLHDBC hdbc,
+ SQLINTEGER fAttribute,
+ SQLPOINTER rgbValue,
+ SQLINTEGER cbValue);
+
+SQLRETURN SQL_API SQLSetCursorNameA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCursor,
+ SQLSMALLINT cbCursor);
+
+
+
+
+
+
+
+SQLRETURN SQL_API SQLColumnsA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLCHAR *szColumnName,
+ SQLSMALLINT cbColumnName);
+
+SQLRETURN SQL_API SQLGetConnectOptionA(
+ SQLHDBC hdbc,
+ SQLUSMALLINT fOption,
+ SQLPOINTER pvParam);
+
+
+
+SQLRETURN SQL_API SQLGetInfoA(
+ SQLHDBC hdbc,
+ SQLUSMALLINT fInfoType,
+ SQLPOINTER rgbInfoValue,
+ SQLSMALLINT cbInfoValueMax,
+ SQLSMALLINT* pcbInfoValue);
+
+SQLRETURN SQL_API SQLGetStmtOptionA(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT fOption,
+ SQLPOINTER pvParam);
+
+SQLRETURN SQL_API SQLSetConnectOptionA(
+ SQLHDBC hdbc,
+ SQLUSMALLINT fOption,
+ SQLULEN vParam);
+
+SQLRETURN SQL_API SQLSetStmtOptionA(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT fOption,
+ SQLULEN vParam);
+
+SQLRETURN SQL_API SQLSpecialColumnsA(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT fColType,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLUSMALLINT fScope,
+ SQLUSMALLINT fNullable);
+
+SQLRETURN SQL_API SQLStatisticsA(
+ SQLHSTMT hstmt,
+
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLUSMALLINT fUnique,
+ SQLUSMALLINT fAccuracy);
+
+SQLRETURN SQL_API SQLTablesA(
+ SQLHSTMT hstmt,
+
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLCHAR *szTableType,
+
+ SQLSMALLINT cbTableType);
+
+
+
+SQLRETURN SQL_API SQLDataSourcesA(
+ SQLHENV henv,
+ SQLUSMALLINT fDirection,
+ SQLCHAR *szDSN,
+ SQLSMALLINT cbDSNMax,
+ SQLSMALLINT *pcbDSN,
+ SQLCHAR *szDescription,
+ SQLSMALLINT cbDescriptionMax,
+ SQLSMALLINT *pcbDescription);
+
+
+
+
+SQLRETURN SQL_API SQLDriverConnectA(
+ SQLHDBC hdbc,
+ SQLHWND hwnd,
+ SQLCHAR *szConnStrIn,
+ SQLSMALLINT cbConnStrIn,
+ SQLCHAR *szConnStrOut,
+ SQLSMALLINT cbConnStrOutMax,
+ SQLSMALLINT *pcbConnStrOut,
+ SQLUSMALLINT fDriverCompletion);
+
+
+SQLRETURN SQL_API SQLBrowseConnectA(
+ SQLHDBC hdbc,
+ SQLCHAR *szConnStrIn,
+ SQLSMALLINT cbConnStrIn,
+ SQLCHAR *szConnStrOut,
+ SQLSMALLINT cbConnStrOutMax,
+ SQLSMALLINT *pcbConnStrOut);
+
+SQLRETURN SQL_API SQLColumnPrivilegesA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName,
+ SQLCHAR *szColumnName,
+ SQLSMALLINT cbColumnName);
+
+SQLRETURN SQL_API SQLDescribeParamA(
+ SQLHSTMT hstmt,
+ SQLUSMALLINT ipar,
+ SQLSMALLINT *pfSqlType,
+ SQLUINTEGER *pcbParamDef,
+ SQLSMALLINT *pibScale,
+ SQLSMALLINT *pfNullable);
+
+
+SQLRETURN SQL_API SQLForeignKeysA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szPkCatalogName,
+ SQLSMALLINT cbPkCatalogName,
+ SQLCHAR *szPkSchemaName,
+ SQLSMALLINT cbPkSchemaName,
+ SQLCHAR *szPkTableName,
+ SQLSMALLINT cbPkTableName,
+ SQLCHAR *szFkCatalogName,
+ SQLSMALLINT cbFkCatalogName,
+ SQLCHAR *szFkSchemaName,
+ SQLSMALLINT cbFkSchemaName,
+ SQLCHAR *szFkTableName,
+ SQLSMALLINT cbFkTableName);
+
+
+SQLRETURN SQL_API SQLNativeSqlA(
+ SQLHDBC hdbc,
+ SQLCHAR *szSqlStrIn,
+ SQLINTEGER cbSqlStrIn,
+ SQLCHAR *szSqlStr,
+ SQLINTEGER cbSqlStrMax,
+ SQLINTEGER *pcbSqlStr);
+
+
+SQLRETURN SQL_API SQLPrimaryKeysA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName);
+
+SQLRETURN SQL_API SQLProcedureColumnsA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szProcName,
+ SQLSMALLINT cbProcName,
+ SQLCHAR *szColumnName,
+ SQLSMALLINT cbColumnName);
+
+SQLRETURN SQL_API SQLProceduresA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szProcName,
+ SQLSMALLINT cbProcName);
+
+
+SQLRETURN SQL_API SQLTablePrivilegesA(
+ SQLHSTMT hstmt,
+ SQLCHAR *szCatalogName,
+ SQLSMALLINT cbCatalogName,
+ SQLCHAR *szSchemaName,
+ SQLSMALLINT cbSchemaName,
+ SQLCHAR *szTableName,
+ SQLSMALLINT cbTableName);
+
+SQLRETURN SQL_API SQLDriversA(
+ SQLHENV henv,
+ SQLUSMALLINT fDirection,
+ SQLCHAR *szDriverDesc,
+ SQLSMALLINT cbDriverDescMax,
+ SQLSMALLINT *pcbDriverDesc,
+ SQLCHAR *szDriverAttributes,
+ SQLSMALLINT cbDrvrAttrMax,
+ SQLSMALLINT *pcbDrvrAttr);
+
+
+
+
+
+/*---------------------------------------------*/
+/* Mapping macros for Unicode */
+/*---------------------------------------------*/
+
+#ifndef SQL_NOUNICODEMAP /* define this to disable the mapping */
+#ifdef UNICODE
+
+#define SQLColAttribute SQLColAttributeW
+#define SQLColAttributes SQLColAttributesW
+#define SQLConnect SQLConnectW
+#define SQLDescribeCol SQLDescribeColW
+#define SQLError SQLErrorW
+#define SQLExecDirect SQLExecDirectW
+#define SQLGetConnectAttr SQLGetConnectAttrW
+#define SQLGetCursorName SQLGetCursorNameW
+#define SQLGetDescField SQLGetDescFieldW
+#define SQLGetDescRec SQLGetDescRecW
+#define SQLGetDiagField SQLGetDiagFieldW
+#define SQLGetDiagRec SQLGetDiagRecW
+#define SQLPrepare SQLPrepareW
+#define SQLSetConnectAttr SQLSetConnectAttrW
+#define SQLSetCursorName SQLSetCursorNameW
+#define SQLSetDescField SQLSetDescFieldW
+#define SQLSetStmtAttr SQLSetStmtAttrW
+#define SQLGetStmtAttr SQLGetStmtAttrW
+#define SQLColumns SQLColumnsW
+#define SQLGetConnectOption SQLGetConnectOptionW
+#define SQLGetInfo SQLGetInfoW
+#define SQLGetTypeInfo SQLGetTypeInfoW
+#define SQLSetConnectOption SQLSetConnectOptionW
+#define SQLSpecialColumns SQLSpecialColumnsW
+#define SQLStatistics SQLStatisticsW
+#define SQLTables SQLTablesW
+#define SQLDataSources SQLDataSourcesW
+#define SQLDriverConnect SQLDriverConnectW
+#define SQLBrowseConnect SQLBrowseConnectW
+#define SQLColumnPrivileges SQLColumnPrivilegesW
+#define SQLForeignKeys SQLForeignKeysW
+#define SQLNativeSql SQLNativeSqlW
+#define SQLPrimaryKeys SQLPrimaryKeysW
+#define SQLProcedureColumns SQLProcedureColumnsW
+#define SQLProcedures SQLProceduresW
+#define SQLTablePrivileges SQLTablePrivilegesW
+#define SQLDrivers SQLDriversW
+
+#endif /* UNICODE */
+#endif /* SQL_NOUNICODEMAP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef __SQLEXT_H
+#include <odbx/sqlext.h>
+
+#endif
+
+
+#endif
diff --git a/external/xmlsec/ExternalPackage_xmlsec.mk b/external/xmlsec/ExternalPackage_xmlsec.mk
new file mode 100644
index 000000000..68ddfaff8
--- /dev/null
+++ b/external/xmlsec/ExternalPackage_xmlsec.mk
@@ -0,0 +1,19 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,xmlsec,xmlsec))
+
+$(eval $(call gb_ExternalPackage_use_external_project,xmlsec,xmlsec))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,xmlsec,$(LIBO_LIB_FOLDER)/libxmlsec-mscng.dll,win32/binaries/libxmlsec-mscng.dll))
+$(eval $(call gb_ExternalPackage_add_file,xmlsec,$(LIBO_LIB_FOLDER)/libxmlsec.dll,win32/binaries/libxmlsec.dll))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/xmlsec/ExternalProject_xmlsec.mk b/external/xmlsec/ExternalProject_xmlsec.mk
new file mode 100644
index 000000000..f41e9362f
--- /dev/null
+++ b/external/xmlsec/ExternalProject_xmlsec.mk
@@ -0,0 +1,79 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_ExternalProject_ExternalProject,xmlsec))
+
+$(eval $(call gb_ExternalProject_use_externals,xmlsec,\
+ libxml2 \
+ $(if $(ENABLE_NSS),nss3,$(if $(ENABLE_OPENSSL),openssl)) \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,xmlsec,\
+ build \
+))
+
+# note: it's possible to use XSLT in XML signatures - that appears to be a
+# really bad idea from a security point of view though, because it will run
+# an XSLT script supplied as untrusted input, and XSLT implementations
+# tend to have extension functions, and some of these trivially allow
+# running arbitrary code... so investigate the situation with libxslt
+# before enabling it here; hopefully nobody uses XSLT in practice anyway.
+
+ifeq ($(OS),WNT)
+
+$(eval $(call gb_ExternalProject_use_nmake,xmlsec,build))
+
+$(call gb_ExternalProject_get_state_target,xmlsec,build) :
+ $(call gb_Trace_StartRange,xmlsec,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ cscript /e:javascript configure.js crypto=mscng xslt=no iconv=no static=no \
+ lib=$(call gb_UnpackedTarball_get_dir,libxml2)/win32/bin.msvc \
+ $(if $(filter TRUE,$(ENABLE_DBGUTIL)),debug=yes cruntime=/MDd) \
+ cflags="$(SOLARINC) -I$(WORKDIR)/UnpackedTarball/libxml2/include -I$(WORKDIR)/UnpackedTarball/icu/source/i18n -I$(WORKDIR)/UnpackedTarball/icu/source/common" \
+ && nmake \
+ ,win32)
+ $(call gb_Trace_EndRange,xmlsec,EXTERNAL)
+
+else
+
+$(call gb_ExternalProject_get_state_target,xmlsec,build) :
+ $(call gb_Trace_StartRange,xmlsec,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ $(if $(filter iOS MACOSX,$(OS_FOR_BUILD)),ACLOCAL="aclocal -I $(SRCDIR)/m4/mac") \
+ $(if $(filter AIX,$(OS)),ACLOCAL="aclocal -I /opt/freeware/share/aclocal") \
+ autoreconf \
+ && $(gb_RUN_CONFIGURE) ./configure \
+ --with-pic --disable-shared --disable-crypto-dl --without-libxslt --without-gnutls --without-gcrypt --disable-apps --disable-docs \
+ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \
+ CFLAGS="$(CFLAGS) $(call gb_ExternalProject_get_build_flags,xmlsec) $(gb_VISIBILITY_FLAGS)" \
+ $(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
+ $(if $(ENABLE_NSS), \
+ --without-openssl \
+ $(if $(SYSTEM_NSS),, \
+ $(if $(filter MACOSX,$(OS_FOR_BUILD)),--disable-pkgconfig) \
+ NSPR_CFLAGS="-I$(call gb_UnpackedTarball_get_dir,nss)/dist/out/include" NSPR_LIBS="-L$(call gb_UnpackedTarball_get_dir,nss)/dist/out/lib -lnspr4" \
+ NSS_CFLAGS="-I$(call gb_UnpackedTarball_get_dir,nss)/dist/public/nss" NSS_LIBS="-L$(call gb_UnpackedTarball_get_dir,nss)/dist/out/lib -lsmime3 -lnss3 -lnssutil3" \
+ ), \
+ $(if $(ENABLE_OPENSSL), \
+ $(if $(SYSTEM_OPENSSL),, \
+ OPENSSL_CFLAGS="-I$(call gb_UnpackedTarball_get_dir,openssl)/include" \
+ OPENSSL_LIBS="-L$(call gb_UnpackedTarball_get_dir,openssl) -lcrypto -lssl" \
+ ), \
+ --without-openssl) \
+ ) \
+ $(gb_CONFIGURE_PLATFORMS) \
+ $(if $(SYSBASE),CFLAGS="-I$(SYSBASE)/usr/include" \
+ LDFLAGS="$(call gb_ExternalProject_get_link_flags,xmlsec) -L$(SYSBASE)/usr/lib $(if $(filter-out LINUX FREEBSD,$(OS)),",-Wl$(COMMA)-z$(COMMA)origin -Wl$(COMMA)-rpath$(COMMA)\\"\$$\$$ORIGIN)) \
+ && $(MAKE) \
+ )
+ $(call gb_Trace_EndRange,xmlsec,EXTERNAL)
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/xmlsec/Makefile b/external/xmlsec/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/xmlsec/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/xmlsec/Module_xmlsec.mk b/external/xmlsec/Module_xmlsec.mk
new file mode 100644
index 000000000..55b0a4654
--- /dev/null
+++ b/external/xmlsec/Module_xmlsec.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,xmlsec))
+
+$(eval $(call gb_Module_add_targets,xmlsec,\
+ UnpackedTarball_xmlsec \
+ ExternalPackage_xmlsec \
+ ExternalProject_xmlsec \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/xmlsec/README b/external/xmlsec/README
new file mode 100644
index 000000000..9f2c5e5e7
--- /dev/null
+++ b/external/xmlsec/README
@@ -0,0 +1,5 @@
+XML signing, etc. From [http://www.aleksey.com/xmlsec/].
+
+The certificate vertification functionality of libxmlsec is not used, both the
+mscng and nss backends specify the
+XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS flag during verification.
diff --git a/external/xmlsec/UnpackedTarball_xmlsec.mk b/external/xmlsec/UnpackedTarball_xmlsec.mk
new file mode 100644
index 000000000..3ad978cdb
--- /dev/null
+++ b/external/xmlsec/UnpackedTarball_xmlsec.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+xmlsec_patches :=
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,xmlsec))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,xmlsec,$(XMLSEC_TARBALL),,xmlsec))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,xmlsec))
+
+$(eval $(call gb_UnpackedTarball_add_patches,xmlsec,\
+ $(foreach patch,$(xmlsec_patches),external/xmlsec/$(patch)) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/xsltml/Makefile b/external/xsltml/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/xsltml/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/xsltml/Module_xsltml.mk b/external/xsltml/Module_xsltml.mk
new file mode 100644
index 000000000..09877a7e7
--- /dev/null
+++ b/external/xsltml/Module_xsltml.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,xsltml))
+
+ifeq ($(ENABLE_MEDIAWIKI),TRUE)
+
+$(eval $(call gb_Module_add_targets,xsltml,\
+ UnpackedTarball_xsltml \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/xsltml/README b/external/xsltml/README
new file mode 100644
index 000000000..ab22e5e59
--- /dev/null
+++ b/external/xsltml/README
@@ -0,0 +1,14 @@
+XSLT MathML Library from [http://xsltml.sourceforge.net/].
+
+This project is used in the Wiki filter that is installed
+with the WikiPublisher extension. The extension is built
+in mudule swext.
+
+Building of the module provides a set of xslt transformation
+related files that are used by the filter to transform
+embedded formula objects into media wiki format.
+
+The archive was downloaded from:
+[http://xsltml.sourceforge.net]
+on 2009-02-16.
+
diff --git a/external/xsltml/UnpackedTarball_xsltml.mk b/external/xsltml/UnpackedTarball_xsltml.mk
new file mode 100644
index 000000000..743f2a01a
--- /dev/null
+++ b/external/xsltml/UnpackedTarball_xsltml.mk
@@ -0,0 +1,28 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,xsltml))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,xsltml,$(XSLTML_TARBALL),0))
+
+$(eval $(call gb_UnpackedTarball_fix_end_of_line,xsltml,\
+ cmarkup.xsl \
+ entities.xsl \
+ glayout.xsl \
+ mmltex.xsl \
+ scripts.xsl \
+ tables.xsl \
+ tokens.xsl \
+))
+
+$(eval $(call gb_UnpackedTarball_add_patches,xsltml,\
+ external/xsltml/xsltml_2.1.2.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/xsltml/xsltml_2.1.2.patch b/external/xsltml/xsltml_2.1.2.patch
new file mode 100644
index 000000000..f02b0c594
--- /dev/null
+++ b/external/xsltml/xsltml_2.1.2.patch
@@ -0,0 +1,1718 @@
+--- misc/xsltml_2.1.2/cmarkup.xsl 2009-03-27 08:11:02.000000000 +0100
++++ misc/build/xsltml_2.1.2/cmarkup.xsl 2008-03-07 21:36:34.000000000 +0100
+@@ -5,9 +5,9 @@
+ version='1.0'>
+
+ <!-- ====================================================================== -->
+-<!-- $Id: cmarkup.xsl,v 1.8 2003/06/10 12:24:04 shade33 Exp $
++<!-- $Id: cmarkup.xsl 2755 2008-03-07 20:35:56Z hauma $
+ This file is part of the XSLT MathML Library distribution.
+- See ./README or http://www.raleigh.ru/MathML/mmltex for
++ See ./README or http://xsltml.sf.net for
+ copyright and other information -->
+ <!-- ====================================================================== -->
+
+@@ -156,7 +156,7 @@
+ <xsl:text> &amp; \text{if $</xsl:text>
+ <xsl:apply-templates select="*[2]"/>
+ <xsl:text>$}</xsl:text>
+- <xsl:if test="not(position()=last()) or ../m:otherwise"><xsl:text>\\ </xsl:text></xsl:if>
++ <xsl:if test="not(position()=last()) or ../m:otherwise"><xsl:text>\\ &#13;&#10;</xsl:text></xsl:if>
+ </xsl:template>
+
+ <xsl:template match="m:otherwise">
+@@ -223,7 +223,7 @@
+ <xsl:template match="m:apply[*[1][self::m:minus] and count(*)=2]">
+ <xsl:text>-</xsl:text>
+ <xsl:apply-templates select="*[2]">
+- <xsl:with-param name="p" select="5"/>
++ <xsl:with-param name="p" select="2"/>
+ </xsl:apply-templates>
+ </xsl:template>
+
+@@ -234,7 +234,8 @@
+ <xsl:with-param name="p" select="$p"/>
+ <xsl:with-param name="this-p" select="2"/>
+ </xsl:call-template>
+-</xsl:template>
++</xsl:template>
++
+
+ <!-- 4.4.3.6 plus-->
+ <xsl:template match="m:apply[*[1][self::m:plus]]">
+@@ -585,12 +586,15 @@
+ </xsl:template>
+
+ <xsl:template match="m:apply[*[1][self::m:partialdiff]]" priority="1">
+- <xsl:text>\frac{\partial^{</xsl:text>
++ <xsl:text>\frac{\partial</xsl:text>
+ <xsl:choose>
+ <xsl:when test="m:degree">
++ <xsl:text>^{</xsl:text>
+ <xsl:apply-templates select="m:degree/node()"/>
++ <xsl:text>}</xsl:text>
+ </xsl:when>
+ <xsl:when test="m:bvar/m:degree[string(number(.))='NaN']">
++ <xsl:text>^{</xsl:text>
+ <xsl:for-each select="m:bvar/m:degree">
+ <xsl:apply-templates select="node()"/>
+ <xsl:if test="position()&lt;last()"><xsl:text>+</xsl:text></xsl:if>
+@@ -599,12 +603,15 @@
+ <xsl:text>+</xsl:text>
+ <xsl:value-of select="count(m:bvar[not(m:degree)])"/>
+ </xsl:if>
++ <xsl:text>}</xsl:text>
++ </xsl:when>
++ <xsl:when test="sum(m:bvar/m:degree)+count(m:bvar[not(m:degree)]) > 1">
++ <xsl:text>^{</xsl:text>
++ <xsl:value-of select="sum(m:bvar/m:degree)+count(m:bvar[not(m:degree)])"/>
++ <xsl:text>}</xsl:text>
+ </xsl:when>
+- <xsl:otherwise>
+- <xsl:value-of select="sum(m:bvar/m:degree)+count(m:bvar[not(m:degree)])"/>
+- </xsl:otherwise>
+ </xsl:choose>
+- <xsl:text>}</xsl:text>
++ <xsl:text> </xsl:text>
+ <xsl:apply-templates select="*[last()]"/>
+ <xsl:text>}{</xsl:text>
+ <xsl:for-each select="m:bvar">
+@@ -943,7 +950,7 @@
+ <xsl:text>\left(\begin{array}{c}</xsl:text>
+ <xsl:for-each select="*">
+ <xsl:apply-templates select="."/>
+- <xsl:if test="position()!=last()"><xsl:text>\\ </xsl:text></xsl:if>
++ <xsl:if test="position()!=last()"><xsl:text>\\ &#13;&#10;</xsl:text></xsl:if>
+ </xsl:for-each>
+ <xsl:text>\end{array}\right)</xsl:text>
+ </xsl:template>
+@@ -961,7 +968,7 @@
+ <xsl:apply-templates select="."/>
+ <xsl:if test="position()!=last()"><xsl:text> &amp; </xsl:text></xsl:if>
+ </xsl:for-each>
+- <xsl:if test="position()!=last()"><xsl:text>\\ </xsl:text></xsl:if>
++ <xsl:if test="position()!=last()"><xsl:text>\\ &#13;&#10;</xsl:text></xsl:if>
+ </xsl:template>
+
+ <!-- 4.4.10.4 determinant -->
+--- misc/xsltml_2.1.2/entities.xsl 2009-03-27 08:11:02.000000000 +0100
++++ misc/build/xsltml_2.1.2/entities.xsl 2008-03-07 21:36:34.000000000 +0100
+@@ -4,17 +4,56 @@
+ version='1.0'>
+
+ <!-- ====================================================================== -->
+-<!-- $Id: entities.xsl,v 1.13 2003/06/10 12:28:03 shade33 Exp $
++<!-- $Id: entities.xsl 2755 2008-03-07 20:35:56Z hauma $
+ This file is part of the XSLT MathML Library distribution.
+- See ./README or http://www.raleigh.ru/MathML/mmltex for
++ See ./README or http://xsltml.sf.net for
+ copyright and other information -->
+ <!-- ====================================================================== -->
++<xsl:variable name="apos">'</xsl:variable>
++
++<!--
++ Missing MathML equivalents for:
++
++ a \leslant b
++ a \geslant b
++
++ Unsupported in WikiMedia:
++
++ \oiint x
++ \oiiint x
++ Æ›
++ \adots
++
++ -->
+
+ <xsl:template name="replaceEntities">
+ <xsl:param name="content"/>
+ <xsl:if test="string-length($content)>0">
+ <xsl:choose>
+ <xsl:when test="starts-with($content,' ')"><xsl:value-of select="'\; '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, ' ')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02009;&#x0200A;&#x0200A;')"><xsl:value-of select="'\; '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02009;&#x0200A;&#x0200A;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x00023;')"><xsl:value-of select="'\# '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00023;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x00024;')"><xsl:value-of select="'\$ '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00024;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x00025;')"><xsl:value-of select="'\% '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00025;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x00026;')"><xsl:value-of select="'\&amp; '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00026;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0002A;')"><xsl:value-of select="'\ast '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0002A;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0003A;')"><xsl:value-of select="'\colon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0003A;')"/></xsl:call-template></xsl:when>
++ <!-- Note: \less is not supported by WikiMedia. -->
++ <xsl:when test="starts-with($content,'&#x0003C;')"><xsl:value-of select="'&lt; '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0003C;')"/></xsl:call-template></xsl:when>
++ <!-- Note: \greater is not supported by WikiMedia. -->
++ <xsl:when test="starts-with($content,'&#x0003E;')"><xsl:value-of select="'&gt; '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0003E;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0005B;')"><xsl:value-of select="'\lbrack '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0005B;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0005C;')"><xsl:value-of select="'\backslash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0005C;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0005D;')"><xsl:value-of select="'\rbrack '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0005D;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0005E;')"><xsl:value-of select="'\textasciicircumflex '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0005E;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0005F;')"><xsl:value-of select="'\_ '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0005F;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x00060;')"><xsl:value-of select="'\textasciigrave '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00060;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0007B;')"><xsl:value-of select="'\lbrace '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0007B;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0007C;')"><xsl:value-of select="'\vert '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0007C;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0007D;')"><xsl:value-of select="'\rbrace '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0007D;')"/></xsl:call-template></xsl:when>
++ <!-- Note: \textasciitilde is not supported by WikiMedia. -->
++ <xsl:when test="starts-with($content,'&#x0007E;')"><xsl:value-of select="'\sim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0007E;')"/></xsl:call-template></xsl:when>
++
+ <xsl:when test="starts-with($content,'&#x0025B;')"><xsl:value-of select="'\varepsilon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0025B;')"/></xsl:call-template></xsl:when> <!--/varepsilon -->
+ <xsl:when test="starts-with($content,'&#x002D9;')"><xsl:value-of select="'\dot{}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002D9;')"/></xsl:call-template></xsl:when> <!--/DiacriticalDot -->
+ <!-- ====================================================================== -->
+@@ -22,51 +61,324 @@
+ C1 Controls and Latin-1 Supplement
+ Range: 0080-00FF
+ http://www.unicode.org/charts/PDF/U0080.pdf -->
+-<!-- ====================================================================== -->
++<!-- ====================================================================== -->
++ <xsl:when test="starts-with($content,'&#x000A1;')"><xsl:value-of select="'\textexclamdown '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000A1;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000A2;')"><xsl:value-of select="'\mbox{\textcent}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000A2;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x000A3;')"><xsl:value-of select="'\pounds '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000A3;')"/></xsl:call-template></xsl:when> <!--pound sign -->
++ <xsl:when test="starts-with($content,'&#x000A4;')"><xsl:value-of select="'\mbox{\textcurrency}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000A4;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x000A5;')"><xsl:value-of select="'\yen '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000A5;')"/></xsl:call-template></xsl:when> <!--/yen =yen sign --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x000A7;')"><xsl:value-of select="'\S '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000A7;')"/></xsl:call-template></xsl:when> <!--section sign -->
++ <xsl:when test="starts-with($content,'&#x000A8;')"><xsl:value-of select="'\textasciidieresis '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000A8;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x000A9;')"><xsl:value-of select="'\copyright '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000A9;')"/></xsl:call-template></xsl:when> <!--copyright sign -->
++ <xsl:when test="starts-with($content,'&#x000AA;')"><xsl:value-of select="'\textordfeminine '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000AA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000AB;')"><xsl:value-of select="'\mbox{\guillemotleft}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000AB;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x000AC;')"><xsl:value-of select="'\neg '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000AC;')"/></xsl:call-template></xsl:when> <!--/neg /lnot =not sign -->
++ <xsl:when test="starts-with($content,'&#x000AD;')"><xsl:value-of select="'\- '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000AD;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x000AE;')"><xsl:value-of select="'\circledR '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000AE;')"/></xsl:call-template></xsl:when> <!--/circledR =registered sign --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x000AF;')"><xsl:value-of select="'\textasciimacron '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000AF;')"/></xsl:call-template></xsl:when>
++ <!-- Note: The degree sign is not supported by WikiMedia. Instead of "^\circ" (as supposed by the WikiMedia TeX help), simply \circ is used, because this is what the OOo math editor displays (bug?). -->
++ <xsl:when test="starts-with($content,'&#x000B0;')"><xsl:value-of select="'\circ '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B0;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x000B1;')"><xsl:value-of select="'\pm '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B1;')"/></xsl:call-template></xsl:when> <!--/pm B: =plus-or-minus sign -->
+- <xsl:when test="starts-with($content,'&#x000B5;')"><xsl:value-of select="'\mu '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B5;')"/></xsl:call-template></xsl:when> <!--=micro sign -->
++ <xsl:when test="starts-with($content,'&#x000B2;')"><xsl:value-of select="'{^2}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B2;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000B3;')"><xsl:value-of select="'{^3}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B3;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000B4;')"><xsl:value-of select="'\textasciiacute '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B4;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000B5;')"><xsl:value-of select="'\mathrm{\mu}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B5;')"/></xsl:call-template></xsl:when> <!--=micro sign -->
+ <xsl:when test="starts-with($content,'&#x000B6;')"><xsl:value-of select="'\P '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B6;')"/></xsl:call-template></xsl:when> <!--pilcrow (paragraph sign) -->
++ <xsl:when test="starts-with($content,'&#x000B7;')"><xsl:value-of select="'\cdotp '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B7;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000B8;')"><xsl:value-of select="'\mbox{\c{}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B8;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000B9;')"><xsl:value-of select="'{^1}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000B9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000BA;')"><xsl:value-of select="'\textordmasculine '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000BA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000BB;')"><xsl:value-of select="'\mbox{\guillemotright}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000BB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000C0;')"><xsl:value-of select="'\grave{A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C0;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000C1;')"><xsl:value-of select="'\acute{A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C1;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000C2;')"><xsl:value-of select="'\hat{A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C2;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000C3;')"><xsl:value-of select="'\tilde{A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C3;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000C4;')"><xsl:value-of select="'\ddot{A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C4;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x000C5;')"><xsl:value-of select="'\AA '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C5;')"/></xsl:call-template></xsl:when> <!--capital A, ring --> <!-- invalid in math mode -->
+ <xsl:when test="starts-with($content,'&#x000C6;')"><xsl:value-of select="'\AE '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C6;')"/></xsl:call-template></xsl:when> <!--capital AE diphthong (ligature) --> <!-- invalid in math mode -->
++ <xsl:when test="starts-with($content,'&#x000C7;')"><xsl:value-of select="'\mbox{\c{C}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C7;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000C8;')"><xsl:value-of select="'\grave{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C8;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000C9;')"><xsl:value-of select="'\acute{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000C9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000CA;')"><xsl:value-of select="'\hat{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000CA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000CB;')"><xsl:value-of select="'\ddot{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000CB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000CC;')"><xsl:value-of select="'\grave{I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000CC;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000CD;')"><xsl:value-of select="'\acute{I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000CD;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000CE;')"><xsl:value-of select="'\hat{I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000CE;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000CF;')"><xsl:value-of select="'\ddot{I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000CF;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000D0;')"><xsl:value-of select="'\DH '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D0;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000D1;')"><xsl:value-of select="'\tilde{N}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D1;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000D2;')"><xsl:value-of select="'\grave{O}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D2;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000D3;')"><xsl:value-of select="'\acute{O}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D3;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000D4;')"><xsl:value-of select="'\hat{O}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D4;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000D5;')"><xsl:value-of select="'\tilde{O}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D5;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000D6;')"><xsl:value-of select="'\ddot{O}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D6;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x000D7;')"><xsl:value-of select="'\times '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D7;')"/></xsl:call-template></xsl:when> <!--/times B: =multiply sign -->
++ <xsl:when test="starts-with($content,'&#x000D8;')"><xsl:value-of select="'\O '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D8;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000D9;')"><xsl:value-of select="'\grave{U}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000D9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000DA;')"><xsl:value-of select="'\acute{U}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000DA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000DB;')"><xsl:value-of select="'\hat{U}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000DB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000DC;')"><xsl:value-of select="'\ddot{U}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000DC;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000DD;')"><xsl:value-of select="'\acute{Y}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000DD;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000DE;')"><xsl:value-of select="'\TH '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000DE;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000DF;')"><xsl:value-of select="'\ss '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000DF;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000E0;')"><xsl:value-of select="'\grave{a}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E0;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000E1;')"><xsl:value-of select="'\acute{a}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E1;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000E2;')"><xsl:value-of select="'\hat{a}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E2;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000E3;')"><xsl:value-of select="'\tilde{a}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E3;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000E4;')"><xsl:value-of select="'\ddot{a}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E4;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000E5;')"><xsl:value-of select="'\aa '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E5;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x000E6;')"><xsl:value-of select="'\ae '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E6;')"/></xsl:call-template></xsl:when> <!--small ae diphthong (ligature) --> <!-- invalid in math mode -->
+-
++ <xsl:when test="starts-with($content,'&#x000E7;')"><xsl:value-of select="'\mbox{\c{c}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E7;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000E8;')"><xsl:value-of select="'\grave{e}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E8;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000E9;')"><xsl:value-of select="'\acute{e}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000E9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000EA;')"><xsl:value-of select="'\hat{e}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000EA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000EB;')"><xsl:value-of select="'\ddot{e}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000EB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000EC;')"><xsl:value-of select="'\grave{\imath}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000EC;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000ED;')"><xsl:value-of select="'\acute{\imath}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000ED;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000EE;')"><xsl:value-of select="'\hat{\imath}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000EE;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000EF;')"><xsl:value-of select="'\ddot{\imath}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000EF;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F0;')"><xsl:value-of select="'\eth '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F0;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F1;')"><xsl:value-of select="'\tilde{n}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F1;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F2;')"><xsl:value-of select="'\grave{o}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F2;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F3;')"><xsl:value-of select="'\acute{o}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F3;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F4;')"><xsl:value-of select="'\hat{o}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F4;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F5;')"><xsl:value-of select="'\tilde{o}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F5;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F6;')"><xsl:value-of select="'\ddot{o}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F6;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F7;')"><xsl:value-of select="'\div '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F7;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F8;')"><xsl:value-of select="'\o '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F8;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000F9;')"><xsl:value-of select="'\grave{u}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000F9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000FA;')"><xsl:value-of select="'\acute{u}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000FA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000FB;')"><xsl:value-of select="'\hat{u}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000FB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000FC;')"><xsl:value-of select="'\ddot{u}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000FC;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000FD;')"><xsl:value-of select="'\acute{y}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000FD;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000FE;')"><xsl:value-of select="'\th '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000FE;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x000FF;')"><xsl:value-of select="'\ddot{y}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x000FF;')"/></xsl:call-template></xsl:when>
++<!-- ====================================================================== -->
++<!-- Unicode 3.2
++ -->
++<!-- ====================================================================== -->
++<xsl:when test="starts-with($content,'&#x00100;')"><xsl:value-of select="'\bar{A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00100;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00101;')"><xsl:value-of select="'\bar{a}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00101;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00102;')"><xsl:value-of select="'\breve{A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00102;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00103;')"><xsl:value-of select="'\u{a}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00103;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00106;')"><xsl:value-of select="'\acute{C}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00106;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00107;')"><xsl:value-of select="'\acute{c}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00107;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00108;')"><xsl:value-of select="'\hat{C}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00108;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00109;')"><xsl:value-of select="'\hat{c}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00109;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0010A;')"><xsl:value-of select="'\dot{C}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0010A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0010B;')"><xsl:value-of select="'\dot{c}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0010B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0010C;')"><xsl:value-of select="'\check{C}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0010C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0010D;')"><xsl:value-of select="'\check{c}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0010D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0010E;')"><xsl:value-of select="'\check{D}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0010E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0010F;')"><xsl:value-of select="'\check{d}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0010F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00112;')"><xsl:value-of select="'\bar{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00112;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00113;')"><xsl:value-of select="'\bar{e}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00113;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00114;')"><xsl:value-of select="'\breve{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00114;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00115;')"><xsl:value-of select="'\breve{e}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00115;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00116;')"><xsl:value-of select="'\dot{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00116;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00117;')"><xsl:value-of select="'\dot{e}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00117;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00118;')"><xsl:value-of select="'\k{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00118;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0011A;')"><xsl:value-of select="'\check{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0011A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0011B;')"><xsl:value-of select="'\check{e}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0011B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0011C;')"><xsl:value-of select="'\hat{G}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0011C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0011D;')"><xsl:value-of select="'\hat{g}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0011D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0011E;')"><xsl:value-of select="'\breve{G}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0011E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0011F;')"><xsl:value-of select="'\breve{g}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0011F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00120;')"><xsl:value-of select="'\dot{G}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00120;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00121;')"><xsl:value-of select="'\dot{g}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00121;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00122;')"><xsl:value-of select="'\mbox{\c{G}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00122;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00123;')"><xsl:value-of select="'\mbox{\c{g}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00123;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00124;')"><xsl:value-of select="'\hat{H}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00124;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00125;')"><xsl:value-of select="'\hat{h}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00125;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00127;')"><xsl:value-of select="'\Elzxh '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00127;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00128;')"><xsl:value-of select="'\tilde{I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00128;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00129;')"><xsl:value-of select="'\tilde{\imath}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00129;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0012A;')"><xsl:value-of select="'\bar{I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0012A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0012B;')"><xsl:value-of select="'\bar{\imath}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0012B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0012C;')"><xsl:value-of select="'\breve{I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0012C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0012D;')"><xsl:value-of select="'\breve{\imath}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0012D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00130;')"><xsl:value-of select="'\dot{I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00130;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00131;')"><xsl:value-of select="'\imath '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00131;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00134;')"><xsl:value-of select="'\hat{J}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00134;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00135;')"><xsl:value-of select="'\hat{\jmath}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00135;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00136;')"><xsl:value-of select="'\mbox{\c{K}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00136;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00137;')"><xsl:value-of select="'\mbox{\c{k}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00137;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00139;')"><xsl:value-of select="'\acute{L}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00139;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0013A;')"><xsl:value-of select="'\acute{l}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0013A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0013B;')"><xsl:value-of select="'\mbox{\c{L}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0013B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0013C;')"><xsl:value-of select="'\mbox{\c{l}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0013C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0013D;')"><xsl:value-of select="'\check{L}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0013D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0013E;')"><xsl:value-of select="'\check{l}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0013E;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x00141;')"><xsl:value-of select="'\L '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00141;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x00142;')"><xsl:value-of select="'\l '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00142;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00143;')"><xsl:value-of select="'\acute{N}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00143;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00144;')"><xsl:value-of select="'\acute{n}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00144;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00145;')"><xsl:value-of select="'\mbox{\c{N}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00145;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00146;')"><xsl:value-of select="'\mbox{\c{n}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00146;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00147;')"><xsl:value-of select="'\check{N}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00147;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00148;')"><xsl:value-of select="'\check{n}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00148;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0014C;')"><xsl:value-of select="'\bar{O}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0014C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0014D;')"><xsl:value-of select="'\bar{o}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0014D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0014E;')"><xsl:value-of select="'\breve{O}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0014E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0014F;')"><xsl:value-of select="'\breve{o}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0014F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00150;')"><xsl:value-of select="'\mbox{\H{O}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00150;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00151;')"><xsl:value-of select="'\mbox{\H{o}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00151;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x00152;')"><xsl:value-of select="'\OE '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00152;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x00153;')"><xsl:value-of select="'\oe '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00153;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00154;')"><xsl:value-of select="'\acute{R}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00154;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00155;')"><xsl:value-of select="'\acute{r}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00155;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00156;')"><xsl:value-of select="'\mbox{\c{R}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00156;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00157;')"><xsl:value-of select="'\mbox{\c{r}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00157;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00158;')"><xsl:value-of select="'\check{R}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00158;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00159;')"><xsl:value-of select="'\check{r}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00159;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0015A;')"><xsl:value-of select="'\acute{S}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0015A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0015B;')"><xsl:value-of select="'\acute{s}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0015B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0015C;')"><xsl:value-of select="'\hat{S}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0015C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0015D;')"><xsl:value-of select="'\hat{s}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0015D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0015E;')"><xsl:value-of select="'\mbox{\c{S}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0015E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0015F;')"><xsl:value-of select="'\mbox{\c{s}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0015F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00160;')"><xsl:value-of select="'\check{S}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00160;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00161;')"><xsl:value-of select="'\check{s}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00161;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00162;')"><xsl:value-of select="'\mbox{\c{T}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00162;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00163;')"><xsl:value-of select="'\mbox{\c{t}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00163;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00164;')"><xsl:value-of select="'\check{T}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00164;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00165;')"><xsl:value-of select="'\check{t}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00165;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00168;')"><xsl:value-of select="'\tilde{U}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00168;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00169;')"><xsl:value-of select="'\tilde{u}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00169;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0016A;')"><xsl:value-of select="'\bar{U}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0016A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0016B;')"><xsl:value-of select="'\bar{u}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0016B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0016C;')"><xsl:value-of select="'\breve{U}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0016C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0016D;')"><xsl:value-of select="'\breve{u}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0016D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0016E;')"><xsl:value-of select="'\mathring{U}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0016E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0016F;')"><xsl:value-of select="'\mathring{u}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0016F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00170;')"><xsl:value-of select="'\mbox{\H{U}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00170;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00171;')"><xsl:value-of select="'\mbox{\H{u}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00171;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00172;')"><xsl:value-of select="'\k{U}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00172;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00174;')"><xsl:value-of select="'\hat{W}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00174;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00175;')"><xsl:value-of select="'\hat{w}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00175;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00176;')"><xsl:value-of select="'\hat{Y}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00176;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00177;')"><xsl:value-of select="'\hat{y}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00177;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00178;')"><xsl:value-of select="'\ddot{Y}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00178;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00179;')"><xsl:value-of select="'\acute{Z}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00179;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0017A;')"><xsl:value-of select="'\acute{z}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0017A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0017B;')"><xsl:value-of select="'\dot{Z}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0017B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0017C;')"><xsl:value-of select="'\dot{z}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0017C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0017D;')"><xsl:value-of select="'\check{Z}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0017D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0017E;')"><xsl:value-of select="'\check{z}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0017E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00192;')"><xsl:value-of select="'f'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00192;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x001AA;')"><xsl:value-of select="'\eth '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x001AA;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x001F5;')"><xsl:value-of select="'\acute{g}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x001F5;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00250;')"><xsl:value-of select="'\Elztrna '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00250;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00252;')"><xsl:value-of select="'\Elztrnsa '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00252;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00254;')"><xsl:value-of select="'\Elzopeno '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00254;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00256;')"><xsl:value-of select="'\Elzrtld '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00256;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00259;')"><xsl:value-of select="'\Elzschwa '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00259;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0025B;')"><xsl:value-of select="'\varepsilon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0025B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00263;')"><xsl:value-of select="'\Elzpgamma '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00263;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00264;')"><xsl:value-of select="'\Elzpbgam '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00264;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00265;')"><xsl:value-of select="'\Elztrnh '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00265;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0026C;')"><xsl:value-of select="'\Elzbtdl '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0026C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0026D;')"><xsl:value-of select="'\Elzrtll '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0026D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0026F;')"><xsl:value-of select="'\Elztrnm '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0026F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00270;')"><xsl:value-of select="'\Elztrnmlr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00270;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00271;')"><xsl:value-of select="'\Elzltlmr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00271;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00273;')"><xsl:value-of select="'\Elzrtln '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00273;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00277;')"><xsl:value-of select="'\Elzclomeg '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00277;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00279;')"><xsl:value-of select="'\Elztrnr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00279;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0027A;')"><xsl:value-of select="'\Elztrnrl '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0027A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0027B;')"><xsl:value-of select="'\Elzrttrnr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0027B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0027C;')"><xsl:value-of select="'\Elzrl '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0027C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0027D;')"><xsl:value-of select="'\Elzrtlr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0027D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0027E;')"><xsl:value-of select="'\Elzfhr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0027E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00282;')"><xsl:value-of select="'\Elzrtls '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00282;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00283;')"><xsl:value-of select="'\Elzesh '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00283;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00287;')"><xsl:value-of select="'\Elztrnt '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00287;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00288;')"><xsl:value-of select="'\Elzrtlt '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00288;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0028A;')"><xsl:value-of select="'\Elzpupsil '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0028A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0028B;')"><xsl:value-of select="'\Elzpscrv '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0028B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0028C;')"><xsl:value-of select="'\Elzinvv '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0028C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0028D;')"><xsl:value-of select="'\Elzinvw '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0028D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0028E;')"><xsl:value-of select="'\Elztrny '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0028E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00290;')"><xsl:value-of select="'\Elzrtlz '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00290;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00292;')"><xsl:value-of select="'\Elzyogh '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00292;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00294;')"><xsl:value-of select="'\Elzglst '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00294;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00295;')"><xsl:value-of select="'\Elzreglst '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00295;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00296;')"><xsl:value-of select="'\Elzinglst '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00296;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002A4;')"><xsl:value-of select="'\Elzdyogh '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002A4;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002A7;')"><xsl:value-of select="'\Elztesh '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002A7;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x002BC;')"><xsl:value-of select="'\rasp '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002BC;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002C8;')"><xsl:value-of select="'\Elzverts '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002C8;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002CC;')"><xsl:value-of select="'\Elzverti '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002CC;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002D0;')"><xsl:value-of select="'\Elzlmrk '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002D0;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002D1;')"><xsl:value-of select="'\Elzhlmrk '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002D1;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002D2;')"><xsl:value-of select="'\Elzsbrhr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002D2;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002D3;')"><xsl:value-of select="'\Elzsblhr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002D3;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002D4;')"><xsl:value-of select="'\Elzrais '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002D4;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002D5;')"><xsl:value-of select="'\Elzlow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002D5;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002D8;')"><xsl:value-of select="'\u '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002D8;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002D9;')"><xsl:value-of select="'\dot{}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002D9;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002DA;')"><xsl:value-of select="'\mathring{}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002DA;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002DB;')"><xsl:value-of select="'\mbox{\k{}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002DB;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x002DD;')"><xsl:value-of select="'\mbox{\H{}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x002DD;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00300;')"><xsl:value-of select="'\grave '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00300;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00301;')"><xsl:value-of select="'\acute '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00301;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00302;')"><xsl:value-of select="'\hat '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00302;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00303;')"><xsl:value-of select="'\tilde '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00303;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00304;')"><xsl:value-of select="'\bar '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00304;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00306;')"><xsl:value-of select="'\breve '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00306;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00307;')"><xsl:value-of select="'\dot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00307;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00308;')"><xsl:value-of select="'\ddot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00308;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0030A;')"><xsl:value-of select="'\ocirc '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0030A;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0030B;')"><xsl:value-of select="'\H '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0030B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0030C;')"><xsl:value-of select="'\check '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0030C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00321;')"><xsl:value-of select="'\Elzpalh '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00321;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0032A;')"><xsl:value-of select="'\Elzsbbrg '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0032A;')"/></xsl:call-template></xsl:when>
+ <!-- ====================================================================== -->
+ <!-- Unicode 3.2
+ Greek
+ Range: 0370-03FF
+ http://www.unicode.org/charts/PDF/U0370.pdf -->
+-<!-- ====================================================================== -->
+- <xsl:when test="starts-with($content,'&#x00391;')"><xsl:value-of select="'{\rm A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00391;')"/></xsl:call-template></xsl:when> <!--greek capital letter alpha -->
+- <xsl:when test="starts-with($content,'&#x00392;')"><xsl:value-of select="'{\rm B}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00392;')"/></xsl:call-template></xsl:when> <!-- greek capital letter beta -->
+- <xsl:when test="starts-with($content,'&#x00393;')"><xsl:value-of select="'\Gamma '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00393;')"/></xsl:call-template></xsl:when> <!--/Gamma capital Gamma, Greek -->
+- <xsl:when test="starts-with($content,'&#x00394;')"><xsl:value-of select="'\Delta '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00394;')"/></xsl:call-template></xsl:when> <!--/Delta capital Delta, Greek -->
+- <xsl:when test="starts-with($content,'&#x00395;')"><xsl:value-of select="'{\rm E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00395;')"/></xsl:call-template></xsl:when> <!-- greek capital letter epsilon -->
+- <xsl:when test="starts-with($content,'&#x00396;')"><xsl:value-of select="'{\rm Z}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00396;')"/></xsl:call-template></xsl:when> <!-- greek capital letter zeta -->
+- <xsl:when test="starts-with($content,'&#x00397;')"><xsl:value-of select="'{\rm H}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00397;')"/></xsl:call-template></xsl:when> <!-- greek capital letter eta -->
+- <xsl:when test="starts-with($content,'&#x00398;')"><xsl:value-of select="'\Theta '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00398;')"/></xsl:call-template></xsl:when> <!--/Theta capital Theta, Greek -->
+- <xsl:when test="starts-with($content,'&#x00399;')"><xsl:value-of select="'{\rm I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00399;')"/></xsl:call-template></xsl:when> <!-- greek capital letter iota -->
+- <xsl:when test="starts-with($content,'&#x0039A;')"><xsl:value-of select="'{\rm K}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039A;')"/></xsl:call-template></xsl:when> <!-- greek capital letter kappa -->
+- <xsl:when test="starts-with($content,'&#x0039B;')"><xsl:value-of select="'\Lambda '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039B;')"/></xsl:call-template></xsl:when> <!--/Lambda capital Lambda, Greek -->
+- <xsl:when test="starts-with($content,'&#x0039C;')"><xsl:value-of select="'{\rm M}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039C;')"/></xsl:call-template></xsl:when> <!-- greek capital letter mu -->
+- <xsl:when test="starts-with($content,'&#x0039D;')"><xsl:value-of select="'{\rm N}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039D;')"/></xsl:call-template></xsl:when> <!-- greek capital letter nu -->
+- <xsl:when test="starts-with($content,'&#x0039E;')"><xsl:value-of select="'\Xi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039E;')"/></xsl:call-template></xsl:when> <!--/Xi capital Xi, Greek -->
+- <xsl:when test="starts-with($content,'&#x0039F;')"><xsl:value-of select="'{\rm O}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039F;')"/></xsl:call-template></xsl:when> <!-- greek capital letter omicron -->
+- <xsl:when test="starts-with($content,'&#x003A0;')"><xsl:value-of select="'\Pi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A0;')"/></xsl:call-template></xsl:when> <!--/Pi capital Pi, Greek -->
+- <xsl:when test="starts-with($content,'&#x003A1;')"><xsl:value-of select="'{\rm P}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A1;')"/></xsl:call-template></xsl:when> <!-- greek capital letter rho -->
+- <xsl:when test="starts-with($content,'&#x003A3;')"><xsl:value-of select="'\Sigma '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A3;')"/></xsl:call-template></xsl:when> <!--/Sigma capital Sigma, Greek -->
+- <xsl:when test="starts-with($content,'&#x003A4;')"><xsl:value-of select="'{\rm T}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A4;')"/></xsl:call-template></xsl:when> <!-- greek capital letter tau -->
+- <xsl:when test="starts-with($content,'&#x003A5;')"><xsl:value-of select="'{\rm Y}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A5;')"/></xsl:call-template></xsl:when> <!-- greek capital letter upsilon -->
+- <xsl:when test="starts-with($content,'&#x003A6;')"><xsl:value-of select="'\Phi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A6;')"/></xsl:call-template></xsl:when> <!--/Phi capital Phi, Greek -->
+- <xsl:when test="starts-with($content,'&#x003A7;')"><xsl:value-of select="'{\rm X}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A7;')"/></xsl:call-template></xsl:when> <!-- greek capital letter chi -->
+- <xsl:when test="starts-with($content,'&#x003A8;')"><xsl:value-of select="'\Psi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A8;')"/></xsl:call-template></xsl:when> <!--/Psi capital Psi, Greek -->
+- <xsl:when test="starts-with($content,'&#x003A9;')"><xsl:value-of select="'\Omega '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A9;')"/></xsl:call-template></xsl:when> <!--/Omega capital Omega, Greek -->
++<!-- ====================================================================== -->
++<xsl:when test="starts-with($content,'&#x00386;')"><xsl:value-of select="'\acute{A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00386;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00388;')"><xsl:value-of select="'\acute{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00388;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00389;')"><xsl:value-of select="'\grave{H}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00389;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0038A;')"><xsl:value-of select="concat('\mathrm{',$apos,'I}')" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0038A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0038C;')"><xsl:value-of select="concat('\mathrm{',$apos,'O}')" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0038C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0038E;')"><xsl:value-of select="concat('\mathrm{',$apos,'Y}')" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0038E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0038F;')"><xsl:value-of select="concat('\mathrm{',$apos,'\Omega}')" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0038F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00390;')"><xsl:value-of select="'\acute{\ddot{\iota}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00390;')"/></xsl:call-template></xsl:when>
++
++<xsl:when test="starts-with($content,'&#x00391;')"><xsl:value-of select="'\Alpha '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00391;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00392;')"><xsl:value-of select="'\Beta '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00392;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00393;')"><xsl:value-of select="'\Gamma '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00393;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00394;')"><xsl:value-of select="'\Delta '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00394;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00395;')"><xsl:value-of select="'\Epsilon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00395;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00396;')"><xsl:value-of select="'\Zeta '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00396;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00397;')"><xsl:value-of select="'\Eta '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00397;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00398;')"><xsl:value-of select="'\Theta '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00398;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x00399;')"><xsl:value-of select="'\Iota '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x00399;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0039A;')"><xsl:value-of select="'\Kappa '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0039B;')"><xsl:value-of select="'\Lambda '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0039C;')"><xsl:value-of select="'M'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0039D;')"><xsl:value-of select="'N'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0039E;')"><xsl:value-of select="'\Xi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0039F;')"><xsl:value-of select="'O'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0039F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003A0;')"><xsl:value-of select="'\Pi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A0;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003A1;')"><xsl:value-of select="'\Rho '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A1;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003A3;')"><xsl:value-of select="'\Sigma '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A3;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003A4;')"><xsl:value-of select="'\Tau '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A4;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003A5;')"><xsl:value-of select="'\Upsilon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A5;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003A6;')"><xsl:value-of select="'\Phi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A6;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003A7;')"><xsl:value-of select="'\Chi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A7;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003A8;')"><xsl:value-of select="'\Psi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A8;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003A9;')"><xsl:value-of select="'\Omega '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003A9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x003AA;')"><xsl:value-of select="'\mathrm{\ddot{I}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003AA;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003AB;')"><xsl:value-of select="'\mathrm{\ddot{Y}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003AB;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003AC;')"><xsl:value-of select="'\acute{\alpha}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003AC;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003AD;')"><xsl:value-of select="'\acute{\epsilon}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003AD;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003AE;')"><xsl:value-of select="'\acute{\eta}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003AE;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003AF;')"><xsl:value-of select="'\acute{\iota}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003AF;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003B0;')"><xsl:value-of select="'\acute{\ddot{\upsilon}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003B0;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x003B1;')"><xsl:value-of select="'\alpha '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003B1;')"/></xsl:call-template></xsl:when> <!--/alpha small alpha, Greek -->
+ <xsl:when test="starts-with($content,'&#x003B2;')"><xsl:value-of select="'\beta '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003B2;')"/></xsl:call-template></xsl:when> <!--/beta small beta, Greek -->
+ <xsl:when test="starts-with($content,'&#x003B3;')"><xsl:value-of select="'\gamma '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003B3;')"/></xsl:call-template></xsl:when> <!--/gamma small gamma, Greek -->
+@@ -92,60 +404,143 @@
+ <xsl:when test="starts-with($content,'&#x003C7;')"><xsl:value-of select="'\chi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003C7;')"/></xsl:call-template></xsl:when> <!--/chi small chi, Greek -->
+ <xsl:when test="starts-with($content,'&#x003C8;')"><xsl:value-of select="'\psi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003C8;')"/></xsl:call-template></xsl:when> <!--/psi small psi, Greek -->
+ <xsl:when test="starts-with($content,'&#x003C9;')"><xsl:value-of select="'\omega '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003C9;')"/></xsl:call-template></xsl:when> <!--/omega small omega, Greek -->
++ <xsl:when test="starts-with($content,'&#x003CA;')"><xsl:value-of select="'\ddot{\iota}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003CA;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003CB;')"><xsl:value-of select="'\ddot{\upsilon}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003CB;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003CC;')"><xsl:value-of select="'\acute{o}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003CC;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003CD;')"><xsl:value-of select="'\acute{\upsilon}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003CD;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003CE;')"><xsl:value-of select="'\acute{\omega}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003CE;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x003D1;')"><xsl:value-of select="'\vartheta '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003D1;')"/></xsl:call-template></xsl:when> <!--/vartheta - curly or open theta -->
+ <xsl:when test="starts-with($content,'&#x003D2;')"><xsl:value-of select="'\Upsilon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003D2;')"/></xsl:call-template></xsl:when> <!--/Upsilon capital Upsilon, Greek -->
+- <xsl:when test="starts-with($content,'&#x003D5;')"><xsl:value-of select="'\varphi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003D5;')"/></xsl:call-template></xsl:when> <!--/varphi - curly or open phi -->
++ <xsl:when test="starts-with($content,'&#x003D5;')"><xsl:value-of select="'\phi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003D5;')"/></xsl:call-template></xsl:when> <!--/varphi - curly or open phi -->
+ <xsl:when test="starts-with($content,'&#x003D6;')"><xsl:value-of select="'\varpi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003D6;')"/></xsl:call-template></xsl:when> <!--/varpi -->
++<xsl:when test="starts-with($content,'&#x003DA;')"><xsl:value-of select="'\Stigma '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003DA;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003DC;')"><xsl:value-of select="'\Digamma '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003DC;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003DD;')"><xsl:value-of select="'\digamma '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003DD;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003DE;')"><xsl:value-of select="'\Koppa '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003DE;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003E0;')"><xsl:value-of select="'\Sampi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003E0;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x003F0;')"><xsl:value-of select="'\varkappa '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003F0;')"/></xsl:call-template></xsl:when> <!--/varkappa -->
+ <xsl:when test="starts-with($content,'&#x003F1;')"><xsl:value-of select="'\varrho '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003F1;')"/></xsl:call-template></xsl:when> <!--/varrho -->
+-
++<xsl:when test="starts-with($content,'&#x003F5;')"><xsl:value-of select="'\epsilon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003F5;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x003F6;')"><xsl:value-of select="'\backepsilon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x003F6;')"/></xsl:call-template></xsl:when>
+ <!-- ====================================================================== -->
+ <!-- Unicode 3.2
+ General Punctuation
+ Range: 2000-206F
+ http://www.unicode.org/charts/PDF/U2000.pdf -->
+ <!-- ====================================================================== -->
+- <xsl:when test="starts-with($content,'&#x02002;')"><xsl:value-of select='"\hspace{0.5em}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02002;')"/></xsl:call-template></xsl:when> <!-- en space (1/2-em) -->
+- <xsl:when test="starts-with($content,'&#x02003;')"><xsl:value-of select='"\hspace{1em}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02003;')"/></xsl:call-template></xsl:when> <!-- emsp - space of width 1em -->
++ <xsl:when test="starts-with($content,'&#x02002;')"><xsl:value-of select='"\enspace "' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02002;')"/></xsl:call-template></xsl:when> <!-- en space (1/2-em) -->
++ <xsl:when test="starts-with($content,'&#x02003;')"><xsl:value-of select='"\quad "' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02003;')"/></xsl:call-template></xsl:when> <!-- emsp - space of width 1em -->
+ <xsl:when test="starts-with($content,'&#x02004;')"><xsl:value-of select='"\hspace{0.33em}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02004;')"/></xsl:call-template></xsl:when> <!-- emsp13 - space of width 1/3 em -->
+- <xsl:when test="starts-with($content,'&#x02005;')"><xsl:value-of select='"\hspace{0.25em}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02005;')"/></xsl:call-template></xsl:when> <!-- ThickSpace - space of width 1/4 em -->
+- <xsl:when test="starts-with($content,'&#x02009;')"><xsl:value-of select='"\hspace{0.17em}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02009;')"/></xsl:call-template></xsl:when> <!-- ThinSpace - space of width 3/18 em -->
++ <xsl:when test="starts-with($content,'&#x02005;')"><xsl:value-of select='"\thickspace "' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02005;')"/></xsl:call-template></xsl:when> <!-- ThickSpace - space of width 1/4 em -->
++ <xsl:when test="starts-with($content,'&#x02006;')"><xsl:value-of select='"\hspace{0.166em}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02006;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02007;')"><xsl:value-of select='"\hphantom{0}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02007;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02008;')"><xsl:value-of select='"\hphantom{,}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02008;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02009;')"><xsl:value-of select='"\thinspace "' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02009;')"/></xsl:call-template></xsl:when> <!-- ThinSpace - space of width 3/18 em -->
++ <xsl:when test="starts-with($content,'&#x0200A;')"><xsl:value-of select="'\hspace '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0200A;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0200B;')"><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0200B;')"/></xsl:call-template></xsl:when> <!--zero width space -->
++ <xsl:when test="starts-with($content,'&#x02010;')"><xsl:value-of select="'-'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02010;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02013;')"><xsl:value-of select="'\endash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02013;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02014;')"><xsl:value-of select="'\emdash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02014;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02016;')"><xsl:value-of select="'\Vert '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02016;')"/></xsl:call-template></xsl:when> <!--/Vert dbl vertical bar -->
++ <xsl:when test="starts-with($content,'&#x02018;')"><xsl:value-of select="'\lq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02018;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02019;')"><xsl:value-of select="'\rq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02019;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0201B;')"><xsl:value-of select="'\Elzreapos '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0201B;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0201C;')"><xsl:value-of select="'\textquotedblleft '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0201C;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0201D;')"><xsl:value-of select="'\textquotedblright '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0201D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02020;')"><xsl:value-of select="'\dagger '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02020;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02021;')"><xsl:value-of select="'\ddager '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02021;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02022;')"><xsl:value-of select="'\bullet '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02022;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02026;')"><xsl:value-of select="'\dots '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02026;')"/></xsl:call-template></xsl:when> <!--horizontal ellipsis = three dot leader -->
+ <xsl:when test="starts-with($content,'&#x02032;')"><xsl:value-of select="'\prime '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02032;')"/></xsl:call-template></xsl:when> <!--/prime prime or minute -->
++<xsl:when test="starts-with($content,'&#x02033;')"><xsl:value-of select="concat('{',$apos,$apos,'}')" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02033;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02034;')"><xsl:value-of select="concat('{',$apos,$apos,$apos,'}')" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02034;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02035;')"><xsl:value-of select="'\backprime '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02035;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02041;')"><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02041;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02044;')"><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02044;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0204E;')"><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0204E;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02057;')"><xsl:value-of select="concat($apos,$apos,$apos,$apos)" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02057;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0205F;')"><xsl:value-of select="'\mkern4mu '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0205F;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02061;')"><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02061;')"/></xsl:call-template></xsl:when> <!-- ApplyFunction -->
+ <xsl:when test="starts-with($content,'&#x02062;')"><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02062;')"/></xsl:call-template></xsl:when> <!-- InvisibleTimes -->
+ <xsl:when test="starts-with($content,'&#x02063;')"><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02063;')"/></xsl:call-template></xsl:when> <!-- InvisibleComma, used as a separator, e.g., in indices -->
+ <!-- ====================================================================== -->
+ <!-- Unicode 3.2
++ -->
++<!-- ====================================================================== -->
++<xsl:when test="starts-with($content,'&#x020A7;')"><xsl:value-of select="'\Elzpes'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x020A7;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x020AC;')"><xsl:value-of select="'\mbox{\texteuro}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x020AC;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x020DB;')"><xsl:value-of select="'\dddot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x020DB;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x020DC;')"><xsl:value-of select="'\ddddot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x020DC;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x020E7;')"><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x020E7;')"/></xsl:call-template></xsl:when>
++<!-- ====================================================================== -->
++<!-- Unicode 3.2
+ Letterlike Symbols
+ Range: 2100-214F
+ http://www.unicode.org/charts/PDF/U2100.pdf -->
+ <!-- ====================================================================== -->
++<xsl:when test="starts-with($content,'&#x02102;')"><xsl:value-of select="'\mathbb{C}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02102;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0210A;')"><xsl:value-of select="'\mathscr{g}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0210A;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0210B;')"><xsl:value-of select="'\mathscr{H}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0210B;')"/></xsl:call-template></xsl:when> <!--H Hamiltonian -->
++ <xsl:when test="starts-with($content,'&#x0210C;')"><xsl:value-of select="'\mathfrak{H}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0210C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0210D;')"><xsl:value-of select="'\mathbb{H}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0210D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0210E;')"><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0210E;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0210F;&#x0FE00;')"><xsl:value-of select="'\hbar '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0210F;&#x0FE00;')"/></xsl:call-template></xsl:when> <!--/hbar - Planck's over 2pi -->
+ <xsl:when test="starts-with($content,'&#x0210F;')"><xsl:value-of select="'\hslash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0210F;')"/></xsl:call-template></xsl:when> <!--/hslash - variant Planck's over 2pi --> <!-- Required amssymb -->
++<xsl:when test="starts-with($content,'&#x02110;')"><xsl:value-of select="'\mathscr{I}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02110;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02111;')"><xsl:value-of select="'\Im '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02111;')"/></xsl:call-template></xsl:when> <!--/Im - imaginary -->
++<xsl:when test="starts-with($content,'&#x02112;')"><xsl:value-of select="'\mathscr{L}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02112;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02113;')"><xsl:value-of select="'\ell '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02113;')"/></xsl:call-template></xsl:when> <!--/ell - cursive small l -->
+ <xsl:when test="starts-with($content,'&#x02115;')"><xsl:value-of select="'\mathbb{N}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02115;')"/></xsl:call-template></xsl:when> <!--the semi-ring of natural numbers --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02116;')"><xsl:value-of select="'\textnumero '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02116;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02118;')"><xsl:value-of select="'\wp '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02118;')"/></xsl:call-template></xsl:when> <!--/wp - Weierstrass p -->
+ <xsl:when test="starts-with($content,'&#x02119;')"><xsl:value-of select="'\mathbb{P}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02119;')"/></xsl:call-template></xsl:when> <!--the prime natural numbers --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x0211A;')"><xsl:value-of select="'\mathbb{Q}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0211A;')"/></xsl:call-template></xsl:when> <!--the field of rational numbers --> <!-- Required amssymb -->
++<xsl:when test="starts-with($content,'&#x0211B;')"><xsl:value-of select="'\mathscr{R}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0211B;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0211C;')"><xsl:value-of select="'\Re '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0211C;')"/></xsl:call-template></xsl:when> <!--/Re - real -->
++ <xsl:when test="starts-with($content,'&#x0211D;')"><xsl:value-of select="'\mathbb{R}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0211D;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0211E;')"><xsl:value-of select="'\Elzxrat '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0211E;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02124;')"><xsl:value-of select="'\mathbb{Z}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02124;')"/></xsl:call-template></xsl:when> <!--the ring of integers --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02126;')"><xsl:value-of select="'\Omega '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02126;')"/></xsl:call-template></xsl:when> <!--ohm sign -->
+ <xsl:when test="starts-with($content,'&#x02127;')"><xsl:value-of select="'\mho '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02127;')"/></xsl:call-template></xsl:when> <!--/mho - conductance -->
++<xsl:when test="starts-with($content,'&#x02128;')"><xsl:value-of select="'\mathfrak{Z}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02128;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02129;')"><xsl:value-of select="'\ElsevierGlyph{2129}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02129;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0212B;')"><xsl:value-of select="'\AA'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0212B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0212C;')"><xsl:value-of select="'\mathscr{B}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0212C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0212D;')"><xsl:value-of select="'\mathfrak{C}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0212D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0212F;')"><xsl:value-of select="'\mathscr{e}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0212F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02130;')"><xsl:value-of select="'\mathscr{E}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02130;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02131;')"><xsl:value-of select="'\mathscr{F}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02131;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02133;')"><xsl:value-of select="'\mathscr{M}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02133;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02134;')"><xsl:value-of select="'\mathscr{o}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02134;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02135;')"><xsl:value-of select="'\aleph '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02135;')"/></xsl:call-template></xsl:when> <!--/aleph aleph, Hebrew -->
+ <xsl:when test="starts-with($content,'&#x02136;')"><xsl:value-of select="'\beth '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02136;')"/></xsl:call-template></xsl:when> <!--/beth - beth, Hebrew --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02137;')"><xsl:value-of select="'\gimel '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02137;')"/></xsl:call-template></xsl:when> <!--/gimel - gimel, Hebrew --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02138;')"><xsl:value-of select="'\daleth '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02138;')"/></xsl:call-template></xsl:when> <!--/daleth - daleth, Hebrew --> <!-- Required amssymb -->
++<xsl:when test="starts-with($content,'&#x0213F;')"><xsl:value-of select="'\BbbPi '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0213F;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02140;')"><xsl:value-of select="'\bbsum '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02140;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02141;')"><xsl:value-of select="'\Game '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02141;')"/></xsl:call-template></xsl:when>
++
+ <xsl:when test="starts-with($content,'&#x02145;')"><xsl:value-of select="'D'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02145;')"/></xsl:call-template></xsl:when> <!--D for use in differentials, e.g., within integrals -->
+ <xsl:when test="starts-with($content,'&#x02146;')"><xsl:value-of select="'d'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02146;')"/></xsl:call-template></xsl:when> <!--d for use in differentials, e.g., within integrals -->
+ <xsl:when test="starts-with($content,'&#x02147;')"><xsl:value-of select="'e'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02147;')"/></xsl:call-template></xsl:when> <!--e use for the exponential base of the natural logarithms -->
+ <xsl:when test="starts-with($content,'&#x02148;')"><xsl:value-of select="'i'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02148;')"/></xsl:call-template></xsl:when> <!--i for use as a square root of -1 -->
+ <xsl:when test="starts-with($content,'&#x02149;')"><xsl:value-of select="'j'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02149;')"/></xsl:call-template></xsl:when>
+-
++<!-- ====================================================================== -->
++<!-- Unicode 3.2
++ -->
++<!-- ====================================================================== -->
++<xsl:when test="starts-with($content,'&#x02153;')"><xsl:value-of select="'\textfrac{1}{3}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02153;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02154;')"><xsl:value-of select="'\textfrac{2}{3}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02154;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02155;')"><xsl:value-of select="'\textfrac{1}{5}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02155;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02156;')"><xsl:value-of select="'\textfrac{2}{5}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02156;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02157;')"><xsl:value-of select="'\textfrac{3}{5}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02157;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02158;')"><xsl:value-of select="'\textfrac{4}{5}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02158;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x02159;')"><xsl:value-of select="'\textfrac{1}{6}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02159;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0215A;')"><xsl:value-of select="'\textfrac{5}{6}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0215A;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0215B;')"><xsl:value-of select="'\textfrac{1}{8}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0215B;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0215C;')"><xsl:value-of select="'\textfrac{3}{8}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0215C;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0215D;')"><xsl:value-of select="'\textfrac{5}{8}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0215D;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x0215E;')"><xsl:value-of select="'\textfrac{7}{8}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0215E;')"/></xsl:call-template></xsl:when>
+ <!-- ====================================================================== -->
+ <!-- Unicode 3.2
+ Arrows
+@@ -154,7 +549,7 @@
+ <!-- ====================================================================== -->
+ <xsl:when test="starts-with($content,'&#x02190;')"><xsl:value-of select="'\leftarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02190;')"/></xsl:call-template></xsl:when> <!--/leftarrow /gets A: =leftward arrow -->
+ <xsl:when test="starts-with($content,'&#x02191;')"><xsl:value-of select="'\uparrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02191;')"/></xsl:call-template></xsl:when> <!--/uparrow A: =upward arrow -->
+- <xsl:when test="starts-with($content,'&#x02192;')"><xsl:value-of select="'\to '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02192;')"/></xsl:call-template></xsl:when> <!--/rightarrow /to A: =rightward arrow -->
++ <xsl:when test="starts-with($content,'&#x02192;')"><xsl:value-of select="'\rightarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02192;')"/></xsl:call-template></xsl:when> <!--/rightarrow /to A: =rightward arrow -->
+ <xsl:when test="starts-with($content,'&#x02193;')"><xsl:value-of select="'\downarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02193;')"/></xsl:call-template></xsl:when> <!--/downarrow A: =downward arrow -->
+ <xsl:when test="starts-with($content,'&#x02194;')"><xsl:value-of select="'\leftrightarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02194;')"/></xsl:call-template></xsl:when> <!--/leftrightarrow A: l&r arrow -->
+ <xsl:when test="starts-with($content,'&#x02195;')"><xsl:value-of select="'\updownarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02195;')"/></xsl:call-template></xsl:when> <!--/updownarrow A: up&down arrow -->
+@@ -164,6 +559,7 @@
+ <xsl:when test="starts-with($content,'&#x02199;')"><xsl:value-of select="'\swarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02199;')"/></xsl:call-template></xsl:when> <!--/swarrow A: SW pointing arrow -->
+ <xsl:when test="starts-with($content,'&#x0219A;')"><xsl:value-of select="'\nleftarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0219A;')"/></xsl:call-template></xsl:when> <!--/nleftarrow A: not left arrow --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x0219B;')"><xsl:value-of select="'\nrightarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0219B;')"/></xsl:call-template></xsl:when> <!--/nrightarrow A: not right arrow --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x0219C;')"><xsl:value-of select="'\leftsquigarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0219C;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0219D;')"><xsl:value-of select="'\rightsquigarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0219D;')"/></xsl:call-template></xsl:when> <!--/rightsquigarrow A: rt arrow-wavy --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x0219E;')"><xsl:value-of select="'\twoheadleftarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0219E;')"/></xsl:call-template></xsl:when> <!--/twoheadleftarrow A: --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021A0;')"><xsl:value-of select="'\twoheadrightarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021A0;')"/></xsl:call-template></xsl:when> <!--/twoheadrightarrow A: --> <!-- Required amssymb -->
+@@ -178,6 +574,7 @@
+ <xsl:when test="starts-with($content,'&#x021AE;')"><xsl:value-of select="'\nleftrightarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021AE;')"/></xsl:call-template></xsl:when> <!--/nleftrightarrow A: not l&r arrow --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021B0;')"><xsl:value-of select="'\Lsh '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021B0;')"/></xsl:call-template></xsl:when> <!--/Lsh A: --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021B1;')"><xsl:value-of select="'\Rsh '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021B1;')"/></xsl:call-template></xsl:when> <!--/Rsh A: --> <!-- Required amssymb -->
++<xsl:when test="starts-with($content,'&#x021B3;')"><xsl:value-of select="'\ElsevierGlyph{21B3}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021B3;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x021B6;')"><xsl:value-of select="'\curvearrowleft '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021B6;')"/></xsl:call-template></xsl:when> <!--/curvearrowleft A: left curved arrow --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021B7;')"><xsl:value-of select="'\curvearrowright '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021B7;')"/></xsl:call-template></xsl:when> <!--/curvearrowright A: rt curved arrow --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021BA;')"><xsl:value-of select="'\circlearrowleft '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021BA;')"/></xsl:call-template></xsl:when> <!--/circlearrowleft A: l arr in circle --> <!-- Required amssymb -->
+@@ -191,6 +588,7 @@
+ <xsl:when test="starts-with($content,'&#x021C2;')"><xsl:value-of select="'\downharpoonright '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021C2;')"/></xsl:call-template></xsl:when> <!--/downharpoonright A: down harpoon-rt --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021C3;')"><xsl:value-of select="'\downharpoonleft '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021C3;')"/></xsl:call-template></xsl:when> <!--/downharpoonleft A: dn harpoon-left --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021C4;')"><xsl:value-of select="'\rightleftarrows '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021C4;')"/></xsl:call-template></xsl:when> <!--/rightleftarrows A: r arr over l arr --> <!-- Required amssymb -->
++<xsl:when test="starts-with($content,'&#x021C5;')"><xsl:value-of select="'\dblarrowupdown '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021C5;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x021C6;')"><xsl:value-of select="'\leftrightarrows '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021C6;')"/></xsl:call-template></xsl:when> <!--/leftrightarrows A: l arr over r arr --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021C7;')"><xsl:value-of select="'\leftleftarrows '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021C7;')"/></xsl:call-template></xsl:when> <!--/leftleftarrows A: two left arrows --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021C8;')"><xsl:value-of select="'\upuparrows '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021C8;')"/></xsl:call-template></xsl:when> <!--/upuparrows A: two up arrows --> <!-- Required amssymb -->
+@@ -205,12 +603,16 @@
+ <xsl:when test="starts-with($content,'&#x021D1;')"><xsl:value-of select="'\Uparrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021D1;')"/></xsl:call-template></xsl:when> <!--/Uparrow A: up dbl arrow -->
+ <xsl:when test="starts-with($content,'&#x021D2;')"><xsl:value-of select="'\Rightarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021D2;')"/></xsl:call-template></xsl:when> <!--/Rightarrow A: implies -->
+ <xsl:when test="starts-with($content,'&#x021D3;')"><xsl:value-of select="'\Downarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021D3;')"/></xsl:call-template></xsl:when> <!--/Downarrow A: down dbl arrow -->
+-<!-- <xsl:when test="starts-with($content,'&#x021D4;')"><xsl:value-of select="'\Leftrightarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021D4;')"/></xsl:call-template></xsl:when> /Leftrightarrow A: l&r dbl arrow -->
+- <xsl:when test="starts-with($content,'&#x021D4;')"><xsl:value-of select="'\iff '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021D4;')"/></xsl:call-template></xsl:when> <!--/iff if and only if -->
++ <xsl:when test="starts-with($content,'&#x021D4;')"><xsl:value-of select="'\Leftrightarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021D4;')"/></xsl:call-template></xsl:when> <!--/Leftrightarrow A: l&r dbl arrow -->
++<!-- <xsl:when test="starts-with($content,'&#x021D4;')"><xsl:value-of select="'\iff '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021D4;')"/></xsl:call-template></xsl:when> /iff if and only if -->
+ <xsl:when test="starts-with($content,'&#x021D5;')"><xsl:value-of select="'\Updownarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021D5;')"/></xsl:call-template></xsl:when> <!--/Updownarrow A: up&down dbl arrow -->
+ <xsl:when test="starts-with($content,'&#x021DA;')"><xsl:value-of select="'\Lleftarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021DA;')"/></xsl:call-template></xsl:when> <!--/Lleftarrow A: left triple arrow --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x021DB;')"><xsl:value-of select="'\Rrightarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021DB;')"/></xsl:call-template></xsl:when> <!--/Rrightarrow A: right triple arrow --> <!-- Required amssymb -->
+-
++<xsl:when test="starts-with($content,'&#x021DD;')"><xsl:value-of select="'\rightsquigarrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021DD;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x021F5;')"><xsl:value-of select="'\DownArrowUpArrow '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021F5;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x021FD;')"><xsl:value-of select="'\leftarrowtriangle '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021FD;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x021FE;')"><xsl:value-of select="'\rightarrowtriangle '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021FE;')"/></xsl:call-template></xsl:when>
++<xsl:when test="starts-with($content,'&#x021FF;')"><xsl:value-of select="'\leftrightarrowtria* '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x021FF;')"/></xsl:call-template></xsl:when>
+ <!-- ====================================================================== -->
+ <!-- Unicode 3.2
+ Mathematical Operators
+@@ -224,7 +626,6 @@
+ <xsl:when test="starts-with($content,'&#x02204;')"><xsl:value-of select="'\nexists '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02204;')"/></xsl:call-template></xsl:when> <!--/nexists - negated exists --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02205;&#x0FE00;')"><xsl:value-of select="'\emptyset '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02205;&#x0FE00;')"/></xsl:call-template></xsl:when> <!--/emptyset - zero, slash -->
+ <xsl:when test="starts-with($content,'&#x02205;')"><xsl:value-of select="'\varnothing '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02205;')"/></xsl:call-template></xsl:when> <!--/varnothing - circle, slash --> <!-- Required amssymb -->
+-<!-- <xsl:when test="starts-with($content,'&#x02206;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02206;')"/></xsl:call-template></xsl:when>-->
+ <xsl:when test="starts-with($content,'&#x02207;')"><xsl:value-of select="'\nabla '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02207;')"/></xsl:call-template></xsl:when> <!--/nabla del, Hamilton operator -->
+ <xsl:when test="starts-with($content,'&#x02208;')"><xsl:value-of select="'\in '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02208;')"/></xsl:call-template></xsl:when> <!--/in R: set membership -->
+ <xsl:when test="starts-with($content,'&#x02209;')"><xsl:value-of select="'\notin '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02209;')"/></xsl:call-template></xsl:when> <!--/notin N: negated set membership -->
+@@ -236,7 +637,6 @@
+ <xsl:when test="starts-with($content,'&#x02212;')"><xsl:value-of select="'-'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02212;')"/></xsl:call-template></xsl:when> <!--B: minus sign -->
+ <xsl:when test="starts-with($content,'&#x02213;')"><xsl:value-of select="'\mp '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02213;')"/></xsl:call-template></xsl:when> <!--/mp B: minus-or-plus sign -->
+ <xsl:when test="starts-with($content,'&#x02214;')"><xsl:value-of select="'\dotplus '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02214;')"/></xsl:call-template></xsl:when> <!--/dotplus B: plus sign, dot above --> <!-- Required amssymb -->
+-<!-- <xsl:when test="starts-with($content,'&#x02215;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02215;')"/></xsl:call-template></xsl:when>-->
+ <xsl:when test="starts-with($content,'&#x02216;')"><xsl:value-of select="'\setminus '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02216;')"/></xsl:call-template></xsl:when> <!--/setminus B: reverse solidus -->
+ <xsl:when test="starts-with($content,'&#x02217;')"><xsl:value-of select="'\ast '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02217;')"/></xsl:call-template></xsl:when> <!--low asterisk -->
+ <xsl:when test="starts-with($content,'&#x02218;')"><xsl:value-of select="'\circ '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02218;')"/></xsl:call-template></xsl:when> <!--/circ B: composite function (small circle) -->
+@@ -244,11 +644,11 @@
+ <xsl:when test="starts-with($content,'&#x0221A;')"><xsl:value-of select="'\surd '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0221A;')"/></xsl:call-template></xsl:when> <!--/surd radical -->
+ <xsl:when test="starts-with($content,'&#x0221D;')"><xsl:value-of select="'\propto '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0221D;')"/></xsl:call-template></xsl:when> <!--/propto R: is proportional to -->
+ <xsl:when test="starts-with($content,'&#x0221E;')"><xsl:value-of select="'\infty '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0221E;')"/></xsl:call-template></xsl:when> <!--/infty infinity -->
+-<!-- <xsl:when test="starts-with($content,'&#x0221F;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0221F;')"/></xsl:call-template></xsl:when> right (90 degree) angle -->
++ <xsl:when test="starts-with($content,'&#x0221F;')"><xsl:value-of select="'\rightangle '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0221F;')"/></xsl:call-template></xsl:when> <!--/right (90 degree) angle -->
+ <xsl:when test="starts-with($content,'&#x02220;')"><xsl:value-of select="'\angle '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02220;')"/></xsl:call-template></xsl:when> <!--/angle - angle -->
+ <xsl:when test="starts-with($content,'&#x02221;')"><xsl:value-of select="'\measuredangle '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02221;')"/></xsl:call-template></xsl:when> <!--/measuredangle - angle-measured --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02222;')"><xsl:value-of select="'\sphericalangle '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02222;')"/></xsl:call-template></xsl:when><!--/sphericalangle angle-spherical --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02223;')"><xsl:value-of select="'\mid '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02223;')"/></xsl:call-template></xsl:when> <!--/mid R: -->
++ <xsl:when test="starts-with($content,'&#x02223;')"><xsl:value-of select="'|'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02223;')"/></xsl:call-template></xsl:when> <!--/mid R: -->
+ <xsl:when test="starts-with($content,'&#x02224;&#x0FE00;')"><xsl:value-of select="'\nshortmid '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02224;&#x0FE00;')"/></xsl:call-template></xsl:when> <!--/nshortmid --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02224;')"><xsl:value-of select="'\nmid '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02224;')"/></xsl:call-template></xsl:when> <!--/nmid --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02225;')"><xsl:value-of select="'\parallel '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02225;')"/></xsl:call-template></xsl:when> <!--/parallel R: parallel -->
+@@ -262,95 +662,104 @@
+ <xsl:when test="starts-with($content,'&#x0222C;')"><xsl:value-of select="'\iint '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0222C;')"/></xsl:call-template></xsl:when> <!--double integral operator --> <!-- Required amsmath -->
+ <xsl:when test="starts-with($content,'&#x0222D;')"><xsl:value-of select="'\iiint '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0222D;')"/></xsl:call-template></xsl:when> <!--/iiint triple integral operator --> <!-- Required amsmath -->
+ <xsl:when test="starts-with($content,'&#x0222E;')"><xsl:value-of select="'\oint '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0222E;')"/></xsl:call-template></xsl:when> <!--/oint L: contour integral operator -->
+-<!-- <xsl:when test="starts-with($content,'&#x0222F;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0222F;')"/></xsl:call-template></xsl:when>-->
+-<!-- <xsl:when test="starts-with($content,'&#x02230;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02230;')"/></xsl:call-template></xsl:when>-->
+-<!-- <xsl:when test="starts-with($content,'&#x02231;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02231;')"/></xsl:call-template></xsl:when>-->
+-<!-- <xsl:when test="starts-with($content,'&#x02232;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02232;')"/></xsl:call-template></xsl:when>-->
+-<!-- <xsl:when test="starts-with($content,'&#x02233;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02233;')"/></xsl:call-template></xsl:when>-->
++ <xsl:when test="starts-with($content,'&#x0222F;')"><xsl:value-of select="'\backslash oiint '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0222F;')"/></xsl:call-template></xsl:when> <!-- \surfintegral -->
++ <xsl:when test="starts-with($content,'&#x02230;')"><xsl:value-of select="'\backslash oiiint '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02230;')"/></xsl:call-template></xsl:when> <!-- \volintegral -->
++ <xsl:when test="starts-with($content,'&#x02231;')"><xsl:value-of select="'\clwintegral '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02231;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02232;')"><xsl:value-of select="'\ElsevierGlyph{2232}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02232;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02233;')"><xsl:value-of select="'\ElsevierGlyph{2233}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02233;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02234;')"><xsl:value-of select="'\therefore '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02234;')"/></xsl:call-template></xsl:when> <!--/therefore R: therefore --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02235;')"><xsl:value-of select="'\because '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02235;')"/></xsl:call-template></xsl:when> <!--/because R: because --> <!-- Required amssymb -->
+ <!-- ? --> <xsl:when test="starts-with($content,'&#x02236;')"><xsl:value-of select="':'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02236;')"/></xsl:call-template></xsl:when> <!--/ratio -->
+-<!-- ? --> <xsl:when test="starts-with($content,'&#x02237;')"><xsl:value-of select="'\colon\colon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02237;')"/></xsl:call-template></xsl:when> <!--/Colon, two colons -->
+-<!-- ? --> <xsl:when test="starts-with($content,'&#x02238;')"><xsl:value-of select="'\dot{-}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02238;')"/></xsl:call-template></xsl:when> <!--/dotminus B: minus sign, dot above -->
++ <xsl:when test="starts-with($content,'&#x02237;')"><xsl:value-of select="'\Colon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02237;')"/></xsl:call-template></xsl:when> <!--/Colon, two colons -->
++ <xsl:when test="starts-with($content,'&#x02238;')"><xsl:value-of select="'\dotminus '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02238;')"/></xsl:call-template></xsl:when> <!--/dotminus B: minus sign, dot above -->
+ <!-- <xsl:when test="starts-with($content,'&#x02239;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02239;')"/></xsl:call-template></xsl:when> -->
+-<!-- <xsl:when test="starts-with($content,'&#x0223A;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0223A;')"/></xsl:call-template></xsl:when> minus with four dots, geometric properties -->
+-<!-- <xsl:when test="starts-with($content,'&#x0223B;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0223B;')"/></xsl:call-template></xsl:when> homothetic -->
++ <xsl:when test="starts-with($content,'&#x0223A;')"><xsl:value-of select="'\mathbin{{:}\!\!{-}\!\!{:}}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0223A;')"/></xsl:call-template></xsl:when> <!-- minus with four dots, geometric properties -->
++ <xsl:when test="starts-with($content,'&#x0223B;')"><xsl:value-of select="'\kernelcontraction '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0223B;')"/></xsl:call-template></xsl:when> <!-- homothetic -->
+ <xsl:when test="starts-with($content,'&#x0223C;')"><xsl:value-of select="'\sim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0223C;')"/></xsl:call-template></xsl:when> <!--/sim R: similar -->
+ <xsl:when test="starts-with($content,'&#x0223D;')"><xsl:value-of select="'\backsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0223D;')"/></xsl:call-template></xsl:when> <!--/backsim R: reverse similar --> <!-- Required amssymb -->
+-<!-- <xsl:when test="starts-with($content,'&#x0223E;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0223E;')"/></xsl:call-template></xsl:when> most positive -->
++ <xsl:when test="starts-with($content,'&#x0223E;')"><xsl:value-of select="'\lazysinv '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0223E;')"/></xsl:call-template></xsl:when> <!-- most positive -->
+ <!-- <xsl:when test="starts-with($content,'&#x0223F;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0223F;')"/></xsl:call-template></xsl:when> ac current -->
+ <xsl:when test="starts-with($content,'&#x02240;')"><xsl:value-of select="'\wr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02240;')"/></xsl:call-template></xsl:when> <!--/wr B: wreath product -->
+ <xsl:when test="starts-with($content,'&#x02241;')"><xsl:value-of select="'\nsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02241;')"/></xsl:call-template></xsl:when> <!--/nsim N: not similar --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02242;&#x00338;')"><xsl:value-of select="'\neqsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02242;&#x00338;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02242;')"><xsl:value-of select="'\eqsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02242;')"/></xsl:call-template></xsl:when> <!--/esim R: equals, similar --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02243;')"><xsl:value-of select="'\simeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02243;')"/></xsl:call-template></xsl:when> <!--/simeq R: similar, equals -->
+- <xsl:when test="starts-with($content,'&#x02244;')"><xsl:value-of select="'\not\simeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02244;')"/></xsl:call-template></xsl:when> <!--/nsimeq N: not similar, equals -->
++ <xsl:when test="starts-with($content,'&#x02244;')"><xsl:value-of select="'\nsime '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02244;')"/></xsl:call-template></xsl:when> <!--/nsimeq N: not similar, equals -->
+ <xsl:when test="starts-with($content,'&#x02245;')"><xsl:value-of select="'\cong '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02245;')"/></xsl:call-template></xsl:when> <!--/cong R: congruent with -->
+-<!-- <xsl:when test="starts-with($content,'&#x02246;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02246;')"/></xsl:call-template></xsl:when> similar, not equals -->
++ <xsl:when test="starts-with($content,'&#x02246;')"><xsl:value-of select="'\approxnotequal '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02246;')"/></xsl:call-template></xsl:when><!-- similar, not equals -->
+ <xsl:when test="starts-with($content,'&#x02247;')"><xsl:value-of select="'\ncong '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02247;')"/></xsl:call-template></xsl:when> <!--/ncong N: not congruent with --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02248;')"><xsl:value-of select="'\approx '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02248;')"/></xsl:call-template></xsl:when> <!--/approx R: approximate -->
++ <xsl:when test="starts-with($content,'&#x02248;')"><xsl:value-of select="'\approx '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02248;')"/></xsl:call-template></xsl:when> <!--/approx R: approximate -->
+ <!-- <xsl:when test="starts-with($content,'&#x02249;&#x00338;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02249;&#x00338;')"/></xsl:call-template></xsl:when> not, vert, approximate -->
+- <xsl:when test="starts-with($content,'&#x02249;')"><xsl:value-of select="'\not\approx '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02249;')"/></xsl:call-template></xsl:when> <!--/napprox N: not approximate -->
++ <xsl:when test="starts-with($content,'&#x02249;')"><xsl:value-of select="'\napprox '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02249;')"/></xsl:call-template></xsl:when> <!--/napprox N: not approximate -->
+ <xsl:when test="starts-with($content,'&#x0224A;')"><xsl:value-of select="'\approxeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224A;')"/></xsl:call-template></xsl:when> <!--/approxeq R: approximate, equals --> <!-- Required amssymb -->
+-<!-- <xsl:when test="starts-with($content,'&#x0224B;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224B;')"/></xsl:call-template></xsl:when> approximately identical to -->
+-<!-- <xsl:when test="starts-with($content,'&#x0224C;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224C;')"/></xsl:call-template></xsl:when> /backcong R: reverse congruent -->
++ <xsl:when test="starts-with($content,'&#x0224B;&#x00338;')"><xsl:value-of select="'\not\apid '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224B;&#x00338;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0224B;')"><xsl:value-of select="'\tildetrpl '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224B;')"/></xsl:call-template></xsl:when> <!-- approximately identical to -->
++ <xsl:when test="starts-with($content,'&#x0224C;')"><xsl:value-of select="'\allequal '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224C;')"/></xsl:call-template></xsl:when> <!-- /backcong R: reverse congruent -->
+ <xsl:when test="starts-with($content,'&#x0224D;')"><xsl:value-of select="'\asymp '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224D;')"/></xsl:call-template></xsl:when> <!--/asymp R: asymptotically equal to -->
+- <xsl:when test="starts-with($content,'&#x0224E;')"><xsl:value-of select="'\Bumpeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224E;')"/></xsl:call-template></xsl:when> <!--/Bumpeq R: bumpy equals --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x0224F;')"><xsl:value-of select="'\bumpeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224F;')"/></xsl:call-template></xsl:when> <!--/bumpeq R: bumpy equals, equals --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x0224E;&#x00338;')"><xsl:value-of select="'\nBumpeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224E;&#x00338;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0224E;')"><xsl:value-of select="'\Bumpeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224E;')"/></xsl:call-template></xsl:when> <!--/Bumpeq R: bumpy equals --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x0224F;&#x00338;')"><xsl:value-of select="'\nbumpeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224F;&#x00338;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0224F;')"><xsl:value-of select="'\bumpeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0224F;')"/></xsl:call-template></xsl:when> <!--/bumpeq R: bumpy equals, equals --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02250;&#x00338;')"><xsl:value-of select="'\not\doteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02250;&#x00338;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02250;')"><xsl:value-of select="'\doteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02250;')"/></xsl:call-template></xsl:when> <!--/doteq R: equals, single dot above -->
+- <xsl:when test="starts-with($content,'&#x02251;')"><xsl:value-of select="'\doteqdot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02251;')"/></xsl:call-template></xsl:when> <!--/doteqdot /Doteq R: eq, even dots --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02252;')"><xsl:value-of select="'\fallingdotseq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02252;')"/></xsl:call-template></xsl:when> <!--/fallingdotseq R: eq, falling dots --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02251;')"><xsl:value-of select="'\Doteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02251;')"/></xsl:call-template></xsl:when> <!--/doteqdot /Doteq R: eq, even dots --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02252;')"><xsl:value-of select="'\fallingdotseq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02252;')"/></xsl:call-template></xsl:when><!--/fallingdotseq R: eq, falling dots --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02253;')"><xsl:value-of select="'\risingdotseq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02253;')"/></xsl:call-template></xsl:when> <!--/risingdotseq R: eq, rising dots --> <!-- Required amssymb -->
+-<!-- <xsl:when test="starts-with($content,'&#x02254;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02254;')"/></xsl:call-template></xsl:when> /coloneq R: colon, equals -->
+-<!-- <xsl:when test="starts-with($content,'&#x02255;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02255;')"/></xsl:call-template></xsl:when> /eqcolon R: equals, colon -->
+- <xsl:when test="starts-with($content,'&#x02256;')"><xsl:value-of select="'\eqcirc '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02256;')"/></xsl:call-template></xsl:when> <!--/eqcirc R: circle on equals sign --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02257;')"><xsl:value-of select="'\circeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02257;')"/></xsl:call-template></xsl:when> <!--/circeq R: circle, equals --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02254;')"><xsl:value-of select="'\coloneq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02254;')"/></xsl:call-template></xsl:when> <!--/coloneq R: colon, equals -->
++ <xsl:when test="starts-with($content,'&#x02255;')"><xsl:value-of select="'\eqcolon '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02255;')"/></xsl:call-template></xsl:when> <!--/eqcolon R: equals, colon -->
++ <xsl:when test="starts-with($content,'&#x02256;')"><xsl:value-of select="'\eqcirc '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02256;')"/></xsl:call-template></xsl:when> <!--/eqcirc R: circle on equals sign --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02257;')"><xsl:value-of select="'\circeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02257;')"/></xsl:call-template></xsl:when> <!--/circeq R: circle, equals --> <!-- Required amssymb -->
+ <!-- ? --> <xsl:when test="starts-with($content,'&#x02258;')"><xsl:value-of select="'\stackrel{\frown}{=}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02258;')"/></xsl:call-template></xsl:when>
+-<!-- ? --> <xsl:when test="starts-with($content,'&#x02259;')"><xsl:value-of select="'\stackrel{\wedge}{=}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02259;')"/></xsl:call-template></xsl:when> <!--/wedgeq R: corresponds to (wedge, equals) -->
+-<!-- ? --> <xsl:when test="starts-with($content,'&#x0225A;')"><xsl:value-of select="'\stackrel{\vee}{=}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0225A;')"/></xsl:call-template></xsl:when> <!--logical or, equals -->
+-<!-- ? --> <xsl:when test="starts-with($content,'&#x0225B;')"><xsl:value-of select="'\stackrel{\star}{=}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0225B;')"/></xsl:call-template></xsl:when> <!--equal, asterisk above -->
++ <xsl:when test="starts-with($content,'&#x02259;')"><xsl:value-of select="'\wedgeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02259;')"/></xsl:call-template></xsl:when> <!--/wedgeq R: corresponds to (wedge, equals) -->
++ <xsl:when test="starts-with($content,'&#x0225A;')"><xsl:value-of select="'\ElsevierGlyph{225A}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0225A;')"/></xsl:call-template></xsl:when> <!--logical or, equals -->
++ <xsl:when test="starts-with($content,'&#x0225B;')"><xsl:value-of select="'\starequal '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0225B;')"/></xsl:call-template></xsl:when> <!--equal, asterisk above -->
+ <xsl:when test="starts-with($content,'&#x0225C;')"><xsl:value-of select="'\triangleq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0225C;')"/></xsl:call-template></xsl:when> <!--/triangleq R: triangle, equals --> <!-- Required amssymb -->
+ <!-- ? --> <xsl:when test="starts-with($content,'&#x0225D;')"><xsl:value-of select="'\stackrel{\scriptscriptstyle\mathrm{def}}{=}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0225D;')"/></xsl:call-template></xsl:when>
+ <!-- ? --> <xsl:when test="starts-with($content,'&#x0225E;')"><xsl:value-of select="'\stackrel{\scriptscriptstyle\mathrm{m}}{=}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0225E;')"/></xsl:call-template></xsl:when>
+-<!-- ? --> <xsl:when test="starts-with($content,'&#x0225F;')"><xsl:value-of select="'\stackrel{?}{=}'" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0225F;')"/></xsl:call-template></xsl:when> <!--/questeq R: equal with questionmark -->
++ <xsl:when test="starts-with($content,'&#x0225F;')"><xsl:value-of select="'\questeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0225F;')"/></xsl:call-template></xsl:when> <!--/questeq R: equal with questionmark -->
+ <!-- <xsl:when test="starts-with($content,'&#x02260;&#x0FE00;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02260;&#x0FE00;')"/></xsl:call-template></xsl:when> not equal, dot -->
+ <xsl:when test="starts-with($content,'&#x02260;')"><xsl:value-of select="'\ne '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02260;')"/></xsl:call-template></xsl:when> <!--/ne /neq R: not equal -->
+ <!-- <xsl:when test="starts-with($content,'&#x02261;&#x020E5;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02261;&#x020E5;')"/></xsl:call-template></xsl:when> reverse not equivalent -->
+ <xsl:when test="starts-with($content,'&#x02261;')"><xsl:value-of select="'\equiv '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02261;')"/></xsl:call-template></xsl:when> <!--/equiv R: identical with -->
+- <xsl:when test="starts-with($content,'&#x02262;')"><xsl:value-of select="'\not\equiv '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02262;')"/></xsl:call-template></xsl:when> <!--/nequiv N: not identical with -->
++ <xsl:when test="starts-with($content,'&#x02262;')"><xsl:value-of select="'\nequiv '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02262;')"/></xsl:call-template></xsl:when> <!--/nequiv N: not identical with -->
+ <!-- <xsl:when test="starts-with($content,'&#x02263;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02263;')"/></xsl:call-template></xsl:when> -->
+ <xsl:when test="starts-with($content,'&#x02264;')"><xsl:value-of select="'\le '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02264;')"/></xsl:call-template></xsl:when> <!--/leq /le R: less-than-or-equal -->
+ <xsl:when test="starts-with($content,'&#x02265;')"><xsl:value-of select="'\ge '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02265;')"/></xsl:call-template></xsl:when> <!--/geq /ge R: greater-than-or-equal -->
+ <xsl:when test="starts-with($content,'&#x02266;')"><xsl:value-of select="'\leqq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02266;')"/></xsl:call-template></xsl:when> <!--/leqq R: less, double equals --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02267;')"><xsl:value-of select="'\geqq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02267;')"/></xsl:call-template></xsl:when> <!--/geqq R: greater, double equals --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02268;&#x0FE00;')"><xsl:value-of select="'\lvertneqq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02268;&#x0FE00;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02268;')"><xsl:value-of select="'\lneqq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02268;')"/></xsl:call-template></xsl:when> <!--/lneqq N: less, not double equals --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02269;&#x0FE00;')"><xsl:value-of select="'\gvertneqq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02269;&#x0FE00;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02269;')"><xsl:value-of select="'\gneqq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02269;')"/></xsl:call-template></xsl:when> <!--/gneqq N: greater, not dbl equals --> <!-- Required amssymb -->
+ <!-- <xsl:when test="starts-with($content,'&#x0226A;&#x00338;&#x0FE00;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226A;&#x00338;&#x0FE00;')"/></xsl:call-template></xsl:when> not much less than, variant -->
+-<!-- <xsl:when test="starts-with($content,'&#x0226A;&#x00338;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226A;&#x00338;')"/></xsl:call-template></xsl:when> not, vert, much less than -->
++ <xsl:when test="starts-with($content,'&#x0226A;&#x00338;')"><xsl:value-of select="'\NotLessLess '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226A;&#x00338;')"/></xsl:call-template></xsl:when> <!-- not, vert, much less than -->
+ <xsl:when test="starts-with($content,'&#x0226A;')"><xsl:value-of select="'\ll '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226A;')"/></xsl:call-template></xsl:when> <!--/ll R: double less-than sign -->
+ <!-- <xsl:when test="starts-with($content,'&#x0226B;&#x00338;&#x0FE00;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226B;&#x00338;&#x0FE00;')"/></xsl:call-template></xsl:when> not much greater than, variant -->
+-<!-- <xsl:when test="starts-with($content,'&#x0226B;&#x00338;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226B;&#x00338;')"/></xsl:call-template></xsl:when> not, vert, much greater than -->
++ <xsl:when test="starts-with($content,'&#x0226B;&#x00338;')"><xsl:value-of select="'\NotGreaterGreater '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226B;&#x00338;')"/></xsl:call-template></xsl:when> <!-- not, vert, much greater than -->
+ <xsl:when test="starts-with($content,'&#x0226B;')"><xsl:value-of select="'\gg '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226B;')"/></xsl:call-template></xsl:when> <!--/gg R: dbl greater-than sign -->
+ <xsl:when test="starts-with($content,'&#x0226C;')"><xsl:value-of select="'\between '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226C;')"/></xsl:call-template></xsl:when> <!--/between R: between --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x0226D;')"><xsl:value-of select="'\not\asymp '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226D;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0226D;')"><xsl:value-of select="'\not\kern-0.3em\times '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226D;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0226E;')"><xsl:value-of select="'\nless '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226E;')"/></xsl:call-template></xsl:when> <!--/nless N: not less-than --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x0226F;')"><xsl:value-of select="'\ngtr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0226F;')"/></xsl:call-template></xsl:when> <!--/ngtr N: not greater-than --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02270;&#x020E5;')"><xsl:value-of select="'\nleq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02270;&#x020E5;')"/></xsl:call-template></xsl:when> <!--/nleq N: not less-than-or-equal --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02270;')"><xsl:value-of select="'\nleqq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02270;')"/></xsl:call-template></xsl:when> <!--/nleqq N: not less, dbl equals --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02271;&#x020E5;')"><xsl:value-of select="'\ngeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02271;&#x020E5;')"/></xsl:call-template></xsl:when> <!--/ngeq N: not greater-than-or-equal --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02271;')"><xsl:value-of select="'\ngeqq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02271;')"/></xsl:call-template></xsl:when> <!--/ngeqq N: not greater, dbl equals --> <!-- Required amssymb -->
++<!-- <xsl:when test="starts-with($content,'&#x02270;&#x020E5;')"><xsl:value-of select="'\nleq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02270;&#x020E5;')"/></xsl:call-template></xsl:when> /nleq N: not less-than-or-equal --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02270;')"><xsl:value-of select="'\nleq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02270;')"/></xsl:call-template></xsl:when> <!--/nleqq N: not less, dbl equals --> <!-- Required amssymb -->
++<!-- <xsl:when test="starts-with($content,'&#x02271;&#x020E5;')"><xsl:value-of select="'\ngeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02271;&#x020E5;')"/></xsl:call-template></xsl:when> /ngeq N: not greater-than-or-equal --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02271;')"><xsl:value-of select="'\ngeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02271;')"/></xsl:call-template></xsl:when> <!--/ngeqq N: not greater, dbl equals --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02272;')"><xsl:value-of select="'\lesssim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02272;')"/></xsl:call-template></xsl:when> <!--/lesssim R: less, similar --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02273;')"><xsl:value-of select="'\gtrsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02273;')"/></xsl:call-template></xsl:when> <!--/gtrsim R: greater, similar --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02274;')"><xsl:value-of select="'\not\lesssim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02274;')"/></xsl:call-template></xsl:when> <!--not less, similar --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02275;')"><xsl:value-of select="'\not\gtrsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02275;')"/></xsl:call-template></xsl:when> <!--not greater, similar --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02274;')"><xsl:value-of select="'\ElsevierGlyph{2274} '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02274;')"/></xsl:call-template></xsl:when> <!--not less, similar --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02275;')"><xsl:value-of select="'\ElsevierGlyph{2275} '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02275;')"/></xsl:call-template></xsl:when> <!--not greater, similar --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02276;')"><xsl:value-of select="'\lessgtr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02276;')"/></xsl:call-template></xsl:when> <!--/lessgtr R: less, greater --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02277;')"><xsl:value-of select="'\gtrless '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02277;')"/></xsl:call-template></xsl:when> <!--/gtrless R: greater, less --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02278;')"><xsl:value-of select="'\not\lessgtr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02278;')"/></xsl:call-template></xsl:when> <!--not less, greater --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x02279;')"><xsl:value-of select="'\not\gtrless '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02279;')"/></xsl:call-template></xsl:when> <!--not greater, less --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02278;')"><xsl:value-of select="'\notlessgreater '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02278;')"/></xsl:call-template></xsl:when> <!--not less, greater --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x02279;')"><xsl:value-of select="'\notgreaterless '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02279;')"/></xsl:call-template></xsl:when> <!--not greater, less --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x0227A;')"><xsl:value-of select="'\prec '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0227A;')"/></xsl:call-template></xsl:when> <!--/prec R: precedes -->
+ <xsl:when test="starts-with($content,'&#x0227B;')"><xsl:value-of select="'\succ '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0227B;')"/></xsl:call-template></xsl:when> <!--/succ R: succeeds -->
+ <xsl:when test="starts-with($content,'&#x0227C;')"><xsl:value-of select="'\preccurlyeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0227C;')"/></xsl:call-template></xsl:when> <!--/preccurlyeq R: precedes, curly eq --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x0227D;')"><xsl:value-of select="'\succcurlyeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0227D;')"/></xsl:call-template></xsl:when> <!--/succcurlyeq R: succeeds, curly eq --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x0227E;&#x00338;')"><xsl:value-of select="'\nprecsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0227E;&#x00338;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0227E;')"><xsl:value-of select="'\precsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0227E;')"/></xsl:call-template></xsl:when> <!--/precsim R: precedes, similar --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x0227F;&#x00338;')"><xsl:value-of select="'\nsuccsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0227F;&#x00338;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0227F;')"><xsl:value-of select="'\succsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0227F;')"/></xsl:call-template></xsl:when> <!--/succsim R: succeeds, similar --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02280;')"><xsl:value-of select="'\nprec '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02280;')"/></xsl:call-template></xsl:when> <!--/nprec N: not precedes --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x02281;')"><xsl:value-of select="'\nsucc '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02281;')"/></xsl:call-template></xsl:when> <!--/nsucc N: not succeeds --> <!-- Required amssymb -->
+@@ -360,21 +769,59 @@
+ <xsl:when test="starts-with($content,'&#x02285;')"><xsl:value-of select="'\not\supset '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02285;')"/></xsl:call-template></xsl:when> <!--not superset -->
+ <xsl:when test="starts-with($content,'&#x02286;')"><xsl:value-of select="'\subseteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02286;')"/></xsl:call-template></xsl:when> <!--/subseteq R: subset, equals -->
+ <xsl:when test="starts-with($content,'&#x02287;')"><xsl:value-of select="'\supseteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02287;')"/></xsl:call-template></xsl:when> <!--/supseteq R: superset, equals -->
++ <xsl:when test="starts-with($content,'&#x02288;')"><xsl:value-of select="'\nsubseteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02288;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02289;')"><xsl:value-of select="'\nsupseteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02289;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0228A;&#x0FE00;')"><xsl:value-of select="'\varsubsetneqq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0228A;&#x0FE00;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0228A;')"><xsl:value-of select="'\subsetneq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0228A;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0228B;&#x0FE00;')"><xsl:value-of select="'\varsupsetneq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0228B;&#x0FE00;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0228B;')"><xsl:value-of select="'\supsetneq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0228B;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0228D;')"><xsl:value-of select="'\cupdot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0228D;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0228E;')"><xsl:value-of select="'\uplus '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0228E;')"/></xsl:call-template></xsl:when> <!--/uplus B: plus sign in union -->
++ <xsl:when test="starts-with($content,'&#x0228F;&#x00338;')"><xsl:value-of select="'\NotSquareSubset '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0228F;&#x00338;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0228F;')"><xsl:value-of select="'\sqsubset '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0228F;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02290;&#x00338;')"><xsl:value-of select="'\NotSquareSuperset '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02290;&#x00338;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02290;')"><xsl:value-of select="'\sqsupset '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02290;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02291;')"><xsl:value-of select="'\sqsubseteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02291;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x02292;')"><xsl:value-of select="'\sqsupseteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02292;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x02293;')"><xsl:value-of select="'\sqcap '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02293;')"/></xsl:call-template></xsl:when> <!--/sqcap B: square intersection -->
+- <xsl:when test="starts-with($content,'&#x02294;')"><xsl:value-of select="'\bigsqcup '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02294;')"/></xsl:call-template></xsl:when> <!--/sqcup B: square union -->
++ <xsl:when test="starts-with($content,'&#x02294;')"><xsl:value-of select="'\sqcup '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02294;')"/></xsl:call-template></xsl:when> <!--/sqcup B: square union -->
+ <xsl:when test="starts-with($content,'&#x02295;')"><xsl:value-of select="'\oplus '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02295;')"/></xsl:call-template></xsl:when> <!--/oplus B: plus sign in circle -->
+ <xsl:when test="starts-with($content,'&#x02296;')"><xsl:value-of select="'\ominus '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02296;')"/></xsl:call-template></xsl:when> <!--/ominus B: minus sign in circle -->
+ <xsl:when test="starts-with($content,'&#x02297;')"><xsl:value-of select="'\otimes '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02297;')"/></xsl:call-template></xsl:when> <!--/otimes B: multiply sign in circle -->
+ <xsl:when test="starts-with($content,'&#x02298;')"><xsl:value-of select="'\oslash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02298;')"/></xsl:call-template></xsl:when> <!--/oslash B: solidus in circle -->
+-<!-- ? --> <xsl:when test="starts-with($content,'&#x02299;')"><xsl:value-of select="'\odot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02299;')"/></xsl:call-template></xsl:when> <!--/odot B: middle dot in circle --> <!--/bigodot L: circle dot operator -->
++ <xsl:when test="starts-with($content,'&#x02299;')"><xsl:value-of select="'\odot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x02299;')"/></xsl:call-template></xsl:when> <!--/odot B: middle dot in circle --> <!--/bigodot L: circle dot operator -->
++ <xsl:when test="starts-with($content,'&#x0229A;')"><xsl:value-of select="'\circledcirc '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0229A;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0229B;')"><xsl:value-of select="'\circledast '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0229B;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0229D;')"><xsl:value-of select="'\circleddash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0229D;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x0229E;')"><xsl:value-of select="'\boxplus '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0229E;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x0229F;')"><xsl:value-of select="'\boxminus '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x0229F;')"/></xsl:call-template></xsl:when> <!--/boxminus B: minus sign in box --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x022A0;')"><xsl:value-of select="'\boxtimes '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A0;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022A1;')"><xsl:value-of select="'\boxdot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A1;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022A2;')"><xsl:value-of select="'\vdash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A2;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022A3;')"><xsl:value-of select="'\dashv '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A3;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x022A4;')"><xsl:value-of select="'\top '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A4;')"/></xsl:call-template></xsl:when> <!--/top top -->
+ <xsl:when test="starts-with($content,'&#x022A5;')"><xsl:value-of select="'\perp '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A5;')"/></xsl:call-template></xsl:when> <!--/perp R: perpendicular --><!--/bot bottom -->
+- <xsl:when test="starts-with($content,'&#x022A6;')"><xsl:value-of select="'\vdash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A6;')"/></xsl:call-template></xsl:when> <!--/vdash R: vertical, dash -->
+- <xsl:when test="starts-with($content,'&#x022A7;')"><xsl:value-of select="'\vDash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A7;')"/></xsl:call-template></xsl:when> <!--/vDash R: vertical, dbl dash --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x022A8;')"><xsl:value-of select="'\models '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A8;')"/></xsl:call-template></xsl:when> <!--/models R: -->
++<!-- <xsl:when test="starts-with($content,'&#x022A6;')"><xsl:value-of select="'\vdash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A6;')"/></xsl:call-template></xsl:when> /vdash R: vertical, dash -->
++ <xsl:when test="starts-with($content,'&#x022A7;')"><xsl:value-of select="'\models '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A7;')"/></xsl:call-template></xsl:when> <!--/vDash R: vertical, dbl dash --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x022A8;')"><xsl:value-of select="'\vDash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A8;')"/></xsl:call-template></xsl:when> <!--/models R: -->
++ <xsl:when test="starts-with($content,'&#x022A9;')"><xsl:value-of select="'\Vdash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022A9;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x022AA;')"><xsl:value-of select="'\Vvdash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022AA;')"/></xsl:call-template></xsl:when> <!--/Vvdash R: triple vertical, dash --> <!-- Required amssymb -->
++ <xsl:when test="starts-with($content,'&#x022AB;')"><xsl:value-of select="'\VDash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022AB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022AC;')"><xsl:value-of select="'\nvdash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022AC;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022AD;')"><xsl:value-of select="'\nvDash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022AD;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022AE;')"><xsl:value-of select="'\nVdash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022AE;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022AF;')"><xsl:value-of select="'\nVDash '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022AF;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022B2;')"><xsl:value-of select="'\vartriangleleft '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022B2;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022B3;')"><xsl:value-of select="'\vartriangleright '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022B3;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022B4;')"><xsl:value-of select="'\trianglelefteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022B4;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022B5;')"><xsl:value-of select="'\trianglerighteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022B5;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022B6;')"><xsl:value-of select="'\original '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022B6;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022B7;')"><xsl:value-of select="'\image '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022B7;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022B8;')"><xsl:value-of select="'\multimap '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022B8;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022B9;')"><xsl:value-of select="'\hermitconjmatrix '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022B9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022BA;')"><xsl:value-of select="'\intercal '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022BA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022BB;')"><xsl:value-of select="'\veebar '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022BB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022BE;')"><xsl:value-of select="'\rightanglearc '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022BE;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x022C0;')"><xsl:value-of select="'\bigwedge '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022C0;')"/></xsl:call-template></xsl:when> <!--/bigwedge L: logical or operator -->
+ <xsl:when test="starts-with($content,'&#x022C1;')"><xsl:value-of select="'\bigvee '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022C1;')"/></xsl:call-template></xsl:when> <!--/bigcap L: intersection operator -->
+ <xsl:when test="starts-with($content,'&#x022C2;')"><xsl:value-of select="'\bigcap '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022C2;')"/></xsl:call-template></xsl:when> <!--/bigvee L: logical and operator -->
+@@ -384,11 +831,41 @@
+ <xsl:when test="starts-with($content,'&#x022C6;')"><xsl:value-of select="'\star '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022C6;')"/></xsl:call-template></xsl:when> <!--/star B: small star, filled -->
+ <xsl:when test="starts-with($content,'&#x022C7;')"><xsl:value-of select="'\divideontimes '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022C7;')"/></xsl:call-template></xsl:when> <!--/divideontimes B: division on times --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x022C8;')"><xsl:value-of select="'\bowtie '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022C8;')"/></xsl:call-template></xsl:when> <!--/bowtie R: -->
++ <xsl:when test="starts-with($content,'&#x022C9;')"><xsl:value-of select="'\ltimes '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022C9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022CA;')"><xsl:value-of select="'\rtimes '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022CA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022CB;')"><xsl:value-of select="'\leftthreetimes '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022CB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022CC;')"><xsl:value-of select="'\rightthreetimes '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022CC;')"/></xsl:call-template></xsl:when>
+ <xsl:when test="starts-with($content,'&#x022CD;')"><xsl:value-of select="'\backsimeq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022CD;')"/></xsl:call-template></xsl:when> <!--/backsimeq R: reverse similar, eq --> <!-- Required amssymb -->
+- <xsl:when test="starts-with($content,'&#x022EF;')"><xsl:value-of select="'\cdots '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022EF;')"/></xsl:call-template></xsl:when> <!--/cdots, three dots, centered -->
+-<!-- <xsl:when test="starts-with($content,'&#x022F0;')"><xsl:value-of select="' '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022F0;')"/></xsl:call-template></xsl:when> three dots, ascending -->
+- <xsl:when test="starts-with($content,'&#x022F1;')"><xsl:value-of select="'\ddots '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022F1;')"/></xsl:call-template></xsl:when> <!--/ddots, three dots, descending -->
+-
++ <xsl:when test="starts-with($content,'&#x022CE;')"><xsl:value-of select="'\curlyvee '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022CE;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022CF;')"><xsl:value-of select="'\curlywedge '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022CF;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022D0;')"><xsl:value-of select="'\Subset '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022D0;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022D1;')"><xsl:value-of select="'\Supset '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022D1;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022D2;')"><xsl:value-of select="'\Cap '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022D2;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022D3;')"><xsl:value-of select="'\Cup '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022D3;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022D4;')"><xsl:value-of select="'\pitchfork '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022D4;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022D6;')"><xsl:value-of select="'\lessdot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022D6;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022D7;')"><xsl:value-of select="'\gtrdot '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022D7;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022D8;')"><xsl:value-of select="'\verymuchless '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022D8;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022D9;')"><xsl:value-of select="'\ggg '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022D9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022DA;')"><xsl:value-of select="'\lesseqgtr '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022DA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022DB;')"><xsl:value-of select="'\gtreqless '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022DB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022DE;')"><xsl:value-of select="'\curlyeqprec '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022DE;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022DF;')"><xsl:value-of select="'\curlyeqsucc '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022DF;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022E2;')"><xsl:value-of select="'\not\sqsubseteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022E2;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022E3;')"><xsl:value-of select="'\not\sqsupseteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022E3;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022E5;')"><xsl:value-of select="'\Elzsqspne '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022E5;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022E6;')"><xsl:value-of select="'\lnsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022E6;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022E7;')"><xsl:value-of select="'\gnsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022E7;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022E8;')"><xsl:value-of select="'\precnsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022E8;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022E9;')"><xsl:value-of select="'\succnsim '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022E9;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022EA;')"><xsl:value-of select="'\ntriangleleft '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022EA;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022EB;')"><xsl:value-of select="'\ntriangleright '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022EB;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022EC;')"><xsl:value-of select="'\ntrianglelefteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022EC;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022ED;')"><xsl:value-of select="'\ntrianglerighteq '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022ED;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022EE;')"><xsl:value-of select="'\vdots '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022EE;')"/></xsl:call-template></xsl:when>
++ <xsl:when test="starts-with($content,'&#x022EF;')"><xsl:value-of select="'\cdots '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022EF;')"/></xsl:call-template></xsl:when> <!--/cdots, three dots, centered -->
++ <xsl:when test="starts-with($content,'&#x022F0;')"><xsl:value-of select="'\backslash adots '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022F0;')"/></xsl:call-template></xsl:when> <!-- three dots, ascending -->
++ <xsl:when test="starts-with($content,'&#x022F1;')"><xsl:value-of select="'\ddots '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x022F1;')"/></xsl:call-template></xsl:when> <!--/ddots, three dots, descending -->
+ <!-- ====================================================================== -->
+ <!-- Unicode 3.2
+ Miscellaneous Technical
+@@ -404,20 +881,22 @@
+ <!-- ====================================================================== -->
+ <xsl:when test="starts-with($content,'&#x025A1;')"><xsl:value-of select="'\square '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x025A1;')"/></xsl:call-template></xsl:when> <!--/square, square --> <!-- Required amssymb -->
+ <xsl:when test="starts-with($content,'&#x025AA;')"><xsl:value-of select="'\blacksquare '" /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x025AA;')"/></xsl:call-template></xsl:when> <!--/blacksquare, square, filled --> <!-- Required amssymb -->
++
++ <xsl:when test='starts-with($content,"&#x19b;")'><xsl:value-of select='"\lambda\!\!\!{}^{-}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x19b;')"/></xsl:call-template></xsl:when>
++
++<!-- Double brackets (only supported as workaround in MediaWiki). -->
++ <xsl:when test='starts-with($content,"&#x301a;")'><xsl:value-of select='"[\!["' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x301a;')"/></xsl:call-template></xsl:when>
++ <xsl:when test='starts-with($content,"&#x301b;")'><xsl:value-of select='"]\!]"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#x301b;')"/></xsl:call-template></xsl:when>
++
++<!-- Entities undefined in Unicode, but used by OOo for parenteses. -->
++ <xsl:when test='starts-with($content,"&#xe09e;")'><xsl:value-of select='"("' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#xe09e;')"/></xsl:call-template></xsl:when>
++ <xsl:when test='starts-with($content,"&#xe09f;")'><xsl:value-of select='")"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&#xe09f;')"/></xsl:call-template></xsl:when>
+
+ <xsl:when test='starts-with($content,"&apos;")'><xsl:value-of select='"\text{&apos;}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select='substring-after($content, "&apos;")'/></xsl:call-template></xsl:when><!-- \text required amslatex -->
+
+ <xsl:when test='starts-with($content,"{")'><xsl:value-of select='"\{"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '{')"/></xsl:call-template></xsl:when>
+ <xsl:when test='starts-with($content,"}")'><xsl:value-of select='"\}"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '}')"/></xsl:call-template></xsl:when>
+-
+-<!--- special characters -->
+- <xsl:when test='starts-with($content,"$")'><xsl:value-of select='"\$"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '$')"/></xsl:call-template></xsl:when>
+- <xsl:when test='starts-with($content,"#")'><xsl:value-of select='"\#"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '#')"/></xsl:call-template></xsl:when>
+- <xsl:when test='starts-with($content,"&amp;")'><xsl:value-of select='"\&amp;"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '&amp;')"/></xsl:call-template></xsl:when>
+- <xsl:when test='starts-with($content,"%")'><xsl:value-of select='"\%"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '%')"/></xsl:call-template></xsl:when>
+- <xsl:when test='starts-with($content,"_")'><xsl:value-of select='"\_"' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '_')"/></xsl:call-template></xsl:when>
+- <xsl:when test='starts-with($content,"\")'><xsl:value-of select='"\backslash "' /><xsl:call-template name="replaceEntities"><xsl:with-param name="content" select="substring-after($content, '\')"/></xsl:call-template></xsl:when>
+-
++
+ <xsl:otherwise>
+ <xsl:value-of select="substring($content,1,1)"/>
+ <xsl:call-template name="replaceEntities">
+@@ -445,7 +924,12 @@
+ <xsl:when test='starts-with($content,"&amp;")'><xsl:value-of select='"\&amp;"' /><xsl:call-template name="replaceMtextEntities"><xsl:with-param name="content" select="substring-after($content, '&amp;')"/></xsl:call-template></xsl:when>
+ <xsl:when test='starts-with($content,"%")'><xsl:value-of select='"\%"' /><xsl:call-template name="replaceMtextEntities"><xsl:with-param name="content" select="substring-after($content, '%')"/></xsl:call-template></xsl:when>
+ <xsl:when test='starts-with($content,"_")'><xsl:value-of select='"\_"' /><xsl:call-template name="replaceMtextEntities"><xsl:with-param name="content" select="substring-after($content, '_')"/></xsl:call-template></xsl:when>
+- <xsl:when test='starts-with($content,"\")'><xsl:call-template name="replaceMtextEntities"><xsl:with-param name="content" select="substring-after($content, '\')"/></xsl:call-template></xsl:when>
++ <xsl:when test='starts-with($content,"\")'><xsl:call-template name="replaceMtextEntities"><xsl:with-param name="content" select="substring-after($content, '\')"/></xsl:call-template></xsl:when>
++
++ <!-- Ignore "lower than" and "greater than" symbols, which break the MediaWiki parser in text mode. -->
++ <xsl:when test='starts-with($content,"&gt;")'><xsl:call-template name="replaceMtextEntities"><xsl:with-param name="content" select="substring-after($content, '&gt;')"/></xsl:call-template></xsl:when>
++ <xsl:when test='starts-with($content,"&lt;")'><xsl:call-template name="replaceMtextEntities"><xsl:with-param name="content" select="substring-after($content, '&lt;')"/></xsl:call-template></xsl:when>
++
+ <xsl:otherwise>
+ <xsl:value-of select="substring($content,1,1)"/>
+ <xsl:call-template name="replaceMtextEntities">
+--- misc/xsltml_2.1.2/glayout.xsl 2009-03-27 08:11:02.000000000 +0100
++++ misc/build/xsltml_2.1.2/glayout.xsl 2008-03-07 21:36:34.000000000 +0100
+@@ -1,12 +1,13 @@
+ <?xml version='1.0' encoding="UTF-8"?>
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+- xmlns:m="http://www.w3.org/1998/Math/MathML"
++ xmlns:m="http://www.w3.org/1998/Math/MathML"
++ xmlns:oomath="http://www.w3.org/1998/Math/MathML"
+ version='1.0'>
+
+ <!-- ====================================================================== -->
+-<!-- $Id: glayout.xsl,v 1.5 2003/06/10 12:24:04 shade33 Exp $
++<!-- $Id: glayout.xsl 2755 2008-03-07 20:35:56Z hauma $
+ This file is part of the XSLT MathML Library distribution.
+- See ./README or http://www.raleigh.ru/MathML/mmltex for
++ See ./README or http://xsltml.sf.net for
+ copyright and other information -->
+ <!-- ====================================================================== -->
+
+@@ -92,17 +93,16 @@
+
+ <xsl:template match="m:mfenced">
+ <xsl:choose>
+- <xsl:when test="@open">
+- <xsl:if test="translate(@open,'{}[]()|','{{{{{{{')='{'">
++ <xsl:when test="@oomath:open">
++ <xsl:if test="translate(@oomath:open,'{}[]()&#xe09e;&#xe09f;|&#x02223;','{{{{{{{{{{')='{'">
+ <xsl:text>\left</xsl:text>
+ </xsl:if>
+- <xsl:if test="@open='{' or @open='}'">
+- <xsl:text>\</xsl:text>
+- </xsl:if>
+- <xsl:if test="translate(@open,'{}[]()|','{{{{{{{')!='{' and (translate(@close,'{}[]()|','{{{{{{{')='{' or not(@close))">
++ <xsl:if test="translate(@oomath:open,'{}[]()&#xe09e;&#xe09f;|&#x02223;','{{{{{{{{{{')!='{' and (translate(@oomath:close,'{}[]()&#xe09e;&#xe09f;|&#x02223;','{{{{{{{{{{')='{' or not(@oomath:close))">
+ <xsl:text>\left.</xsl:text>
+- </xsl:if>
+- <xsl:value-of select="@open"/>
++ </xsl:if>
++ <xsl:call-template name="replaceEntities">
++ <xsl:with-param name="content" select="@oomath:open"/>
++ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise><xsl:text>\left(</xsl:text></xsl:otherwise>
+ </xsl:choose>
+@@ -128,26 +128,30 @@
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:choose>
+- <xsl:when test="@close">
+- <xsl:if test="translate(@close,'{}[]()|','{{{{{{{')='{'">
++ <xsl:when test="@oomath:close">
++ <xsl:if test="translate(@oomath:close,'{}[]()&#xe09e;&#xe09f;|&#x02223;','{{{{{{{{{{')='{'">
+ <xsl:text>\right</xsl:text>
+ </xsl:if>
+- <xsl:if test="@close='{' or @close='}'">
+- <xsl:text>\</xsl:text>
+- </xsl:if>
+- <xsl:if test="translate(@close,'{}[]()|','{{{{{{{')!='{' and (translate(@open,'{}[]()|','{{{{{{{')='{' or not(@open))">
++ <xsl:if test="translate(@oomath:close,'{}[]()&#xe09e;&#xe09f;|&#x02223;','{{{{{{{{{{')!='{' and (translate(@oomath:open,'{}[]()&#xe09e;&#xe09f;|&#x02223;','{{{{{{{{{{')='{' or not(@oomath:open))">
+ <xsl:text>\right.</xsl:text>
+ </xsl:if>
+- <xsl:value-of select="@close"/>
++ <xsl:call-template name="replaceEntities">
++ <xsl:with-param name="content" select="@oomath:close"/>
++ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise><xsl:text>\right)</xsl:text></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="m:mphantom">
+- <xsl:text>\phantom{</xsl:text>
+- <xsl:apply-templates/>
++<!-- Not supported by MediaWiki. -->
++<!--
++ <xsl:text>\phantom{</xsl:text>
++ -->
++ <xsl:apply-templates/>
++<!--
+ <xsl:text>}</xsl:text>
++ -->
+ </xsl:template>
+
+ <xsl:template match="m:menclose">
+@@ -193,15 +197,21 @@
+ </xsl:call-template>
+ <xsl:text>}{$</xsl:text>
+ </xsl:if>
+- <xsl:if test="@color[not(@mathcolor)] or @mathcolor">
++ <xsl:if test="@color or @mathcolor">
++ <xsl:variable name="color">
++ <xsl:choose>
++ <xsl:when test="@mathcolor"><xsl:value-of select="@mathcolor"/></xsl:when>
++ <xsl:when test="@color"><xsl:value-of select="@color"/></xsl:when>
++ </xsl:choose>
++ </xsl:variable>
+ <xsl:text>\textcolor[rgb]{</xsl:text>
+ <xsl:call-template name="color">
+- <xsl:with-param name="color" select="@color|@mathcolor"/>
++ <xsl:with-param name="color" select="$color"/>
+ </xsl:call-template>
+ <xsl:text>}{</xsl:text>
+ </xsl:if>
+ <xsl:apply-templates/>
+- <xsl:if test="@color[not(@mathcolor)] or @mathcolor">
++ <xsl:if test="@color or @mathcolor">
+ <xsl:text>}</xsl:text>
+ </xsl:if>
+ <xsl:if test="@background">
+--- misc/xsltml_2.1.2/mmltex.xsl 2009-03-27 08:11:02.000000000 +0100
++++ misc/build/xsltml_2.1.2/mmltex.xsl 2008-03-07 21:36:34.000000000 +0100
+@@ -6,9 +6,9 @@
+ <xsl:output method="text" indent="no" encoding="UTF-8"/>
+
+ <!-- ====================================================================== -->
+-<!-- $Id: mmltex.xsl,v 1.7 2003/06/10 12:24:04 shade33 Exp $
++<!-- $Id: mmltex.xsl 2755 2008-03-07 20:35:56Z hauma $
+ This file is part of the XSLT MathML Library distribution.
+- See ./README or http://www.raleigh.ru/MathML/mmltex for
++ See ./README or http://xsltml.sf.net for
+ copyright and other information -->
+ <!-- ====================================================================== -->
+
+--- misc/xsltml_2.1.2/scripts.xsl 2009-03-27 08:11:02.000000000 +0100
++++ misc/build/xsltml_2.1.2/scripts.xsl 2008-03-07 21:36:34.000000000 +0100
+@@ -1,12 +1,13 @@
+ <?xml version='1.0' encoding="UTF-8"?>
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+- xmlns:m="http://www.w3.org/1998/Math/MathML"
++ xmlns:m="http://www.w3.org/1998/Math/MathML"
++ xmlns:oomath="http://www.w3.org/1998/Math/MathML"
+ version='1.0'>
+
+ <!-- ====================================================================== -->
+-<!-- $Id: scripts.xsl,v 1.4 2003/06/10 12:24:04 shade33 Exp $
++<!-- $Id: scripts.xsl 2755 2008-03-07 20:35:56Z hauma $
+ This file is part of the XSLT MathML Library distribution.
+- See ./README or http://www.raleigh.ru/MathML/mmltex for
++ See ./README or http://xsltml.sf.net for
+ copyright and other information -->
+ <!-- ====================================================================== -->
+
+@@ -23,7 +24,7 @@
+ </xsl:call-template>
+ <xsl:text>}</xsl:text>
+ </xsl:when>
+- <xsl:when test="$over='&#x0FE37;'"> <!-- OverBrace - over brace -->
++ <xsl:when test="$over='&#x0FE37;' or $over='&#xf612;'"> <!-- OverBrace - over brace -->
+ <xsl:text>\overbrace{</xsl:text>
+ <xsl:call-template name="munder">
+ <xsl:with-param name="base" select="$base"/>
+@@ -64,7 +65,7 @@
+ </xsl:call-template>
+ <xsl:text>}</xsl:text>
+ </xsl:when>
+- <xsl:when test="$under='&#x0FE38;'"> <!-- UnderBrace - under brace -->
++ <xsl:when test="$under='&#x0FE38;' or $under='&#xf613;'"> <!-- UnderBrace - under brace -->
+ <xsl:text>\underbrace{</xsl:text>
+ <xsl:call-template name="mover">
+ <xsl:with-param name="base" select="$base"/>
+@@ -153,7 +154,7 @@
+ <xsl:apply-templates select="./*[1]"/>
+ <xsl:text>}</xsl:text>
+ </xsl:when>
+- <xsl:when test="$over='&#x0FE37;'"> <!-- OverBrace - over brace -->
++ <xsl:when test="$over='&#x0FE37;' or $over='&#xf612;'"> <!-- OverBrace - over brace -->
+ <xsl:text>\overbrace{</xsl:text>
+ <xsl:apply-templates select="./*[1]"/>
+ <xsl:text>}</xsl:text>
+@@ -192,10 +193,51 @@
+ <xsl:text>\ddot{</xsl:text>
+ <xsl:apply-templates select="./*[1]"/>
+ <xsl:text>}</xsl:text>
+- </xsl:when>
+- <xsl:when test="$over='&#x00302;' or $over='&#x0005E;'"> <!-- Hat or circ - circumflex accent -->
++ </xsl:when>
++ <xsl:when test="$over='&#xb4;'"> <!-- Acute accent "´" -->
++ <xsl:text>\acute{</xsl:text>
++ <xsl:apply-templates select="./*[1]"/>
++ <xsl:text>}</xsl:text>
++ </xsl:when>
++ <xsl:when test="$over='&#x60;'"> <!-- Grave accent "`" -->
++ <xsl:text>\grave{</xsl:text>
++ <xsl:apply-templates select="./*[1]"/>
++ <xsl:text>}</xsl:text>
++ </xsl:when>
++ <xsl:when test="$over='&#x2c7;'"> <!-- Caron (Mandarin Chinese third tone) "ˇ" -->
++ <xsl:text>\check{</xsl:text>
++ <xsl:apply-templates select="./*[1]"/>
++ <xsl:text>}</xsl:text>
++ </xsl:when>
++ <xsl:when test="$over='&#x2d8;'"> <!-- Breve accent "˘" -->
++ <xsl:text>\breve{</xsl:text>
++ <xsl:apply-templates select="./*[1]"/>
++ <xsl:text>}</xsl:text>
++ </xsl:when>
++ <xsl:when test="$over='&#x2da;'"> <!-- ring above "Ëš" -->
++ <xsl:text>\overset{\circ}{</xsl:text>
++ <xsl:apply-templates select="./*[1]"/>
++ <xsl:text>}</xsl:text>
++ </xsl:when>
++ <xsl:when test="$over='&#x2c9;'"> <!-- modifier letter Macron (Mandarin Chinese first tone) "ˉ" -->
++ <xsl:text>\bar{</xsl:text>
++ <xsl:apply-templates select="./*[1]"/>
++ <xsl:text>}</xsl:text>
++ </xsl:when>
++ <xsl:when test="$over='&#xa8;'"> <!-- Diaeresis "¨" -->
++ <xsl:text>\ddot{</xsl:text>
++ <xsl:apply-templates select="./*[1]"/>
++ <xsl:text>}</xsl:text>
++ </xsl:when>
++ <xsl:when test="$over='&#x20d7;'"> <!-- Vector -->
++ <xsl:text>\vec{</xsl:text>
++ <xsl:apply-templates select="./*[1]"/>
++ <xsl:text>}</xsl:text>
++ </xsl:when>
++
++ <xsl:when test="$over='&#x00302;' or $over='&#x0005E;' or $over='&#x2c6;'"> <!-- Hat or circ - circumflex accent -->
+ <xsl:choose>
+- <xsl:when test="@accent='true'">
++ <xsl:when test="@oomath:accent='true'">
+ <xsl:text>\widehat{</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+@@ -244,7 +281,7 @@
+ <xsl:apply-templates select="./*[1]"/>
+ <xsl:text>}</xsl:text>
+ </xsl:when>
+- <xsl:when test="$under='&#x0FE38;'"> <!-- UnderBrace - under brace -->
++ <xsl:when test="$under='&#x0FE38;' or $under='&#xf613;'"> <!-- UnderBrace - under brace -->
+ <xsl:text>\underbrace{</xsl:text>
+ <xsl:apply-templates select="./*[1]"/>
+ <xsl:text>}</xsl:text>
+--- misc/xsltml_2.1.2/tables.xsl 2009-03-27 08:11:02.000000000 +0100
++++ misc/build/xsltml_2.1.2/tables.xsl 2008-03-07 21:36:34.000000000 +0100
+@@ -1,130 +1,218 @@
+-<?xml version='1.0' encoding="UTF-8"?>
+-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+- xmlns:m="http://www.w3.org/1998/Math/MathML"
+- version='1.0'>
+-
+-<!-- ====================================================================== -->
+-<!-- $id: tables.xsl, 2002/17/05 Exp $
+- This file is part of the XSLT MathML Library distribution.
+- See ./README or http://www.raleigh.ru/MathML/mmltex for
+- copyright and other information -->
+-<!-- ====================================================================== -->
+-
+-<xsl:template match="m:mtd[@columnspan]">
+- <xsl:text>\multicolumn{</xsl:text>
+- <xsl:value-of select="@columnspan"/>
+- <xsl:text>}{c}{</xsl:text>
+- <xsl:apply-templates/>
+- <xsl:text>}</xsl:text>
+- <xsl:if test="count(following-sibling::*)>0">
+- <xsl:text>&amp; </xsl:text>
+- </xsl:if>
+-</xsl:template>
+-
+-
+-<xsl:template match="m:mtd">
+- <xsl:if test="@columnalign='right' or @columnalign='center'">
+- <xsl:text>\hfill </xsl:text>
+- </xsl:if>
+- <xsl:apply-templates/>
+- <xsl:if test="@columnalign='left' or @columnalign='center'">
+- <xsl:text>\hfill </xsl:text>
+- </xsl:if>
+- <xsl:if test="count(following-sibling::*)>0">
+-<!-- this test valid for Sablotron, another form - test="not(position()=last())".
+- Also for m:mtd[@columnspan] and m:mtr -->
+- <xsl:text>&amp; </xsl:text>
+- </xsl:if>
+-</xsl:template>
+-
+-<xsl:template match="m:mtr">
+- <xsl:apply-templates/>
+- <xsl:if test="count(following-sibling::*)>0">
+- <xsl:text>\\ </xsl:text>
+- </xsl:if>
+-</xsl:template>
+-
+-<xsl:template match="m:mtable">
+- <xsl:text>\begin{array}{</xsl:text>
+- <xsl:if test="@frame='solid'">
+- <xsl:text>|</xsl:text>
+- </xsl:if>
+- <xsl:variable name="numbercols" select="count(./m:mtr[1]/m:mtd[not(@columnspan)])+sum(./m:mtr[1]/m:mtd/@columnspan)"/>
+- <xsl:choose>
+- <xsl:when test="@columnalign">
+- <xsl:variable name="colalign">
+- <xsl:call-template name="colalign">
+- <xsl:with-param name="colalign" select="@columnalign"/>
+- </xsl:call-template>
+- </xsl:variable>
+- <xsl:choose>
+- <xsl:when test="string-length($colalign) > $numbercols">
+- <xsl:value-of select="substring($colalign,1,$numbercols)"/>
+- </xsl:when>
+- <xsl:when test="string-length($colalign) &lt; $numbercols">
+- <xsl:value-of select="$colalign"/>
+- <xsl:call-template name="generate-string">
+- <xsl:with-param name="text" select="substring($colalign,string-length($colalign))"/>
+- <xsl:with-param name="count" select="$numbercols - string-length($colalign)"/>
+- </xsl:call-template>
+- </xsl:when>
+- <xsl:otherwise>
+- <xsl:value-of select="$colalign"/>
+- </xsl:otherwise>
+- </xsl:choose>
+- </xsl:when>
+- <xsl:otherwise>
+- <xsl:call-template name="generate-string">
+- <xsl:with-param name="text" select="'c'"/>
+- <xsl:with-param name="count" select="$numbercols"/>
+- </xsl:call-template>
+- </xsl:otherwise>
+- </xsl:choose>
+- <xsl:if test="@frame='solid'">
+- <xsl:text>|</xsl:text>
+- </xsl:if>
+- <xsl:text>}</xsl:text>
+- <xsl:if test="@frame='solid'">
+- <xsl:text>\hline </xsl:text>
+- </xsl:if>
+- <xsl:apply-templates/>
+- <xsl:if test="@frame='solid'">
+- <xsl:text>\\ \hline</xsl:text>
+- </xsl:if>
+- <xsl:text>\end{array}</xsl:text>
+-</xsl:template>
+-
+-<xsl:template name="colalign">
+- <xsl:param name="colalign"/>
+- <xsl:choose>
+- <xsl:when test="contains($colalign,' ')">
+- <xsl:value-of select="substring($colalign,1,1)"/>
+- <xsl:call-template name="colalign">
+- <xsl:with-param name="colalign" select="substring-after($colalign,' ')"/>
+- </xsl:call-template>
+- </xsl:when>
+- <xsl:otherwise>
+- <xsl:value-of select="substring($colalign,1,1)"/>
+- </xsl:otherwise>
+- </xsl:choose>
+-</xsl:template>
+-
+-<xsl:template name="generate-string">
+-<!-- template from XSLT Standard Library v1.1 -->
+- <xsl:param name="text"/>
+- <xsl:param name="count"/>
+-
+- <xsl:choose>
+- <xsl:when test="string-length($text) = 0 or $count &lt;= 0"/>
+-
+- <xsl:otherwise>
+- <xsl:value-of select="$text"/>
+- <xsl:call-template name="generate-string">
+- <xsl:with-param name="text" select="$text"/>
+- <xsl:with-param name="count" select="$count - 1"/>
+- </xsl:call-template>
+- </xsl:otherwise>
+- </xsl:choose>
+-</xsl:template>
+-
+-</xsl:stylesheet>
+\ No newline at end of file
++<?xml version='1.0' encoding="UTF-8"?>
++<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
++ xmlns:m="http://www.w3.org/1998/Math/MathML"
++ version='1.0'>
++
++<!-- ====================================================================== -->
++<!-- $Id: tables.xsl 2755 2008-03-07 20:35:56Z hauma $
++ This file is part of the XSLT MathML Library distribution.
++ See ./README or http://xsltml.sf.net for
++ copyright and other information -->
++<!-- ====================================================================== -->
++
++<xsl:template match="m:mtd[@columnspan]">
++ <xsl:text>\multicolumn{</xsl:text>
++ <xsl:value-of select="@columnspan"/>
++ <xsl:text>}{c}{</xsl:text>
++ <xsl:apply-templates/>
++ <xsl:text>}</xsl:text>
++ <xsl:if test="count(following-sibling::*)>0">
++ <xsl:text>&amp; </xsl:text>
++ </xsl:if>
++</xsl:template>
++
++
++<xsl:template match="m:mtd">
++ <xsl:if test="@columnalign='right' or @columnalign='center'">
++ <xsl:text>\hfill </xsl:text>
++ </xsl:if>
++ <xsl:apply-templates/>
++ <xsl:if test="@columnalign='left' or @columnalign='center'">
++ <xsl:text>\hfill </xsl:text>
++ </xsl:if>
++</xsl:template>
++
++<xsl:template match="m:mtr">
++ <xsl:for-each select="*">
++ <xsl:apply-templates select="current()"/>
++ <xsl:if test="not(position()=last())">
++ <xsl:text>&amp; </xsl:text>
++ </xsl:if>
++ </xsl:for-each>
++ <xsl:if test="not(position()=last())">
++ <xsl:text>\\ &#13;&#10;</xsl:text>
++ <xsl:if test="../@rowlines">
++ <xsl:variable name="line">
++ <xsl:call-template name="getToken">
++ <xsl:with-param name="text" select="../@rowlines"/>
++ <xsl:with-param name="position" select="position()"/>
++ </xsl:call-template>
++ </xsl:variable>
++ <xsl:if test="$line='solid'">
++ <xsl:text>\hline </xsl:text>
++ </xsl:if>
++ </xsl:if>
++ </xsl:if>
++</xsl:template>
++
++<xsl:template match="m:mtable">
++ <xsl:text>\begin{array}{</xsl:text>
++ <xsl:if test="@frame='solid'">
++ <xsl:text>|</xsl:text>
++ </xsl:if>
++ <xsl:variable name="numbercols" select="count(./m:mtr[1]/*[not(@columnspan)])+sum(./m:mtr[1]/m:mtd/@columnspan)"/>
++ <xsl:choose>
++ <xsl:when test="@columnalign and @columnlines">
++ <xsl:call-template name="generateAlignString">
++ <xsl:with-param name="columnalignstring" select="@columnalign"/>
++ <xsl:with-param name="columnlinestring" select="@columnlines"/>
++ <xsl:with-param name="count" select="$numbercols"/>
++ </xsl:call-template>
++ </xsl:when>
++ <xsl:when test="@columnlines">
++ <xsl:call-template name="generateAlignString">
++ <xsl:with-param name="columnlinestring" select="@columnlines"/>
++ <xsl:with-param name="count" select="$numbercols"/>
++ </xsl:call-template>
++ </xsl:when>
++ <xsl:when test="@columnalign">
++ <xsl:call-template name="generateAlignString">
++ <xsl:with-param name="columnalignstring" select="@columnalign"/>
++ <xsl:with-param name="count" select="$numbercols"/>
++ </xsl:call-template>
++ </xsl:when>
++ <xsl:otherwise>
++ <xsl:call-template name="generateAlignString">
++ <xsl:with-param name="count" select="$numbercols"/>
++ </xsl:call-template>
++ </xsl:otherwise>
++ </xsl:choose>
++ <xsl:if test="@frame='solid'">
++ <xsl:text>|</xsl:text>
++ </xsl:if>
++ <xsl:text>}</xsl:text>
++ <xsl:if test="@frame='solid'">
++ <xsl:text>\hline </xsl:text>
++ </xsl:if>
++ <xsl:apply-templates/>
++ <xsl:if test="@frame='solid'">
++ <xsl:text>\\ \hline&#13;&#10;</xsl:text>
++ </xsl:if>
++ <xsl:text>\end{array}</xsl:text>
++</xsl:template>
++
++<xsl:template name="colalign">
++ <xsl:param name="colalign"/>
++ <xsl:choose>
++ <xsl:when test="contains($colalign,' ')">
++ <xsl:value-of select="substring($colalign,1,1)"/>
++ <xsl:call-template name="colalign">
++ <xsl:with-param name="colalign" select="substring-after($colalign,' ')"/>
++ </xsl:call-template>
++ </xsl:when>
++ <xsl:otherwise>
++ <xsl:value-of select="substring($colalign,1,1)"/>
++ </xsl:otherwise>
++ </xsl:choose>
++</xsl:template>
++
++<xsl:template name="generate-string">
++<!-- template from XSLT Standard Library v1.1 -->
++ <xsl:param name="text"/>
++ <xsl:param name="count"/>
++
++ <xsl:choose>
++ <xsl:when test="string-length($text) = 0 or $count &lt;= 0"/>
++
++ <xsl:otherwise>
++ <xsl:value-of select="$text"/>
++ <xsl:call-template name="generate-string">
++ <xsl:with-param name="text" select="$text"/>
++ <xsl:with-param name="count" select="$count - 1"/>
++ </xsl:call-template>
++ </xsl:otherwise>
++ </xsl:choose>
++</xsl:template>
++
++<xsl:template name="generateAlignString">
++ <xsl:param name="columnalignstring">center</xsl:param>
++ <xsl:param name="columnlinestring"/>
++ <xsl:param name="count"/>
++ <xsl:choose>
++ <xsl:when test="$count &lt;= 0"/>
++ <xsl:otherwise>
++ <xsl:variable name="columnalign">
++ <xsl:call-template name="getToken">
++ <xsl:with-param name="text" select="$columnalignstring"/>
++ <xsl:with-param name="position" select="1"/>
++ </xsl:call-template>
++ </xsl:variable>
++ <xsl:variable name="columnline">
++ <xsl:call-template name="getToken">
++ <xsl:with-param name="text" select="$columnlinestring"/>
++ <xsl:with-param name="position" select="1"/>
++ </xsl:call-template>
++ </xsl:variable>
++ <xsl:value-of select="substring($columnalign,1,1)"/>
++ <xsl:if test="$columnline='solid' and $count>1"><xsl:text>|</xsl:text></xsl:if>
++ <xsl:variable name="leftPartOrLastTokenA">
++ <xsl:choose>
++ <xsl:when test="substring-after($columnalignstring,' ')">
++ <xsl:value-of select="substring-after($columnalignstring,' ')"/>
++ </xsl:when>
++ <xsl:otherwise>
++ <xsl:value-of select="$columnalignstring"/>
++ </xsl:otherwise>
++ </xsl:choose>
++ </xsl:variable>
++ <xsl:variable name="leftPartOrLastTokenB">
++ <xsl:choose>
++ <xsl:when test="substring-after($columnlinestring,' ')">
++ <xsl:value-of select="substring-after($columnlinestring,' ')"/>
++ </xsl:when>
++ <xsl:otherwise>
++ <xsl:value-of select="$columnlinestring"/>
++ </xsl:otherwise>
++ </xsl:choose>
++ </xsl:variable>
++ <xsl:call-template name="generateAlignString">
++ <xsl:with-param name="columnalignstring" select="$leftPartOrLastTokenA"/>
++ <xsl:with-param name="columnlinestring" select="$leftPartOrLastTokenB"/>
++ <xsl:with-param name="count" select="$count - 1"/>
++ </xsl:call-template>
++ </xsl:otherwise>
++ </xsl:choose>
++</xsl:template>
++
++
++<xsl:template name="getToken">
++ <xsl:param name="text"/>
++ <xsl:param name="char" select="string(' ')"/>
++ <xsl:param name="position"/>
++ <xsl:choose>
++ <xsl:when test="$position = 1 or not(contains($text ,$char))">
++ <xsl:choose>
++ <xsl:when test="contains($text ,$char)">
++ <xsl:value-of select="substring-before($text,$char)"/>
++ </xsl:when>
++ <xsl:otherwise>
++ <xsl:value-of select="$text"/>
++ </xsl:otherwise>
++ </xsl:choose>
++ </xsl:when>
++ <xsl:when test="contains($text ,$char) and $position &gt; 1">
++ <xsl:variable name="last" select="substring-after($text,$char)"/>
++ <xsl:choose>
++ <xsl:when test="$position &gt; 1">
++ <xsl:call-template name="getToken">
++ <xsl:with-param name="text" select="$last"/>
++ <xsl:with-param name="char" select="$char"/>
++ <xsl:with-param name="position" select="$position - 1"/>
++ </xsl:call-template>
++ </xsl:when>
++ </xsl:choose>
++ </xsl:when>
++ </xsl:choose>
++ </xsl:template>
++
++</xsl:stylesheet>
+\ No newline at end of file
+--- misc/xsltml_2.1.2/tokens.xsl 2009-03-27 08:11:02.000000000 +0100
++++ misc/build/xsltml_2.1.2/tokens.xsl 2008-03-07 21:36:34.000000000 +0100
+@@ -1,12 +1,13 @@
+ <?xml version='1.0' encoding="UTF-8"?>
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+- xmlns:m="http://www.w3.org/1998/Math/MathML"
++ xmlns:m="http://www.w3.org/1998/Math/MathML"
++ xmlns:oomath="http://www.w3.org/1998/Math/MathML"
+ version='1.0'>
+
+ <!-- ====================================================================== -->
+-<!-- $Id: tokens.xsl,v 1.7 2003/06/10 12:24:05 shade33 Exp $
++<!-- $Id: tokens.xsl 2755 2008-03-07 20:35:56Z hauma $
+ This file is part of the XSLT MathML Library distribution.
+- See ./README or http://www.raleigh.ru/MathML/mmltex for
++ See ./README or http://xsltml.sf.net for
+ copyright and other information -->
+ <!-- ====================================================================== -->
+
+@@ -22,7 +23,15 @@
+ </xsl:template>
+
+ <xsl:template name="mi">
++ <xsl:variable name="op">
++ <xsl:value-of select="concat(' ',normalize-space(.),' ')"/>
++ </xsl:variable>
+ <xsl:choose>
++ <xsl:when test="contains(' arccos cos csc exp ker limsup min sinh arcsin cosh deg gcd lg ln Pr sup arctan cot det hom lim log sec tan arg coth dim inf liminf max sin tanh ',$op)">
++ <xsl:text>\</xsl:text>
++ <xsl:value-of select="normalize-space(.)"/>
++ <xsl:text> </xsl:text>
++ </xsl:when>
+ <xsl:when test="string-length(normalize-space(.))>1 and not(@mathvariant)">
+ <xsl:text>\mathrm{</xsl:text>
+ <xsl:apply-templates/>
+@@ -51,10 +60,10 @@
+ <xsl:template name="mo">
+ <xsl:if test="translate(normalize-space(.),'()[]}|','{{{{{{')='{'">
+ <xsl:choose>
+- <xsl:when test="not(@stretchy='false') and count(preceding-sibling::m:mo[translate(normalize-space(.),'()[]}|','{{{{{{')='{'])mod 2=0 and following-sibling::m:mo[1][not(@stretchy='false')][translate(normalize-space(.),'()[]}|','{{{{{{')='{']">
++ <xsl:when test="not(@oomath:stretchy='false') and count(preceding-sibling::m:mo[translate(normalize-space(.),'()[]}|','{{{{{{')='{'])mod 2=0 and following-sibling::m:mo[1][not(@oomath:stretchy='false')][translate(normalize-space(.),'()[]}|','{{{{{{')='{']">
+ <xsl:text>\left</xsl:text>
+ </xsl:when>
+- <xsl:when test="not(@stretchy='false') and count(preceding-sibling::m:mo[translate(normalize-space(.),'()[]}|','{{{{{{')='{'])mod 2=1 and preceding-sibling::m:mo[1][not(@stretchy='false')][translate(normalize-space(.),'()[]}|','{{{{{{')='{']">
++ <xsl:when test="not(@oomath:stretchy='false') and count(preceding-sibling::m:mo[translate(normalize-space(.),'()[]}|','{{{{{{')='{'])mod 2=1 and preceding-sibling::m:mo[1][not(@oomath:stretchy='false')][translate(normalize-space(.),'()[]}|','{{{{{{')='{']">
+ <xsl:text>\right</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+@@ -67,10 +76,13 @@
+ <xsl:call-template name="replaceMtextEntities">
+ <xsl:with-param name="content" select="normalize-space(.)"/>
+ </xsl:call-template>
+- </xsl:variable>
+- <xsl:text>\text{</xsl:text>
+- <xsl:value-of select="$content"/>
+- <xsl:text>}</xsl:text>
++ </xsl:variable>
++ <!-- Empty text content breaks the MediaWiki parser. -->
++ <xsl:if test="string-length($content) &gt; 0">
++ <xsl:text>\text{</xsl:text>
++ <xsl:value-of select="$content"/>
++ <xsl:text>}</xsl:text>
++ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="m:mspace">
+@@ -111,10 +123,16 @@
+ </xsl:call-template>
+ <xsl:text>}{$</xsl:text>
+ </xsl:if>
+- <xsl:if test="@color[not(@mathcolor)] or @mathcolor"> <!-- Note: @color is deprecated in MathML 2.0 -->
++ <xsl:if test="@color or @mathcolor"> <!-- Note: @color is deprecated in MathML 2.0 -->
++ <xsl:variable name="color">
++ <xsl:choose>
++ <xsl:when test="@mathcolor"><xsl:value-of select="@mathcolor"/></xsl:when>
++ <xsl:when test="@color"><xsl:value-of select="@color"/></xsl:when>
++ </xsl:choose>
++ </xsl:variable>
+ <xsl:text>\textcolor[rgb]{</xsl:text>
+ <xsl:call-template name="color">
+- <xsl:with-param name="color" select="@color|@mathcolor"/>
++ <xsl:with-param name="color" select="$color"/>
+ </xsl:call-template>
+ <xsl:text>}{</xsl:text>
+ </xsl:if>
diff --git a/external/zlib/Makefile b/external/zlib/Makefile
new file mode 100644
index 000000000..569ad8a0b
--- /dev/null
+++ b/external/zlib/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zlib/Module_zlib.mk b/external/zlib/Module_zlib.mk
new file mode 100644
index 000000000..468cb2dea
--- /dev/null
+++ b/external/zlib/Module_zlib.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,zlib))
+
+$(eval $(call gb_Module_add_targets,zlib,\
+ StaticLibrary_zlib \
+ UnpackedTarball_zlib \
+))
+
+ifeq ($(BUILD_X64),TRUE)
+$(eval $(call gb_Module_add_targets,zlib,\
+ StaticLibrary_zlib_x64 \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zlib/README b/external/zlib/README
new file mode 100644
index 000000000..401875737
--- /dev/null
+++ b/external/zlib/README
@@ -0,0 +1 @@
+Compression library from [http://www.zlib.net/].
diff --git a/external/zlib/StaticLibrary_zlib.mk b/external/zlib/StaticLibrary_zlib.mk
new file mode 100644
index 000000000..f5263bef7
--- /dev/null
+++ b/external/zlib/StaticLibrary_zlib.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,zlib))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,zlib,zlib))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,zlib))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,zlib,\
+ UnpackedTarball/zlib/adler32 \
+ UnpackedTarball/zlib/compress \
+ UnpackedTarball/zlib/crc32 \
+ UnpackedTarball/zlib/deflate \
+ UnpackedTarball/zlib/gzclose \
+ UnpackedTarball/zlib/gzlib \
+ UnpackedTarball/zlib/gzread \
+ UnpackedTarball/zlib/gzwrite \
+ UnpackedTarball/zlib/inffast \
+ UnpackedTarball/zlib/inflate \
+ UnpackedTarball/zlib/inftrees \
+ UnpackedTarball/zlib/trees \
+ UnpackedTarball/zlib/zutil \
+))
+
+ifeq ($(ENABLE_DEBUG),TRUE)
+$(eval $(call gb_StaticLibrary_add_cflags,zlib,-DZLIB_DEBUG))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zlib/StaticLibrary_zlib_x64.mk b/external/zlib/StaticLibrary_zlib_x64.mk
new file mode 100644
index 000000000..a51f326d1
--- /dev/null
+++ b/external/zlib/StaticLibrary_zlib_x64.mk
@@ -0,0 +1,39 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,zlib_x64))
+
+$(eval $(call gb_StaticLibrary_set_x64,zlib_x64,YES))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,zlib_x64,zlib))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,zlib_x64))
+
+$(eval $(call gb_StaticLibrary_set_include,zlib_x64,\
+ -I$(call gb_UnpackedTarball_get_dir,zlib) \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_StaticLibrary_add_x64_generated_cobjects,zlib_x64,\
+ UnpackedTarball/zlib/x64/adler32 \
+ UnpackedTarball/zlib/x64/compress \
+ UnpackedTarball/zlib/x64/crc32 \
+ UnpackedTarball/zlib/x64/deflate \
+ UnpackedTarball/zlib/x64/inffast \
+ UnpackedTarball/zlib/x64/inflate \
+ UnpackedTarball/zlib/x64/inftrees \
+ UnpackedTarball/zlib/x64/trees \
+ UnpackedTarball/zlib/x64/zutil \
+))
+
+ifeq ($(ENABLE_DEBUG),TRUE)
+$(eval $(call gb_StaticLibrary_add_cflags,zlib_x64,-DZLIB_DEBUG))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zlib/UnpackedTarball_zlib.mk b/external/zlib/UnpackedTarball_zlib.mk
new file mode 100644
index 000000000..dd9fc1c31
--- /dev/null
+++ b/external/zlib/UnpackedTarball_zlib.mk
@@ -0,0 +1,21 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,zlib))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,zlib,$(ZLIB_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_post_action,zlib,\
+ mkdir -p x64 && \
+ cp $(addsuffix .c,adler32 compress crc32 deflate inffast inflate inftrees trees zutil) x64 \
+))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,zlib,0))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zxing/0001-Use-a-patch-file-to-document-changes-from-upstream-s.patch b/external/zxing/0001-Use-a-patch-file-to-document-changes-from-upstream-s.patch
new file mode 100644
index 000000000..2ef284f53
--- /dev/null
+++ b/external/zxing/0001-Use-a-patch-file-to-document-changes-from-upstream-s.patch
@@ -0,0 +1,35 @@
+From 1d031966e08aef92ef742ae3cf91e1addaf95a47 Mon Sep 17 00:00:00 2001
+From: "Benjamin A. Beasley" <code@musicinmybrain.net>
+Date: Wed, 8 Dec 2021 18:14:54 -0500
+Subject: [PATCH 1/4] Use a patch file to document changes from upstream
+ stb_image.h
+
+---
+ thirdparty/stb/stb_image.patch | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+ create mode 100644 thirdparty/stb/stb_image.patch
+
+diff --git a/thirdparty/stb/stb_image.patch b/thirdparty/stb/stb_image.patch
+new file mode 100644
+index 0000000..5153728
+--- /dev/null
++++ b/thirdparty/stb/stb_image.patch
+@@ -0,0 +1,15 @@
++diff -Naur upstream/stb_image.h zxing/stb_image.h
++--- upstream/stb_image.h 2021-12-08 18:11:28.170529096 -0500
+++++ zxing/stb_image.h 2021-12-08 18:06:42.706717697 -0500
++@@ -1644,7 +1644,11 @@
++
++ static stbi_uc stbi__compute_y(int r, int g, int b)
++ {
+++#if 0 // ori
++ return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8);
+++#else // zxing (see ReadBarcode.cpp:RGBToGray)
+++ return (stbi_uc) ((306 * r + 601 * g + 117 * b + 0x200) >> 10);
+++#endif
++ }
++ #endif
++
+--
+2.33.1
+
diff --git a/external/zxing/0002-Update-stb_image_write-from-1.14-to-1.16.patch b/external/zxing/0002-Update-stb_image_write-from-1.14-to-1.16.patch
new file mode 100644
index 000000000..de62ff0a9
--- /dev/null
+++ b/external/zxing/0002-Update-stb_image_write-from-1.14-to-1.16.patch
@@ -0,0 +1,361 @@
+From 38f86eecd1e790329d56a4491ee0498d75d61c42 Mon Sep 17 00:00:00 2001
+From: "Benjamin A. Beasley" <code@musicinmybrain.net>
+Date: Wed, 8 Dec 2021 18:16:46 -0500
+Subject: [PATCH 2/4] Update stb_image_write from 1.14 to 1.16
+
+ 1.16 (2021-07-11)
+ make Deflate code emit uncompressed blocks when it would
+ otherwise expand support writing BMPs with alpha channel
+ 1.15 (2020-07-13) unknown
+---
+ thirdparty/stb/stb_image_write.h | 132 ++++++++++++++++++++++---------
+ 1 file changed, 95 insertions(+), 37 deletions(-)
+
+diff --git a/thirdparty/stb/stb_image_write.h b/thirdparty/stb/stb_image_write.h
+index cffd473..e4b32ed 100644
+--- a/thirdparty/stb/stb_image_write.h
++++ b/thirdparty/stb/stb_image_write.h
+@@ -1,4 +1,4 @@
+-/* stb_image_write - v1.14 - public domain - http://nothings.org/stb
++/* stb_image_write - v1.16 - public domain - http://nothings.org/stb
+ writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
+ no warranty implied; use at your own risk
+
+@@ -140,6 +140,7 @@ CREDITS:
+ Ivan Tikhonov
+ github:ignotion
+ Adam Schackart
++ Andrew Kensler
+
+ LICENSE
+
+@@ -166,9 +167,9 @@ LICENSE
+ #endif
+
+ #ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations
+-extern int stbi_write_tga_with_rle;
+-extern int stbi_write_png_compression_level;
+-extern int stbi_write_force_png_filter;
++STBIWDEF int stbi_write_tga_with_rle;
++STBIWDEF int stbi_write_png_compression_level;
++STBIWDEF int stbi_write_force_png_filter;
+ #endif
+
+ #ifndef STBI_WRITE_NO_STDIO
+@@ -178,7 +179,7 @@ STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const
+ STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
+ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality);
+
+-#ifdef STBI_WINDOWS_UTF8
++#ifdef STBIW_WINDOWS_UTF8
+ STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
+ #endif
+ #endif
+@@ -267,6 +268,8 @@ typedef struct
+ {
+ stbi_write_func *func;
+ void *context;
++ unsigned char buffer[64];
++ int buf_used;
+ } stbi__write_context;
+
+ // initialize a callback-based context
+@@ -283,7 +286,7 @@ static void stbi__stdio_write(void *context, void *data, int size)
+ fwrite(data,1,size,(FILE*) context);
+ }
+
+-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
++#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
+ #ifdef __cplusplus
+ #define STBIW_EXTERN extern "C"
+ #else
+@@ -294,25 +297,25 @@ STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned in
+
+ STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
+ {
+- return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
++ return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
+ }
+ #endif
+
+ static FILE *stbiw__fopen(char const *filename, char const *mode)
+ {
+ FILE *f;
+-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
++#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8)
+ wchar_t wMode[64];
+ wchar_t wFilename[1024];
+- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
++ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
+ return 0;
+
+- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
++ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
+ return 0;
+
+-#if _MSC_VER >= 1400
+- if (0 != _wfopen_s(&f, wFilename, wMode))
+- f = 0;
++#if defined(_MSC_VER) && _MSC_VER >= 1400
++ if (0 != _wfopen_s(&f, wFilename, wMode))
++ f = 0;
+ #else
+ f = _wfopen(wFilename, wMode);
+ #endif
+@@ -380,16 +383,36 @@ static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
+ va_end(v);
+ }
+
++static void stbiw__write_flush(stbi__write_context *s)
++{
++ if (s->buf_used) {
++ s->func(s->context, &s->buffer, s->buf_used);
++ s->buf_used = 0;
++ }
++}
++
+ static void stbiw__putc(stbi__write_context *s, unsigned char c)
+ {
+ s->func(s->context, &c, 1);
+ }
+
++static void stbiw__write1(stbi__write_context *s, unsigned char a)
++{
++ if ((size_t)s->buf_used + 1 > sizeof(s->buffer))
++ stbiw__write_flush(s);
++ s->buffer[s->buf_used++] = a;
++}
++
+ static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
+ {
+- unsigned char arr[3];
+- arr[0] = a; arr[1] = b; arr[2] = c;
+- s->func(s->context, arr, 3);
++ int n;
++ if ((size_t)s->buf_used + 3 > sizeof(s->buffer))
++ stbiw__write_flush(s);
++ n = s->buf_used;
++ s->buf_used = n+3;
++ s->buffer[n+0] = a;
++ s->buffer[n+1] = b;
++ s->buffer[n+2] = c;
+ }
+
+ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
+@@ -398,7 +421,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
+ int k;
+
+ if (write_alpha < 0)
+- s->func(s->context, &d[comp - 1], 1);
++ stbiw__write1(s, d[comp - 1]);
+
+ switch (comp) {
+ case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
+@@ -406,7 +429,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
+ if (expand_mono)
+ stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
+ else
+- s->func(s->context, d, 1); // monochrome TGA
++ stbiw__write1(s, d[0]); // monochrome TGA
+ break;
+ case 4:
+ if (!write_alpha) {
+@@ -422,7 +445,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
+ break;
+ }
+ if (write_alpha > 0)
+- s->func(s->context, &d[comp - 1], 1);
++ stbiw__write1(s, d[comp - 1]);
+ }
+
+ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
+@@ -447,6 +470,7 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i
+ unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
+ stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
+ }
++ stbiw__write_flush(s);
+ s->func(s->context, &zero, scanline_pad);
+ }
+ }
+@@ -467,16 +491,27 @@ static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x,
+
+ static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
+ {
+- int pad = (-x*3) & 3;
+- return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
+- "11 4 22 4" "4 44 22 444444",
+- 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
+- 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
++ if (comp != 4) {
++ // write RGB bitmap
++ int pad = (-x*3) & 3;
++ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
++ "11 4 22 4" "4 44 22 444444",
++ 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
++ 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
++ } else {
++ // RGBA bitmaps need a v4 header
++ // use BI_BITFIELDS mode with 32bpp and alpha mask
++ // (straight BI_RGB with alpha mask doesn't work in most readers)
++ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0,
++ "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444",
++ 'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header
++ 108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header
++ }
+ }
+
+ STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
+ {
+- stbi__write_context s;
++ stbi__write_context s = { 0 };
+ stbi__start_write_callbacks(&s, func, context);
+ return stbi_write_bmp_core(&s, x, y, comp, data);
+ }
+@@ -484,7 +519,7 @@ STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x,
+ #ifndef STBI_WRITE_NO_STDIO
+ STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
+ {
+- stbi__write_context s;
++ stbi__write_context s = { 0 };
+ if (stbi__start_write_file(&s,filename)) {
+ int r = stbi_write_bmp_core(&s, x, y, comp, data);
+ stbi__end_write_file(&s);
+@@ -557,24 +592,25 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v
+
+ if (diff) {
+ unsigned char header = STBIW_UCHAR(len - 1);
+- s->func(s->context, &header, 1);
++ stbiw__write1(s, header);
+ for (k = 0; k < len; ++k) {
+ stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
+ }
+ } else {
+ unsigned char header = STBIW_UCHAR(len - 129);
+- s->func(s->context, &header, 1);
++ stbiw__write1(s, header);
+ stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
+ }
+ }
+ }
++ stbiw__write_flush(s);
+ }
+ return 1;
+ }
+
+ STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
+ {
+- stbi__write_context s;
++ stbi__write_context s = { 0 };
+ stbi__start_write_callbacks(&s, func, context);
+ return stbi_write_tga_core(&s, x, y, comp, (void *) data);
+ }
+@@ -582,7 +618,7 @@ STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x,
+ #ifndef STBI_WRITE_NO_STDIO
+ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
+ {
+- stbi__write_context s;
++ stbi__write_context s = { 0 };
+ if (stbi__start_write_file(&s,filename)) {
+ int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
+ stbi__end_write_file(&s);
+@@ -598,6 +634,8 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
+
+ #define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
+
++#ifndef STBI_WRITE_NO_STDIO
++
+ static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
+ {
+ int exponent;
+@@ -732,7 +770,7 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
+ char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
+ s->func(s->context, header, sizeof(header)-1);
+
+-#ifdef __STDC_WANT_SECURE_LIB__
++#ifdef __STDC_LIB_EXT1__
+ len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
+ #else
+ len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
+@@ -748,15 +786,14 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
+
+ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
+ {
+- stbi__write_context s;
++ stbi__write_context s = { 0 };
+ stbi__start_write_callbacks(&s, func, context);
+ return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
+ }
+
+-#ifndef STBI_WRITE_NO_STDIO
+ STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
+ {
+- stbi__write_context s;
++ stbi__write_context s = { 0 };
+ if (stbi__start_write_file(&s,filename)) {
+ int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
+ stbi__end_write_file(&s);
+@@ -944,6 +981,23 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
+ (void) stbiw__sbfree(hash_table[i]);
+ STBIW_FREE(hash_table);
+
++ // store uncompressed instead if compression was worse
++ if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) {
++ stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1
++ for (j = 0; j < data_len;) {
++ int blocklen = data_len - j;
++ if (blocklen > 32767) blocklen = 32767;
++ stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression
++ stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN
++ stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8));
++ stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN
++ stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8));
++ memcpy(out+stbiw__sbn(out), data+j, blocklen);
++ stbiw__sbn(out) += blocklen;
++ j += blocklen;
++ }
++ }
++
+ {
+ // compute adler32 on input
+ unsigned int s1=1, s2=0;
+@@ -1552,7 +1606,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
+
+ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality)
+ {
+- stbi__write_context s;
++ stbi__write_context s = { 0 };
+ stbi__start_write_callbacks(&s, func, context);
+ return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality);
+ }
+@@ -1561,7 +1615,7 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
+ #ifndef STBI_WRITE_NO_STDIO
+ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
+ {
+- stbi__write_context s;
++ stbi__write_context s = { 0 };
+ if (stbi__start_write_file(&s,filename)) {
+ int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
+ stbi__end_write_file(&s);
+@@ -1574,6 +1628,10 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
+ #endif // STB_IMAGE_WRITE_IMPLEMENTATION
+
+ /* Revision history
++ 1.16 (2021-07-11)
++ make Deflate code emit uncompressed blocks when it would otherwise expand
++ support writing BMPs with alpha channel
++ 1.15 (2020-07-13) unknown
+ 1.14 (2020-02-02) updated JPEG writer to downsample chroma channels
+ 1.13
+ 1.12
+@@ -1611,7 +1669,7 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
+ add HDR output
+ fix monochrome BMP
+ 0.95 (2014-08-17)
+- add monochrome TGA output
++ add monochrome TGA output
+ 0.94 (2014-05-31)
+ rename private functions to avoid conflicts with stb_image.h
+ 0.93 (2014-05-27)
+--
+2.33.1
+
diff --git a/external/zxing/0003-Update-stb_image-from-2.25-to-2.27.patch b/external/zxing/0003-Update-stb_image-from-2.25-to-2.27.patch
new file mode 100644
index 000000000..ad6ab0b6c
--- /dev/null
+++ b/external/zxing/0003-Update-stb_image-from-2.25-to-2.27.patch
@@ -0,0 +1,1162 @@
+From 40f3e3eb96adb4f1bfc612837653c8e81d8ad46d Mon Sep 17 00:00:00 2001
+From: "Benjamin A. Beasley" <code@musicinmybrain.net>
+Date: Wed, 8 Dec 2021 18:20:00 -0500
+Subject: [PATCH 3/4] Update stb_image from 2.25 to 2.27
+
+ 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
+ 2.26 (2020-07-13) many minor fixes
+---
+ thirdparty/stb/stb_image.h | 475 +++++++++++++++++++++++++--------
+ thirdparty/stb/stb_image.patch | 6 +-
+ 2 files changed, 361 insertions(+), 120 deletions(-)
+
+diff --git a/thirdparty/stb/stb_image.h b/thirdparty/stb/stb_image.h
+index ee8f61c..c58bc0c 100644
+--- a/thirdparty/stb/stb_image.h
++++ b/thirdparty/stb/stb_image.h
+@@ -1,4 +1,4 @@
+-/* stb_image - v2.25 - public domain image loader - http://nothings.org/stb
++/* stb_image - v2.27 - public domain image loader - http://nothings.org/stb
+ no warranty implied; use at your own risk
+
+ Do this:
+@@ -48,6 +48,8 @@ LICENSE
+
+ RECENT REVISION HISTORY:
+
++ 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
++ 2.26 (2020-07-13) many minor fixes
+ 2.25 (2020-02-02) fix warnings
+ 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically
+ 2.23 (2019-08-11) fix clang static analysis warning
+@@ -88,27 +90,37 @@ RECENT REVISION HISTORY:
+ Jeremy Sawicki (handle all ImageNet JPGs)
+ Optimizations & bugfixes Mikhail Morozov (1-bit BMP)
+ Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
+- Arseny Kapoulkine
++ Arseny Kapoulkine Simon Breuss (16-bit PNM)
+ John-Mark Allen
+ Carmelo J Fdez-Aguera
+
+ Bug & warning fixes
+- Marc LeBlanc David Woo Guillaume George Martins Mozeiko
+- Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
+- Dave Moore Roy Eltham Hayaki Saito Nathan Reed
+- Won Chun Luke Graham Johan Duparc Nick Verigakis
+- the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh
+- Janez Zemva John Bartholomew Michal Cichon github:romigrou
+- Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
+- Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar
+- Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex
+- Ryamond Barbiero Paul Du Bois Engin Manap github:grim210
+- Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
+- Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
+- Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
+- Christian Floisand Kevin Schmidt JR Smith github:darealshinji
+- Brad Weinberger Matvey Cherevko github:Michaelangel007
+- Blazej Dariusz Roszkowski Alexander Veselov
++ Marc LeBlanc David Woo Guillaume George Martins Mozeiko
++ Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski
++ Phil Jordan Dave Moore Roy Eltham
++ Hayaki Saito Nathan Reed Won Chun
++ Luke Graham Johan Duparc Nick Verigakis the Horde3D community
++ Thomas Ruf Ronny Chevalier github:rlyeh
++ Janez Zemva John Bartholomew Michal Cichon github:romigrou
++ Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
++ Eugene Golushkov Laurent Gomila Cort Stratton github:snagar
++ Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex
++ Cass Everitt Ryamond Barbiero github:grim210
++ Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
++ Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
++ Josh Tobin Matthew Gregan github:poppolopoppo
++ Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
++ Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
++ Brad Weinberger Matvey Cherevko github:mosra
++ Luca Sas Alexander Veselov Zack Middleton [reserved]
++ Ryan C. Gordon [reserved] [reserved]
++ DO NOT ADD YOUR NAME HERE
++
++ Jacko Dirks
++
++ To add your name to the credits, pick a random blank space in the middle and fill it.
++ 80% of merge conflicts on stb PRs are due to people adding their name at the end
++ of the credits.
+ */
+
+ #ifndef STBI_INCLUDE_STB_IMAGE_H
+@@ -167,6 +179,32 @@ RECENT REVISION HISTORY:
+ //
+ // Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
+ //
++// To query the width, height and component count of an image without having to
++// decode the full file, you can use the stbi_info family of functions:
++//
++// int x,y,n,ok;
++// ok = stbi_info(filename, &x, &y, &n);
++// // returns ok=1 and sets x, y, n if image is a supported format,
++// // 0 otherwise.
++//
++// Note that stb_image pervasively uses ints in its public API for sizes,
++// including sizes of memory buffers. This is now part of the API and thus
++// hard to change without causing breakage. As a result, the various image
++// loaders all have certain limits on image size; these differ somewhat
++// by format but generally boil down to either just under 2GB or just under
++// 1GB. When the decoded image would be larger than this, stb_image decoding
++// will fail.
++//
++// Additionally, stb_image will reject image files that have any of their
++// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS,
++// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit,
++// the only way to have an image with such dimensions load correctly
++// is for it to have a rather extreme aspect ratio. Either way, the
++// assumption here is that such larger images are likely to be malformed
++// or malicious. If you do need to load an image with individual dimensions
++// larger than that, and it still fits in the overall size limit, you can
++// #define STBI_MAX_DIMENSIONS on your own to be something larger.
++//
+ // ===========================================================================
+ //
+ // UNICODE:
+@@ -272,11 +310,10 @@ RECENT REVISION HISTORY:
+ //
+ // iPhone PNG support:
+ //
+-// By default we convert iphone-formatted PNGs back to RGB, even though
+-// they are internally encoded differently. You can disable this conversion
+-// by calling stbi_convert_iphone_png_to_rgb(0), in which case
+-// you will always just get the native iphone "format" through (which
+-// is BGR stored in RGB).
++// We optionally support converting iPhone-formatted PNGs (which store
++// premultiplied BGRA) back to RGB, even though they're internally encoded
++// differently. To enable this conversion, call
++// stbi_convert_iphone_png_to_rgb(1).
+ //
+ // Call stbi_set_unpremultiply_on_load(1) as well to force a divide per
+ // pixel to remove any premultiplied alpha *only* if the image file explicitly
+@@ -318,7 +355,14 @@ RECENT REVISION HISTORY:
+ // - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
+ // want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
+ //
+-
++// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater
++// than that size (in either width or height) without further processing.
++// This is to let programs in the wild set an upper bound to prevent
++// denial-of-service attacks on untrusted data, as one could generate a
++// valid image of gigantic dimensions and force stb_image to allocate a
++// huge block of memory and spend disproportionate time decoding it. By
++// default this is set to (1 << 24), which is 16777216, but that's still
++// very big.
+
+ #ifndef STBI_NO_STDIO
+ #include <stdio.h>
+@@ -473,6 +517,8 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
+ // as above, but only applies to images loaded on the thread that calls the function
+ // this function is only available if your compiler supports thread-local variables;
+ // calling it will fail to link if your compiler doesn't
++STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply);
++STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert);
+ STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip);
+
+ // ZLIB client - used by PNG, available for other purposes
+@@ -574,13 +620,19 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
+ #ifndef STBI_NO_THREAD_LOCALS
+ #if defined(__cplusplus) && __cplusplus >= 201103L
+ #define STBI_THREAD_LOCAL thread_local
+- #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+- #define STBI_THREAD_LOCAL _Thread_local
+- #elif defined(__GNUC__)
++ #elif defined(__GNUC__) && __GNUC__ < 5
+ #define STBI_THREAD_LOCAL __thread
+ #elif defined(_MSC_VER)
+ #define STBI_THREAD_LOCAL __declspec(thread)
+-#endif
++ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
++ #define STBI_THREAD_LOCAL _Thread_local
++ #endif
++
++ #ifndef STBI_THREAD_LOCAL
++ #if defined(__GNUC__)
++ #define STBI_THREAD_LOCAL __thread
++ #endif
++ #endif
+ #endif
+
+ #ifdef _MSC_VER
+@@ -612,7 +664,7 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
+ #ifdef STBI_HAS_LROTL
+ #define stbi_lrot(x,y) _lrotl(x,y)
+ #else
+- #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
++ #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31)))
+ #endif
+
+ #if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
+@@ -726,14 +778,21 @@ static int stbi__sse2_available(void)
+
+ #ifdef STBI_NEON
+ #include <arm_neon.h>
+-// assume GCC or Clang on ARM targets
++#ifdef _MSC_VER
++#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
++#else
+ #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
+ #endif
++#endif
+
+ #ifndef STBI_SIMD_ALIGN
+ #define STBI_SIMD_ALIGN(type, name) type name
+ #endif
+
++#ifndef STBI_MAX_DIMENSIONS
++#define STBI_MAX_DIMENSIONS (1 << 24)
++#endif
++
+ ///////////////////////////////////////////////
+ //
+ // stbi__context struct and start_xxx functions
+@@ -751,6 +810,7 @@ typedef struct
+ int read_from_callbacks;
+ int buflen;
+ stbi_uc buffer_start[128];
++ int callback_already_read;
+
+ stbi_uc *img_buffer, *img_buffer_end;
+ stbi_uc *img_buffer_original, *img_buffer_original_end;
+@@ -764,6 +824,7 @@ static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
+ {
+ s->io.read = NULL;
+ s->read_from_callbacks = 0;
++ s->callback_already_read = 0;
+ s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
+ s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
+ }
+@@ -775,7 +836,8 @@ static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *
+ s->io_user_data = user;
+ s->buflen = sizeof(s->buffer_start);
+ s->read_from_callbacks = 1;
+- s->img_buffer_original = s->buffer_start;
++ s->callback_already_read = 0;
++ s->img_buffer = s->img_buffer_original = s->buffer_start;
+ stbi__refill_buffer(s);
+ s->img_buffer_original_end = s->img_buffer_end;
+ }
+@@ -789,12 +851,17 @@ static int stbi__stdio_read(void *user, char *data, int size)
+
+ static void stbi__stdio_skip(void *user, int n)
+ {
++ int ch;
+ fseek((FILE*) user, n, SEEK_CUR);
++ ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */
++ if (ch != EOF) {
++ ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */
++ }
+ }
+
+ static int stbi__stdio_eof(void *user)
+ {
+- return feof((FILE*) user);
++ return feof((FILE*) user) || ferror((FILE *) user);
+ }
+
+ static stbi_io_callbacks stbi__stdio_callbacks =
+@@ -890,6 +957,7 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
+ static int stbi__pnm_test(stbi__context *s);
+ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
++static int stbi__pnm_is16(stbi__context *s);
+ #endif
+
+ static
+@@ -964,7 +1032,7 @@ static int stbi__mad3sizes_valid(int a, int b, int c, int add)
+ }
+
+ // returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow
+-#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
++#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM)
+ static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
+ {
+ return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
+@@ -987,7 +1055,7 @@ static void *stbi__malloc_mad3(int a, int b, int c, int add)
+ return stbi__malloc(a*b*c + add);
+ }
+
+-#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
++#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM)
+ static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
+ {
+ if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL;
+@@ -1053,9 +1121,8 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
+ ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
+ ri->num_channels = 0;
+
+- #ifndef STBI_NO_JPEG
+- if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
+- #endif
++ // test the formats with a very explicit header first (at least a FOURCC
++ // or distinctive magic number first)
+ #ifndef STBI_NO_PNG
+ if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri);
+ #endif
+@@ -1073,6 +1140,13 @@ static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int re
+ #ifndef STBI_NO_PIC
+ if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
+ #endif
++
++ // then the formats that can end up attempting to load with just 1 or 2
++ // bytes matching expectations; these are prone to false positives, so
++ // try them later
++ #ifndef STBI_NO_JPEG
++ if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
++ #endif
+ #ifndef STBI_NO_PNM
+ if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri);
+ #endif
+@@ -1171,8 +1245,10 @@ static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x,
+ if (result == NULL)
+ return NULL;
+
++ // it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
++ STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
++
+ if (ri.bits_per_channel != 8) {
+- STBI_ASSERT(ri.bits_per_channel == 16);
+ result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
+ ri.bits_per_channel = 8;
+ }
+@@ -1195,8 +1271,10 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
+ if (result == NULL)
+ return NULL;
+
++ // it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
++ STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
++
+ if (ri.bits_per_channel != 16) {
+- STBI_ASSERT(ri.bits_per_channel == 8);
+ result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
+ ri.bits_per_channel = 16;
+ }
+@@ -1224,12 +1302,12 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
+
+ #ifndef STBI_NO_STDIO
+
+-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
++#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
+ STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
+ STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
+ #endif
+
+-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
++#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
+ STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
+ {
+ return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
+@@ -1239,16 +1317,16 @@ STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wch
+ static FILE *stbi__fopen(char const *filename, char const *mode)
+ {
+ FILE *f;
+-#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
++#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8)
+ wchar_t wMode[64];
+ wchar_t wFilename[1024];
+- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
++ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename)))
+ return 0;
+
+- if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
++ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode)))
+ return 0;
+
+-#if _MSC_VER >= 1400
++#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (0 != _wfopen_s(&f, wFilename, wMode))
+ f = 0;
+ #else
+@@ -1499,6 +1577,7 @@ enum
+ static void stbi__refill_buffer(stbi__context *s)
+ {
+ int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
++ s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original);
+ if (n == 0) {
+ // at end of file, treat same as if from memory, but need to handle case
+ // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
+@@ -1544,6 +1623,7 @@ stbi_inline static int stbi__at_eof(stbi__context *s)
+ #else
+ static void stbi__skip(stbi__context *s, int n)
+ {
++ if (n == 0) return; // already there!
+ if (n < 0) {
+ s->img_buffer = s->img_buffer_end;
+ return;
+@@ -1622,7 +1702,8 @@ static int stbi__get16le(stbi__context *s)
+ static stbi__uint32 stbi__get32le(stbi__context *s)
+ {
+ stbi__uint32 z = stbi__get16le(s);
+- return z + (stbi__get16le(s) << 16);
++ z += (stbi__uint32)stbi__get16le(s) << 16;
++ return z;
+ }
+ #endif
+
+@@ -1690,7 +1771,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
+ STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
+ STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
+ STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
+- default: STBI_ASSERT(0);
++ default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion");
+ }
+ #undef STBI__CASE
+ }
+@@ -1747,7 +1828,7 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
+ STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
+ STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
+ STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
+- default: STBI_ASSERT(0);
++ default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion");
+ }
+ #undef STBI__CASE
+ }
+@@ -2054,13 +2135,12 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
+ int sgn;
+ if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
+
+- sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
++ sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative)
+ k = stbi_lrot(j->code_buffer, n);
+- STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask)));
+ j->code_buffer = k & ~stbi__bmask[n];
+ k &= stbi__bmask[n];
+ j->code_bits -= n;
+- return k + (stbi__jbias[n] & ~sgn);
++ return k + (stbi__jbias[n] & (sgn - 1));
+ }
+
+ // get some unsigned bits
+@@ -2110,7 +2190,7 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
+
+ if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
+ t = stbi__jpeg_huff_decode(j, hdc);
+- if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG");
++ if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG");
+
+ // 0 all the ac values now so we can do it 32-bits at a time
+ memset(data,0,64*sizeof(data[0]));
+@@ -2167,11 +2247,12 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
+ // first scan for DC coefficient, must be first
+ memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
+ t = stbi__jpeg_huff_decode(j, hdc);
++ if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
+ diff = t ? stbi__extend_receive(j, t) : 0;
+
+ dc = j->img_comp[b].dc_pred + diff;
+ j->img_comp[b].dc_pred = dc;
+- data[0] = (short) (dc << j->succ_low);
++ data[0] = (short) (dc * (1 << j->succ_low));
+ } else {
+ // refinement scan for DC coefficient
+ if (stbi__jpeg_get_bit(j))
+@@ -2208,7 +2289,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
+ j->code_buffer <<= s;
+ j->code_bits -= s;
+ zig = stbi__jpeg_dezigzag[k++];
+- data[zig] = (short) ((r >> 8) << shift);
++ data[zig] = (short) ((r >> 8) * (1 << shift));
+ } else {
+ int rs = stbi__jpeg_huff_decode(j, hac);
+ if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
+@@ -2226,7 +2307,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
+ } else {
+ k += r;
+ zig = stbi__jpeg_dezigzag[k++];
+- data[zig] = (short) (stbi__extend_receive(j,s) << shift);
++ data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift));
+ }
+ }
+ } while (k <= j->spec_end);
+@@ -3157,6 +3238,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
+ p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
+ s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
+ s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
++ if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
++ if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
+ c = stbi__get8(s);
+ if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
+ s->img_n = c;
+@@ -3188,6 +3271,13 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
+ if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v;
+ }
+
++ // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios
++ // and I've never seen a non-corrupted JPEG file actually use them
++ for (i=0; i < s->img_n; ++i) {
++ if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG");
++ if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG");
++ }
++
+ // compute interleaved mcu info
+ z->img_h_max = h_max;
+ z->img_v_max = v_max;
+@@ -3743,6 +3833,10 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
+ else
+ decode_n = z->s->img_n;
+
++ // nothing to do if no components requested; check this now to avoid
++ // accessing uninitialized coutput[0] later
++ if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; }
++
+ // resample and color-convert
+ {
+ int k;
+@@ -3885,6 +3979,7 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
+ {
+ unsigned char* result;
+ stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
++ if (!j) return stbi__errpuc("outofmem", "Out of memory");
+ STBI_NOTUSED(ri);
+ j->s = s;
+ stbi__setup_jpeg(j);
+@@ -3897,6 +3992,7 @@ static int stbi__jpeg_test(stbi__context *s)
+ {
+ int r;
+ stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
++ if (!j) return stbi__err("outofmem", "Out of memory");
+ j->s = s;
+ stbi__setup_jpeg(j);
+ r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
+@@ -3921,6 +4017,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
+ {
+ int result;
+ stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
++ if (!j) return stbi__err("outofmem", "Out of memory");
+ j->s = s;
+ result = stbi__jpeg_info_raw(j, x, y, comp);
+ STBI_FREE(j);
+@@ -3940,6 +4037,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
+ // fast-way is faster to check than jpeg huffman, but slow way is slower
+ #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables
+ #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1)
++#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet
+
+ // zlib-style huffman encoding
+ // (jpegs packs from left, zlib from right, so can't share code)
+@@ -3949,8 +4047,8 @@ typedef struct
+ stbi__uint16 firstcode[16];
+ int maxcode[17];
+ stbi__uint16 firstsymbol[16];
+- stbi_uc size[288];
+- stbi__uint16 value[288];
++ stbi_uc size[STBI__ZNSYMS];
++ stbi__uint16 value[STBI__ZNSYMS];
+ } stbi__zhuffman;
+
+ stbi_inline static int stbi__bitreverse16(int n)
+@@ -4037,16 +4135,23 @@ typedef struct
+ stbi__zhuffman z_length, z_distance;
+ } stbi__zbuf;
+
++stbi_inline static int stbi__zeof(stbi__zbuf *z)
++{
++ return (z->zbuffer >= z->zbuffer_end);
++}
++
+ stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
+ {
+- if (z->zbuffer >= z->zbuffer_end) return 0;
+- return *z->zbuffer++;
++ return stbi__zeof(z) ? 0 : *z->zbuffer++;
+ }
+
+ static void stbi__fill_bits(stbi__zbuf *z)
+ {
+ do {
+- STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
++ if (z->code_buffer >= (1U << z->num_bits)) {
++ z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */
++ return;
++ }
+ z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
+ z->num_bits += 8;
+ } while (z->num_bits <= 24);
+@@ -4071,10 +4176,11 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
+ for (s=STBI__ZFAST_BITS+1; ; ++s)
+ if (k < z->maxcode[s])
+ break;
+- if (s == 16) return -1; // invalid code!
++ if (s >= 16) return -1; // invalid code!
+ // code size is s, so:
+ b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
+- STBI_ASSERT(z->size[b] == s);
++ if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere!
++ if (z->size[b] != s) return -1; // was originally an assert, but report failure instead.
+ a->code_buffer >>= s;
+ a->num_bits -= s;
+ return z->value[b];
+@@ -4083,7 +4189,12 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
+ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
+ {
+ int b,s;
+- if (a->num_bits < 16) stbi__fill_bits(a);
++ if (a->num_bits < 16) {
++ if (stbi__zeof(a)) {
++ return -1; /* report error for unexpected end of data. */
++ }
++ stbi__fill_bits(a);
++ }
+ b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
+ if (b) {
+ s = b >> 9;
+@@ -4097,13 +4208,16 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
+ static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
+ {
+ char *q;
+- int cur, limit, old_limit;
++ unsigned int cur, limit, old_limit;
+ z->zout = zout;
+ if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
+- cur = (int) (z->zout - z->zout_start);
+- limit = old_limit = (int) (z->zout_end - z->zout_start);
+- while (cur + n > limit)
++ cur = (unsigned int) (z->zout - z->zout_start);
++ limit = old_limit = (unsigned) (z->zout_end - z->zout_start);
++ if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory");
++ while (cur + n > limit) {
++ if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory");
+ limit *= 2;
++ }
+ q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
+ STBI_NOTUSED(old_limit);
+ if (q == NULL) return stbi__err("outofmem", "Out of memory");
+@@ -4201,11 +4315,12 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
+ c = stbi__zreceive(a,2)+3;
+ if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
+ fill = lencodes[n-1];
+- } else if (c == 17)
++ } else if (c == 17) {
+ c = stbi__zreceive(a,3)+3;
+- else {
+- STBI_ASSERT(c == 18);
++ } else if (c == 18) {
+ c = stbi__zreceive(a,7)+11;
++ } else {
++ return stbi__err("bad codelengths", "Corrupt PNG");
+ }
+ if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
+ memset(lencodes+n, fill, c);
+@@ -4231,7 +4346,7 @@ static int stbi__parse_uncompressed_block(stbi__zbuf *a)
+ a->code_buffer >>= 8;
+ a->num_bits -= 8;
+ }
+- STBI_ASSERT(a->num_bits == 0);
++ if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG");
+ // now fill header the normal way
+ while (k < 4)
+ header[k++] = stbi__zget8(a);
+@@ -4253,6 +4368,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
+ int cm = cmf & 15;
+ /* int cinfo = cmf >> 4; */
+ int flg = stbi__zget8(a);
++ if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
+ if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
+ if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
+ if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
+@@ -4260,7 +4376,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
+ return 1;
+ }
+
+-static const stbi_uc stbi__zdefault_length[288] =
++static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] =
+ {
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+@@ -4306,7 +4422,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
+ } else {
+ if (type == 1) {
+ // use fixed code lengths
+- if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0;
++ if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0;
+ if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0;
+ } else {
+ if (!stbi__compute_huffman_codes(a)) return 0;
+@@ -4514,7 +4630,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
+ return stbi__err("invalid filter","Corrupt PNG");
+
+ if (depth < 8) {
+- STBI_ASSERT(img_width_bytes <= x);
++ if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG");
+ cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
+ filter_bytes = 1;
+ width = img_width_bytes;
+@@ -4702,6 +4818,7 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3
+
+ // de-interlacing
+ final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0);
++ if (!final) return stbi__err("outofmem", "Out of memory");
+ for (p=0; p < 7; ++p) {
+ int xorig[] = { 0,4,0,2,0,1,0 };
+ int yorig[] = { 0,0,4,0,2,0,1 };
+@@ -4822,19 +4939,46 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
+ return 1;
+ }
+
+-static int stbi__unpremultiply_on_load = 0;
+-static int stbi__de_iphone_flag = 0;
++static int stbi__unpremultiply_on_load_global = 0;
++static int stbi__de_iphone_flag_global = 0;
+
+ STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)
+ {
+- stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply;
++ stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply;
+ }
+
+ STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
+ {
+- stbi__de_iphone_flag = flag_true_if_should_convert;
++ stbi__de_iphone_flag_global = flag_true_if_should_convert;
++}
++
++#ifndef STBI_THREAD_LOCAL
++#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global
++#define stbi__de_iphone_flag stbi__de_iphone_flag_global
++#else
++static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set;
++static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set;
++
++STBIDEF void stbi__unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply)
++{
++ stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply;
++ stbi__unpremultiply_on_load_set = 1;
+ }
+
++STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert)
++{
++ stbi__de_iphone_flag_local = flag_true_if_should_convert;
++ stbi__de_iphone_flag_set = 1;
++}
++
++#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \
++ ? stbi__unpremultiply_on_load_local \
++ : stbi__unpremultiply_on_load_global)
++#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \
++ ? stbi__de_iphone_flag_local \
++ : stbi__de_iphone_flag_global)
++#endif // STBI_THREAD_LOCAL
++
+ static void stbi__de_iphone(stbi__png *z)
+ {
+ stbi__context *s = z->s;
+@@ -4909,8 +5053,10 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
+ if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
+ first = 0;
+ if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
+- s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
+- s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
++ s->img_x = stbi__get32be(s);
++ s->img_y = stbi__get32be(s);
++ if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
++ if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
+ z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
+ color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
+ if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
+@@ -5059,10 +5205,12 @@ static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, st
+ void *result=NULL;
+ if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
+ if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
+- if (p->depth < 8)
++ if (p->depth <= 8)
+ ri->bits_per_channel = 8;
++ else if (p->depth == 16)
++ ri->bits_per_channel = 16;
+ else
+- ri->bits_per_channel = p->depth;
++ return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth");
+ result = p->out;
+ p->out = NULL;
+ if (req_comp && req_comp != p->s->img_out_n) {
+@@ -5211,6 +5359,32 @@ typedef struct
+ int extra_read;
+ } stbi__bmp_data;
+
++static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress)
++{
++ // BI_BITFIELDS specifies masks explicitly, don't override
++ if (compress == 3)
++ return 1;
++
++ if (compress == 0) {
++ if (info->bpp == 16) {
++ info->mr = 31u << 10;
++ info->mg = 31u << 5;
++ info->mb = 31u << 0;
++ } else if (info->bpp == 32) {
++ info->mr = 0xffu << 16;
++ info->mg = 0xffu << 8;
++ info->mb = 0xffu << 0;
++ info->ma = 0xffu << 24;
++ info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
++ } else {
++ // otherwise, use defaults, which is all-0
++ info->mr = info->mg = info->mb = info->ma = 0;
++ }
++ return 1;
++ }
++ return 0; // error
++}
++
+ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
+ {
+ int hsz;
+@@ -5223,6 +5397,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
+ info->mr = info->mg = info->mb = info->ma = 0;
+ info->extra_read = 14;
+
++ if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP");
++
+ if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
+ if (hsz == 12) {
+ s->img_x = stbi__get16le(s);
+@@ -5236,6 +5412,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
+ if (hsz != 12) {
+ int compress = stbi__get32le(s);
+ if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
++ if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes
++ if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel
+ stbi__get32le(s); // discard sizeof
+ stbi__get32le(s); // discard hres
+ stbi__get32le(s); // discard vres
+@@ -5250,17 +5428,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
+ }
+ if (info->bpp == 16 || info->bpp == 32) {
+ if (compress == 0) {
+- if (info->bpp == 32) {
+- info->mr = 0xffu << 16;
+- info->mg = 0xffu << 8;
+- info->mb = 0xffu << 0;
+- info->ma = 0xffu << 24;
+- info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
+- } else {
+- info->mr = 31u << 10;
+- info->mg = 31u << 5;
+- info->mb = 31u << 0;
+- }
++ stbi__bmp_set_mask_defaults(info, compress);
+ } else if (compress == 3) {
+ info->mr = stbi__get32le(s);
+ info->mg = stbi__get32le(s);
+@@ -5275,6 +5443,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
+ return stbi__errpuc("bad BMP", "bad BMP");
+ }
+ } else {
++ // V4/V5 header
+ int i;
+ if (hsz != 108 && hsz != 124)
+ return stbi__errpuc("bad BMP", "bad BMP");
+@@ -5282,6 +5451,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
+ info->mg = stbi__get32le(s);
+ info->mb = stbi__get32le(s);
+ info->ma = stbi__get32le(s);
++ if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs
++ stbi__bmp_set_mask_defaults(info, compress);
+ stbi__get32le(s); // discard color space
+ for (i=0; i < 12; ++i)
+ stbi__get32le(s); // discard color space parameters
+@@ -5314,6 +5485,9 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
+ flip_vertically = ((int) s->img_y) > 0;
+ s->img_y = abs((int) s->img_y);
+
++ if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++ if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++
+ mr = info.mr;
+ mg = info.mg;
+ mb = info.mb;
+@@ -5328,7 +5502,9 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
+ psize = (info.offset - info.extra_read - info.hsz) >> 2;
+ }
+ if (psize == 0) {
+- STBI_ASSERT(info.offset == (s->img_buffer - s->buffer_start));
++ if (info.offset != s->callback_already_read + (s->img_buffer - s->img_buffer_original)) {
++ return stbi__errpuc("bad offset", "Corrupt BMP");
++ }
+ }
+
+ if (info.bpp == 24 && ma == 0xff000000)
+@@ -5423,6 +5599,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
+ gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
+ bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
+ ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
++ if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); }
+ }
+ for (j=0; j < (int) s->img_y; ++j) {
+ if (easy) {
+@@ -5647,6 +5824,9 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
+ STBI_NOTUSED(tga_x_origin); // @TODO
+ STBI_NOTUSED(tga_y_origin); // @TODO
+
++ if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++ if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++
+ // do a tiny bit of precessing
+ if ( tga_image_type >= 8 )
+ {
+@@ -5686,6 +5866,11 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
+ // do I need to load a palette?
+ if ( tga_indexed)
+ {
++ if (tga_palette_len == 0) { /* you have to have at least one entry! */
++ STBI_FREE(tga_data);
++ return stbi__errpuc("bad palette", "Corrupt TGA");
++ }
++
+ // any data to skip? (offset usually = 0)
+ stbi__skip(s, tga_palette_start );
+ // load the palette
+@@ -5894,6 +6079,9 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
+ h = stbi__get32be(s);
+ w = stbi__get32be(s);
+
++ if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++ if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++
+ // Make sure the depth is 8 bits.
+ bitdepth = stbi__get16be(s);
+ if (bitdepth != 8 && bitdepth != 16)
+@@ -6248,6 +6436,10 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
+
+ x = stbi__get16be(s);
+ y = stbi__get16be(s);
++
++ if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++ if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++
+ if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)");
+ if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
+
+@@ -6257,6 +6449,7 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
+
+ // intermediate buffer is RGBA
+ result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0);
++ if (!result) return stbi__errpuc("outofmem", "Out of memory");
+ memset(result, 0xff, x*y*4);
+
+ if (!stbi__pic_load_core(s,x,y,comp, result)) {
+@@ -6356,6 +6549,9 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
+ g->ratio = stbi__get8(s);
+ g->transparent = -1;
+
++ if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
++ if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
++
+ if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
+
+ if (is_info) return 1;
+@@ -6369,6 +6565,7 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
+ static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
+ {
+ stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
++ if (!g) return stbi__err("outofmem", "Out of memory");
+ if (!stbi__gif_header(s, g, comp, 1)) {
+ STBI_FREE(g);
+ stbi__rewind( s );
+@@ -6533,7 +6730,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
+ memset(g->history, 0x00, pcount); // pixels that were affected previous frame
+ first_frame = 1;
+ } else {
+- // second frame - how do we dispoase of the previous one?
++ // second frame - how do we dispose of the previous one?
+ dispose = (g->eflags & 0x1C) >> 2;
+ pcount = g->w * g->h;
+
+@@ -6678,6 +6875,17 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
+ }
+ }
+
++static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays)
++{
++ STBI_FREE(g->out);
++ STBI_FREE(g->history);
++ STBI_FREE(g->background);
++
++ if (out) STBI_FREE(out);
++ if (delays && *delays) STBI_FREE(*delays);
++ return stbi__errpuc("outofmem", "Out of memory");
++}
++
+ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
+ {
+ if (stbi__gif_test(s)) {
+@@ -6687,6 +6895,12 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
+ stbi_uc *two_back = 0;
+ stbi__gif g;
+ int stride;
++ int out_size = 0;
++ int delays_size = 0;
++
++ STBI_NOTUSED(out_size);
++ STBI_NOTUSED(delays_size);
++
+ memset(&g, 0, sizeof(g));
+ if (delays) {
+ *delays = 0;
+@@ -6703,22 +6917,31 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
+ stride = g.w * g.h * 4;
+
+ if (out) {
+- void *tmp = (stbi_uc*) STBI_REALLOC( out, layers * stride );
+- if (NULL == tmp) {
+- STBI_FREE(g.out);
+- STBI_FREE(g.history);
+- STBI_FREE(g.background);
+- return stbi__errpuc("outofmem", "Out of memory");
++ void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride );
++ if (!tmp)
++ return stbi__load_gif_main_outofmem(&g, out, delays);
++ else {
++ out = (stbi_uc*) tmp;
++ out_size = layers * stride;
+ }
+- else
+- out = (stbi_uc*) tmp;
++
+ if (delays) {
+- *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
++ int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers );
++ if (!new_delays)
++ return stbi__load_gif_main_outofmem(&g, out, delays);
++ *delays = new_delays;
++ delays_size = layers * sizeof(int);
+ }
+ } else {
+ out = (stbi_uc*)stbi__malloc( layers * stride );
++ if (!out)
++ return stbi__load_gif_main_outofmem(&g, out, delays);
++ out_size = layers * stride;
+ if (delays) {
+ *delays = (int*) stbi__malloc( layers * sizeof(int) );
++ if (!*delays)
++ return stbi__load_gif_main_outofmem(&g, out, delays);
++ delays_size = layers * sizeof(int);
+ }
+ }
+ memcpy( out + ((layers - 1) * stride), u, stride );
+@@ -6897,6 +7120,9 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
+ token += 3;
+ width = (int) strtol(token, NULL, 10);
+
++ if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
++ if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
++
+ *x = width;
+ *y = height;
+
+@@ -7039,9 +7265,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
+
+ info.all_a = 255;
+ p = stbi__bmp_parse_header(s, &info);
+- stbi__rewind( s );
+- if (p == NULL)
++ if (p == NULL) {
++ stbi__rewind( s );
+ return 0;
++ }
+ if (x) *x = s->img_x;
+ if (y) *y = s->img_y;
+ if (comp) {
+@@ -7107,8 +7334,8 @@ static int stbi__psd_is16(stbi__context *s)
+ stbi__rewind( s );
+ return 0;
+ }
+- (void) stbi__get32be(s);
+- (void) stbi__get32be(s);
++ STBI_NOTUSED(stbi__get32be(s));
++ STBI_NOTUSED(stbi__get32be(s));
+ depth = stbi__get16be(s);
+ if (depth != 16) {
+ stbi__rewind( s );
+@@ -7187,7 +7414,6 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
+ // Known limitations:
+ // Does not support comments in the header section
+ // Does not support ASCII image data (formats P2 and P3)
+-// Does not support 16-bit-per-channel
+
+ #ifndef STBI_NO_PNM
+
+@@ -7208,19 +7434,23 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
+ stbi_uc *out;
+ STBI_NOTUSED(ri);
+
+- if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
++ ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n);
++ if (ri->bits_per_channel == 0)
+ return 0;
+
++ if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++ if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
++
+ *x = s->img_x;
+ *y = s->img_y;
+ if (comp) *comp = s->img_n;
+
+- if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
++ if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0))
+ return stbi__errpuc("too large", "PNM too large");
+
+- out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0);
++ out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0);
+ if (!out) return stbi__errpuc("outofmem", "Out of memory");
+- stbi__getn(s, out, s->img_n * s->img_x * s->img_y);
++ stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8));
+
+ if (req_comp && req_comp != s->img_n) {
+ out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
+@@ -7296,11 +7526,19 @@ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
+ stbi__pnm_skip_whitespace(s, &c);
+
+ maxv = stbi__pnm_getinteger(s, &c); // read max value
+-
+- if (maxv > 255)
+- return stbi__err("max value > 255", "PPM image not 8-bit");
++ if (maxv > 65535)
++ return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images");
++ else if (maxv > 255)
++ return 16;
+ else
+- return 1;
++ return 8;
++}
++
++static int stbi__pnm_is16(stbi__context *s)
++{
++ if (stbi__pnm_info(s, NULL, NULL, NULL) == 16)
++ return 1;
++ return 0;
+ }
+ #endif
+
+@@ -7356,6 +7594,9 @@ static int stbi__is_16_main(stbi__context *s)
+ if (stbi__psd_is16(s)) return 1;
+ #endif
+
++ #ifndef STBI_NO_PNM
++ if (stbi__pnm_is16(s)) return 1;
++ #endif
+ return 0;
+ }
+
+diff --git a/thirdparty/stb/stb_image.patch b/thirdparty/stb/stb_image.patch
+index 5153728..f1fee52 100644
+--- a/thirdparty/stb/stb_image.patch
++++ b/thirdparty/stb/stb_image.patch
+@@ -1,7 +1,7 @@
+ diff -Naur upstream/stb_image.h zxing/stb_image.h
+---- upstream/stb_image.h 2021-12-08 18:11:28.170529096 -0500
+-+++ zxing/stb_image.h 2021-12-08 18:06:42.706717697 -0500
+-@@ -1644,7 +1644,11 @@
++--- upstream/stb_image.h 2021-12-08 18:18:07.485461782 -0500
+++++ zxing/stb_image.h 2021-12-08 18:18:29.596689004 -0500
++@@ -1725,7 +1725,11 @@
+
+ static stbi_uc stbi__compute_y(int r, int g, int b)
+ {
+--
+2.33.1
+
diff --git a/external/zxing/0004-Apply-stb-PR-1223-to-stb_image.patch b/external/zxing/0004-Apply-stb-PR-1223-to-stb_image.patch
new file mode 100644
index 000000000..7a231c98c
--- /dev/null
+++ b/external/zxing/0004-Apply-stb-PR-1223-to-stb_image.patch
@@ -0,0 +1,98 @@
+From 5ca63122c53fa0703cad9a8257f123a1ca4c43b1 Mon Sep 17 00:00:00 2001
+From: "Benjamin A. Beasley" <code@musicinmybrain.net>
+Date: Wed, 8 Dec 2021 18:24:31 -0500
+Subject: [PATCH 4/4] Apply stb PR#1223 to stb_image
+
+Fixes a crash and an infinite loop in stb_image that could occur with
+specially constructed PGM and HDR files
+
+https://github.com/nothings/stb/pull/1223
+
+This is a candidate fix for:
+
+ https://nvd.nist.gov/vuln/detail/CVE-2021-42715
+
+ In stb_image's HDR reader, loading a specially constructed invalid HDR
+ file can result in an infinite loop within the RLE decoder
+ https://github.com/nothings/stb/issues/1224
+
+Additionally, this is a candidate fix for:
+
+ https://nvd.nist.gov/vuln/detail/CVE-2021-42716
+
+ stbi__pnm_load heap-buffer-overflow bug
+ https://github.com/nothings/stb/issues/1166
+
+ In stb_image's PNM reader, loading a specially constructed valid
+ 16-bit PGM file with 4 channels can cause a crash due to an
+ out-of-bounds read
+ https://github.com/nothings/stb/issues/1225
+---
+ thirdparty/stb/stb_image.h | 17 ++++++++++++-----
+ thirdparty/stb/stb_image.patch | 4 ++--
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/thirdparty/stb/stb_image.h b/thirdparty/stb/stb_image.h
+index c58bc0c..612bc4c 100644
+--- a/thirdparty/stb/stb_image.h
++++ b/thirdparty/stb/stb_image.h
+@@ -108,7 +108,7 @@ RECENT REVISION HISTORY:
+ Cass Everitt Ryamond Barbiero github:grim210
+ Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
+ Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
+- Josh Tobin Matthew Gregan github:poppolopoppo
++ Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo
+ Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
+ Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
+ Brad Weinberger Matvey Cherevko github:mosra
+@@ -7191,12 +7191,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
+ // Run
+ value = stbi__get8(s);
+ count -= 128;
+- if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
++ if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
+ for (z = 0; z < count; ++z)
+ scanline[i++ * 4 + k] = value;
+ } else {
+ // Dump
+- if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
++ if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
+ for (z = 0; z < count; ++z)
+ scanline[i++ * 4 + k] = stbi__get8(s);
+ }
+@@ -7450,10 +7450,17 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
+
+ out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0);
+ if (!out) return stbi__errpuc("outofmem", "Out of memory");
+- stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8));
++ if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) {
++ STBI_FREE(out);
++ return stbi__errpuc("bad PNM", "PNM file truncated");
++ }
+
+ if (req_comp && req_comp != s->img_n) {
+- out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
++ if (ri->bits_per_channel == 16) {
++ out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y);
++ } else {
++ out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
++ }
+ if (out == NULL) return out; // stbi__convert_format frees input on failure
+ }
+ return out;
+diff --git a/thirdparty/stb/stb_image.patch b/thirdparty/stb/stb_image.patch
+index f1fee52..1768ba8 100644
+--- a/thirdparty/stb/stb_image.patch
++++ b/thirdparty/stb/stb_image.patch
+@@ -1,6 +1,6 @@
+ diff -Naur upstream/stb_image.h zxing/stb_image.h
+---- upstream/stb_image.h 2021-12-08 18:18:07.485461782 -0500
+-+++ zxing/stb_image.h 2021-12-08 18:18:29.596689004 -0500
++--- upstream/stb_image.h 2021-12-08 18:22:56.724466161 -0500
+++++ zxing/stb_image.h 2021-12-08 18:23:15.084657043 -0500
+ @@ -1725,7 +1725,11 @@
+
+ static stbi_uc stbi__compute_y(int r, int g, int b)
+--
+2.33.1
+
diff --git a/external/zxing/Makefile b/external/zxing/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/zxing/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zxing/Module_zxing.mk b/external/zxing/Module_zxing.mk
new file mode 100644
index 000000000..ee53696c5
--- /dev/null
+++ b/external/zxing/Module_zxing.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,zxing))
+
+$(eval $(call gb_Module_add_targets,zxing,\
+ UnpackedTarball_zxing \
+))
+
+$(eval $(call gb_Module_add_targets,zxing,\
+ StaticLibrary_zxing \
+))
+
+# vim: set noet sw=4 ts=4: \ No newline at end of file
diff --git a/external/zxing/README b/external/zxing/README
new file mode 100644
index 000000000..1ca49cbc0
--- /dev/null
+++ b/external/zxing/README
@@ -0,0 +1,3 @@
+Qr code generation library availaible from [https://github.com/nu-book/zxing-cpp]
+
+Qr code generator to make a QR code out of a provided link or text in LibreOffice. \ No newline at end of file
diff --git a/external/zxing/StaticLibrary_zxing.mk b/external/zxing/StaticLibrary_zxing.mk
new file mode 100644
index 000000000..5434489d8
--- /dev/null
+++ b/external/zxing/StaticLibrary_zxing.mk
@@ -0,0 +1,142 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,zxing))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,zxing,zxing))
+
+$(eval $(call gb_StaticLibrary_set_precompiled_header,zxing,external/zxing/inc/pch/precompiled_zxing))
+
+$(eval $(call gb_StaticLibrary_set_generated_cxx_suffix,zxing,cpp))
+
+$(eval $(call gb_StaticLibrary_use_external,zxing,icu_headers))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,zxing))
+
+$(eval $(call gb_StaticLibrary_set_include,zxing,\
+ -I$(call gb_UnpackedTarball_get_dir,zxing/core/src/) \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_exception_objects,zxing,\
+ UnpackedTarball/zxing/core/src/aztec/AZReader \
+ UnpackedTarball/zxing/core/src/aztec/AZToken \
+ UnpackedTarball/zxing/core/src/aztec/AZEncoder \
+ UnpackedTarball/zxing/core/src/aztec/AZDecoder \
+ UnpackedTarball/zxing/core/src/aztec/AZDetector \
+ UnpackedTarball/zxing/core/src/aztec/AZHighLevelEncoder \
+ UnpackedTarball/zxing/core/src/aztec/AZWriter \
+ UnpackedTarball/zxing/core/src/BarcodeFormat \
+ UnpackedTarball/zxing/core/src/BitArray \
+ UnpackedTarball/zxing/core/src/BitMatrixIO \
+ UnpackedTarball/zxing/core/src/BinaryBitmap \
+ UnpackedTarball/zxing/core/src/BitMatrix \
+ UnpackedTarball/zxing/core/src/BitSource \
+ UnpackedTarball/zxing/core/src/textcodec/Big5TextDecoder \
+ UnpackedTarball/zxing/core/src/textcodec/Big5TextEncoder \
+ UnpackedTarball/zxing/core/src/textcodec/Big5MapTable \
+ UnpackedTarball/zxing/core/src/CharacterSetECI \
+ UnpackedTarball/zxing/core/src/ConcentricFinder \
+ UnpackedTarball/zxing/core/src/DecodeHints \
+ UnpackedTarball/zxing/core/src/DecodeStatus \
+ UnpackedTarball/zxing/core/src/datamatrix/DMWriter \
+ UnpackedTarball/zxing/core/src/datamatrix/DMDetector \
+ UnpackedTarball/zxing/core/src/datamatrix/DMVersion \
+ UnpackedTarball/zxing/core/src/datamatrix/DMSymbolInfo \
+ UnpackedTarball/zxing/core/src/datamatrix/DMDecoder \
+ UnpackedTarball/zxing/core/src/datamatrix/DMReader \
+ UnpackedTarball/zxing/core/src/datamatrix/DMBitLayout \
+ UnpackedTarball/zxing/core/src/datamatrix/DMDataBlock \
+ UnpackedTarball/zxing/core/src/datamatrix/DMECEncoder \
+ UnpackedTarball/zxing/core/src/datamatrix/DMHighLevelEncoder \
+ UnpackedTarball/zxing/core/src/GlobalHistogramBinarizer \
+ UnpackedTarball/zxing/core/src/GTIN \
+ UnpackedTarball/zxing/core/src/GenericGF \
+ UnpackedTarball/zxing/core/src/GridSampler \
+ UnpackedTarball/zxing/core/src/GenericLuminanceSource \
+ UnpackedTarball/zxing/core/src/GenericGFPoly \
+ UnpackedTarball/zxing/core/src/textcodec/GBTextEncoder \
+ UnpackedTarball/zxing/core/src/textcodec/GBTextDecoder \
+ UnpackedTarball/zxing/core/src/HybridBinarizer \
+ UnpackedTarball/zxing/core/src/textcodec/JPTextEncoder \
+ UnpackedTarball/zxing/core/src/textcodec/JPTextDecoder \
+ UnpackedTarball/zxing/core/src/textcodec/KRHangulMapping \
+ UnpackedTarball/zxing/core/src/textcodec/KRTextEncoder \
+ UnpackedTarball/zxing/core/src/textcodec/KRTextDecoder \
+ UnpackedTarball/zxing/core/src/LuminanceSource \
+ UnpackedTarball/zxing/core/src/MultiFormatWriter \
+ UnpackedTarball/zxing/core/src/MultiFormatReader \
+ UnpackedTarball/zxing/core/src/maxicode/MCDecoder \
+ UnpackedTarball/zxing/core/src/maxicode/MCBitMatrixParser \
+ UnpackedTarball/zxing/core/src/maxicode/MCReader \
+ UnpackedTarball/zxing/core/src/oned/ODUPCEWriter \
+ UnpackedTarball/zxing/core/src/oned/ODEAN8Writer \
+ UnpackedTarball/zxing/core/src/oned/ODWriterHelper \
+ UnpackedTarball/zxing/core/src/oned/ODITFWriter \
+ UnpackedTarball/zxing/core/src/oned/ODITFReader \
+ UnpackedTarball/zxing/core/src/oned/ODCode39Reader \
+ UnpackedTarball/zxing/core/src/oned/ODDataBarExpandedReader \
+ UnpackedTarball/zxing/core/src/oned/ODCode128Reader \
+ UnpackedTarball/zxing/core/src/oned/ODEAN13Writer \
+ UnpackedTarball/zxing/core/src/oned/ODMultiUPCEANReader \
+ UnpackedTarball/zxing/core/src/oned/ODCodabarWriter \
+ UnpackedTarball/zxing/core/src/oned/ODCode128Writer \
+ UnpackedTarball/zxing/core/src/oned/ODCode93Reader \
+ UnpackedTarball/zxing/core/src/oned/ODCodabarReader \
+ UnpackedTarball/zxing/core/src/oned/ODCode39Writer \
+ UnpackedTarball/zxing/core/src/oned/ODDataBarReader \
+ UnpackedTarball/zxing/core/src/oned/ODUPCEANCommon \
+ UnpackedTarball/zxing/core/src/oned/ODRowReader \
+ UnpackedTarball/zxing/core/src/oned/ODReader \
+ UnpackedTarball/zxing/core/src/oned/ODCode93Writer \
+ UnpackedTarball/zxing/core/src/oned/ODCode128Patterns \
+ UnpackedTarball/zxing/core/src/oned/ODDataBarCommon \
+ UnpackedTarball/zxing/core/src/oned/ODUPCAWriter \
+ UnpackedTarball/zxing/core/src/PerspectiveTransform \
+ UnpackedTarball/zxing/core/src/pdf417/PDFCodewordDecoder \
+ UnpackedTarball/zxing/core/src/pdf417/PDFHighLevelEncoder \
+ UnpackedTarball/zxing/core/src/pdf417/PDFDetectionResultColumn \
+ UnpackedTarball/zxing/core/src/pdf417/PDFReader \
+ UnpackedTarball/zxing/core/src/pdf417/PDFBoundingBox \
+ UnpackedTarball/zxing/core/src/pdf417/PDFScanningDecoder \
+ UnpackedTarball/zxing/core/src/pdf417/PDFModulusGF \
+ UnpackedTarball/zxing/core/src/pdf417/PDFEncoder \
+ UnpackedTarball/zxing/core/src/pdf417/PDFDecodedBitStreamParser \
+ UnpackedTarball/zxing/core/src/pdf417/PDFWriter \
+ UnpackedTarball/zxing/core/src/pdf417/PDFDetectionResult \
+ UnpackedTarball/zxing/core/src/pdf417/PDFModulusPoly \
+ UnpackedTarball/zxing/core/src/pdf417/PDFDetector \
+ UnpackedTarball/zxing/core/src/pdf417/PDFBarcodeValue \
+ UnpackedTarball/zxing/core/src/qrcode/QRDecoder \
+ UnpackedTarball/zxing/core/src/qrcode/QRReader \
+ UnpackedTarball/zxing/core/src/qrcode/QRErrorCorrectionLevel \
+ UnpackedTarball/zxing/core/src/qrcode/QRFormatInformation \
+ UnpackedTarball/zxing/core/src/qrcode/QREncoder \
+ UnpackedTarball/zxing/core/src/qrcode/QRMaskUtil \
+ UnpackedTarball/zxing/core/src/qrcode/QRWriter \
+ UnpackedTarball/zxing/core/src/qrcode/QRMatrixUtil \
+ UnpackedTarball/zxing/core/src/qrcode/QRDetector \
+ UnpackedTarball/zxing/core/src/qrcode/QRVersion \
+ UnpackedTarball/zxing/core/src/qrcode/QRCodecMode \
+ UnpackedTarball/zxing/core/src/qrcode/QRDataBlock \
+ UnpackedTarball/zxing/core/src/qrcode/QRBitMatrixParser \
+ UnpackedTarball/zxing/core/src/Result \
+ UnpackedTarball/zxing/core/src/ReadBarcode \
+ UnpackedTarball/zxing/core/src/ResultPoint \
+ UnpackedTarball/zxing/core/src/ResultMetadata \
+ UnpackedTarball/zxing/core/src/ReedSolomonDecoder \
+ UnpackedTarball/zxing/core/src/ReedSolomonEncoder \
+ UnpackedTarball/zxing/core/src/TextDecoder \
+ UnpackedTarball/zxing/core/src/TextEncoder \
+ UnpackedTarball/zxing/core/src/TextUtfEncoding \
+ UnpackedTarball/zxing/core/src/WhiteRectDetector \
+ UnpackedTarball/zxing/core/src/ZXBigInteger \
+))
+
+# vim: set noet sw=4 ts=4: \ No newline at end of file
diff --git a/external/zxing/UnpackedTarball_zxing.mk b/external/zxing/UnpackedTarball_zxing.mk
new file mode 100644
index 000000000..a171c86de
--- /dev/null
+++ b/external/zxing/UnpackedTarball_zxing.mk
@@ -0,0 +1,25 @@
+#-*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,zxing))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,zxing,$(ZXING_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,zxing,1))
+
+$(eval $(call gb_UnpackedTarball_add_patches,zxing, \
+ external/zxing/zxing_newline.patch.1 \
+ external/zxing/0001-Use-a-patch-file-to-document-changes-from-upstream-s.patch \
+ external/zxing/0002-Update-stb_image_write-from-1.14-to-1.16.patch \
+ external/zxing/0003-Update-stb_image-from-2.25-to-2.27.patch \
+ external/zxing/0004-Apply-stb-PR-1223-to-stb_image.patch \
+ external/zxing/include.patch.0 \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zxing/inc/pch/precompiled_zxing.cxx b/external/zxing/inc/pch/precompiled_zxing.cxx
new file mode 100644
index 000000000..0f24650d9
--- /dev/null
+++ b/external/zxing/inc/pch/precompiled_zxing.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_zxing.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/zxing/inc/pch/precompiled_zxing.hxx b/external/zxing/inc/pch/precompiled_zxing.hxx
new file mode 100644
index 000000000..76d0c84ff
--- /dev/null
+++ b/external/zxing/inc/pch/precompiled_zxing.hxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2021-11-03 15:03:28 using:
+ ./bin/update_pch external/zxing zxing --cutoff=1 --exclude:system --include:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./external/zxing/inc/pch/precompiled_zxing.hxx "make external/zxing.build" --find-conflicts
+*/
+
+#include <sal/config.h>
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <cctype>
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <cwctype>
+#include <fstream>
+#include <functional>
+#include <initializer_list>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <limits>
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <numeric>
+#include <optional>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <type_traits>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <aztec/AZReader.h>
+#include <aztec/AZWriter.h>
+#include <datamatrix/DMReader.h>
+#include <datamatrix/DMWriter.h>
+#include <maxicode/MCReader.h>
+#include <oned/ODCodabarWriter.h>
+#include <oned/ODCode128Writer.h>
+#include <oned/ODCode39Writer.h>
+#include <oned/ODCode93Writer.h>
+#include <oned/ODEAN13Writer.h>
+#include <oned/ODEAN8Writer.h>
+#include <oned/ODITFWriter.h>
+#include <oned/ODReader.h>
+#include <oned/ODUPCAWriter.h>
+#include <oned/ODUPCEWriter.h>
+#include <pdf417/PDFReader.h>
+#include <pdf417/PDFWriter.h>
+#include <qrcode/QRErrorCorrectionLevel.h>
+#include <qrcode/QRReader.h>
+#include <qrcode/QRWriter.h>
+#include <textcodec/Big5TextDecoder.h>
+#include <textcodec/Big5TextEncoder.h>
+#include <textcodec/GBTextDecoder.h>
+#include <textcodec/GBTextEncoder.h>
+#include <textcodec/JPTextDecoder.h>
+#include <textcodec/JPTextEncoder.h>
+#include <textcodec/KRTextDecoder.h>
+#include <textcodec/KRTextEncoder.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/external/zxing/include.patch.0 b/external/zxing/include.patch.0
new file mode 100644
index 000000000..8852b5333
--- /dev/null
+++ b/external/zxing/include.patch.0
@@ -0,0 +1,10 @@
+--- core/src/textcodec/JPTextEncoder.cpp
++++ core/src/textcodec/JPTextEncoder.cpp
+@@ -36,6 +36,7 @@
+ // and the grateful thanks of the Qt team.
+
+ #include "JPTextEncoder.h"
++#include <stdint.h>
+
+ /*
+ * This data is derived from Unicode 1.1,
diff --git a/external/zxing/zxing_newline.patch.1 b/external/zxing/zxing_newline.patch.1
new file mode 100644
index 000000000..57673e431
--- /dev/null
+++ b/external/zxing/zxing_newline.patch.1
@@ -0,0 +1,21 @@
+Add newline at end of KRHangulMapping.h
+
+without this, GCC 11 -E -fdirectives-only produces this:
+
+extern const uint16_t ksc5601_hangul_to_unicode[2350];# 38 "/workdir/UnpackedTarball/zxing/core/src/textcodec/KRHangulMapping.cpp" 2
+
+and compiling that fails with:
+
+KRHangulMapping.h:38:55: error: stray '#' in program
+
+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100392
+
+--- zxing/core/src/textcodec/KRHangulMapping.h.orig 2021-05-01 18:00:09.011795242 +0200
++++ zxing/core/src/textcodec/KRHangulMapping.h 2021-05-01 18:00:16.774788294 +0200
+@@ -35,4 +35,4 @@
+ #include <cstdint>
+
+ /* Table including ksc5601 hangul to unicode */
+-extern const uint16_t ksc5601_hangul_to_unicode[2350];
+\ No newline at end of file
++extern const uint16_t ksc5601_hangul_to_unicode[2350];