diff options
65 files changed, 4282 insertions, 986 deletions
diff --git a/3rdparty/expat/CMake.README b/3rdparty/expat/CMake.README index 86e1eb98918..ba202e7a446 100644 --- a/3rdparty/expat/CMake.README +++ b/3rdparty/expat/CMake.README @@ -3,25 +3,25 @@ The cmake based buildsystem for expat works on Windows (cygwin, mingw, Visual Studio) and should work on all other platform cmake supports. -Assuming ~/expat-2.6.4 is the source directory of expat, add a subdirectory +Assuming ~/expat-2.7.1 is the source directory of expat, add a subdirectory build and change into that directory: -~/expat-2.6.4$ mkdir build && cd build -~/expat-2.6.4/build$ +~/expat-2.7.1$ mkdir build && cd build +~/expat-2.7.1/build$ From that directory, call cmake first, then call make, make test and make install in the usual way: -~/expat-2.6.4/build$ cmake .. +~/expat-2.7.1/build$ cmake .. -- The C compiler identification is GNU -- The CXX compiler identification is GNU .... -- Configuring done -- Generating done --- Build files have been written to: /home/patrick/expat-2.6.4/build +-- Build files have been written to: /home/patrick/expat-2.7.1/build If you want to specify the install location for your files, append -DCMAKE_INSTALL_PREFIX=/your/install/path to the cmake call. -~/expat-2.6.4/build$ make && make test && make install +~/expat-2.7.1/build$ make && make test && make install Scanning dependencies of target expat [ 5%] Building C object CMakeFiles/expat.dir/lib/xmlparse.c.o [ 11%] Building C object CMakeFiles/expat.dir/lib/xmlrole.c.o diff --git a/3rdparty/expat/CMakeLists.txt b/3rdparty/expat/CMakeLists.txt index 1f650339062..4a5ea2b5847 100644 --- a/3rdparty/expat/CMakeLists.txt +++ b/3rdparty/expat/CMakeLists.txt @@ -7,7 +7,7 @@ # # Copyright (c) 2010 Patrick Spendrin <ps_ml@gmx.de> # Copyright (c) 2012 Karl Waclawek <karl@waclawek.net> -# Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> +# Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> # Copyright (c) 2016 Sergei Nikulov <sergey.nikulov@gmail.com> # Copyright (c) 2016 Björn Lindahl <bjorn.lindahl@foi.se> # Copyright (c) 2016 Tobias Taschner <github@tc84.de> @@ -30,15 +30,16 @@ # Copyright (c) 2020 Thomas Beutlich <tc@tbeu.de> # Copyright (c) 2021 Alex Richardson <Alexander.Richardson@cl.cam.ac.uk> # Copyright (c) 2022 Johnny Jazeix <jazeix@gmail.com> +# Copyright (c) 2022 Mark Brand <markbrand@google.com> # Copyright (c) 2022 David Faure <david.faure@kdab.com> # Unlike most of Expat, # this file is copyrighted under the BSD-license for buildsystem files of KDE. -cmake_minimum_required(VERSION 3.5.0) +cmake_minimum_required(VERSION 3.13.0) project(expat VERSION - 2.6.4 + 2.7.1 LANGUAGES C ) @@ -134,7 +135,7 @@ expat_shy_set(EXPAT_SHARED_LIBS ${_EXPAT_SHARED_LIBS_DEFAULT} CACHE BOOL "Build expat_shy_set(EXPAT_BUILD_DOCS ${_EXPAT_BUILD_DOCS_DEFAULT} CACHE BOOL "Build man page for xmlwf") expat_shy_set(EXPAT_BUILD_FUZZERS OFF CACHE BOOL "Build fuzzers for the expat library") expat_shy_set(EXPAT_BUILD_PKGCONFIG ${_EXPAT_BUILD_PKGCONFIG_DEFAULT} CACHE BOOL "Build pkg-config file") -expat_shy_set(EXPAT_OSSFUZZ_BUILD OFF CACHE BOOL "Build fuzzers via ossfuzz for the expat library") +expat_shy_set(EXPAT_OSSFUZZ_BUILD OFF CACHE BOOL "Build fuzzers via OSS-Fuzz for the expat library") if(UNIX OR _EXPAT_HELP) expat_shy_set(EXPAT_WITH_LIBBSD OFF CACHE BOOL "Utilize libbsd (for arc4random_buf)") endif() @@ -169,11 +170,15 @@ if(NOT _EXPAT_HELP) mark_as_advanced(_EXPAT_M32) endif() -if(EXPAT_BUILD_TESTS) +if(EXPAT_BUILD_TESTS OR EXPAT_BUILD_FUZZERS) # We have to call enable_language() before modifying any CMAKE_CXX_* variables enable_language(CXX) - set(CMAKE_CXX_STANDARD 11) + if (EXPAT_BUILD_FUZZERS) + set(CMAKE_CXX_STANDARD 17) # for std::string_view for Abseil for libprotobuf-mutator + else() + set(CMAKE_CXX_STANDARD 11) + endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # i.e. -std=c++11 rather than default -std=gnu++11 endif() @@ -320,7 +325,7 @@ if(FLAG_VISIBILITY) endif() set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -fvisibility=hidden") endif() -if(MINGW) +if(MINGW AND ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")) # Without __USE_MINGW_ANSI_STDIO the compiler produces a false positive set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -Wno-pedantic-ms-format") endif() @@ -467,7 +472,7 @@ foreach(build_type_upper endforeach() set(LIBCURRENT 11) # sync -set(LIBREVISION 0) # with +set(LIBREVISION 2) # with set(LIBAGE 10) # configure.ac! math(EXPR LIBCURRENT_MINUS_AGE "${LIBCURRENT} - ${LIBAGE}") @@ -587,7 +592,7 @@ if(EXPAT_BUILD_TOOLS) if(MINGW AND _EXPAT_UNICODE_WCHAR_T) # https://gcc.gnu.org/onlinedocs/gcc/x86-Windows-Options.html - set_target_properties(xmlwf PROPERTIES LINK_FLAGS -municode) + target_link_options(xmlwf PRIVATE -municode) endif() if(EXPAT_BUILD_DOCS) @@ -724,7 +729,7 @@ if(EXPAT_BUILD_FUZZERS) message(SEND_ERROR "OSS-Fuzz builds require the environment variable " "LIB_FUZZING_ENGINE to be set. If you are seeing this " - "warning, it points to a deeper problem in the ossfuzz " + "warning, it points to a deeper problem in the OSS-Fuzz " "build setup.") endif() @@ -743,24 +748,78 @@ if(EXPAT_BUILD_FUZZERS) target_link_libraries(${target_name} fuzzpat) target_compile_definitions(${target_name} PRIVATE ENCODING_FOR_FUZZING=${encoding_type}) - if(NOT EXPAT_OSSFUZZ_BUILD) - target_compile_options(${target_name} PRIVATE -fsanitize=fuzzer-no-link) - endif() - # NOTE: Avoiding target_link_options here only because it needs CMake >=3.13 if(EXPAT_OSSFUZZ_BUILD) - set_target_properties(${target_name} PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE}) + target_link_options(${target_name} PRIVATE $ENV{LIB_FUZZING_ENGINE}) set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE "CXX") else() - set_target_properties(${target_name} PROPERTIES LINK_FLAGS -fsanitize=fuzzer) + target_compile_options(${target_name} PRIVATE -fsanitize=fuzzer) + target_link_options(${target_name} PRIVATE -fsanitize=fuzzer) endif() set_property( TARGET ${target_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY fuzz) endforeach() endforeach() + + find_package(Protobuf REQUIRED) + + # Only include libprotobuf-mutator here so we don't build it in non-fuzz + # configurations. + include(ExternalProject) + + set(ProtobufMutator_PREFIX libprotobuf-mutator) + set(ProtobufMutator_PATH ${CMAKE_CURRENT_BINARY_DIR}/${ProtobufMutator_PREFIX}/src/${ProtobufMutator_PREFIX}) + set(ProtobufMutator_BUILD_PATH ${ProtobufMutator_PATH}-build) + set(ProtobufMutator_INCLUDE_DIR ${ProtobufMutator_PATH}) + set(ProtobufMutator_LIBRARIES ${ProtobufMutator_BUILD_PATH}/src/libfuzzer/libprotobuf-mutator-libfuzzer.a ${ProtobufMutator_BUILD_PATH}/src/libprotobuf-mutator.a) + + ExternalProject_Add( + ${ProtobufMutator_PREFIX} + PREFIX ${ProtobufMutator_PREFIX} + GIT_REPOSITORY https://github.com/google/libprotobuf-mutator.git + GIT_TAG 57928f41ae52bb27666aa15b310130d086dac245 # v1.4-16-g57928f4 + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + CMAKE_CACHE_ARGS + -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} + -DLIB_PROTO_MUTATOR_EXAMPLES:BOOL=OFF + -DLIB_PROTO_MUTATOR_TESTING:BOOL=OFF + BUILD_BYPRODUCTS ${ProtobufMutator_LIBRARIES} + UPDATE_COMMAND true + INSTALL_COMMAND true) + + # Check for availability of protobuf compiler to avoid hard-to-understand + # errors from make(1) down the line as seen with CMake 3.25.1 on Debian + if(NOT Protobuf_PROTOC_EXECUTABLE) + message(SEND_ERROR + "The protobuf compiler (protoc) could not be found. " + "Is it installed and working properly?") + endif() + + protobuf_generate_cpp(XML_LPM_FUZZER_PROTO_SRCS + XML_LPM_FUZZER_PROTO_HDRS + fuzz/xml_lpm_fuzzer.proto) + + add_executable(xml_lpm_fuzzer + fuzz/xml_lpm_fuzzer.cpp + ${XML_LPM_FUZZER_PROTO_SRCS}) + target_include_directories(xml_lpm_fuzzer PUBLIC ${ProtobufMutator_INCLUDE_DIR}) + target_link_libraries(xml_lpm_fuzzer + fuzzpat + ${ProtobufMutator_LIBRARIES} + ${Protobuf_LIBRARIES}) + add_dependencies(xml_lpm_fuzzer ${ProtobufMutator_PREFIX}) + + if(EXPAT_OSSFUZZ_BUILD) + target_link_options(xml_lpm_fuzzer PRIVATE $ENV{LIB_FUZZING_ENGINE}) + else() + target_compile_options(xml_lpm_fuzzer PRIVATE -fsanitize=fuzzer) + target_link_options(xml_lpm_fuzzer PRIVATE -fsanitize=fuzzer) + endif() + set_property(TARGET xml_lpm_fuzzer PROPERTY RUNTIME_OUTPUT_DIRECTORY fuzz) else() if(EXPAT_OSSFUZZ_BUILD) message(SEND_ERROR - "Attempting to perform an ossfuzz build without turning on the fuzzer build. " + "Attempting to perform an OSS-Fuzz build without turning on the fuzzer build. " "This is likely in error - consider adding " "-DEXPAT_BUILD_FUZZERS=ON to your cmake execution.") endif() @@ -913,13 +972,7 @@ elseif(EXPAT_CHAR_TYPE STREQUAL "wchar_t") else() set(_EXPAT_CHAR_TYPE_SUMMARY "ERROR") endif() -# NOTE: We're not accessing global property GENERATOR_IS_MULTI_CONFIG -# because that would require CMake >=3.9 -if(CMAKE_CONFIGURATION_TYPES) - set(_EXPAT_GENERATOR_IS_MULTI_CONFIG TRUE) -else() - set(_EXPAT_GENERATOR_IS_MULTI_CONFIG FALSE) -endif() +get_property(_EXPAT_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) message(STATUS "===========================================================================") message(STATUS "") diff --git a/3rdparty/expat/COPYING b/3rdparty/expat/COPYING index ce9e5939291..c6d184a8aae 100644 --- a/3rdparty/expat/COPYING +++ b/3rdparty/expat/COPYING @@ -1,5 +1,5 @@ Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper -Copyright (c) 2001-2022 Expat maintainers +Copyright (c) 2001-2025 Expat maintainers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/3rdparty/expat/Changes b/3rdparty/expat/Changes index aa19f70ae21..9d6c64b6a46 100644 --- a/3rdparty/expat/Changes +++ b/3rdparty/expat/Changes @@ -11,16 +11,23 @@ !! The following topics need *additional skilled C developers* to progress !! !! in a timely manner or at all (loosely ordered by descending priority): !! !! !! -!! - <blink>fixing a complex non-public security issue</blink>, !! !! - teaming up on researching and fixing future security reports and !! !! ClusterFuzz findings with few-days-max response times in communication !! !! in order to (1) have a sound fix ready before the end of a 90 days !! !! grace period and (2) in a sustainable manner, !! +!! - helping CPython Expat bindings with supporting Expat's billion laughs !! +!! attack protection API (https://github.com/python/cpython/issues/90949): !! +!! - XML_SetBillionLaughsAttackProtectionActivationThreshold !! +!! - XML_SetBillionLaughsAttackProtectionMaximumAmplification !! +!! - helping Perl's XML::Parser Expat bindings with supporting Expat's !! +!! security API (https://github.com/cpan-authors/XML-Parser/issues/102): !! +!! - XML_SetBillionLaughsAttackProtectionActivationThreshold !! +!! - XML_SetBillionLaughsAttackProtectionMaximumAmplification !! +!! - XML_SetReparseDeferralEnabled !! !! - implementing and auto-testing XML 1.0r5 support !! !! (needs discussion before pull requests), !! !! - smart ideas on fixing the Autotools CMake files generation issue !! !! without breaking CI (needs discussion before pull requests), !! -!! - the Windows binaries topic (needs requirements engineering first), !! !! - pushing migration from `int` to `size_t` further !! !! including edge-cases test coverage (needs discussion before anything). !! !! !! @@ -30,6 +37,116 @@ !! THANK YOU! Sebastian Pipping -- Berlin, 2024-03-09 !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +Release 2.7.1 Thu March 27 2025 + Bug fixes: + #980 #989 Restore event pointer behavior from Expat 2.6.4 + (that the fix to CVE-2024-8176 changed in 2.7.0); + affected API functions are: + - XML_GetCurrentByteCount + - XML_GetCurrentByteIndex + - XML_GetCurrentColumnNumber + - XML_GetCurrentLineNumber + - XML_GetInputContext + + Other changes: + #976 #977 Autotools: Integrate files "fuzz/xml_lpm_fuzzer.{cpp,proto}" + with Automake that were missing from 2.7.0 release tarballs + #983 #984 Fix printf format specifiers for 32bit Emscripten + #992 docs: Promote OpenSSF Best Practices self-certification + #978 tests/benchmark: Resolve mistaken double close + #986 Address compiler warnings + #990 #993 Version info bumped from 11:1:10 (libexpat*.so.1.10.1) + to 11:2:10 (libexpat*.so.1.10.2); see https://verbump.de/ + for what these numbers do + + Infrastructure: + #982 CI: Start running Perl XML::Parser integration tests + #987 CI: Enforce Clang Static Analyzer clean code + #991 CI: Re-enable warning clang-analyzer-valist.Uninitialized + for clang-tidy + #981 CI: Cover compilation with musl + #983 #984 CI: Cover compilation with 32bit Emscripten + #976 #977 CI: Protect against fuzzer files missing from future + release archives + + Special thanks to: + Berkay Eren Ürün + Matthew Fernandez + and + Perl XML::Parser + +Release 2.7.0 Thu March 13 2025 + Security fixes: + #893 #973 CVE-2024-8176 -- Fix crash from chaining a large number + of entities caused by stack overflow by resolving use of + recursion, for all three uses of entities: + - general entities in character data ("<e>&g1;</e>") + - general entities in attribute values ("<e k1='&g1;'/>") + - parameter entities ("%p1;") + Known impact is (reliable and easy) denial of service: + CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H/E:H/RL:O/RC:C + (Base Score: 7.5, Temporal Score: 7.2) + Please note that a layer of compression around XML can + significantly reduce the minimum attack payload size. + + Other changes: + #935 #937 Autotools: Make generated CMake files look for + libexpat.@SO_MAJOR@.dylib on macOS + #925 Autotools: Sync CMake templates with CMake 3.29 + #945 #962 #966 CMake: Drop support for CMake <3.13 + #942 CMake: Small fuzzing related improvements + #921 docs: Add missing documentation of error code + XML_ERROR_NOT_STARTED that was introduced with 2.6.4 + #941 docs: Document need for C++11 compiler for use from C++ + #959 tests/benchmark: Fix a (harmless) TOCTTOU + #944 Windows: Fix installer target location of file xmlwf.xml + for CMake + #953 Windows: Address warning -Wunknown-warning-option + about -Wno-pedantic-ms-format from LLVM MinGW + #971 Address Cppcheck warnings + #969 #970 Mass-migrate links from http:// to https:// + #947 #958 .. + #974 #975 Document changes since the previous release + #974 #975 Version info bumped from 11:0:10 (libexpat*.so.1.10.0) + to 11:1:10 (libexpat*.so.1.10.1); see https://verbump.de/ + for what these numbers do + + Infrastructure: + #926 tests: Increase robustness + #927 #932 .. + #930 #933 tests: Increase test coverage + #617 #950 .. + #951 #952 .. + #954 #955 .. Fuzzing: Add new fuzzer "xml_lpm_fuzzer" based on + #961 Google's libprotobuf-mutator ("LPM") + #957 Fuzzing|CI: Start producing fuzzing code coverage reports + #936 CI: Pass -q -q for LCOV >=2.1 in coverage.sh + #942 CI: Small fuzzing related improvements + #139 #203 .. + #791 #946 CI: Make GitHub Actions build using MSVC on Windows and + produce 32bit and 64bit Windows binaries + #956 CI: Get off of about-to-be-removed Ubuntu 20.04 + #960 #964 CI: Start uploading to Coverity Scan for static analysis + #972 CI: Stop loading DTD from the internet to address flaky CI + #971 CI: Adapt to breaking changes in Cppcheck + + Special thanks to: + Alexander Gieringer + Berkay Eren Ürün + Hanno Böck + Jann Horn + Mark Brand + Sebastian Andrzej Siewior + Snild Dolkow + Thomas Pröll + Tomas Korbar + valord577 + and + Google Project Zero + Linutronix + Red Hat + Siemens + Release 2.6.4 Wed November 6 2024 Security fixes: #915 CVE-2024-50602 -- Fix crash within function XML_ResumeParser @@ -46,6 +163,8 @@ Release 2.6.4 Wed November 6 2024 #904 tests: Resolve duplicate handler #317 #918 tests: Improve tests on doctype closing (ex CVE-2019-15903) #914 Fix signedness of format strings + #915 For use from C++, expat.h started requiring C++11 due to + use of C99 features #919 #920 Version info bumped from 10:3:9 (libexpat*.so.1.9.3) to 11:0:10 (libexpat*.so.1.10.0); see https://verbump.de/ for what these numbers do diff --git a/3rdparty/expat/Makefile.am b/3rdparty/expat/Makefile.am index 3a7f0a0e950..c20531a8d6c 100644 --- a/3rdparty/expat/Makefile.am +++ b/3rdparty/expat/Makefile.am @@ -6,12 +6,12 @@ # \___/_/\_\ .__/ \__,_|\__| # |_| XML parser # -# Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org> +# Copyright (c) 2017-2025 Sebastian Pipping <sebastian@pipping.org> # Copyright (c) 2018 KangLin <kl222@126.com> # Copyright (c) 2022 Johnny Jazeix <jazeix@gmail.com> # Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com> # Copyright (c) 2024 Alexander Bluhm <alexander.bluhm@gmx.net> -# Copyright (c) 2024 Dag-Erling Smrgrav <des@des.dev> +# Copyright (c) 2024 Dag-Erling Smørgrav <des@des.dev> # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining @@ -96,6 +96,8 @@ EXTRA_DIST = \ conftools/expat.m4 \ conftools/get-version.sh \ \ + fuzz/xml_lpm_fuzzer.cpp \ + fuzz/xml_lpm_fuzzer.proto \ fuzz/xml_parsebuffer_fuzzer.c \ fuzz/xml_parse_fuzzer.c \ \ diff --git a/3rdparty/expat/Makefile.in b/3rdparty/expat/Makefile.in index 2c702547191..069ec4047ee 100644 --- a/3rdparty/expat/Makefile.in +++ b/3rdparty/expat/Makefile.in @@ -22,12 +22,12 @@ # \___/_/\_\ .__/ \__,_|\__| # |_| XML parser # -# Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org> +# Copyright (c) 2017-2025 Sebastian Pipping <sebastian@pipping.org> # Copyright (c) 2018 KangLin <kl222@126.com> # Copyright (c) 2022 Johnny Jazeix <jazeix@gmail.com> # Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com> # Copyright (c) 2024 Alexander Bluhm <alexander.bluhm@gmx.net> -# Copyright (c) 2024 Dag-Erling Smrgrav <des@des.dev> +# Copyright (c) 2024 Dag-Erling Smørgrav <des@des.dev> # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining @@ -494,6 +494,8 @@ EXTRA_DIST = \ conftools/expat.m4 \ conftools/get-version.sh \ \ + fuzz/xml_lpm_fuzzer.cpp \ + fuzz/xml_lpm_fuzzer.proto \ fuzz/xml_parsebuffer_fuzzer.c \ fuzz/xml_parse_fuzzer.c \ \ diff --git a/3rdparty/expat/README.md b/3rdparty/expat/README.md index 2a90b376137..77c6bf27d30 100644 --- a/3rdparty/expat/README.md +++ b/3rdparty/expat/README.md @@ -3,6 +3,7 @@ [](https://repology.org/metapackage/expat/versions) [](https://sourceforge.net/projects/expat/files/) [](https://github.com/libexpat/libexpat/releases) +[](https://www.bestpractices.dev/projects/10205) > [!CAUTION] > @@ -11,7 +12,7 @@ > at the top of the `Changes` file. -# Expat, Release 2.6.4 +# Expat, Release 2.7.1 This is Expat, a C99 library for parsing [XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by @@ -22,9 +23,9 @@ are called when the parser discovers the associated structures in the document being parsed. A start tag is an example of the kind of structures for which you may register handlers. -Expat supports the following compilers: +Expat supports the following C99 compilers: -- GNU GCC >=4.5 +- GNU GCC >=4.5 (for use from C) or GNU GCC >=4.8.1 (for use from C++) - LLVM Clang >=3.5 - Microsoft Visual Studio >=16.0/2019 (rolling `${today} minus 5 years`) @@ -52,7 +53,7 @@ This approach leverages CMake's own [module `FindEXPAT`](https://cmake.org/cmake Notice the *uppercase* `EXPAT` in the following example: ```cmake -cmake_minimum_required(VERSION 3.0) # or 3.10, see below +cmake_minimum_required(VERSION 3.10) project(hello VERSION 1.0.0) @@ -62,17 +63,12 @@ add_executable(hello hello.c ) -# a) for CMake >=3.10 (see CMake's FindEXPAT docs) target_link_libraries(hello PUBLIC EXPAT::EXPAT) - -# b) for CMake >=3.0 -target_include_directories(hello PRIVATE ${EXPAT_INCLUDE_DIRS}) -target_link_libraries(hello PUBLIC ${EXPAT_LIBRARIES}) ``` ### b) `find_package` with Config Mode -This approach requires files from +This approach requires files from… - libexpat >=2.2.8 where packaging uses the CMake build system or @@ -85,7 +81,7 @@ or Notice the *lowercase* `expat` in the following example: ```cmake -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.10) project(hello VERSION 1.0.0) @@ -100,7 +96,7 @@ target_link_libraries(hello PUBLIC expat::expat) ### c) The `FetchContent` module -This approach as demonstrated below requires CMake >=3.18 for both the +This approach — as demonstrated below — requires CMake >=3.18 for both the [`FetchContent` module](https://cmake.org/cmake/help/latest/module/FetchContent.html) and its support for the `SOURCE_SUBDIR` option to be available. @@ -109,7 +105,7 @@ Please note that: of libexpat is neither advised nor considered officially supported. - Pinning to a specific commit is great for robust CI. - Pinning to a specific commit needs updating every time there is a new - release of libexpat either manually or through automation , + release of libexpat — either manually or through automation —, to not miss out on libexpat security updates. For an example that pulls in libexpat via Git: @@ -295,7 +291,7 @@ EXPAT_ENABLE_INSTALL:BOOL=ON // Use /MT flag (static CRT) when compiling in MSVC EXPAT_MSVC_STATIC_CRT:BOOL=OFF -// Build fuzzers via ossfuzz for the expat library +// Build fuzzers via OSS-Fuzz for the expat library EXPAT_OSSFUZZ_BUILD:BOOL=OFF // Build a shared expat library diff --git a/3rdparty/expat/cmake/autotools/expat-noconfig__macos.cmake.in b/3rdparty/expat/cmake/autotools/expat-noconfig__macos.cmake.in index bb48d9810ee..484e5bc6338 100644 --- a/3rdparty/expat/cmake/autotools/expat-noconfig__macos.cmake.in +++ b/3rdparty/expat/cmake/autotools/expat-noconfig__macos.cmake.in @@ -8,12 +8,12 @@ set(CMAKE_IMPORT_FILE_VERSION 1) # Import target "expat::expat" for configuration "NoConfig" set_property(TARGET expat::expat APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG) set_target_properties(expat::expat PROPERTIES - IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/@LIBDIR_BASENAME@/libexpat.@SO_MAJOR@.@SO_MINOR@.@SO_PATCH@.dylib" + IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/@LIBDIR_BASENAME@/libexpat.@SO_MAJOR@.dylib" IMPORTED_SONAME_NOCONFIG "@rpath/libexpat.@SO_MAJOR@.dylib" ) list(APPEND _cmake_import_check_targets expat::expat ) -list(APPEND _cmake_import_check_files_for_expat::expat "${_IMPORT_PREFIX}/@LIBDIR_BASENAME@/libexpat.@SO_MAJOR@.@SO_MINOR@.@SO_PATCH@.dylib" ) +list(APPEND _cmake_import_check_files_for_expat::expat "${_IMPORT_PREFIX}/@LIBDIR_BASENAME@/libexpat.@SO_MAJOR@.dylib" ) # Commands beyond this point should not need to know the version. set(CMAKE_IMPORT_FILE_VERSION) diff --git a/3rdparty/expat/cmake/autotools/expat.cmake b/3rdparty/expat/cmake/autotools/expat.cmake index 7850358bb3a..ecb2df12ada 100644 --- a/3rdparty/expat/cmake/autotools/expat.cmake +++ b/3rdparty/expat/cmake/autotools/expat.cmake @@ -1,13 +1,13 @@ # Generated by CMake if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8) - message(FATAL_ERROR "CMake >= 2.8.0 required") + message(FATAL_ERROR "CMake >= 2.8.12 required") endif() if(CMAKE_VERSION VERSION_LESS "2.8.12") message(FATAL_ERROR "CMake >= 2.8.12 required") endif() cmake_policy(PUSH) -cmake_policy(VERSION 2.8.12...3.28) +cmake_policy(VERSION 2.8.12...3.29) #---------------------------------------------------------------- # Generated CMake target import file. #---------------------------------------------------------------- diff --git a/3rdparty/expat/configure b/3rdparty/expat/configure index c2f7bb797ef..54b6f929686 100755 --- a/3rdparty/expat/configure +++ b/3rdparty/expat/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for expat 2.6.4. +# Generated by GNU Autoconf 2.71 for expat 2.7.1. # # Report bugs to <https://github.com/libexpat/libexpat/issues>. # @@ -621,8 +621,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='expat' PACKAGE_TARNAME='expat' -PACKAGE_VERSION='2.6.4' -PACKAGE_STRING='expat 2.6.4' +PACKAGE_VERSION='2.7.1' +PACKAGE_STRING='expat 2.7.1' PACKAGE_BUGREPORT='https://github.com/libexpat/libexpat/issues' PACKAGE_URL='' @@ -1426,7 +1426,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures expat 2.6.4 to adapt to many kinds of systems. +\`configure' configures expat 2.7.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1497,7 +1497,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of expat 2.6.4:";; + short | recursive ) echo "Configuration of expat 2.7.1:";; esac cat <<\_ACEOF @@ -1634,7 +1634,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -expat configure 2.6.4 +expat configure 2.7.1 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2265,7 +2265,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by expat $as_me 2.6.4, which was +It was created by expat $as_me 2.7.1, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3831,7 +3831,7 @@ fi # Define the identity of the package. PACKAGE='expat' - VERSION='2.6.4' + VERSION='2.7.1' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -3962,7 +3962,7 @@ fi LIBCURRENT=11 # sync -LIBREVISION=0 # with +LIBREVISION=2 # with LIBAGE=10 # CMakeLists.txt! ac_config_headers="$ac_config_headers expat_config.h" @@ -5458,8 +5458,8 @@ esac -macro_version='2.5.3' -macro_revision='2.5.3' +macro_version='2.5.4' +macro_revision='2.5.4' @@ -6220,9 +6220,9 @@ else $as_nop lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. + gnu* | ironclad*) + # Under GNU Hurd and Ironclad, this test is not required because there + # is no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; @@ -6777,7 +6777,11 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +*-mlibc) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else @@ -6811,6 +6815,10 @@ rdos*) lt_cv_deplibs_check_method=pass_all ;; +serenity*) + lt_cv_deplibs_check_method=pass_all + ;; + solaris*) lt_cv_deplibs_check_method=pass_all ;; @@ -7691,11 +7699,8 @@ _LT_EOF test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -9073,6 +9078,21 @@ printf "%s\n" "$lt_cv_ld_force_load" >&6; } if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi + _lt_dar_needs_single_mod=no + case $host_os in + rhapsody* | darwin1.*) + _lt_dar_needs_single_mod=yes ;; + darwin*) + # When targeting Mac OS X 10.4 (darwin 8) or later, + # -single_module is the default and -multi_module is unsupported. + # The toolchain on macOS 10.14 (darwin 18) and later cannot + # target any OS version that needs -single_module. + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*-darwin[567].*|10.[0-3],*-darwin[5-9].*|10.[0-3],*-darwin1[0-7].*) + _lt_dar_needs_single_mod=yes ;; + esac + ;; + esac if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else @@ -10287,7 +10307,7 @@ lt_prog_compiler_static= lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; - *flang* | ftn) + *flang* | ftn | f18* | f95*) # Flang compiler. lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' @@ -10375,6 +10395,12 @@ lt_prog_compiler_static= lt_prog_compiler_static='-Bstatic' ;; + *-mlibc) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. @@ -10391,6 +10417,9 @@ lt_prog_compiler_static= lt_prog_compiler_static='-non_shared' ;; + serenity*) + ;; + solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' @@ -10771,9 +10800,6 @@ printf %s "checking whether the $compiler linker ($LD) supports shared libraries # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; - openbsd*) - with_gnu_ld=no - ;; esac ld_shlibs=yes @@ -10884,6 +10910,7 @@ _LT_EOF enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + file_list_spec='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -10903,7 +10930,7 @@ _LT_EOF haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - link_all_deplibs=yes + link_all_deplibs=no ;; os2*) @@ -11009,6 +11036,7 @@ _LT_EOF case $cc_basename in tcc*) + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) @@ -11029,7 +11057,12 @@ _LT_EOF fi ;; - netbsd*) + *-mlibc) + 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' + ;; + + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -11436,14 +11469,14 @@ fi # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -Fe $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_cmds='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ - $CC -Fe $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' @@ -11723,11 +11756,15 @@ printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; esac ;; - netbsd*) + *-mlibc) + ;; + + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -11828,6 +11865,9 @@ printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } hardcode_libdir_separator=: ;; + serenity*) + ;; + solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then @@ -12470,28 +12510,28 @@ cygwin* | mingw* | windows* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - # If user builds GCC with mulitlibs enabled, + # If user builds GCC with multilib enabled, # it should just install on $(libdir) # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones. - if test yes = $multilib; then - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - $install_prog $dir/$dlname $destdir/$dlname~ - chmod a+x $destdir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib $destdir/$dlname'\'' || exit \$?; - fi' + if test xyes = x"$multilib"; then + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + $install_prog $dir/$dlname $destdir/$dlname~ + chmod a+x $destdir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib $destdir/$dlname'\'' || exit \$?; + fi' else - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' fi postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ @@ -12694,8 +12734,9 @@ haiku*) soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes + sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib' + sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib' + hardcode_into_libs=no ;; hpux9* | hpux10* | hpux11*) @@ -12895,6 +12936,18 @@ fi dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -12913,6 +12966,18 @@ netbsd*) hardcode_into_libs=yes ;; +*-mlibc) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='mlibc ld.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' @@ -12992,6 +13057,17 @@ rdos*) dynamic_linker=no ;; +serenity*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + dynamic_linker='SerenityOS LibELF' + ;; + solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no @@ -13089,6 +13165,493 @@ uts4*) shlibpath_var=LD_LIBRARY_PATH ;; +emscripten*) + version_type=none + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + dynamic_linker="Emscripten linker" + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + *flang* | ftn | f18* | f95*) + # Flang compiler. + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | $SED 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *-mlibc) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + serenity*) + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + +='-fPIC' + archive_cmds='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib' + archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym' + archive_cmds_need_lc=no + no_undefined_flag= + ;; + *) dynamic_linker=no ;; @@ -15323,7 +15886,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[-]L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [-]L"' else GXX=no @@ -15674,6 +16237,7 @@ fi allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes + file_list_spec_CXX='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -15717,7 +16281,7 @@ fi module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds_CXX="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" - if test yes != "$lt_cv_apple_cc_single_mod"; then + if test yes = "$_lt_dar_needs_single_mod" -a yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi @@ -15793,7 +16357,7 @@ fi haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - link_all_deplibs_CXX=yes + link_all_deplibs_CXX=no ;; hpux9*) @@ -15885,7 +16449,7 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "[-]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " [-]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -16117,6 +16681,10 @@ fi esac ;; + *-mlibc) + ld_shlibs_CXX=yes + ;; + netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' @@ -16224,7 +16792,7 @@ fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[-]L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [-]L"' else # FIXME: insert proper C++ library support @@ -16239,6 +16807,9 @@ fi ld_shlibs_CXX=no ;; + serenity*) + ;; + sunos4*) case $cc_basename in CC*) @@ -16308,7 +16879,7 @@ fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[-]L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [-]L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -16319,7 +16890,7 @@ fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[-]L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [-]L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' @@ -16833,7 +17404,9 @@ lt_prog_compiler_static_CXX= ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) + ;; + *-mlibc) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise @@ -16863,6 +17436,8 @@ lt_prog_compiler_static_CXX= ;; psos*) ;; + serenity*) + ;; solaris*) case $cc_basename in CC* | sunCC*) @@ -17535,28 +18110,28 @@ cygwin* | mingw* | windows* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - # If user builds GCC with mulitlibs enabled, + # If user builds GCC with multilib enabled, # it should just install on $(libdir) # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones. - if test yes = $multilib; then - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - $install_prog $dir/$dlname $destdir/$dlname~ - chmod a+x $destdir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib $destdir/$dlname'\'' || exit \$?; - fi' + if test xyes = x"$multilib"; then + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + $install_prog $dir/$dlname $destdir/$dlname~ + chmod a+x $destdir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib $destdir/$dlname'\'' || exit \$?; + fi' else - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' fi postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ @@ -17757,8 +18332,9 @@ haiku*) soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes + sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib' + sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib' + hardcode_into_libs=no ;; hpux9* | hpux10* | hpux11*) @@ -17958,6 +18534,18 @@ fi dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -17976,6 +18564,18 @@ netbsd*) hardcode_into_libs=yes ;; +*-mlibc) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='mlibc ld.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' @@ -18055,6 +18655,17 @@ rdos*) dynamic_linker=no ;; +serenity*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + dynamic_linker='SerenityOS LibELF' + ;; + solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no @@ -18152,6 +18763,476 @@ uts4*) shlibpath_var=LD_LIBRARY_PATH ;; +emscripten*) + version_type=none + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + dynamic_linker="Emscripten linker" + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly* | midnightbsd*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | $SED 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *-mlibc) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + serenity*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + +='-fPIC' + archive_cmds_CXX='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib' + archive_expsym_cmds_CXX='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym' + archive_cmds_need_lc_CXX=no + no_undefined_flag_CXX= + ;; + *) dynamic_linker=no ;; @@ -21018,7 +22099,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by expat $as_me 2.6.4, which was +This file was extended by expat $as_me 2.7.1, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -21086,7 +22167,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -expat config.status 2.6.4 +expat config.status 2.7.1 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/3rdparty/expat/configure.ac b/3rdparty/expat/configure.ac index 5685f73bd64..0c88b886701 100644 --- a/3rdparty/expat/configure.ac +++ b/3rdparty/expat/configure.ac @@ -11,7 +11,7 @@ dnl Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> dnl Copyright (c) 2000-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> dnl Copyright (c) 2001-2003 Greg Stein <gstein@users.sourceforge.net> dnl Copyright (c) 2006-2012 Karl Waclawek <karl@waclawek.net> -dnl Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> +dnl Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> dnl Copyright (c) 2017 S. P. Zeidler <spz@netbsd.org> dnl Copyright (c) 2017 Stephen Groat <stephen@groat.us> dnl Copyright (c) 2017-2020 Joe Orton <jorton@redhat.com> @@ -22,8 +22,8 @@ dnl Copyright (c) 2018 KangLin <kl222@126.com> dnl Copyright (c) 2019 Mohammed Khajapasha <mohammed.khajapasha@intel.com> dnl Copyright (c) 2019 Kishore Kunche <kishore.kunche@intel.com> dnl Copyright (c) 2020 Jeffrey Walton <noloader@gmail.com> -dnl Copyright (c) 2024 Ferenc Gczi <ferenc.gm@gmail.com> -dnl Copyright (c) 2024 Dag-Erling Smrgrav <des@des.dev> +dnl Copyright (c) 2024 Ferenc Géczi <ferenc.gm@gmail.com> +dnl Copyright (c) 2024 Dag-Erling Smørgrav <des@des.dev> dnl Licensed under the MIT license: dnl dnl Permission is hereby granted, free of charge, to any person obtaining @@ -85,7 +85,7 @@ dnl If the API changes incompatibly set LIBAGE back to 0 dnl LIBCURRENT=11 # sync -LIBREVISION=0 # with +LIBREVISION=2 # with LIBAGE=10 # CMakeLists.txt! AC_CONFIG_HEADERS([expat_config.h]) diff --git a/3rdparty/expat/conftools/ltmain.sh b/3rdparty/expat/conftools/ltmain.sh index ff225947570..d57f0982354 100755..100644 --- a/3rdparty/expat/conftools/ltmain.sh +++ b/3rdparty/expat/conftools/ltmain.sh @@ -2,7 +2,7 @@ ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2019-02-19.15 -# libtool (GNU libtool) 2.5.3 +# libtool (GNU libtool) 2.5.4 # Provide generalized library-building support services. # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 @@ -31,8 +31,8 @@ PROGRAM=libtool PACKAGE=libtool -VERSION=2.5.3 -package_revision=2.5.3 +VERSION=2.5.4 +package_revision=2.5.4 ## ------ ## @@ -589,7 +589,7 @@ func_require_term_colors () # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is - # useable or anything else if it does not work. + # usable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes @@ -739,7 +739,7 @@ eval 'func_dirname () # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. -# value retuned in "$func_basename_result" +# value returned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () @@ -897,7 +897,7 @@ func_mkdir_p () # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. + # list in case some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done @@ -2215,7 +2215,30 @@ func_version () # End: # Set a version string. -scriptversion='(GNU libtool) 2.5.3' +scriptversion='(GNU libtool) 2.5.4' + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + year=`date +%Y` + + cat <<EOF +$progname $scriptversion +Copyright (C) $year Free Software Foundation, Inc. +License GPLv2+: GNU GPL version 2 or later <https://gnu.org/licenses/gpl.html> +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Originally written by Gordon Matzigkeit, 1996 +(See AUTHORS for complete contributor listing) +EOF + + exit $? +} # func_echo ARG... @@ -2238,18 +2261,6 @@ func_echo () } -# func_warning ARG... -# ------------------- -# Libtool warnings are not categorized, so override funclib.sh -# func_warning with this simpler definition. -func_warning () -{ - $debug_cmd - - $warning_func ${1+"$@"} -} - - ## ---------------- ## ## Options parsing. ## ## ---------------- ## @@ -2261,19 +2272,23 @@ usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: - --config show all configuration variables - --debug enable verbose shell tracing - -n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --mode=MODE use operation mode MODE - --no-warnings equivalent to '-Wnone' - --preserve-dup-deps don't remove duplicate dependency libraries - --quiet, --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - -v, --verbose print more informational messages than default - --version print version information - -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] - -h, --help, --help-all print short, long, or detailed help message + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information + --finish use operation '--mode=finish' + --mode=MODE use operation mode MODE + --no-finish don't update shared library cache + --no-quiet, --no-silent print default informational messages + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --reorder-cache=DIRS reorder shared library cache for preferred DIRS + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. @@ -2306,7 +2321,7 @@ include the following information: compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname (GNU libtool) 2.5.3 + version: $progname $scriptversion automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` @@ -2502,8 +2517,11 @@ libtool_options_prep () opt_dry_run=false opt_help=false opt_mode= + opt_reorder_cache=false opt_preserve_dup_deps=false opt_quiet=false + opt_finishing=true + opt_warning= nonopt= preserve_args= @@ -2593,14 +2611,18 @@ libtool_parse_options () clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error - *) func_error "invalid argument for $_G_opt" + *) func_error "invalid argument '$1' for $_G_opt" exit_cmd=exit - break ;; esac shift ;; + --no-finish) + opt_finishing=false + func_append preserve_args " $_G_opt" + ;; + --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" @@ -2616,6 +2638,24 @@ libtool_parse_options () func_append preserve_args " $_G_opt" ;; + --reorder-cache) + opt_reorder_cache=true + shared_lib_dirs=$1 + if test -n "$shared_lib_dirs"; then + case $1 in + # Must begin with /: + /*) ;; + + # Catch anything else as an error (relative paths) + *) func_error "invalid argument '$1' for $_G_opt" + func_error "absolute paths are required for $_G_opt" + exit_cmd=exit + ;; + esac + fi + shift + ;; + --silent|--quiet) opt_quiet=: opt_verbose=false @@ -2652,6 +2692,18 @@ libtool_parse_options () func_add_hook func_parse_options libtool_parse_options +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + if $opt_warning; then + $debug_cmd + $warning_func ${1+"$@"} + fi +} + # libtool_validate_options [ARG]... # --------------------------------- @@ -3181,6 +3233,15 @@ func_convert_path_front_back_pathsep () # end func_convert_path_front_back_pathsep +# func_convert_delimited_path PATH ORIG_DELIMITER NEW_DELIMITER +# Replaces a delimiter for a given path. +func_convert_delimited_path () +{ + converted_path=`$ECHO "$1" | $SED "s#$2#$3#g"` +} +# end func_convert_delimited_path + + ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## @@ -3515,6 +3576,65 @@ func_dll_def_p () } +# func_reorder_shared_lib_cache DIRS +# Reorder the shared library cache by unconfiguring previous shared library cache +# and configuring preferred search directories before previous search directories. +# Previous shared library cache: /usr/lib /usr/local/lib +# Preferred search directories: /tmp/testing +# Reordered shared library cache: /tmp/testing /usr/lib /usr/local/lib +func_reorder_shared_lib_cache () +{ + $debug_cmd + + case $host_os in + openbsd*) + get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"` + func_convert_delimited_path "$get_search_directories" ':' '\ ' + save_search_directories=$converted_path + func_convert_delimited_path "$1" ':' '\ ' + + # Ensure directories exist + for dir in $converted_path; do + # Ensure each directory is an absolute path + case $dir in + /*) ;; + *) func_error "Directory '$dir' is not an absolute path" + exit $EXIT_FAILURE ;; + esac + # Ensure no trailing slashes + func_stripname '' '/' "$dir" + dir=$func_stripname_result + if test -d "$dir"; then + if test -n "$preferred_search_directories"; then + preferred_search_directories="$preferred_search_directories $dir" + else + preferred_search_directories=$dir + fi + else + func_error "Directory '$dir' does not exist" + exit $EXIT_FAILURE + fi + done + + PATH="$PATH:/sbin" ldconfig -U $save_search_directories + PATH="$PATH:/sbin" ldconfig -m $preferred_search_directories $save_search_directories + get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"` + func_convert_delimited_path "$get_search_directories" ':' '\ ' + reordered_search_directories=$converted_path + + $ECHO "Original: $save_search_directories" + $ECHO "Reordered: $reordered_search_directories" + exit $EXIT_SUCCESS + ;; + *) + func_error "--reorder-cache is not supported for host_os=$host_os." + exit $EXIT_FAILURE + ;; + esac +} +# end func_reorder_shared_lib_cache + + # func_mode_compile arg... func_mode_compile () { @@ -4087,6 +4207,12 @@ if $opt_help; then fi +# If option '--reorder-cache', reorder the shared library cache and exit. +if $opt_reorder_cache; then + func_reorder_shared_lib_cache $shared_lib_dirs +fi + + # func_mode_execute arg... func_mode_execute () { @@ -4271,7 +4397,7 @@ func_mode_finish () fi fi - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs" && $opt_finishing; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. @@ -4296,6 +4422,12 @@ func_mode_finish () for libdir in $libdirs; do $ECHO " $libdir" done + if test "false" = "$opt_finishing"; then + echo + echo "NOTE: finish_cmds were not executed during testing, so you must" + echo "manually run ldconfig to add a given test directory, LIBDIR, to" + echo "the search path for generated executables." + fi echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" @@ -4532,8 +4664,15 @@ func_mode_install () func_append dir "$objdir" if test -n "$relink_command"; then + # Strip any trailing slash from the destination. + func_stripname '' '/' "$libdir" + destlibdir=$func_stripname_result + + func_stripname '' '/' "$destdir" + s_destdir=$func_stripname_result + # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + inst_prefix_dir=`$ECHO "X$s_destdir" | $Xsed -e "s%$destlibdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that @@ -6782,6 +6921,7 @@ func_mode_link () finalize_command=$nonopt compile_rpath= + compile_rpath_tail= finalize_rpath= compile_shlibpath= finalize_shlibpath= @@ -7337,7 +7477,8 @@ func_mode_link () # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot|--sysroot) + # -q <option> for IBM XL C/C++ compiler. + -model|-arch|-isysroot|--sysroot|-q) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" @@ -8433,10 +8574,11 @@ func_mode_link () case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) - case "$compile_rpath " in + case "$compile_rpath$compile_rpath_tail " in *" $absdir "*) ;; *) case $absdir in "$progdir/"*) func_append compile_rpath " $absdir" ;; + *) func_append compile_rpath_tail " $absdir" ;; esac esac ;; @@ -8509,10 +8651,11 @@ func_mode_link () case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) - case "$compile_rpath " in + case "$compile_rpath$compile_rpath_tail " in *" $absdir "*) ;; *) case $absdir in "$progdir/"*) func_append compile_rpath " $absdir" ;; + *) func_append compile_rpath_tail " $absdir" ;; esac esac ;; @@ -8588,6 +8731,7 @@ func_mode_link () case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-emscripten*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) @@ -8876,6 +9020,8 @@ func_mode_link () done # for deplib in $libs func_append temp_rpath "$temp_rpath_tail" + func_append compile_rpath "$compile_rpath_tail" + if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" @@ -9163,6 +9309,9 @@ func_mode_link () revision=$number_minor lt_irix_increment=no ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; esac ;; no) @@ -10059,20 +10208,7 @@ func_mode_link () last_robj= k=1 - if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then - output=$output_objdir/$output_la.lnkscript - func_verbose "creating GNU ld script: $output" - echo 'INPUT (' > $output - for obj in $save_libobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - echo ')' >> $output - func_append delfiles " $output" - func_to_tool_file "$output" - output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + if test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output @@ -10091,6 +10227,19 @@ func_mode_link () func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + elif test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." diff --git a/3rdparty/expat/doc/reference.html b/3rdparty/expat/doc/reference.html index 450fea84c29..2b3bd39580a 100644 --- a/3rdparty/expat/doc/reference.html +++ b/3rdparty/expat/doc/reference.html @@ -14,12 +14,12 @@ Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> Copyright (c) 2000-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2002-2012 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2017-2024 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2017-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017 Jakub Wilk <jwilk@jwilk.net> Copyright (c) 2021 Tomas Korbar <tkorbar@redhat.com> Copyright (c) 2021 Nicolas Cavallari <nicolas.cavallari@green-communications.fr> Copyright (c) 2022 Thijs Schreijer <thijs@thijsschreijer.nl> - Copyright (c) 2023 Hanno Bck <hanno@gentoo.org> + Copyright (c) 2023 Hanno Böck <hanno@gentoo.org> Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com> Licensed under the MIT license: @@ -52,7 +52,7 @@ <div> <h1> The Expat XML Parser - <small>Release 2.6.4</small> + <small>Release 2.7.1</small> </h1> </div> <div class="content"> @@ -1267,6 +1267,11 @@ call-backs, except when parsing an external parameter entity and <code>XML_STATUS_ERROR</code> otherwise. The possible error codes are:</p> <dl> + <dt><code>XML_ERROR_NOT_STARTED</code></dt> + <dd> + when stopping or suspending a parser before it has started, + added in Expat 2.6.4. + </dd> <dt><code>XML_ERROR_SUSPENDED</code></dt> <dd>when suspending an already suspended parser.</dd> <dt><code>XML_ERROR_FINISHED</code></dt> diff --git a/3rdparty/expat/doc/xmlwf.1 b/3rdparty/expat/doc/xmlwf.1 index 61b302581ce..76aa7e30d07 100644 --- a/3rdparty/expat/doc/xmlwf.1 +++ b/3rdparty/expat/doc/xmlwf.1 @@ -5,7 +5,7 @@ \\$2 \(la\\$1\(ra\\$3 .. .if \n(.g .mso www.tmac -.TH XMLWF 1 "November 6, 2024" "" "" +.TH XMLWF 1 "March 27, 2025" "" "" .SH NAME xmlwf \- Determines if an XML document is well-formed .SH SYNOPSIS diff --git a/3rdparty/expat/doc/xmlwf.xml b/3rdparty/expat/doc/xmlwf.xml index cf6d984af46..17e9cf51c19 100644 --- a/3rdparty/expat/doc/xmlwf.xml +++ b/3rdparty/expat/doc/xmlwf.xml @@ -9,7 +9,7 @@ Copyright (c) 2001 Scott Bronson <bronson@rinspin.com> Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2009 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2016 Ardo van Rangelrooij <ardo@debian.org> Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2020 Joe Orton <jorton@redhat.com> @@ -21,7 +21,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [ <!ENTITY dhfirstname "<firstname>Scott</firstname>"> <!ENTITY dhsurname "<surname>Bronson</surname>"> - <!ENTITY dhdate "<date>November 6, 2024</date>"> + <!ENTITY dhdate "<date>March 27, 2025</date>"> <!-- Please adjust this^^ date whenever cutting a new release. --> <!ENTITY dhsection "<manvolnum>1</manvolnum>"> <!ENTITY dhemail "<email>bronson@rinspin.com</email>"> diff --git a/3rdparty/expat/expat_config.h b/3rdparty/expat/expat_config.h new file mode 100644 index 00000000000..9cb3b81a2aa --- /dev/null +++ b/3rdparty/expat/expat_config.h @@ -0,0 +1,143 @@ +/* expat_config.h. Generated from expat_config.h.in by configure. */ +/* expat_config.h.in. Generated from configure.ac by autoheader. */ + +#ifndef EXPAT_CONFIG_H +#define EXPAT_CONFIG_H 1 + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* 1234 = LILENDIAN, 4321 = BIGENDIAN */ +#define BYTEORDER 1234 + +/* Define to 1 if you have the `arc4random' function. */ +/* #undef HAVE_ARC4RANDOM */ + +/* Define to 1 if you have the `arc4random_buf' function. */ +#define HAVE_ARC4RANDOM_BUF 1 + +/* define if the compiler supports basic C++11 syntax */ +#define HAVE_CXX11 1 + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the `getrandom' function. */ +#define HAVE_GETRANDOM 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `bsd' library (-lbsd). */ +/* #undef HAVE_LIBBSD */ + +/* Define to 1 if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdio.h> header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have `syscall' and `SYS_getrandom'. */ +#define HAVE_SYSCALL_GETRANDOM 1 + +/* Define to 1 if you have the <sys/param.h> header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "expat" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://github.com/libexpat/libexpat/issues" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "expat" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "expat 2.7.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "expat" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.7.1" + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "2.7.1" + +/* 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 allow retrieving the byte offsets for attribute names and values. + */ +/* #undef XML_ATTR_INFO */ + +/* Define to specify how much context to retain around the current parse + point, 0 to disable. */ +#define XML_CONTEXT_BYTES 1024 + +/* Define to include code reading entropy from `/dev/urandom'. */ +#define XML_DEV_URANDOM 1 + +/* Define to make parameter entity parsing functionality available. */ +#define XML_DTD 1 + +/* Define as 1/0 to enable/disable support for general entities. */ +#define XML_GE 1 + +/* Define to make XML Namespaces functionality available. */ +#define XML_NS 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `long int' if <sys/types.h> does not define. */ +/* #undef off_t */ + +#endif // ndef EXPAT_CONFIG_H diff --git a/3rdparty/expat/fix-xmltest-log.sh b/3rdparty/expat/fix-xmltest-log.sh index 18cc6f642d2..4739acab6b0 100755 --- a/3rdparty/expat/fix-xmltest-log.sh +++ b/3rdparty/expat/fix-xmltest-log.sh @@ -7,7 +7,7 @@ # |_| XML parser # # Copyright (c) 2019-2022 Sebastian Pipping <sebastian@pipping.org> -# Copyright (c) 2024 Dag-Erling Smrgrav <des@des.dev> +# Copyright (c) 2024 Dag-Erling Smørgrav <des@des.dev> # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining diff --git a/3rdparty/expat/fuzz/xml_lpm_fuzzer.cpp b/3rdparty/expat/fuzz/xml_lpm_fuzzer.cpp new file mode 100644 index 00000000000..f52ea7b21e4 --- /dev/null +++ b/3rdparty/expat/fuzz/xml_lpm_fuzzer.cpp @@ -0,0 +1,464 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 2022 Mark Brand <markbrand@google.com> + Copyright (c) 2025 Sebastian Pipping <sebastian@pipping.org> + Licensed under the MIT license: + + 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. +*/ + +#if defined(NDEBUG) +# undef NDEBUG // because checks below rely on assert(...) +#endif + +#include <assert.h> +#include <stdint.h> +#include <vector> + +#include "expat.h" +#include "xml_lpm_fuzzer.pb.h" +#include "src/libfuzzer/libfuzzer_macro.h" + +static const char *g_encoding = nullptr; +static const char *g_external_entity = nullptr; +static size_t g_external_entity_size = 0; + +void +SetEncoding(const xml_lpm_fuzzer::Encoding &e) { + switch (e) { + case xml_lpm_fuzzer::Encoding::UTF8: + g_encoding = "UTF-8"; + break; + + case xml_lpm_fuzzer::Encoding::UTF16: + g_encoding = "UTF-16"; + break; + + case xml_lpm_fuzzer::Encoding::ISO88591: + g_encoding = "ISO-8859-1"; + break; + + case xml_lpm_fuzzer::Encoding::ASCII: + g_encoding = "US-ASCII"; + break; + + case xml_lpm_fuzzer::Encoding::NONE: + g_encoding = NULL; + break; + + default: + g_encoding = "UNKNOWN"; + break; + } +} + +static int g_allocation_count = 0; +static std::vector<int> g_fail_allocations = {}; + +void * +MallocHook(size_t size) { + g_allocation_count += 1; + for (auto index : g_fail_allocations) { + if (index == g_allocation_count) { + return NULL; + } + } + return malloc(size); +} + +void * +ReallocHook(void *ptr, size_t size) { + g_allocation_count += 1; + for (auto index : g_fail_allocations) { + if (index == g_allocation_count) { + return NULL; + } + } + return realloc(ptr, size); +} + +void +FreeHook(void *ptr) { + free(ptr); +} + +XML_Memory_Handling_Suite memory_handling_suite + = {MallocHook, ReallocHook, FreeHook}; + +void InitializeParser(XML_Parser parser); + +// We want a parse function that supports resumption, so that we can cover the +// suspend/resume code. +enum XML_Status +Parse(XML_Parser parser, const char *input, int input_len, int is_final) { + enum XML_Status status = XML_Parse(parser, input, input_len, is_final); + while (status == XML_STATUS_SUSPENDED) { + status = XML_ResumeParser(parser); + } + return status; +} + +// When the fuzzer is compiled with instrumentation such as ASan, then the +// accesses in TouchString will fault if they access invalid memory (ie. detect +// either a use-after-free or buffer-overflow). By calling TouchString in each +// of the callbacks, we can check that the arguments meet the API specifications +// in terms of length/null-termination. no_optimize is used to ensure that the +// compiler has to emit actual memory reads, instead of removing them. +static volatile size_t no_optimize = 0; +static void +TouchString(const XML_Char *ptr, int len = -1) { + if (! ptr) { + return; + } + + if (len == -1) { + for (XML_Char value = *ptr++; value; value = *ptr++) { + no_optimize += value; + } + } else { + for (int i = 0; i < len; ++i) { + no_optimize += ptr[i]; + } + } +} + +static void +TouchNodeAndRecurse(XML_Content *content) { + switch (content->type) { + case XML_CTYPE_EMPTY: + case XML_CTYPE_ANY: + assert(content->quant == XML_CQUANT_NONE); + assert(content->name == NULL); + assert(content->numchildren == 0); + assert(content->children == NULL); + break; + + case XML_CTYPE_MIXED: + assert(content->quant == XML_CQUANT_NONE + || content->quant == XML_CQUANT_REP); + assert(content->name == NULL); + for (unsigned int i = 0; i < content->numchildren; ++i) { + assert(content->children[i].type == XML_CTYPE_NAME); + assert(content->children[i].quant == XML_CQUANT_NONE); + assert(content->children[i].numchildren == 0); + assert(content->children[i].children == NULL); + TouchString(content->children[i].name); + } + break; + + case XML_CTYPE_NAME: + assert((content->quant == XML_CQUANT_NONE) + || (content->quant == XML_CQUANT_OPT) + || (content->quant == XML_CQUANT_REP) + || (content->quant == XML_CQUANT_PLUS)); + assert(content->numchildren == 0); + assert(content->children == NULL); + TouchString(content->name); + break; + + case XML_CTYPE_CHOICE: + case XML_CTYPE_SEQ: + assert((content->quant == XML_CQUANT_NONE) + || (content->quant == XML_CQUANT_OPT) + || (content->quant == XML_CQUANT_REP) + || (content->quant == XML_CQUANT_PLUS)); + assert(content->name == NULL); + for (unsigned int i = 0; i < content->numchildren; ++i) { + TouchNodeAndRecurse(&content->children[i]); + } + break; + + default: + assert(false); + } +} + +static void XMLCALL +ElementDeclHandler(void *userData, const XML_Char *name, XML_Content *model) { + TouchString(name); + TouchNodeAndRecurse(model); + XML_FreeContentModel((XML_Parser)userData, model); +} + +static void XMLCALL +AttlistDeclHandler(void *userData, const XML_Char *elname, + const XML_Char *attname, const XML_Char *atttype, + const XML_Char *dflt, int isrequired) { + (void)userData; + TouchString(elname); + TouchString(attname); + TouchString(atttype); + TouchString(dflt); + (void)isrequired; +} + +static void XMLCALL +XmlDeclHandler(void *userData, const XML_Char *version, + const XML_Char *encoding, int standalone) { + (void)userData; + TouchString(version); + TouchString(encoding); + (void)standalone; +} + +static void XMLCALL +StartElementHandler(void *userData, const XML_Char *name, + const XML_Char **atts) { + (void)userData; + TouchString(name); + for (size_t i = 0; atts[i] != NULL; ++i) { + TouchString(atts[i]); + } +} + +static void XMLCALL +EndElementHandler(void *userData, const XML_Char *name) { + (void)userData; + TouchString(name); +} + +static void XMLCALL +CharacterDataHandler(void *userData, const XML_Char *s, int len) { + (void)userData; + TouchString(s, len); +} + +static void XMLCALL +ProcessingInstructionHandler(void *userData, const XML_Char *target, + const XML_Char *data) { + (void)userData; + TouchString(target); + TouchString(data); +} + +static void XMLCALL +CommentHandler(void *userData, const XML_Char *data) { + TouchString(data); + // Use the comment handler to trigger parser suspend, so that we can get + // coverage of that code. + XML_StopParser((XML_Parser)userData, XML_TRUE); +} + +static void XMLCALL +StartCdataSectionHandler(void *userData) { + (void)userData; +} + +static void XMLCALL +EndCdataSectionHandler(void *userData) { + (void)userData; +} + +static void XMLCALL +DefaultHandler(void *userData, const XML_Char *s, int len) { + (void)userData; + TouchString(s, len); +} + +static void XMLCALL +StartDoctypeDeclHandler(void *userData, const XML_Char *doctypeName, + const XML_Char *sysid, const XML_Char *pubid, + int has_internal_subset) { + (void)userData; + TouchString(doctypeName); + TouchString(sysid); + TouchString(pubid); + (void)has_internal_subset; +} + +static void XMLCALL +EndDoctypeDeclHandler(void *userData) { + (void)userData; +} + +static void XMLCALL +EntityDeclHandler(void *userData, const XML_Char *entityName, + int is_parameter_entity, const XML_Char *value, + int value_length, const XML_Char *base, + const XML_Char *systemId, const XML_Char *publicId, + const XML_Char *notationName) { + (void)userData; + TouchString(entityName); + (void)is_parameter_entity; + TouchString(value, value_length); + TouchString(base); + TouchString(systemId); + TouchString(publicId); + TouchString(notationName); +} + +static void XMLCALL +NotationDeclHandler(void *userData, const XML_Char *notationName, + const XML_Char *base, const XML_Char *systemId, + const XML_Char *publicId) { + (void)userData; + TouchString(notationName); + TouchString(base); + TouchString(systemId); + TouchString(publicId); +} + +static void XMLCALL +StartNamespaceDeclHandler(void *userData, const XML_Char *prefix, + const XML_Char *uri) { + (void)userData; + TouchString(prefix); + TouchString(uri); +} + +static void XMLCALL +EndNamespaceDeclHandler(void *userData, const XML_Char *prefix) { + (void)userData; + TouchString(prefix); +} + +static int XMLCALL +NotStandaloneHandler(void *userData) { + (void)userData; + return XML_STATUS_OK; +} + +static int XMLCALL +ExternalEntityRefHandler(XML_Parser parser, const XML_Char *context, + const XML_Char *base, const XML_Char *systemId, + const XML_Char *publicId) { + int rc = XML_STATUS_ERROR; + TouchString(context); + TouchString(base); + TouchString(systemId); + TouchString(publicId); + + if (g_external_entity) { + XML_Parser ext_parser + = XML_ExternalEntityParserCreate(parser, context, g_encoding); + rc = Parse(ext_parser, g_external_entity, g_external_entity_size, 1); + XML_ParserFree(ext_parser); + } + + return rc; +} + +static void XMLCALL +SkippedEntityHandler(void *userData, const XML_Char *entityName, + int is_parameter_entity) { + (void)userData; + TouchString(entityName); + (void)is_parameter_entity; +} + +static int XMLCALL +UnknownEncodingHandler(void *encodingHandlerData, const XML_Char *name, + XML_Encoding *info) { + (void)encodingHandlerData; + TouchString(name); + (void)info; + return XML_STATUS_ERROR; +} + +void +InitializeParser(XML_Parser parser) { + XML_SetUserData(parser, (void *)parser); + XML_SetHashSalt(parser, 0x41414141); + XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); + + XML_SetElementDeclHandler(parser, ElementDeclHandler); + XML_SetAttlistDeclHandler(parser, AttlistDeclHandler); + XML_SetXmlDeclHandler(parser, XmlDeclHandler); + XML_SetElementHandler(parser, StartElementHandler, EndElementHandler); + XML_SetCharacterDataHandler(parser, CharacterDataHandler); + XML_SetProcessingInstructionHandler(parser, ProcessingInstructionHandler); + XML_SetCommentHandler(parser, CommentHandler); + XML_SetCdataSectionHandler(parser, StartCdataSectionHandler, + EndCdataSectionHandler); + // XML_SetDefaultHandler disables entity expansion + XML_SetDefaultHandlerExpand(parser, DefaultHandler); + XML_SetDoctypeDeclHandler(parser, StartDoctypeDeclHandler, + EndDoctypeDeclHandler); + // Note: This is mutually exclusive with XML_SetUnparsedEntityDeclHandler, + // and there isn't any significant code change between the two. + XML_SetEntityDeclHandler(parser, EntityDeclHandler); + XML_SetNotationDeclHandler(parser, NotationDeclHandler); + XML_SetNamespaceDeclHandler(parser, StartNamespaceDeclHandler, + EndNamespaceDeclHandler); + XML_SetNotStandaloneHandler(parser, NotStandaloneHandler); + XML_SetExternalEntityRefHandler(parser, ExternalEntityRefHandler); + XML_SetSkippedEntityHandler(parser, SkippedEntityHandler); + XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, (void *)parser); +} + +DEFINE_TEXT_PROTO_FUZZER(const xml_lpm_fuzzer::Testcase &testcase) { + g_external_entity = nullptr; + + if (! testcase.actions_size()) { + return; + } + + g_allocation_count = 0; + g_fail_allocations.clear(); + for (int i = 0; i < testcase.fail_allocations_size(); ++i) { + g_fail_allocations.push_back(testcase.fail_allocations(i)); + } + + SetEncoding(testcase.encoding()); + XML_Parser parser + = XML_ParserCreate_MM(g_encoding, &memory_handling_suite, "|"); + InitializeParser(parser); + + for (int i = 0; i < testcase.actions_size(); ++i) { + const auto &action = testcase.actions(i); + switch (action.action_case()) { + case xml_lpm_fuzzer::Action::kChunk: + if (XML_STATUS_ERROR + == Parse(parser, action.chunk().data(), action.chunk().size(), 0)) { + // Force a reset after parse error. + XML_ParserReset(parser, g_encoding); + InitializeParser(parser); + } + break; + + case xml_lpm_fuzzer::Action::kLastChunk: + Parse(parser, action.last_chunk().data(), action.last_chunk().size(), 1); + XML_ParserReset(parser, g_encoding); + InitializeParser(parser); + break; + + case xml_lpm_fuzzer::Action::kReset: + XML_ParserReset(parser, g_encoding); + InitializeParser(parser); + break; + + case xml_lpm_fuzzer::Action::kExternalEntity: + g_external_entity = action.external_entity().data(); + g_external_entity_size = action.external_entity().size(); + break; + + default: + break; + } + } + + XML_ParserFree(parser); +} diff --git a/3rdparty/expat/fuzz/xml_lpm_fuzzer.proto b/3rdparty/expat/fuzz/xml_lpm_fuzzer.proto new file mode 100644 index 00000000000..ddc4e958b91 --- /dev/null +++ b/3rdparty/expat/fuzz/xml_lpm_fuzzer.proto @@ -0,0 +1,58 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 2022 Mark Brand <markbrand@google.com> + Copyright (c) 2025 Sebastian Pipping <sebastian@pipping.org> + Licensed under the MIT license: + + 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. +*/ + +syntax = "proto2"; +package xml_lpm_fuzzer; + +enum Encoding { + UTF8 = 0; + UTF16 = 1; + ISO88591 = 2; + ASCII = 3; + UNKNOWN = 4; + NONE = 5; +} + +message Action { + oneof action { + string chunk = 1; + string last_chunk = 2; + bool reset = 3; + string external_entity = 4; + } +} + +message Testcase { + required Encoding encoding = 1; + repeated Action actions = 2; + repeated int32 fail_allocations = 3; +} diff --git a/3rdparty/expat/fuzz/xml_parse_fuzzer.c b/3rdparty/expat/fuzz/xml_parse_fuzzer.c index a7e8414ce35..6a1affe2b1f 100644 --- a/3rdparty/expat/fuzz/xml_parse_fuzzer.c +++ b/3rdparty/expat/fuzz/xml_parse_fuzzer.c @@ -5,7 +5,7 @@ * 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 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/3rdparty/expat/fuzz/xml_parsebuffer_fuzzer.c b/3rdparty/expat/fuzz/xml_parsebuffer_fuzzer.c index 0327aa9f952..cfc4af20285 100644 --- a/3rdparty/expat/fuzz/xml_parsebuffer_fuzzer.c +++ b/3rdparty/expat/fuzz/xml_parsebuffer_fuzzer.c @@ -5,7 +5,7 @@ * 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 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/3rdparty/expat/lib/expat.h b/3rdparty/expat/lib/expat.h index c2c75ef4f05..610e1ddc0e9 100644 --- a/3rdparty/expat/lib/expat.h +++ b/3rdparty/expat/lib/expat.h @@ -11,12 +11,12 @@ Copyright (c) 2000-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> - Copyright (c) 2016 Cristian Rodrguez <crrodriguez@opensuse.org> + Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org> Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de> Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2022 Thijs Schreijer <thijs@thijsschreijer.nl> - Copyright (c) 2023 Hanno Bck <hanno@gentoo.org> + Copyright (c) 2023 Hanno Böck <hanno@gentoo.org> Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com> Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> Licensed under the MIT license: @@ -1067,8 +1067,8 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled); See https://semver.org */ #define XML_MAJOR_VERSION 2 -#define XML_MINOR_VERSION 6 -#define XML_MICRO_VERSION 4 +#define XML_MINOR_VERSION 7 +#define XML_MICRO_VERSION 1 #ifdef __cplusplus } diff --git a/3rdparty/expat/lib/expat_external.h b/3rdparty/expat/lib/expat_external.h index 162e2bd0ec8..8829f770910 100644 --- a/3rdparty/expat/lib/expat_external.h +++ b/3rdparty/expat/lib/expat_external.h @@ -11,7 +11,7 @@ Copyright (c) 2000-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016 Cristian Rodrguez <crrodriguez@opensuse.org> + Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org> Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com> diff --git a/3rdparty/expat/lib/internal.h b/3rdparty/expat/lib/internal.h index 167ec36804a..6bde6ae6b31 100644 --- a/3rdparty/expat/lib/internal.h +++ b/3rdparty/expat/lib/internal.h @@ -28,7 +28,7 @@ Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net> Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> - Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com> Copyright (c) 2019 David Loffredo <loffredo@steptools.com> Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com> @@ -127,6 +127,9 @@ # elif ULONG_MAX == 18446744073709551615u // 2^64-1 # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld" # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu" +# elif defined(EMSCRIPTEN) // 32bit mode Emscripten +# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld" +# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "zu" # else # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d" # define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u" diff --git a/3rdparty/expat/lib/xmlparse.c b/3rdparty/expat/lib/xmlparse.c index 503d318abba..38a2d9657b6 100644 --- a/3rdparty/expat/lib/xmlparse.c +++ b/3rdparty/expat/lib/xmlparse.c @@ -1,4 +1,4 @@ -/* c5625880f4bf417c1463deee4eb92d86ff413f802048621c57e25fe483eb59e4 (2.6.4+) +/* d19ae032c224863c1527ba44d228cc34b99192c3a4c5a27af1f4e054d45ee031 (2.7.1+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -13,14 +13,14 @@ Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> Copyright (c) 2005-2009 Steven Solie <steven@solie.ca> Copyright (c) 2016 Eric Rahm <erahm@mozilla.com> - Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2016 Gaurav <g.gupta@samsung.com> Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de> Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr> Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com> Copyright (c) 2016 Ed Schouten <ed@nuxi.nl> Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> - Copyright (c) 2017 Vclav Slavk <vaclav@slavik.io> + Copyright (c) 2017 Václav Slavík <vaclav@slavik.io> Copyright (c) 2017 Viktor Szakats <commit@vsz.me> Copyright (c) 2017 Chanho Park <chanho61.park@samsung.com> Copyright (c) 2017 Rolf Eike Beer <eike@sf-mail.de> @@ -39,8 +39,8 @@ Copyright (c) 2022 Sean McBride <sean@rogue-research.com> Copyright (c) 2023 Owain Davies <owaind@bath.edu> Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com> - Copyright (c) 2024 Berkay Eren rn <berkay.ueruen@siemens.com> - Copyright (c) 2024 Hanno Bck <hanno@gentoo.org> + Copyright (c) 2024-2025 Berkay Eren Ürün <berkay.ueruen@siemens.com> + Copyright (c) 2024 Hanno Böck <hanno@gentoo.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -325,6 +325,10 @@ typedef struct { const XML_Char *publicId; const XML_Char *notation; XML_Bool open; + XML_Bool hasMore; /* true if entity has not been completely processed */ + /* An entity can be open while being already completely processed (hasMore == + XML_FALSE). The reason is the delayed closing of entities until their inner + entities are processed and closed */ XML_Bool is_param; XML_Bool is_internal; /* true if declared in internal subset outside PE */ } ENTITY; @@ -415,6 +419,12 @@ typedef struct { int *scaffIndex; } DTD; +enum EntityType { + ENTITY_INTERNAL, + ENTITY_ATTRIBUTE, + ENTITY_VALUE, +}; + typedef struct open_internal_entity { const char *internalEventPtr; const char *internalEventEndPtr; @@ -422,6 +432,7 @@ typedef struct open_internal_entity { ENTITY *entity; int startTagLevel; XML_Bool betweenDecl; /* WFC: PE Between Declarations */ + enum EntityType type; } OPEN_INTERNAL_ENTITY; enum XML_Account { @@ -481,8 +492,8 @@ static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, const char *next, const char **nextPtr, XML_Bool haveMore, XML_Bool allowClosingDoctype, enum XML_Account account); -static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity, - XML_Bool betweenDecl); +static enum XML_Error processEntity(XML_Parser parser, ENTITY *entity, + XML_Bool betweenDecl, enum EntityType type); static enum XML_Error doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, const char *start, const char *end, const char **endPtr, @@ -513,18 +524,22 @@ static enum XML_Error storeAttributeValue(XML_Parser parser, const char *ptr, const char *end, STRING_POOL *pool, enum XML_Account account); -static enum XML_Error appendAttributeValue(XML_Parser parser, - const ENCODING *enc, - XML_Bool isCdata, const char *ptr, - const char *end, STRING_POOL *pool, - enum XML_Account account); +static enum XML_Error +appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, + const char *ptr, const char *end, STRING_POOL *pool, + enum XML_Account account, const char **nextPtr); static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType); #if XML_GE == 1 static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end, - enum XML_Account account); + enum XML_Account account, + const char **nextPtr); +static enum XML_Error callStoreEntityValue(XML_Parser parser, + const ENCODING *enc, + const char *start, const char *end, + enum XML_Account account); #else static enum XML_Error storeSelfEntityValue(XML_Parser parser, ENTITY *entity); #endif @@ -709,6 +724,10 @@ struct XML_ParserStruct { const char *m_positionPtr; OPEN_INTERNAL_ENTITY *m_openInternalEntities; OPEN_INTERNAL_ENTITY *m_freeInternalEntities; + OPEN_INTERNAL_ENTITY *m_openAttributeEntities; + OPEN_INTERNAL_ENTITY *m_freeAttributeEntities; + OPEN_INTERNAL_ENTITY *m_openValueEntities; + OPEN_INTERNAL_ENTITY *m_freeValueEntities; XML_Bool m_defaultExpandInternalEntities; int m_tagLevel; ENTITY *m_declEntity; @@ -756,6 +775,7 @@ struct XML_ParserStruct { ACCOUNTING m_accounting; ENTITY_STATS m_entity_stats; #endif + XML_Bool m_reenter; }; #define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) @@ -1028,7 +1048,29 @@ callProcessor(XML_Parser parser, const char *start, const char *end, #if defined(XML_TESTING) g_bytesScanned += (unsigned)have_now; #endif - const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr); + // Run in a loop to eliminate dangerous recursion depths + enum XML_Error ret; + *endPtr = start; + while (1) { + // Use endPtr as the new start in each iteration, since it will + // be set to the next start point by m_processor. + ret = parser->m_processor(parser, *endPtr, end, endPtr); + + // Make parsing status (and in particular XML_SUSPENDED) take + // precedence over re-enter flag when they disagree + if (parser->m_parsingStatus.parsing != XML_PARSING) { + parser->m_reenter = XML_FALSE; + } + + if (! parser->m_reenter) { + break; + } + + parser->m_reenter = XML_FALSE; + if (ret != XML_ERROR_NONE) + return ret; + } + if (ret == XML_ERROR_NONE) { // if we consumed nothing, remember what we had on this parse attempt. if (*endPtr == start) { @@ -1139,6 +1181,8 @@ parserCreate(const XML_Char *encodingName, parser->m_freeBindingList = NULL; parser->m_freeTagList = NULL; parser->m_freeInternalEntities = NULL; + parser->m_freeAttributeEntities = NULL; + parser->m_freeValueEntities = NULL; parser->m_groupSize = 0; parser->m_groupConnector = NULL; @@ -1241,6 +1285,8 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) { parser->m_eventEndPtr = NULL; parser->m_positionPtr = NULL; parser->m_openInternalEntities = NULL; + parser->m_openAttributeEntities = NULL; + parser->m_openValueEntities = NULL; parser->m_defaultExpandInternalEntities = XML_TRUE; parser->m_tagLevel = 0; parser->m_tagStack = NULL; @@ -1251,6 +1297,8 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) { parser->m_unknownEncodingData = NULL; parser->m_parentParser = NULL; parser->m_parsingStatus.parsing = XML_INITIALIZED; + // Reentry can only be triggered inside m_processor calls + parser->m_reenter = XML_FALSE; #ifdef XML_DTD parser->m_isParamEntity = XML_FALSE; parser->m_useForeignDTD = XML_FALSE; @@ -1310,6 +1358,24 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { openEntity->next = parser->m_freeInternalEntities; parser->m_freeInternalEntities = openEntity; } + /* move m_openAttributeEntities to m_freeAttributeEntities (i.e. same task but + * for attributes) */ + openEntityList = parser->m_openAttributeEntities; + while (openEntityList) { + OPEN_INTERNAL_ENTITY *openEntity = openEntityList; + openEntityList = openEntity->next; + openEntity->next = parser->m_freeAttributeEntities; + parser->m_freeAttributeEntities = openEntity; + } + /* move m_openValueEntities to m_freeValueEntities (i.e. same task but + * for value entities) */ + openEntityList = parser->m_openValueEntities; + while (openEntityList) { + OPEN_INTERNAL_ENTITY *openEntity = openEntityList; + openEntityList = openEntity->next; + openEntity->next = parser->m_freeValueEntities; + parser->m_freeValueEntities = openEntity; + } moveToFreeBindingList(parser, parser->m_inheritedBindings); FREE(parser, parser->m_unknownEncodingMem); if (parser->m_unknownEncodingRelease) @@ -1323,6 +1389,19 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { return XML_TRUE; } +static XML_Bool +parserBusy(XML_Parser parser) { + switch (parser->m_parsingStatus.parsing) { + case XML_PARSING: + case XML_SUSPENDED: + return XML_TRUE; + case XML_INITIALIZED: + case XML_FINISHED: + default: + return XML_FALSE; + } +} + enum XML_Status XMLCALL XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { if (parser == NULL) @@ -1331,8 +1410,7 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { XXX There's no way for the caller to determine which of the XXX possible error cases caused the XML_STATUS_ERROR return. */ - if (parser->m_parsingStatus.parsing == XML_PARSING - || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parserBusy(parser)) return XML_STATUS_ERROR; /* Get rid of any previous encoding name */ @@ -1569,7 +1647,34 @@ XML_ParserFree(XML_Parser parser) { entityList = entityList->next; FREE(parser, openEntity); } - + /* free m_openAttributeEntities and m_freeAttributeEntities */ + entityList = parser->m_openAttributeEntities; + for (;;) { + OPEN_INTERNAL_ENTITY *openEntity; + if (entityList == NULL) { + if (parser->m_freeAttributeEntities == NULL) + break; + entityList = parser->m_freeAttributeEntities; + parser->m_freeAttributeEntities = NULL; + } + openEntity = entityList; + entityList = entityList->next; + FREE(parser, openEntity); + } + /* free m_openValueEntities and m_freeValueEntities */ + entityList = parser->m_openValueEntities; + for (;;) { + OPEN_INTERNAL_ENTITY *openEntity; + if (entityList == NULL) { + if (parser->m_freeValueEntities == NULL) + break; + entityList = parser->m_freeValueEntities; + parser->m_freeValueEntities = NULL; + } + openEntity = entityList; + entityList = entityList->next; + FREE(parser, openEntity); + } destroyBindings(parser->m_freeBindingList, parser); destroyBindings(parser->m_inheritedBindings, parser); poolDestroy(&parser->m_tempPool); @@ -1611,8 +1716,7 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { return XML_ERROR_INVALID_ARGUMENT; #ifdef XML_DTD /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING - || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parserBusy(parser)) return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; parser->m_useForeignDTD = useDTD; return XML_ERROR_NONE; @@ -1627,8 +1731,7 @@ XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { if (parser == NULL) return; /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING - || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parserBusy(parser)) return; parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; } @@ -1897,8 +2000,7 @@ XML_SetParamEntityParsing(XML_Parser parser, if (parser == NULL) return 0; /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING - || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parserBusy(parser)) return 0; #ifdef XML_DTD parser->m_paramEntityParsing = peParsing; @@ -1915,8 +2017,7 @@ XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { if (parser->m_parentParser) return XML_SetHashSalt(parser->m_parentParser, hash_salt); /* block after XML_Parse()/XML_ParseBuffer() has been called */ - if (parser->m_parsingStatus.parsing == XML_PARSING - || parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parserBusy(parser)) return 0; parser->m_hash_secret_salt = hash_salt; return 1; @@ -2230,6 +2331,11 @@ XML_GetBuffer(XML_Parser parser, int len) { return parser->m_bufferEnd; } +static void +triggerReenter(XML_Parser parser) { + parser->m_reenter = XML_TRUE; +} + enum XML_Status XMLCALL XML_StopParser(XML_Parser parser, XML_Bool resumable) { if (parser == NULL) @@ -2704,8 +2810,9 @@ static enum XML_Error PTRCALL contentProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doContent( - parser, 0, parser->m_encoding, start, end, endPtr, - (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); + parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, start, end, + endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer, + XML_ACCOUNT_DIRECT); if (result == XML_ERROR_NONE) { if (! storeRawNames(parser)) return XML_ERROR_NO_MEMORY; @@ -2793,6 +2900,11 @@ externalEntityInitProcessor3(XML_Parser parser, const char *start, return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; + case XML_PARSING: + if (parser->m_reenter) { + return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE + } + /* Fall through */ default: start = next; } @@ -2966,7 +3078,7 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, reportDefault(parser, enc, s, next); break; } - result = processInternalEntity(parser, entity, XML_FALSE); + result = processEntity(parser, entity, XML_FALSE, ENTITY_INTERNAL); if (result != XML_ERROR_NONE) return result; } else if (parser->m_externalEntityRefHandler) { @@ -3092,7 +3204,9 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, } if ((parser->m_tagLevel == 0) && (parser->m_parsingStatus.parsing != XML_FINISHED)) { - if (parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_SUSPENDED + || (parser->m_parsingStatus.parsing == XML_PARSING + && parser->m_reenter)) parser->m_processor = epilogProcessor; else return epilogProcessor(parser, next, end, nextPtr); @@ -3153,7 +3267,9 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, } if ((parser->m_tagLevel == 0) && (parser->m_parsingStatus.parsing != XML_FINISHED)) { - if (parser->m_parsingStatus.parsing == XML_SUSPENDED) + if (parser->m_parsingStatus.parsing == XML_SUSPENDED + || (parser->m_parsingStatus.parsing == XML_PARSING + && parser->m_reenter)) parser->m_processor = epilogProcessor; else return epilogProcessor(parser, next, end, nextPtr); @@ -3286,14 +3402,22 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, break; /* LCOV_EXCL_STOP */ } - *eventPP = s = next; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: + *eventPP = next; *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: + *eventPP = next; return XML_ERROR_ABORTED; + case XML_PARSING: + if (parser->m_reenter) { + *nextPtr = next; + return XML_ERROR_NONE; + } + /* Fall through */ default:; + *eventPP = s = next; } } /* not reached */ @@ -4210,14 +4334,21 @@ doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, /* LCOV_EXCL_STOP */ } - *eventPP = s = next; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: + *eventPP = next; *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: + *eventPP = next; return XML_ERROR_ABORTED; + case XML_PARSING: + if (parser->m_reenter) { + return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE + } + /* Fall through */ default:; + *eventPP = s = next; } } /* not reached */ @@ -4549,7 +4680,7 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end, } /* found end of entity value - can store it now */ return storeEntityValue(parser, parser->m_encoding, s, end, - XML_ACCOUNT_DIRECT); + XML_ACCOUNT_DIRECT, NULL); } else if (tok == XML_TOK_XML_DECL) { enum XML_Error result; result = processXmlDecl(parser, 0, start, next); @@ -4676,7 +4807,7 @@ entityValueProcessor(XML_Parser parser, const char *s, const char *end, break; } /* found end of entity value - can store it now */ - return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT); + return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT, NULL); } start = next; } @@ -5119,9 +5250,9 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, #if XML_GE == 1 // This will store the given replacement text in // parser->m_declEntity->textPtr. - enum XML_Error result - = storeEntityValue(parser, enc, s + enc->minBytesPerChar, - next - enc->minBytesPerChar, XML_ACCOUNT_NONE); + enum XML_Error result = callStoreEntityValue( + parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar, + XML_ACCOUNT_NONE); if (parser->m_declEntity) { parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); parser->m_declEntity->textLen @@ -5546,7 +5677,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, enum XML_Error result; XML_Bool betweenDecl = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); - result = processInternalEntity(parser, entity, betweenDecl); + result = processEntity(parser, entity, betweenDecl, ENTITY_INTERNAL); if (result != XML_ERROR_NONE) return result; handleDefault = XML_FALSE; @@ -5751,6 +5882,12 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, return XML_ERROR_NONE; case XML_FINISHED: return XML_ERROR_ABORTED; + case XML_PARSING: + if (parser->m_reenter) { + *nextPtr = next; + return XML_ERROR_NONE; + } + /* Fall through */ default: s = next; tok = XmlPrologTok(enc, s, end, &next); @@ -5818,28 +5955,58 @@ epilogProcessor(XML_Parser parser, const char *s, const char *end, default: return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; } - parser->m_eventPtr = s = next; switch (parser->m_parsingStatus.parsing) { case XML_SUSPENDED: + parser->m_eventPtr = next; *nextPtr = next; return XML_ERROR_NONE; case XML_FINISHED: + parser->m_eventPtr = next; return XML_ERROR_ABORTED; + case XML_PARSING: + if (parser->m_reenter) { + return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE + } + /* Fall through */ default:; + parser->m_eventPtr = s = next; } } } static enum XML_Error -processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) { - const char *textStart, *textEnd; - const char *next; - enum XML_Error result; - OPEN_INTERNAL_ENTITY *openEntity; +processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl, + enum EntityType type) { + OPEN_INTERNAL_ENTITY *openEntity, **openEntityList, **freeEntityList; + switch (type) { + case ENTITY_INTERNAL: + parser->m_processor = internalEntityProcessor; + openEntityList = &parser->m_openInternalEntities; + freeEntityList = &parser->m_freeInternalEntities; + break; + case ENTITY_ATTRIBUTE: + openEntityList = &parser->m_openAttributeEntities; + freeEntityList = &parser->m_freeAttributeEntities; + break; + case ENTITY_VALUE: + openEntityList = &parser->m_openValueEntities; + freeEntityList = &parser->m_freeValueEntities; + break; + /* default case serves merely as a safety net in case of a + * wrong entityType. Therefore we exclude the following lines + * from the test coverage. + * + * LCOV_EXCL_START + */ + default: + // Should not reach here + assert(0); + /* LCOV_EXCL_STOP */ + } - if (parser->m_freeInternalEntities) { - openEntity = parser->m_freeInternalEntities; - parser->m_freeInternalEntities = openEntity->next; + if (*freeEntityList) { + openEntity = *freeEntityList; + *freeEntityList = openEntity->next; } else { openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); @@ -5847,55 +6014,34 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) { return XML_ERROR_NO_MEMORY; } entity->open = XML_TRUE; + entity->hasMore = XML_TRUE; #if XML_GE == 1 entityTrackingOnOpen(parser, entity, __LINE__); #endif entity->processed = 0; - openEntity->next = parser->m_openInternalEntities; - parser->m_openInternalEntities = openEntity; + openEntity->next = *openEntityList; + *openEntityList = openEntity; openEntity->entity = entity; + openEntity->type = type; openEntity->startTagLevel = parser->m_tagLevel; openEntity->betweenDecl = betweenDecl; openEntity->internalEventPtr = NULL; openEntity->internalEventEndPtr = NULL; - textStart = (const char *)entity->textPtr; - textEnd = (const char *)(entity->textPtr + entity->textLen); - /* Set a safe default value in case 'next' does not get set */ - next = textStart; - - if (entity->is_param) { - int tok - = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, - tok, next, &next, XML_FALSE, XML_FALSE, - XML_ACCOUNT_ENTITY_EXPANSION); - } else { - result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, - textStart, textEnd, &next, XML_FALSE, - XML_ACCOUNT_ENTITY_EXPANSION); - } - if (result == XML_ERROR_NONE) { - if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { - entity->processed = (int)(next - textStart); - parser->m_processor = internalEntityProcessor; - } else if (parser->m_openInternalEntities->entity == entity) { -#if XML_GE == 1 - entityTrackingOnClose(parser, entity, __LINE__); -#endif /* XML_GE == 1 */ - entity->open = XML_FALSE; - parser->m_openInternalEntities = openEntity->next; - /* put openEntity back in list of free instances */ - openEntity->next = parser->m_freeInternalEntities; - parser->m_freeInternalEntities = openEntity; - } + // Only internal entities make use of the reenter flag + // therefore no need to set it for other entity types + if (type == ENTITY_INTERNAL) { + triggerReenter(parser); } - return result; + return XML_ERROR_NONE; } static enum XML_Error PTRCALL internalEntityProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { + UNUSED_P(s); + UNUSED_P(end); + UNUSED_P(nextPtr); ENTITY *entity; const char *textStart, *textEnd; const char *next; @@ -5905,68 +6051,67 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end, return XML_ERROR_UNEXPECTED_STATE; entity = openEntity->entity; - textStart = ((const char *)entity->textPtr) + entity->processed; - textEnd = (const char *)(entity->textPtr + entity->textLen); - /* Set a safe default value in case 'next' does not get set */ - next = textStart; - - if (entity->is_param) { - int tok - = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); - result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, - tok, next, &next, XML_FALSE, XML_TRUE, - XML_ACCOUNT_ENTITY_EXPANSION); - } else { - result = doContent(parser, openEntity->startTagLevel, - parser->m_internalEncoding, textStart, textEnd, &next, - XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION); - } - if (result != XML_ERROR_NONE) - return result; + // This will return early + if (entity->hasMore) { + textStart = ((const char *)entity->textPtr) + entity->processed; + textEnd = (const char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + next = textStart; + + if (entity->is_param) { + int tok + = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, + tok, next, &next, XML_FALSE, XML_FALSE, + XML_ACCOUNT_ENTITY_EXPANSION); + } else { + result = doContent(parser, openEntity->startTagLevel, + parser->m_internalEncoding, textStart, textEnd, &next, + XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION); + } - if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { - entity->processed = (int)(next - (const char *)entity->textPtr); + if (result != XML_ERROR_NONE) + return result; + // Check if entity is complete, if not, mark down how much of it is + // processed + if (textEnd != next + && (parser->m_parsingStatus.parsing == XML_SUSPENDED + || (parser->m_parsingStatus.parsing == XML_PARSING + && parser->m_reenter))) { + entity->processed = (int)(next - (const char *)entity->textPtr); + return result; + } + + // Entity is complete. We cannot close it here since we need to first + // process its possible inner entities (which are added to the + // m_openInternalEntities during doProlog or doContent calls above) + entity->hasMore = XML_FALSE; + triggerReenter(parser); return result; - } + } // End of entity processing, "if" block will return here + // Remove fully processed openEntity from open entity list. #if XML_GE == 1 entityTrackingOnClose(parser, entity, __LINE__); #endif + // openEntity is m_openInternalEntities' head, as we set it at the start of + // this function and we skipped doProlog and doContent calls with hasMore set + // to false. This means we can directly remove the head of + // m_openInternalEntities + assert(parser->m_openInternalEntities == openEntity); entity->open = XML_FALSE; - parser->m_openInternalEntities = openEntity->next; + parser->m_openInternalEntities = parser->m_openInternalEntities->next; + /* put openEntity back in list of free instances */ openEntity->next = parser->m_freeInternalEntities; parser->m_freeInternalEntities = openEntity; - // If there are more open entities we want to stop right here and have the - // upcoming call to XML_ResumeParser continue with entity content, or it would - // be ignored altogether. - if (parser->m_openInternalEntities != NULL - && parser->m_parsingStatus.parsing == XML_SUSPENDED) { - return XML_ERROR_NONE; - } - - if (entity->is_param) { - int tok; - parser->m_processor = prologProcessor; - tok = XmlPrologTok(parser->m_encoding, s, end, &next); - return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, - (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, - XML_ACCOUNT_DIRECT); - } else { - parser->m_processor = contentProcessor; - /* see externalEntityContentProcessor vs contentProcessor */ - result = doContent(parser, parser->m_parentParser ? 1 : 0, - parser->m_encoding, s, end, nextPtr, - (XML_Bool)! parser->m_parsingStatus.finalBuffer, - XML_ACCOUNT_DIRECT); - if (result == XML_ERROR_NONE) { - if (! storeRawNames(parser)) - return XML_ERROR_NO_MEMORY; - } - return result; + if (parser->m_openInternalEntities == NULL) { + parser->m_processor = entity->is_param ? prologProcessor : contentProcessor; } + triggerReenter(parser); + return XML_ERROR_NONE; } static enum XML_Error PTRCALL @@ -5982,8 +6127,70 @@ static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, const char *ptr, const char *end, STRING_POOL *pool, enum XML_Account account) { - enum XML_Error result - = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account); + const char *next = ptr; + enum XML_Error result = XML_ERROR_NONE; + + while (1) { + if (! parser->m_openAttributeEntities) { + result = appendAttributeValue(parser, enc, isCdata, next, end, pool, + account, &next); + } else { + OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openAttributeEntities; + if (! openEntity) + return XML_ERROR_UNEXPECTED_STATE; + + ENTITY *const entity = openEntity->entity; + const char *const textStart + = ((const char *)entity->textPtr) + entity->processed; + const char *const textEnd + = (const char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + const char *nextInEntity = textStart; + if (entity->hasMore) { + result = appendAttributeValue( + parser, parser->m_internalEncoding, isCdata, textStart, textEnd, + pool, XML_ACCOUNT_ENTITY_EXPANSION, &nextInEntity); + if (result != XML_ERROR_NONE) + break; + // Check if entity is complete, if not, mark down how much of it is + // processed. A XML_SUSPENDED check here is not required as + // appendAttributeValue will never suspend the parser. + if (textEnd != nextInEntity) { + entity->processed + = (int)(nextInEntity - (const char *)entity->textPtr); + continue; + } + + // Entity is complete. We cannot close it here since we need to first + // process its possible inner entities (which are added to the + // m_openAttributeEntities during appendAttributeValue) + entity->hasMore = XML_FALSE; + continue; + } // End of entity processing, "if" block skips the rest + + // Remove fully processed openEntity from open entity list. +#if XML_GE == 1 + entityTrackingOnClose(parser, entity, __LINE__); +#endif + // openEntity is m_openAttributeEntities' head, since we set it at the + // start of this function and because we skipped appendAttributeValue call + // with hasMore set to false. This means we can directly remove the head + // of m_openAttributeEntities + assert(parser->m_openAttributeEntities == openEntity); + entity->open = XML_FALSE; + parser->m_openAttributeEntities = parser->m_openAttributeEntities->next; + + /* put openEntity back in list of free instances */ + openEntity->next = parser->m_freeAttributeEntities; + parser->m_freeAttributeEntities = openEntity; + } + + // Break if an error occurred or there is nothing left to process + if (result || (parser->m_openAttributeEntities == NULL && end == next)) { + break; + } + } + if (result) return result; if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) @@ -5996,7 +6203,7 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, const char *ptr, const char *end, STRING_POOL *pool, - enum XML_Account account) { + enum XML_Account account, const char **nextPtr) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ #ifndef XML_DTD UNUSED_P(account); @@ -6014,6 +6221,9 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, #endif switch (tok) { case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = next; + } return XML_ERROR_NONE; case XML_TOK_INVALID: if (enc == parser->m_encoding) @@ -6154,21 +6364,11 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; } else { enum XML_Error result; - const XML_Char *textEnd = entity->textPtr + entity->textLen; - entity->open = XML_TRUE; -#if XML_GE == 1 - entityTrackingOnOpen(parser, entity, __LINE__); -#endif - result = appendAttributeValue(parser, parser->m_internalEncoding, - isCdata, (const char *)entity->textPtr, - (const char *)textEnd, pool, - XML_ACCOUNT_ENTITY_EXPANSION); -#if XML_GE == 1 - entityTrackingOnClose(parser, entity, __LINE__); -#endif - entity->open = XML_FALSE; - if (result) - return result; + result = processEntity(parser, entity, XML_FALSE, ENTITY_ATTRIBUTE); + if ((result == XML_ERROR_NONE) && (nextPtr != NULL)) { + *nextPtr = next; + } + return result; } } break; default: @@ -6197,7 +6397,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *entityTextPtr, const char *entityTextEnd, - enum XML_Account account) { + enum XML_Account account, const char **nextPtr) { DTD *const dtd = parser->m_dtd; /* save one level of indirection */ STRING_POOL *pool = &(dtd->entityValuePool); enum XML_Error result = XML_ERROR_NONE; @@ -6215,8 +6415,9 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc, return XML_ERROR_NO_MEMORY; } + const char *next; for (;;) { - const char *next + next = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */ int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); @@ -6278,16 +6479,8 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc, } else dtd->keepProcessing = dtd->standalone; } else { - entity->open = XML_TRUE; - entityTrackingOnOpen(parser, entity, __LINE__); - result = storeEntityValue( - parser, parser->m_internalEncoding, (const char *)entity->textPtr, - (const char *)(entity->textPtr + entity->textLen), - XML_ACCOUNT_ENTITY_EXPANSION); - entityTrackingOnClose(parser, entity, __LINE__); - entity->open = XML_FALSE; - if (result) - goto endEntityValue; + result = processEntity(parser, entity, XML_FALSE, ENTITY_VALUE); + goto endEntityValue; } break; } @@ -6375,6 +6568,81 @@ endEntityValue: # ifdef XML_DTD parser->m_prologState.inEntityValue = oldInEntityValue; # endif /* XML_DTD */ + // If 'nextPtr' is given, it should be updated during the processing + if (nextPtr != NULL) { + *nextPtr = next; + } + return result; +} + +static enum XML_Error +callStoreEntityValue(XML_Parser parser, const ENCODING *enc, + const char *entityTextPtr, const char *entityTextEnd, + enum XML_Account account) { + const char *next = entityTextPtr; + enum XML_Error result = XML_ERROR_NONE; + while (1) { + if (! parser->m_openValueEntities) { + result + = storeEntityValue(parser, enc, next, entityTextEnd, account, &next); + } else { + OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openValueEntities; + if (! openEntity) + return XML_ERROR_UNEXPECTED_STATE; + + ENTITY *const entity = openEntity->entity; + const char *const textStart + = ((const char *)entity->textPtr) + entity->processed; + const char *const textEnd + = (const char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + const char *nextInEntity = textStart; + if (entity->hasMore) { + result = storeEntityValue(parser, parser->m_internalEncoding, textStart, + textEnd, XML_ACCOUNT_ENTITY_EXPANSION, + &nextInEntity); + if (result != XML_ERROR_NONE) + break; + // Check if entity is complete, if not, mark down how much of it is + // processed. A XML_SUSPENDED check here is not required as + // appendAttributeValue will never suspend the parser. + if (textEnd != nextInEntity) { + entity->processed + = (int)(nextInEntity - (const char *)entity->textPtr); + continue; + } + + // Entity is complete. We cannot close it here since we need to first + // process its possible inner entities (which are added to the + // m_openValueEntities during storeEntityValue) + entity->hasMore = XML_FALSE; + continue; + } // End of entity processing, "if" block skips the rest + + // Remove fully processed openEntity from open entity list. +# if XML_GE == 1 + entityTrackingOnClose(parser, entity, __LINE__); +# endif + // openEntity is m_openValueEntities' head, since we set it at the + // start of this function and because we skipped storeEntityValue call + // with hasMore set to false. This means we can directly remove the head + // of m_openValueEntities + assert(parser->m_openValueEntities == openEntity); + entity->open = XML_FALSE; + parser->m_openValueEntities = parser->m_openValueEntities->next; + + /* put openEntity back in list of free instances */ + openEntity->next = parser->m_freeValueEntities; + parser->m_freeValueEntities = openEntity; + } + + // Break if an error occurred or there is nothing left to process + if (result + || (parser->m_openValueEntities == NULL && entityTextEnd == next)) { + break; + } + } + return result; } @@ -7983,7 +8251,7 @@ entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity, (void *)rootParser, rootParser->m_entity_stats.countEverOpened, rootParser->m_entity_stats.currentDepth, rootParser->m_entity_stats.maximumDepthSeen, - (rootParser->m_entity_stats.currentDepth - 1) * 2, "", + ((int)rootParser->m_entity_stats.currentDepth - 1) * 2, "", entity->is_param ? "%" : "&", entityName, action, entity->textLen, sourceLine); } @@ -8542,11 +8810,13 @@ unsignedCharToPrintable(unsigned char c) { return "\\xFE"; case 255: return "\\xFF"; + // LCOV_EXCL_START default: assert(0); /* never gets here */ return "dead code"; } assert(0); /* never gets here */ + // LCOV_EXCL_STOP } #endif /* XML_GE == 1 */ diff --git a/3rdparty/expat/lib/xmltok.c b/3rdparty/expat/lib/xmltok.c index 3864b9e6676..29a66d72cee 100644 --- a/3rdparty/expat/lib/xmltok.c +++ b/3rdparty/expat/lib/xmltok.c @@ -18,12 +18,12 @@ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2017 Alexander Bluhm <alexander.bluhm@gmx.net> Copyright (c) 2017 Benbuck Nason <bnason@netflix.com> - Copyright (c) 2017 Jos Gutirrez de la Concha <jose@zeroc.com> + Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> Copyright (c) 2019 David Loffredo <loffredo@steptools.com> Copyright (c) 2021 Donghee Na <donghee.na@python.org> Copyright (c) 2022 Martin Ettl <ettl.martin78@googlemail.com> Copyright (c) 2022 Sean McBride <sean@rogue-research.com> - Copyright (c) 2023 Hanno Bck <hanno@gentoo.org> + Copyright (c) 2023 Hanno Böck <hanno@gentoo.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining diff --git a/3rdparty/expat/m4/libtool.m4 b/3rdparty/expat/m4/libtool.m4 index fcfc1c836ea..91a91f82904 100644 --- a/3rdparty/expat/m4/libtool.m4 +++ b/3rdparty/expat/m4/libtool.m4 @@ -32,7 +32,7 @@ m4_define([_LT_COPYING], [dnl # along with this program. If not, see <http://www.gnu.org/licenses/>. ]) -# serial 62 LT_INIT +# serial 63 LT_INIT # LT_PREREQ(VERSION) @@ -1100,6 +1100,21 @@ _LT_EOF if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi + _lt_dar_needs_single_mod=no + case $host_os in + rhapsody* | darwin1.*) + _lt_dar_needs_single_mod=yes ;; + darwin*) + # When targeting Mac OS X 10.4 (darwin 8) or later, + # -single_module is the default and -multi_module is unsupported. + # The toolchain on macOS 10.14 (darwin 18) and later cannot + # target any OS version that needs -single_module. + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*-darwin[[567]].*|10.[[0-3]],*-darwin[[5-9]].*|10.[[0-3]],*-darwin1[[0-7]].*) + _lt_dar_needs_single_mod=yes ;; + esac + ;; + esac if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else @@ -1145,7 +1160,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], -[ if test yes != "$lt_cv_apple_cc_single_mod"; then +[ if test yes = "$_lt_dar_needs_single_mod" -a yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi @@ -1710,9 +1725,9 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. + gnu* | ironclad*) + # Under GNU Hurd and Ironclad, this test is not required because there + # is no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; @@ -2566,28 +2581,28 @@ cygwin* | mingw* | windows* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - # If user builds GCC with mulitlibs enabled, + # If user builds GCC with multilib enabled, # it should just install on $(libdir) # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones. - if test yes = $multilib; then - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - $install_prog $dir/$dlname $destdir/$dlname~ - chmod a+x $destdir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib $destdir/$dlname'\'' || exit \$?; - fi' + if test xyes = x"$multilib"; then + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + $install_prog $dir/$dlname $destdir/$dlname~ + chmod a+x $destdir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib $destdir/$dlname'\'' || exit \$?; + fi' else - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' fi postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ @@ -2784,8 +2799,9 @@ haiku*) soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes + sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib' + sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib' + hardcode_into_libs=no ;; hpux9* | hpux10* | hpux11*) @@ -2963,6 +2979,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -2981,6 +3009,18 @@ netbsd*) hardcode_into_libs=yes ;; +*-mlibc) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='mlibc ld.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' @@ -3060,6 +3100,17 @@ rdos*) dynamic_linker=no ;; +serenity*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + dynamic_linker='SerenityOS LibELF' + ;; + solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no @@ -3157,6 +3208,21 @@ uts4*) shlibpath_var=LD_LIBRARY_PATH ;; +emscripten*) + version_type=none + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + dynamic_linker="Emscripten linker" + _LT_COMPILER_PIC($1)='-fPIC' + _LT_TAGVAR(archive_cmds, $1)='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(no_undefined_flag, $1)= + ;; + *) dynamic_linker=no ;; @@ -3621,7 +3687,11 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +*-mlibc) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else @@ -3655,6 +3725,10 @@ rdos*) lt_cv_deplibs_check_method=pass_all ;; +serenity*) + lt_cv_deplibs_check_method=pass_all + ;; + solaris*) lt_cv_deplibs_check_method=pass_all ;; @@ -4127,7 +4201,8 @@ _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -4499,7 +4574,9 @@ m4_if([$1], [CXX], [ ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) + ;; + *-mlibc) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise @@ -4529,6 +4606,8 @@ m4_if([$1], [CXX], [ ;; psos*) ;; + serenity*) + ;; solaris*) case $cc_basename in CC* | sunCC*) @@ -4767,7 +4846,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; - *flang* | ftn) + *flang* | ftn | f18* | f95*) # Flang compiler. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' @@ -4855,6 +4934,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; + *-mlibc) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. @@ -4871,6 +4956,9 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; + serenity*) + ;; + solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' @@ -5076,9 +5164,6 @@ dnl Note also adjust exclude_expsyms for C++ above. # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; - openbsd*) - with_gnu_ld=no - ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes @@ -5189,6 +5274,7 @@ _LT_EOF _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + _LT_TAGVAR(file_list_spec, $1)='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -5208,7 +5294,7 @@ _LT_EOF haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=no ;; os2*) @@ -5314,6 +5400,7 @@ _LT_EOF case $cc_basename in tcc*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) @@ -5334,7 +5421,12 @@ _LT_EOF fi ;; - netbsd*) + *-mlibc) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -5653,14 +5745,14 @@ _LT_EOF # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -Fe $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ - $CC -Fe $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' @@ -5872,11 +5964,15 @@ _LT_EOF # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; - netbsd*) + *-mlibc) + ;; + + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -5977,6 +6073,9 @@ _LT_EOF _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; + serenity*) + ;; + solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then @@ -6502,7 +6601,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' else GXX=no @@ -6764,6 +6863,7 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -6851,7 +6951,7 @@ if test yes != "$_lt_caught_CXX_error"; then haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=no ;; hpux9*) @@ -6943,7 +7043,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " [[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -7175,6 +7275,10 @@ if test yes != "$_lt_caught_CXX_error"; then esac ;; + *-mlibc) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' @@ -7282,7 +7386,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' else # FIXME: insert proper C++ library support @@ -7297,6 +7401,9 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(ld_shlibs, $1)=no ;; + serenity*) + ;; + sunos4*) case $cc_basename in CC*) @@ -7366,7 +7473,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -7377,7 +7484,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' diff --git a/3rdparty/expat/m4/ltversion.m4 b/3rdparty/expat/m4/ltversion.m4 index 149c9719fa5..228df3f39bf 100644 --- a/3rdparty/expat/m4/ltversion.m4 +++ b/3rdparty/expat/m4/ltversion.m4 @@ -10,15 +10,15 @@ # @configure_input@ -# serial 4392 ltversion.m4 +# serial 4441 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.5.3]) -m4_define([LT_PACKAGE_REVISION], [2.5.3]) +m4_define([LT_PACKAGE_VERSION], [2.5.4]) +m4_define([LT_PACKAGE_REVISION], [2.5.4]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.5.3' -macro_revision='2.5.3' +[macro_version='2.5.4' +macro_revision='2.5.4' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/3rdparty/expat/tests/Makefile.am b/3rdparty/expat/tests/Makefile.am index 3b1b15302a6..d25376be541 100644 --- a/3rdparty/expat/tests/Makefile.am +++ b/3rdparty/expat/tests/Makefile.am @@ -9,7 +9,7 @@ # Copyright (c) 2017-2024 Sebastian Pipping <sebastian@pipping.org> # Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> # Copyright (c) 2020 Jeffrey Walton <noloader@gmail.com> -# Copyright (c) 2024 Dag-Erling Smrgrav <des@des.dev> +# Copyright (c) 2024 Dag-Erling Smørgrav <des@des.dev> # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining diff --git a/3rdparty/expat/tests/Makefile.in b/3rdparty/expat/tests/Makefile.in index c1afa35c334..eb00a068cbd 100644 --- a/3rdparty/expat/tests/Makefile.in +++ b/3rdparty/expat/tests/Makefile.in @@ -25,7 +25,7 @@ # Copyright (c) 2017-2024 Sebastian Pipping <sebastian@pipping.org> # Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> # Copyright (c) 2020 Jeffrey Walton <noloader@gmail.com> -# Copyright (c) 2024 Dag-Erling Smrgrav <des@des.dev> +# Copyright (c) 2024 Dag-Erling Smørgrav <des@des.dev> # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining diff --git a/3rdparty/expat/tests/acc_tests.c b/3rdparty/expat/tests/acc_tests.c index f193aa58a49..b58647a2ab0 100644 --- a/3rdparty/expat/tests/acc_tests.c +++ b/3rdparty/expat/tests/acc_tests.c @@ -360,13 +360,16 @@ END_TEST START_TEST(test_helper_unsigned_char_to_printable) { // Smoke test unsigned char uc = 0; - for (; uc < (unsigned char)-1; uc++) { + for (;; uc++) { set_subtest("char %u", (unsigned)uc); const char *const printable = unsignedCharToPrintable(uc); if (printable == NULL) fail("unsignedCharToPrintable returned NULL"); else if (strlen(printable) < (size_t)1) fail("unsignedCharToPrintable returned empty string"); + if (uc == (unsigned char)-1) { + break; + } } // Two concrete samples diff --git a/3rdparty/expat/tests/alloc_tests.c b/3rdparty/expat/tests/alloc_tests.c index e5d46ebea82..12ea3b2a81d 100644 --- a/3rdparty/expat/tests/alloc_tests.c +++ b/3rdparty/expat/tests/alloc_tests.c @@ -19,6 +19,7 @@ Copyright (c) 2020 Tim Gates <tim.gates@iress.com> Copyright (c) 2021 Donghee Na <donghee.na@python.org> Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com> + Copyright (c) 2025 Berkay Eren Ürün <berkay.ueruen@siemens.com> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -450,6 +451,31 @@ START_TEST(test_alloc_internal_entity) { } END_TEST +START_TEST(test_alloc_parameter_entity) { + const char *text = "<!DOCTYPE foo [" + "<!ENTITY % param1 \"<!ENTITY internal 'some_text'>\">" + "%param1;" + "]> <foo>&internal;content</foo>"; + int i; + const int alloc_test_max_repeats = 30; + + for (i = 0; i < alloc_test_max_repeats; i++) { + g_allocation_count = i; + XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); + if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) + != XML_STATUS_ERROR) + break; + alloc_teardown(); + alloc_setup(); + } + g_allocation_count = -1; + if (i == 0) + fail("Parameter entity processed despite duff allocator"); + if (i == alloc_test_max_repeats) + fail("Parameter entity not processed at max allocation count"); +} +END_TEST + /* Test the robustness against allocation failure of element handling * Based on test_dtd_default_handling(). */ @@ -2079,6 +2105,7 @@ make_alloc_test_case(Suite *s) { tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_external_entity); tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_ext_entity_set_encoding); tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_internal_entity); + tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_parameter_entity); tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_dtd_default_handling); tcase_add_test(tc_alloc, test_alloc_explicit_encoding); tcase_add_test(tc_alloc, test_alloc_set_base); diff --git a/3rdparty/expat/tests/basic_tests.c b/3rdparty/expat/tests/basic_tests.c index d38b8fd1841..e813df8b6fd 100644 --- a/3rdparty/expat/tests/basic_tests.c +++ b/3rdparty/expat/tests/basic_tests.c @@ -10,7 +10,7 @@ Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2017 Joe Orton <jorton@redhat.com> Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> @@ -19,6 +19,7 @@ Copyright (c) 2020 Tim Gates <tim.gates@iress.com> Copyright (c) 2021 Donghee Na <donghee.na@python.org> Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com> + Copyright (c) 2024-2025 Berkay Eren Ürün <berkay.ueruen@siemens.com> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -1191,6 +1192,22 @@ START_TEST(test_not_standalone_handler_accept) { } END_TEST +START_TEST(test_entity_start_tag_level_greater_than_one) { + const char *const text = "<!DOCTYPE t1 [\n" + " <!ENTITY e1 'hello'>\n" + "]>\n" + "<t1>\n" + " <t2>&e1;</t2>\n" + "</t1>\n"; + + XML_Parser parser = XML_ParserCreate(NULL); + assert_true(_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), + /*isFinal*/ XML_TRUE) + == XML_STATUS_OK); + XML_ParserFree(parser); +} +END_TEST + START_TEST(test_wfc_no_recursive_entity_refs) { const char *text = "<!DOCTYPE doc [\n" " <!ENTITY entity '&entity;'>\n" @@ -1202,6 +1219,93 @@ START_TEST(test_wfc_no_recursive_entity_refs) { } END_TEST +START_TEST(test_no_indirectly_recursive_entity_refs) { + struct TestCase { + const char *doc; + bool usesParameterEntities; + }; + + const struct TestCase cases[] = { + // general entity + character data + {"<!DOCTYPE a [\n" + " <!ENTITY e1 '&e2;'>\n" + " <!ENTITY e2 '&e1;'>\n" + "]><a>&e2;</a>\n", + false}, + + // general entity + attribute value + {"<!DOCTYPE a [\n" + " <!ENTITY e1 '&e2;'>\n" + " <!ENTITY e2 '&e1;'>\n" + "]><a k1='&e2;' />\n", + false}, + + // parameter entity + {"<!DOCTYPE doc [\n" + " <!ENTITY % p1 '%p2;'>\n" + " <!ENTITY % p2 '%p1;'>\n" + " <!ENTITY % define_g \"<!ENTITY g '%p2;'>\">\n" + " %define_g;\n" + "]>\n" + "<doc/>\n", + true}, + }; + const XML_Bool reset_or_not[] = {XML_TRUE, XML_FALSE}; + + for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { + for (size_t j = 0; j < sizeof(reset_or_not) / sizeof(reset_or_not[0]); + j++) { + const XML_Bool reset_wanted = reset_or_not[j]; + const char *const doc = cases[i].doc; + const bool usesParameterEntities = cases[i].usesParameterEntities; + + set_subtest("[%i,reset=%i] %s", (int)i, (int)j, doc); + +#ifdef XML_DTD // both GE and DTD + const bool rejection_expected = true; +#elif XML_GE == 1 // GE but not DTD + const bool rejection_expected = ! usesParameterEntities; +#else // neither DTD nor GE + const bool rejection_expected = false; +#endif + + XML_Parser parser = XML_ParserCreate(NULL); + +#ifdef XML_DTD + if (usesParameterEntities) { + assert_true( + XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS) + == 1); + } +#else + UNUSED_P(usesParameterEntities); +#endif // XML_DTD + + const enum XML_Status status + = _XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), + /*isFinal*/ XML_TRUE); + + if (rejection_expected) { + assert_true(status == XML_STATUS_ERROR); + assert_true(XML_GetErrorCode(parser) == XML_ERROR_RECURSIVE_ENTITY_REF); + } else { + assert_true(status == XML_STATUS_OK); + } + + if (reset_wanted) { + // This covers free'ing of (eventually) all three open entity lists by + // XML_ParserReset. + XML_ParserReset(parser, NULL); + } + + // This covers free'ing of (eventually) all three open entity lists by + // XML_ParserFree (unless XML_ParserReset has already done that above). + XML_ParserFree(parser); + } + } +} +END_TEST + START_TEST(test_recursive_external_parameter_entity_2) { struct TestCase { const char *doc; @@ -1417,7 +1521,9 @@ START_TEST(test_suspend_parser_between_char_data_calls) { XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler); g_resumable = XML_TRUE; - if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) + // can't use SINGLE_BYTES here, because it'll return early on suspension, and + // we won't know exactly how much input we actually managed to give Expat. + if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED) xml_failure(g_parser); if (XML_GetErrorCode(g_parser) != XML_ERROR_NONE) @@ -1446,7 +1552,9 @@ START_TEST(test_repeated_stop_parser_between_char_data_calls) { XML_SetCharacterDataHandler(g_parser, parser_stop_character_handler); g_resumable = XML_TRUE; g_abortable = XML_FALSE; - if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) + // can't use SINGLE_BYTES here, because it'll return early on suspension, and + // we won't know exactly how much input we actually managed to give Expat. + if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED) fail("Failed to double-suspend parser"); @@ -1830,12 +1938,19 @@ END_TEST /* Test suspending the parser in cdata handler */ START_TEST(test_suspend_parser_between_cdata_calls) { + if (g_chunkSize != 0) { + // this test does not use SINGLE_BYTES, because of suspension + return; + } + const char *text = long_cdata_text; enum XML_Status result; XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler); g_resumable = XML_TRUE; - result = _XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE); + // can't use SINGLE_BYTES here, because it'll return early on suspension, and + // we won't know exactly how much input we actually managed to give Expat. + result = XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE); if (result != XML_STATUS_SUSPENDED) { if (result == XML_STATUS_ERROR) xml_failure(g_parser); @@ -2378,6 +2493,11 @@ END_TEST * entity. Exercises some obscure code in XML_ParserReset(). */ START_TEST(test_reset_in_entity) { + if (g_chunkSize != 0) { + // this test does not use SINGLE_BYTES, because of suspension + return; + } + const char *text = "<!DOCTYPE doc [\n" "<!ENTITY wombat 'wom'>\n" "<!ENTITY entity 'hi &wom; there'>\n" @@ -2387,7 +2507,9 @@ START_TEST(test_reset_in_entity) { g_resumable = XML_TRUE; XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler); - if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) + // can't use SINGLE_BYTES here, because it'll return early on suspension, and + // we won't know exactly how much input we actually managed to give Expat. + if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) xml_failure(g_parser); XML_GetParsingStatus(g_parser, &status); @@ -3634,7 +3756,9 @@ START_TEST(test_suspend_xdecl) { XML_SetXmlDeclHandler(g_parser, entity_suspending_xdecl_handler); XML_SetUserData(g_parser, g_parser); g_resumable = XML_TRUE; - if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) + // can't use SINGLE_BYTES here, because it'll return early on suspension, and + // we won't know exactly how much input we actually managed to give Expat. + if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED) xml_failure(g_parser); if (XML_GetErrorCode(g_parser) != XML_ERROR_NONE) @@ -3830,13 +3954,20 @@ END_TEST /* Test syntax error is caught at parse resumption */ START_TEST(test_resume_entity_with_syntax_error) { + if (g_chunkSize != 0) { + // this test does not use SINGLE_BYTES, because of suspension + return; + } + const char *text = "<!DOCTYPE doc [\n" "<!ENTITY foo '<suspend>Hi</wombat>'>\n" "]>\n" "<doc>&foo;</doc>\n"; XML_SetStartElementHandler(g_parser, start_element_suspender); - if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) + // can't use SINGLE_BYTES here, because it'll return early on suspension, and + // we won't know exactly how much input we actually managed to give Expat. + if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED) xml_failure(g_parser); if (XML_ResumeParser(g_parser) != XML_STATUS_ERROR) @@ -3960,7 +4091,7 @@ START_TEST(test_skipped_null_loaded_ext_entity) { = {"<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n" "<!ENTITY % pe2 '%pe1;'>\n" "%pe2;\n", - external_entity_null_loader}; + external_entity_null_loader, NULL}; XML_SetUserData(g_parser, &test_data); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); @@ -3978,7 +4109,7 @@ START_TEST(test_skipped_unloaded_ext_entity) { = {"<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n" "<!ENTITY % pe2 '%pe1;'>\n" "%pe2;\n", - NULL}; + NULL, NULL}; XML_SetUserData(g_parser, &test_data); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); @@ -5278,6 +5409,151 @@ START_TEST(test_pool_integrity_with_unfinished_attr) { } END_TEST +/* Test a possible early return location in internalEntityProcessor */ +START_TEST(test_entity_ref_no_elements) { + const char *const text = "<!DOCTYPE foo [\n" + "<!ENTITY e1 \"test\">\n" + "]> <foo>&e1;"; // intentionally missing newline + + XML_Parser parser = XML_ParserCreate(NULL); + assert_true(_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) + == XML_STATUS_ERROR); + assert_true(XML_GetErrorCode(parser) == XML_ERROR_NO_ELEMENTS); + XML_ParserFree(parser); +} +END_TEST + +/* Tests if chained entity references lead to unbounded recursion */ +START_TEST(test_deep_nested_entity) { + const size_t N_LINES = 60000; + const size_t SIZE_PER_LINE = 50; + + char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE); + if (text == NULL) { + fail("malloc failed"); + } + + char *textPtr = text; + + // Create the XML + textPtr += snprintf(textPtr, SIZE_PER_LINE, + "<!DOCTYPE foo [\n" + " <!ENTITY s0 'deepText'>\n"); + + for (size_t i = 1; i < N_LINES; ++i) { + textPtr += snprintf(textPtr, SIZE_PER_LINE, " <!ENTITY s%lu '&s%lu;'>\n", + (long unsigned)i, (long unsigned)(i - 1)); + } + + snprintf(textPtr, SIZE_PER_LINE, "]> <foo>&s%lu;</foo>\n", + (long unsigned)(N_LINES - 1)); + + const XML_Char *const expected = XCS("deepText"); + + CharData storage; + CharData_Init(&storage); + + XML_Parser parser = XML_ParserCreate(NULL); + + XML_SetCharacterDataHandler(parser, accumulate_characters); + XML_SetUserData(parser, &storage); + + if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) + == XML_STATUS_ERROR) + xml_failure(parser); + + CharData_CheckXMLChars(&storage, expected); + XML_ParserFree(parser); + free(text); +} +END_TEST + +/* Tests if chained entity references in attributes +lead to unbounded recursion */ +START_TEST(test_deep_nested_attribute_entity) { + const size_t N_LINES = 60000; + const size_t SIZE_PER_LINE = 100; + + char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE); + if (text == NULL) { + fail("malloc failed"); + } + + char *textPtr = text; + + // Create the XML + textPtr += snprintf(textPtr, SIZE_PER_LINE, + "<!DOCTYPE foo [\n" + " <!ENTITY s0 'deepText'>\n"); + + for (size_t i = 1; i < N_LINES; ++i) { + textPtr += snprintf(textPtr, SIZE_PER_LINE, " <!ENTITY s%lu '&s%lu;'>\n", + (long unsigned)i, (long unsigned)(i - 1)); + } + + snprintf(textPtr, SIZE_PER_LINE, "]> <foo name='&s%lu;'>mainText</foo>\n", + (long unsigned)(N_LINES - 1)); + + AttrInfo doc_info[] = {{XCS("name"), XCS("deepText")}, {NULL, NULL}}; + ElementInfo info[] = {{XCS("foo"), 1, NULL, NULL}, {NULL, 0, NULL, NULL}}; + info[0].attributes = doc_info; + + XML_Parser parser = XML_ParserCreate(NULL); + ParserAndElementInfo parserPlusElemenInfo = {parser, info}; + + XML_SetStartElementHandler(parser, counting_start_element_handler); + XML_SetUserData(parser, &parserPlusElemenInfo); + + if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) + == XML_STATUS_ERROR) + xml_failure(parser); + + XML_ParserFree(parser); + free(text); +} +END_TEST + +START_TEST(test_deep_nested_entity_delayed_interpretation) { + const size_t N_LINES = 70000; + const size_t SIZE_PER_LINE = 100; + + char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE); + if (text == NULL) { + fail("malloc failed"); + } + + char *textPtr = text; + + // Create the XML + textPtr += snprintf(textPtr, SIZE_PER_LINE, + "<!DOCTYPE foo [\n" + " <!ENTITY %% s0 'deepText'>\n"); + + for (size_t i = 1; i < N_LINES; ++i) { + textPtr += snprintf(textPtr, SIZE_PER_LINE, + " <!ENTITY %% s%lu '%s%lu;'>\n", (long unsigned)i, + (long unsigned)(i - 1)); + } + + snprintf(textPtr, SIZE_PER_LINE, + " <!ENTITY %% define_g \"<!ENTITY g '%s%lu;'>\">\n" + " %%define_g;\n" + "]>\n" + "<foo/>\n", + (long unsigned)(N_LINES - 1)); + + XML_Parser parser = XML_ParserCreate(NULL); + + XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); + if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) + == XML_STATUS_ERROR) + xml_failure(parser); + + XML_ParserFree(parser); + free(text); +} +END_TEST + START_TEST(test_nested_entity_suspend) { const char *const text = "<!DOCTYPE a [\n" " <!ENTITY e1 '<!--e1-->'>\n" @@ -5308,6 +5584,35 @@ START_TEST(test_nested_entity_suspend) { } END_TEST +START_TEST(test_nested_entity_suspend_2) { + const char *const text = "<!DOCTYPE doc [\n" + " <!ENTITY ge1 'head1Ztail1'>\n" + " <!ENTITY ge2 'head2&ge1;tail2'>\n" + " <!ENTITY ge3 'head3&ge2;tail3'>\n" + "]>\n" + "<doc>&ge3;</doc>"; + const XML_Char *const expected = XCS("head3") XCS("head2") XCS("head1") + XCS("Z") XCS("tail1") XCS("tail2") XCS("tail3"); + CharData storage; + CharData_Init(&storage); + XML_Parser parser = XML_ParserCreate(NULL); + ParserPlusStorage parserPlusStorage = {parser, &storage}; + + XML_SetCharacterDataHandler(parser, accumulate_char_data_and_suspend); + XML_SetUserData(parser, &parserPlusStorage); + + enum XML_Status status = XML_Parse(parser, text, (int)strlen(text), XML_TRUE); + while (status == XML_STATUS_SUSPENDED) { + status = XML_ResumeParser(parser); + } + if (status != XML_STATUS_OK) + xml_failure(parser); + + CharData_CheckXMLChars(&storage, expected); + XML_ParserFree(parser); +} +END_TEST + /* Regression test for quadratic parsing on large tokens */ START_TEST(test_big_tokens_scale_linearly) { const struct { @@ -5968,7 +6273,9 @@ make_basic_test_case(Suite *s) { tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset); tcase_add_test(tc_basic, test_not_standalone_handler_reject); tcase_add_test(tc_basic, test_not_standalone_handler_accept); + tcase_add_test(tc_basic, test_entity_start_tag_level_greater_than_one); tcase_add_test__if_xml_ge(tc_basic, test_wfc_no_recursive_entity_refs); + tcase_add_test(tc_basic, test_no_indirectly_recursive_entity_refs); tcase_add_test__ifdef_xml_dtd(tc_basic, test_ext_entity_invalid_parse); tcase_add_test__if_xml_ge(tc_basic, test_dtd_default_handling); tcase_add_test(tc_basic, test_dtd_attr_handling); @@ -6147,7 +6454,13 @@ make_basic_test_case(Suite *s) { tcase_add_test(tc_basic, test_empty_element_abort); tcase_add_test__ifdef_xml_dtd(tc_basic, test_pool_integrity_with_unfinished_attr); + tcase_add_test__if_xml_ge(tc_basic, test_entity_ref_no_elements); + tcase_add_test__if_xml_ge(tc_basic, test_deep_nested_entity); + tcase_add_test__if_xml_ge(tc_basic, test_deep_nested_attribute_entity); + tcase_add_test__if_xml_ge(tc_basic, + test_deep_nested_entity_delayed_interpretation); tcase_add_test__if_xml_ge(tc_basic, test_nested_entity_suspend); + tcase_add_test__if_xml_ge(tc_basic, test_nested_entity_suspend_2); tcase_add_test(tc_basic, test_big_tokens_scale_linearly); tcase_add_test(tc_basic, test_set_reparse_deferral); tcase_add_test(tc_basic, test_reparse_deferral_is_inherited); diff --git a/3rdparty/expat/tests/benchmark/benchmark.c b/3rdparty/expat/tests/benchmark/benchmark.c index 355d83f896d..a02b84a0131 100644 --- a/3rdparty/expat/tests/benchmark/benchmark.c +++ b/3rdparty/expat/tests/benchmark/benchmark.c @@ -8,7 +8,7 @@ Copyright (c) 2003-2006 Karl Waclawek <karl@waclawek.net> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> - Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2017-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Licensed under the MIT license: @@ -32,10 +32,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define _POSIX_C_SOURCE 1 // fdopen + +#if defined(_MSC_VER) +# include <io.h> // _open, _close +#else +# include <unistd.h> // close +#endif + +#include <fcntl.h> // open #include <sys/stat.h> #include <assert.h> #include <stddef.h> // ptrdiff_t -#include <stdlib.h> #include <stdio.h> #include <time.h> #include "expat.h" @@ -52,17 +60,18 @@ # define XML_FMT_STR "s" #endif -static void +static int usage(const char *prog, int rc) { fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog); - exit(rc); + return rc; } int main(int argc, char *argv[]) { XML_Parser parser; char *XMLBuf, *XMLBufEnd, *XMLBufPtr; - FILE *fd; + int fd; + FILE *file; struct stat fileAttr; int nrOfLoops, bufferSize, i, isFinal; size_t fileSize; @@ -76,34 +85,48 @@ main(int argc, char *argv[]) { ns = 1; j = 1; } else - usage(argv[0], 1); + return usage(argv[0], 1); } } if (argc != j + 4) - usage(argv[0], 1); + return usage(argv[0], 1); - if (stat(argv[j + 1], &fileAttr) != 0) { - fprintf(stderr, "could not access file '%s'\n", argv[j + 1]); + fd = open(argv[j + 1], O_RDONLY); + if (fd == -1) { + fprintf(stderr, "could not open file '%s'\n", argv[j + 1]); return 2; } - fd = fopen(argv[j + 1], "r"); - if (! fd) { - fprintf(stderr, "could not open file '%s'\n", argv[j + 1]); - exit(2); + if (fstat(fd, &fileAttr) != 0) { + close(fd); + fprintf(stderr, "could not fstat file '%s'\n", argv[j + 1]); + return 2; + } + + file = fdopen(fd, "r"); + if (! file) { + close(fd); + fprintf(stderr, "could not fdopen file '%s'\n", argv[j + 1]); + return 2; } bufferSize = atoi(argv[j + 2]); nrOfLoops = atoi(argv[j + 3]); if (bufferSize <= 0 || nrOfLoops <= 0) { + fclose(file); // NOTE: this closes fd as well fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n"); - exit(3); + return 3; } XMLBuf = malloc(fileAttr.st_size); - fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, fd); - fclose(fd); + if (XMLBuf == NULL) { + fclose(file); // NOTE: this closes fd as well + fprintf(stderr, "ouf of memory.\n"); + return 5; + } + fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, file); + fclose(file); // NOTE: this closes fd as well if (ns) parser = XML_ParserCreateNS(NULL, '!'); @@ -132,7 +155,7 @@ main(int argc, char *argv[]) { XML_GetCurrentColumnNumber(parser)); free(XMLBuf); XML_ParserFree(parser); - exit(4); + return 4; } XMLBufPtr += bufferSize; } while (! isFinal); diff --git a/3rdparty/expat/tests/common.c b/3rdparty/expat/tests/common.c index 3aea8d74d1e..b158385f56a 100644 --- a/3rdparty/expat/tests/common.c +++ b/3rdparty/expat/tests/common.c @@ -10,7 +10,7 @@ Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2017 Joe Orton <jorton@redhat.com> Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> @@ -42,6 +42,8 @@ */ #include <assert.h> +#include <errno.h> +#include <stdint.h> // for SIZE_MAX #include <stdio.h> #include <string.h> @@ -202,6 +204,12 @@ _XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len, for (; len > chunksize; len -= chunksize, s += chunksize) { enum XML_Status res = XML_Parse(parser, s, chunksize, XML_FALSE); if (res != XML_STATUS_OK) { + if ((res == XML_STATUS_SUSPENDED) && (len > chunksize)) { + fail("Use of function _XML_Parse_SINGLE_BYTES with a chunk size " + "greater than 0 (from g_chunkSize) does not work well with " + "suspension. Please consider use of plain XML_Parse at this " + "place in your test, instead."); + } return res; } } @@ -294,3 +302,26 @@ duff_reallocator(void *ptr, size_t size) { g_reallocation_count--; return realloc(ptr, size); } + +// Portable remake of strndup(3) for C99; does not care about space efficiency +char * +portable_strndup(const char *s, size_t n) { + if ((s == NULL) || (n == SIZE_MAX)) { + errno = EINVAL; + return NULL; + } + + char *const buffer = (char *)malloc(n + 1); + if (buffer == NULL) { + errno = ENOMEM; + return NULL; + } + + errno = 0; + + memcpy(buffer, s, n); + + buffer[n] = '\0'; + + return buffer; +} diff --git a/3rdparty/expat/tests/common.h b/3rdparty/expat/tests/common.h index bc4c7da6807..2d1a5f207a0 100644 --- a/3rdparty/expat/tests/common.h +++ b/3rdparty/expat/tests/common.h @@ -10,7 +10,7 @@ Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2017 Joe Orton <jorton@redhat.com> Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> @@ -146,6 +146,8 @@ extern void *duff_allocator(size_t size); extern void *duff_reallocator(void *ptr, size_t size); +extern char *portable_strndup(const char *s, size_t n); + #endif /* XML_COMMON_H */ #ifdef __cplusplus diff --git a/3rdparty/expat/tests/handlers.c b/3rdparty/expat/tests/handlers.c index 0211985fe95..ac459507580 100644 --- a/3rdparty/expat/tests/handlers.c +++ b/3rdparty/expat/tests/handlers.c @@ -1843,6 +1843,15 @@ element_decl_suspender(void *userData, const XML_Char *name, } void XMLCALL +suspend_after_element_declaration(void *userData, const XML_Char *name, + XML_Content *model) { + UNUSED_P(name); + XML_Parser parser = (XML_Parser)userData; + assert_true(XML_StopParser(parser, /*resumable*/ XML_TRUE) == XML_STATUS_OK); + XML_FreeContentModel(parser, model); +} + +void XMLCALL accumulate_pi_characters(void *userData, const XML_Char *target, const XML_Char *data) { CharData *storage = (CharData *)userData; @@ -1883,6 +1892,20 @@ accumulate_entity_decl(void *userData, const XML_Char *entityName, } void XMLCALL +accumulate_char_data_and_suspend(void *userData, const XML_Char *s, int len) { + ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData; + + CharData_AppendXMLChars(parserPlusStorage->storage, s, len); + + for (int i = 0; i < len; i++) { + if (s[i] == 'Z') { + XML_StopParser(parserPlusStorage->parser, /*resumable=*/XML_TRUE); + break; + } + } +} + +void XMLCALL accumulate_start_element(void *userData, const XML_Char *name, const XML_Char **atts) { CharData *const storage = (CharData *)userData; diff --git a/3rdparty/expat/tests/handlers.h b/3rdparty/expat/tests/handlers.h index 8850bb948da..fa6267fbbd0 100644 --- a/3rdparty/expat/tests/handlers.h +++ b/3rdparty/expat/tests/handlers.h @@ -325,6 +325,7 @@ extern int XMLCALL external_entity_devaluer(XML_Parser parser, typedef struct ext_hdlr_data { const char *parse_text; XML_ExternalEntityRefHandler handler; + CharData *storage; } ExtHdlrData; extern int XMLCALL external_entity_oneshot_loader(XML_Parser parser, @@ -557,6 +558,10 @@ extern void XMLCALL suspending_comment_handler(void *userData, extern void XMLCALL element_decl_suspender(void *userData, const XML_Char *name, XML_Content *model); +extern void XMLCALL suspend_after_element_declaration(void *userData, + const XML_Char *name, + XML_Content *model); + extern void XMLCALL accumulate_pi_characters(void *userData, const XML_Char *target, const XML_Char *data); @@ -569,6 +574,10 @@ extern void XMLCALL accumulate_entity_decl( const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); +extern void XMLCALL accumulate_char_data_and_suspend(void *userData, + const XML_Char *s, + int len); + extern void XMLCALL accumulate_start_element(void *userData, const XML_Char *name, const XML_Char **atts); diff --git a/3rdparty/expat/tests/minicheck.h b/3rdparty/expat/tests/minicheck.h index 3d888f8d2a3..29ae4cb2420 100644 --- a/3rdparty/expat/tests/minicheck.h +++ b/3rdparty/expat/tests/minicheck.h @@ -14,7 +14,7 @@ Copyright (c) 2004-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2006-2012 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2022 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com> Licensed under the MIT license: @@ -129,8 +129,10 @@ void _check_set_test_info(char const *function, char const *filename, * Prototypes for the actual implementation. */ -# if defined(__GNUC__) +# if defined(__has_attribute) +# if __has_attribute(noreturn) __attribute__((noreturn)) +# endif # endif void _fail(const char *file, int line, const char *msg); diff --git a/3rdparty/expat/tests/misc_tests.c b/3rdparty/expat/tests/misc_tests.c index 9afe0922d6b..fb95014b142 100644 --- a/3rdparty/expat/tests/misc_tests.c +++ b/3rdparty/expat/tests/misc_tests.c @@ -10,7 +10,7 @@ Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2017 Joe Orton <jorton@redhat.com> Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> @@ -59,6 +59,9 @@ #include "handlers.h" #include "misc_tests.h" +void XMLCALL accumulate_characters_ext_handler(void *userData, + const XML_Char *s, int len); + /* Test that a failure to allocate the parser structure fails gracefully */ START_TEST(test_misc_alloc_create_parser) { XML_Memory_Handling_Suite memsuite = {duff_allocator, realloc, free}; @@ -208,7 +211,7 @@ START_TEST(test_misc_version) { if (! versions_equal(&read_version, &parsed_version)) fail("Version mismatch"); - if (xcstrcmp(version_text, XCS("expat_2.6.4"))) /* needs bump on releases */ + if (xcstrcmp(version_text, XCS("expat_2.7.1"))) /* needs bump on releases */ fail("XML_*_VERSION in expat.h out of sync?\n"); } END_TEST @@ -294,6 +297,7 @@ START_TEST(test_misc_stop_during_end_handler_issue_240_1) { parser = XML_ParserCreate(NULL); XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240); mydata = (DataIssue240 *)malloc(sizeof(DataIssue240)); + assert_true(mydata != NULL); mydata->parser = parser; mydata->deep = 0; XML_SetUserData(parser, mydata); @@ -315,6 +319,7 @@ START_TEST(test_misc_stop_during_end_handler_issue_240_2) { parser = XML_ParserCreate(NULL); XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240); mydata = (DataIssue240 *)malloc(sizeof(DataIssue240)); + assert_true(mydata != NULL); mydata->parser = parser; mydata->deep = 0; XML_SetUserData(parser, mydata); @@ -328,64 +333,119 @@ START_TEST(test_misc_stop_during_end_handler_issue_240_2) { END_TEST START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) { - const char *const inputOne = "<!DOCTYPE d [\n" - "<!ENTITY % e ']><d/>'>\n" - "\n" - "%e;"; + const char *const inputOne + = "<!DOCTYPE d [\n" + "<!ENTITY % element_d '<!ELEMENT d (#PCDATA)*>'>\n" + "%element_d;\n" + "<!ENTITY % e ']><d/>'>\n" + "\n" + "%e;"; const char *const inputTwo = "<!DOCTYPE d [\n" + "<!ENTITY % element_d '<!ELEMENT d (#PCDATA)*>'>\n" + "%element_d;\n" "<!ENTITY % e1 ']><d/>'><!ENTITY % e2 '%e1;'>\n" "\n" "%e2;"; - const char *const inputThree = "<!DOCTYPE d [\n" - "<!ENTITY % e ']><d'>\n" - "\n" - "%e;/>"; - const char *const inputIssue317 = "<!DOCTYPE doc [\n" - "<!ENTITY % foo ']>\n" - "<doc>Hell<oc (#PCDATA)*>'>\n" - "%foo;\n" - "]>\n" - "<doc>Hello, world</dVc>"; + const char *const inputThree + = "<!DOCTYPE d [\n" + "<!ENTITY % element_d '<!ELEMENT d (#PCDATA)*>'>\n" + "%element_d;\n" + "<!ENTITY % e ']><d'>\n" + "\n" + "%e;/>"; + const char *const inputIssue317 + = "<!DOCTYPE doc [\n" + "<!ENTITY % element_doc '<!ELEMENT doc (#PCDATA)*>'>\n" + "%element_doc;\n" + "<!ENTITY % foo ']>\n" + "<doc>Hell<oc (#PCDATA)*>'>\n" + "%foo;\n" + "]>\n" + "<doc>Hello, world</dVc>"; const char *const inputs[] = {inputOne, inputTwo, inputThree, inputIssue317}; + const XML_Bool suspendOrNot[] = {XML_FALSE, XML_TRUE}; size_t inputIndex = 0; for (; inputIndex < sizeof(inputs) / sizeof(inputs[0]); inputIndex++) { - set_subtest("%s", inputs[inputIndex]); - XML_Parser parser; - enum XML_Status parseResult; - int setParamEntityResult; - XML_Size lineNumber; - XML_Size columnNumber; - const char *const input = inputs[inputIndex]; - - parser = XML_ParserCreate(NULL); - setParamEntityResult - = XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); - if (setParamEntityResult != 1) - fail("Failed to set XML_PARAM_ENTITY_PARSING_ALWAYS."); - - parseResult = _XML_Parse_SINGLE_BYTES(parser, input, (int)strlen(input), 0); - if (parseResult != XML_STATUS_ERROR) { - parseResult = _XML_Parse_SINGLE_BYTES(parser, "", 0, 1); + for (size_t suspendOrNotIndex = 0; + suspendOrNotIndex < sizeof(suspendOrNot) / sizeof(suspendOrNot[0]); + suspendOrNotIndex++) { + const char *const input = inputs[inputIndex]; + const XML_Bool suspend = suspendOrNot[suspendOrNotIndex]; + if (suspend && (g_chunkSize > 0)) { + // We cannot use _XML_Parse_SINGLE_BYTES below due to suspension, and + // so chunk sizes >0 would only repeat the very same test + // due to use of plain XML_Parse; we are saving upon that runtime: + return; + } + + set_subtest("[input=%d suspend=%s] %s", (int)inputIndex, + suspend ? "true" : "false", input); + XML_Parser parser; + enum XML_Status parseResult; + int setParamEntityResult; + XML_Size lineNumber; + XML_Size columnNumber; + + parser = XML_ParserCreate(NULL); + setParamEntityResult + = XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); + if (setParamEntityResult != 1) + fail("Failed to set XML_PARAM_ENTITY_PARSING_ALWAYS."); + + if (suspend) { + XML_SetUserData(parser, parser); + XML_SetElementDeclHandler(parser, suspend_after_element_declaration); + } + + if (suspend) { + // can't use SINGLE_BYTES here, because it'll return early on + // suspension, and we won't know exactly how much input we actually + // managed to give Expat. + parseResult = XML_Parse(parser, input, (int)strlen(input), 0); + + while (parseResult == XML_STATUS_SUSPENDED) { + parseResult = XML_ResumeParser(parser); + } + + if (parseResult != XML_STATUS_ERROR) { + // can't use SINGLE_BYTES here, because it'll return early on + // suspension, and we won't know exactly how much input we actually + // managed to give Expat. + parseResult = XML_Parse(parser, "", 0, 1); + } + + while (parseResult == XML_STATUS_SUSPENDED) { + parseResult = XML_ResumeParser(parser); + } + } else { + parseResult + = _XML_Parse_SINGLE_BYTES(parser, input, (int)strlen(input), 0); + + if (parseResult != XML_STATUS_ERROR) { + parseResult = _XML_Parse_SINGLE_BYTES(parser, "", 0, 1); + } + } + if (parseResult != XML_STATUS_ERROR) { fail("Parsing was expected to fail but succeeded."); } - } - if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) - fail("Error code does not match XML_ERROR_INVALID_TOKEN"); + if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN) + fail("Error code does not match XML_ERROR_INVALID_TOKEN"); - lineNumber = XML_GetCurrentLineNumber(parser); - if (lineNumber != 4) - fail("XML_GetCurrentLineNumber does not work as expected."); + lineNumber = XML_GetCurrentLineNumber(parser); + if (lineNumber != 6) + fail("XML_GetCurrentLineNumber does not work as expected."); - columnNumber = XML_GetCurrentColumnNumber(parser); - if (columnNumber != 0) - fail("XML_GetCurrentColumnNumber does not work as expected."); + columnNumber = XML_GetCurrentColumnNumber(parser); + if (columnNumber != 0) + fail("XML_GetCurrentColumnNumber does not work as expected."); - XML_ParserFree(parser); + XML_ParserFree(parser); + } } } END_TEST @@ -519,6 +579,105 @@ START_TEST(test_misc_stopparser_rejects_unstarted_parser) { } END_TEST +/* Adaptation of accumulate_characters that takes ExtHdlrData input to work with + * test_renter_loop_finite_content below */ +void XMLCALL +accumulate_characters_ext_handler(void *userData, const XML_Char *s, int len) { + ExtHdlrData *const test_data = (ExtHdlrData *)userData; + CharData_AppendXMLChars(test_data->storage, s, len); +} + +/* Test that internalEntityProcessor does not re-enter forever; + * based on files tests/xmlconf/xmltest/valid/ext-sa/012.{xml,ent} */ +START_TEST(test_renter_loop_finite_content) { + CharData storage; + CharData_Init(&storage); + const char *const text = "<!DOCTYPE doc [\n" + "<!ENTITY e1 '&e2;'>\n" + "<!ENTITY e2 '&e3;'>\n" + "<!ENTITY e3 SYSTEM '012.ent'>\n" + "<!ENTITY e4 '&e5;'>\n" + "<!ENTITY e5 '(e5)'>\n" + "<!ELEMENT doc (#PCDATA)>\n" + "]>\n" + "<doc>&e1;</doc>\n"; + ExtHdlrData test_data = {"&e4;\n", external_entity_null_loader, &storage}; + const XML_Char *const expected = XCS("(e5)\n"); + + XML_Parser parser = XML_ParserCreate(NULL); + assert_true(parser != NULL); + XML_SetUserData(parser, &test_data); + XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader); + XML_SetCharacterDataHandler(parser, accumulate_characters_ext_handler); + if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) + == XML_STATUS_ERROR) + xml_failure(parser); + + CharData_CheckXMLChars(&storage, expected); + XML_ParserFree(parser); +} +END_TEST + +// Inspired by function XML_OriginalString of Perl's XML::Parser +static char * +dup_original_string(XML_Parser parser) { + const int byte_count = XML_GetCurrentByteCount(parser); + + assert_true(byte_count >= 0); + + int offset = -1; + int size = -1; + + const char *const context = XML_GetInputContext(parser, &offset, &size); + +#if XML_CONTEXT_BYTES > 0 + assert_true(context != NULL); + assert_true(offset >= 0); + assert_true(size >= 0); + return portable_strndup(context + offset, byte_count); +#else + assert_true(context == NULL); + return NULL; +#endif +} + +static void +on_characters_issue_980(void *userData, const XML_Char *s, int len) { + (void)s; + (void)len; + XML_Parser parser = (XML_Parser)userData; + + char *const original_string = dup_original_string(parser); + +#if XML_CONTEXT_BYTES > 0 + assert_true(original_string != NULL); + assert_true(strcmp(original_string, "&draft.day;") == 0); + free(original_string); +#else + assert_true(original_string == NULL); +#endif +} + +START_TEST(test_misc_expected_event_ptr_issue_980) { + // NOTE: This is a tiny subset of sample "REC-xml-19980210.xml" + // from Perl's XML::Parser + const char *const doc = "<!DOCTYPE day [\n" + " <!ENTITY draft.day '10'>\n" + "]>\n" + "<day>&draft.day;</day>\n"; + + XML_Parser parser = XML_ParserCreate(NULL); + XML_SetUserData(parser, parser); + XML_SetCharacterDataHandler(parser, on_characters_issue_980); + + assert_true(_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), + /*isFinal=*/XML_TRUE) + == XML_STATUS_OK); + + XML_ParserFree(parser); +} +END_TEST + void make_miscellaneous_test_case(Suite *s) { TCase *tc_misc = tcase_create("miscellaneous tests"); @@ -545,4 +704,6 @@ make_miscellaneous_test_case(Suite *s) { tcase_add_test(tc_misc, test_misc_char_handler_stop_without_leak); tcase_add_test(tc_misc, test_misc_resumeparser_not_crashing); tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser); + tcase_add_test__if_xml_ge(tc_misc, test_renter_loop_finite_content); + tcase_add_test(tc_misc, test_misc_expected_event_ptr_issue_980); } diff --git a/3rdparty/expat/tests/runtests.c b/3rdparty/expat/tests/runtests.c index 5feaaabe226..ecb1c36be58 100644 --- a/3rdparty/expat/tests/runtests.c +++ b/3rdparty/expat/tests/runtests.c @@ -13,7 +13,7 @@ Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2017 Joe Orton <jorton@redhat.com> - Copyright (c) 2017 Jos Gutirrez de la Concha <jose@zeroc.com> + Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it> Copyright (c) 2019 David Loffredo <loffredo@steptools.com> Copyright (c) 2020 Tim Gates <tim.gates@iress.com> diff --git a/3rdparty/expat/tests/xmltest.sh b/3rdparty/expat/tests/xmltest.sh index dc409d01e45..56e66c56f6e 100755 --- a/3rdparty/expat/tests/xmltest.sh +++ b/3rdparty/expat/tests/xmltest.sh @@ -2,8 +2,8 @@ # EXPAT TEST SCRIPT FOR W3C XML TEST SUITE # # This script can be used to exercise Expat against the -# w3c.org xml test suite, available from -# http://www.w3.org/XML/Test/xmlts20020606.zip. +# w3c.org xml test suite, available from: +# https://www.w3.org/XML/Test/xmlts20020606.zip # # To run this script, first set XMLWF below so that xmlwf can be # found, then set the output directory with OUTPUT. @@ -30,6 +30,7 @@ # Copyright (c) 2002 Karl Waclawek <karl@waclawek.net> # Copyright (c) 2008-2019 Sebastian Pipping <sebastian@pipping.org> # Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> +# Copyright (c) 2025 Hanno Böck <hanno@gentoo.org> # Licensed under the MIT license: # # Permission is hereby granted, free of charge, to any person obtaining diff --git a/3rdparty/expat/win32/expat.iss b/3rdparty/expat/win32/expat.iss index 09aa7e533ce..60159d8c926 100644 --- a/3rdparty/expat/win32/expat.iss +++ b/3rdparty/expat/win32/expat.iss @@ -14,7 +14,7 @@ ; Copyright (c) 2001 Tim Peters <tim.peters@gmail.com> ; Copyright (c) 2001-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> ; Copyright (c) 2006-2017 Karl Waclawek <karl@waclawek.net> -; Copyright (c) 2007-2024 Sebastian Pipping <sebastian@pipping.org> +; Copyright (c) 2007-2025 Sebastian Pipping <sebastian@pipping.org> ; Copyright (c) 2022 Johnny Jazeix <jazeix@gmail.com> ; Copyright (c) 2024 Dag-Erling Smørgrav <des@des.dev> ; Licensed under the MIT license: @@ -38,14 +38,14 @@ ; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ; USE OR OTHER DEALINGS IN THE SOFTWARE. -#define expatVer "2.6.4" +#define expatVer "2.7.1" [Setup] AppName=Expat AppId=expat AppVersion={#expatVer} AppVerName=Expat {#expatVer} -AppCopyright=Copyright © 1997-2022 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers +AppCopyright=Copyright © 1997-2025 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers AppPublisher=The Expat Developers AppPublisherURL=https://libexpat.github.io/ AppSupportURL=https://libexpat.github.io/ @@ -75,7 +75,7 @@ Flags: ignoreversion; Source: COPYING; DestDir: "{app}"; De Flags: ignoreversion; Source: README.md; DestDir: "{app}"; DestName: README.txt Flags: ignoreversion; Source: doc\*.html; DestDir: "{app}\Doc" Flags: ignoreversion; Source: doc\*.css; DestDir: "{app}\Doc" -Flags: ignoreversion; Source: doc\*.xml; DestDir: "{app}\Doc" +Flags: ignoreversion; Source: doc\*.xml; DestDir: "{app}\Source\doc" Flags: ignoreversion; Source: win32\bin\Release\*.dll; DestDir: "{app}\Bin" Flags: ignoreversion; Source: win32\bin\Release\*.lib; DestDir: "{app}\Bin" Flags: ignoreversion; Source: win32\version.rc.cmake; DestDir: "{app}\Source\win32" diff --git a/3rdparty/expat/xmlwf/readfilemap.c b/3rdparty/expat/xmlwf/readfilemap.c index 2cb53feef8d..d8e7fce42ea 100644 --- a/3rdparty/expat/xmlwf/readfilemap.c +++ b/3rdparty/expat/xmlwf/readfilemap.c @@ -14,6 +14,7 @@ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2017 Franek Korta <fkorta@gmail.com> Copyright (c) 2022 Sean McBride <sean@rogue-research.com> + Copyright (c) 2025 Hanno Böck <hanno@gentoo.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -55,7 +56,7 @@ # define EXPAT_read_count_t int # define EXPAT_read_req_t unsigned int #else /* POSIX */ -/* http://pubs.opengroup.org/onlinepubs/009695399/functions/read.html */ +/* https://pubs.opengroup.org/onlinepubs/009695399/functions/read.html */ # define EXPAT_read read # define EXPAT_read_count_t ssize_t # define EXPAT_read_req_t size_t diff --git a/3rdparty/expat/xmlwf/xmlfile.c b/3rdparty/expat/xmlwf/xmlfile.c index cd2533e0257..9c4f7f8dbad 100644 --- a/3rdparty/expat/xmlwf/xmlfile.c +++ b/3rdparty/expat/xmlwf/xmlfile.c @@ -15,7 +15,7 @@ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2019 David Loffredo <loffredo@steptools.com> Copyright (c) 2021 Donghee Na <donghee.na@python.org> - Copyright (c) 2024 Hanno Bck <hanno@gentoo.org> + Copyright (c) 2024 Hanno Böck <hanno@gentoo.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining diff --git a/3rdparty/expat/xmlwf/xmlwf.c b/3rdparty/expat/xmlwf/xmlwf.c index 2bcd4627f7f..7c0a8cd4d6a 100644 --- a/3rdparty/expat/xmlwf/xmlwf.c +++ b/3rdparty/expat/xmlwf/xmlwf.c @@ -15,7 +15,7 @@ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2019 David Loffredo <loffredo@steptools.com> Copyright (c) 2020 Joe Orton <jorton@redhat.com> - Copyright (c) 2020 Kleber Tarcsio <klebertarcisio@yahoo.com.br> + Copyright (c) 2020 Kleber Tarcísio <klebertarcisio@yahoo.com.br> Copyright (c) 2021 Tim Bray <tbray@textuality.com> Copyright (c) 2022 Martin Ettl <ettl.martin78@googlemail.com> Copyright (c) 2022 Sean McBride <sean@rogue-research.com> @@ -161,7 +161,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Expat Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper -Copyright (c) 2001-2022 Expat maintainers +Copyright (c) 2001-2025 Expat maintainers Lua - a powerful, fast, lightweight, embeddable scripting language Copyright (c) 1994-2024 Lua.org, PUC-Rio diff --git a/scripts/src/3rdparty.lua b/scripts/src/3rdparty.lua index ad7932afdc2..b08e847a9ae 100755 --- a/scripts/src/3rdparty.lua +++ b/scripts/src/3rdparty.lua @@ -29,14 +29,14 @@ project "expat" "HAVE_STDLIB_H", "HAVE_STRING_H", "PACKAGE=\"expat\"", - "PACKAGE_BUGREPORT=\"expat-bugs@libexpat.org\"", + "PACKAGE_BUGREPORT=\"https://github.com/libexpat/libexpat/issues\"", "PACKAGE_NAME=\"expat\"", - "PACKAGE_STRING=\"expat-2.2.10\"", + "PACKAGE_STRING=\"expat-2.7.1\"", "PACKAGE_TARNAME=\"expat\"", "PACKAGE_URL=\"\"", - "PACKAGE_VERSION=\"2.2.10\"", + "PACKAGE_VERSION=\"2.7.1\"", "STDC_HEADERS", - "VERSION=\"2.2.10\"", + "VERSION=\"2.7.1\"", "XML_CONTEXT_BYTES=1024", "XML_DTD", "XML_GE=1", diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 65ebc2eacdb..cb130e07527 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -21,9 +21,10 @@ for i, v in ipairs(DRC_CPUS) do break end end +CPU_INCLUDE_DRC_NATIVE = CPU_INCLUDE_DRC and (not _OPTIONS["FORCE_DRC_C_BACKEND"]) and ((_OPTIONS["PLATFORM"] == "x86") or (_OPTIONS["PLATFORM"] == "arm64")) -if (CPU_INCLUDE_DRC) then +if CPU_INCLUDE_DRC then files { MAME_DIR .. "src/devices/cpu/drcbec.cpp", MAME_DIR .. "src/devices/cpu/drcbec.h", @@ -41,16 +42,16 @@ if (CPU_INCLUDE_DRC) then MAME_DIR .. "src/devices/cpu/x86log.h", MAME_DIR .. "src/devices/cpu/drcumlsh.h", } - if (not _OPTIONS["FORCE_DRC_C_BACKEND"]) and ((_OPTIONS["PLATFORM"] == "x86") or (_OPTIONS["PLATFORM"] == "arm64")) then - files { - MAME_DIR .. "src/devices/cpu/drcbearm64.cpp", - MAME_DIR .. "src/devices/cpu/drcbearm64.h", - MAME_DIR .. "src/devices/cpu/drcbex64.cpp", - MAME_DIR .. "src/devices/cpu/drcbex64.h", - MAME_DIR .. "src/devices/cpu/drcbex86.cpp", - MAME_DIR .. "src/devices/cpu/drcbex86.h", - } - end +end +if CPU_INCLUDE_DRC_NATIVE then + files { + MAME_DIR .. "src/devices/cpu/drcbearm64.cpp", + MAME_DIR .. "src/devices/cpu/drcbearm64.h", + MAME_DIR .. "src/devices/cpu/drcbex64.cpp", + MAME_DIR .. "src/devices/cpu/drcbex64.h", + MAME_DIR .. "src/devices/cpu/drcbex86.cpp", + MAME_DIR .. "src/devices/cpu/drcbex86.h", + } end -------------------------------------------------- @@ -1295,7 +1296,7 @@ end -- Beware that opt_tool can set the value, so we want both to be executed always local want_disasm_i86 = opt_tool(CPUS, "I86") local want_disasm_i386 = opt_tool(CPUS, "I386") -if want_disasm_i86 or want_disasm_i386 or CPU_INCLUDE_DRC then +if want_disasm_i86 or want_disasm_i386 or CPU_INCLUDE_DRC_NATIVE then table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/i386/i386dasm.cpp") table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/i386/i386dasm.h") end diff --git a/scripts/src/main.lua b/scripts/src/main.lua index d5f94bb60bd..7b1971d0da1 100644 --- a/scripts/src/main.lua +++ b/scripts/src/main.lua @@ -151,7 +151,7 @@ end ext_lib("jpeg"), "7z", } -if not _OPTIONS["FORCE_DRC_C_BACKEND"] then +if CPU_INCLUDE_DRC_NATIVE then links { "asmjit", } diff --git a/src/devices/cpu/h8/h8_adc.cpp b/src/devices/cpu/h8/h8_adc.cpp index 05c012017f3..6daaaeae890 100644 --- a/src/devices/cpu/h8/h8_adc.cpp +++ b/src/devices/cpu/h8/h8_adc.cpp @@ -157,9 +157,9 @@ void h8_adc_device::notify_standby(int state) void h8_adc_device::conversion_wait(bool first, bool poweron, u64 current_time) { - if(current_time) + if(current_time) { m_next_event = current_time + conversion_time(first, poweron); - else { + } else { m_next_event = m_cpu->total_cycles() + conversion_time(first, poweron); m_cpu->internal_update(); } @@ -185,8 +185,9 @@ void h8_adc_device::sampling() if(m_mode & DUAL) { buffer_value(m_channel, 0); buffer_value(m_channel+1, 1); - } else + } else { buffer_value(m_channel); + } } void h8_adc_device::start_conversion() @@ -224,7 +225,7 @@ void h8_adc_device::timeout(u64 current_time) if(m_mode & ROTATE) { if(m_channel != m_end_channel) { - m_channel++; + m_channel = (m_channel + 1) & 7; sampling(); conversion_wait(false, false, current_time); return; @@ -467,10 +468,12 @@ void h8_adc_2655_device::mode_update() if(m_adcr & 0x04) { m_mode |= DUAL; m_end_channel = (m_adcsr & 6)+1; - } else + } else { m_end_channel = m_adcsr & 7; - } else + } + } else { m_start_channel = m_end_channel = m_adcsr & 7; + } } void h8_adc_2655_device::do_buffering(int buffer) diff --git a/src/devices/cpu/rsp/rsp.cpp b/src/devices/cpu/rsp/rsp.cpp index f39d79b21bb..b58b7169e80 100644 --- a/src/devices/cpu/rsp/rsp.cpp +++ b/src/devices/cpu/rsp/rsp.cpp @@ -62,11 +62,6 @@ DEFINE_DEVICE_TYPE(RSP, rsp_device, "rsp", "Nintendo & SGI Reality Signal Proces #define ZERO 3 #define CLIP2 4 -#define SLICE_H 3 -#define SLICE_M 2 -#define SLICE_L 1 -#define SLICE_LL 0 - #define WRITEBACK_RESULT() memcpy(m_v[VDREG].s, vres, sizeof(uint16_t) * 8); static const int vector_elements_2[16][8] = @@ -265,7 +260,7 @@ void rsp_device::device_start() for (int regIdx = 0; regIdx < 32; regIdx++) m_r[regIdx] = 0; - for(auto & elem : m_v) + for (auto & elem : m_v) { elem.d[0] = 0; elem.d[1] = 0; @@ -284,7 +279,7 @@ void rsp_device::device_start() m_vector_busy = false; m_paired_busy = false; - for(auto & elem : m_accum) + for (auto & elem : m_accum) { elem.q = 0; } @@ -294,6 +289,35 @@ void rsp_device::device_start() m_sr = RSP_STATUS_HALT; m_step_count = 0; + // register for savestates + save_item(NAME(m_pc)); + save_item(NAME(m_r)); + save_item(NAME(m_ideduct)); + save_item(NAME(m_scalar_busy)); + save_item(NAME(m_vector_busy)); + save_item(NAME(m_paired_busy)); + + save_item(NAME(m_sr)); + save_item(NAME(m_step_count)); + save_item(NAME(m_ppc)); + save_item(NAME(m_nextpc)); + + save_item(NAME(m_vres)); + save_item(NAME(m_accum)); + save_item(NAME(m_vcarry)); + save_item(NAME(m_vcompare)); + save_item(NAME(m_vclip1)); + save_item(NAME(m_vzero)); + save_item(NAME(m_vclip2)); + + for (int i = 0; i < std::size(m_v); i++) + save_item(NAME(m_v[i].d), i); + + save_item(NAME(m_reciprocal_res)); + save_item(NAME(m_reciprocal_high)); + save_item(NAME(m_dp_allowed)); + + // register state for debugger state_add( RSP_PC, "PC", m_pc).callimport().callexport().formatstr("%08X"); state_add( RSP_R0, "R0", m_r[0]).formatstr("%08X"); state_add( RSP_R1, "R1", m_r[1]).formatstr("%08X"); @@ -528,15 +552,15 @@ void rsp_device::device_reset() uint16_t rsp_device::SATURATE_ACCUM(int accum, int slice, uint16_t negative, uint16_t positive) { - if ((int16_t)m_accum[accum].w[SLICE_H] < 0) + if ((int16_t)m_accum[accum].w.h3 < 0) { - if ((uint16_t)m_accum[accum].w[SLICE_H] != 0xffff) + if ((uint16_t)m_accum[accum].w.h3 != 0xffff) { return negative; } else { - if ((int16_t)m_accum[accum].w[SLICE_M] >= 0) + if ((int16_t)m_accum[accum].w.h2 >= 0) { return negative; } @@ -544,24 +568,24 @@ uint16_t rsp_device::SATURATE_ACCUM(int accum, int slice, uint16_t negative, uin { if (slice == 0) { - return m_accum[accum].w[SLICE_L]; + return m_accum[accum].w.h; } else if (slice == 1) { - return m_accum[accum].w[SLICE_M]; + return m_accum[accum].w.h2; } } } } else { - if ((uint16_t)m_accum[accum].w[SLICE_H] != 0) + if ((uint16_t)m_accum[accum].w.h3 != 0) { return positive; } else { - if ((int16_t)m_accum[accum].w[SLICE_M] < 0) + if ((int16_t)m_accum[accum].w.h2 < 0) { return positive; } @@ -569,11 +593,11 @@ uint16_t rsp_device::SATURATE_ACCUM(int accum, int slice, uint16_t negative, uin { if (slice == 0) { - return m_accum[accum].w[SLICE_L]; + return m_accum[accum].w.h; } else { - return m_accum[accum].w[SLICE_M]; + return m_accum[accum].w.h2; } } } @@ -610,19 +634,19 @@ void rsp_device::handle_vector_ops(uint32_t op) if (s1 == -32768 && s2 == -32768) { // overflow - m_accum[i].w[SLICE_H] = 0; - m_accum[i].w[SLICE_M] = -32768; - m_accum[i].w[SLICE_L] = -32768; + m_accum[i].w.h3 = 0; + m_accum[i].w.h2 = -32768; + m_accum[i].w.h = -32768; vres[i] = 0x7fff; } else { int64_t r = s1 * s2 * 2; r += 0x8000; // rounding ? - m_accum[i].w[SLICE_H] = (r < 0) ? 0xffff : 0; // Sign-extend to 48-bit - m_accum[i].w[SLICE_M] = (int16_t)(r >> 16); - m_accum[i].w[SLICE_L] = (uint16_t)r; - vres[i] = m_accum[i].w[SLICE_M]; + m_accum[i].w.h3 = (r < 0) ? 0xffff : 0; // Sign-extend to 48-bit + m_accum[i].w.h2 = (int16_t)(r >> 16); + m_accum[i].w.h = (uint16_t)r; + vres[i] = m_accum[i].w.h2; } } WRITEBACK_RESULT(); @@ -645,21 +669,21 @@ void rsp_device::handle_vector_ops(uint32_t op) int64_t r = s1 * s2 * 2; r += 0x8000; // rounding ? - m_accum[i].w[SLICE_H] = (uint16_t)(r >> 32); - m_accum[i].w[SLICE_M] = (uint16_t)(r >> 16); - m_accum[i].w[SLICE_L] = (uint16_t)r; + m_accum[i].w.h3 = (uint16_t)(r >> 32); + m_accum[i].w.h2 = (uint16_t)(r >> 16); + m_accum[i].w.h = (uint16_t)r; if (r < 0) { vres[i] = 0; } - else if (((int16_t)m_accum[i].w[SLICE_H] ^ (int16_t)m_accum[i].w[SLICE_M]) < 0) + else if (((int16_t)m_accum[i].w.h3 ^ (int16_t)m_accum[i].w.h2) < 0) { vres[i] = -1; } else { - vres[i] = m_accum[i].w[SLICE_M]; + vres[i] = m_accum[i].w.h2; } } WRITEBACK_RESULT(); @@ -683,11 +707,11 @@ void rsp_device::handle_vector_ops(uint32_t op) uint32_t s2 = m_v[VS2REG].w[VEC_EL_2(EL, i)]; uint32_t r = s1 * s2; - m_accum[i].w[SLICE_H] = 0; - m_accum[i].w[SLICE_M] = 0; - m_accum[i].w[SLICE_L] = (uint16_t)(r >> 16); + m_accum[i].w.h3 = 0; + m_accum[i].w.h2 = 0; + m_accum[i].w.h = (uint16_t)(r >> 16); - vres[i] = m_accum[i].w[SLICE_L]; + vres[i] = m_accum[i].w.h; } WRITEBACK_RESULT(); break; @@ -710,11 +734,11 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t s2 = m_v[VS2REG].w[VEC_EL_2(EL, i)]; // not sign-extended int32_t r = s1 * s2; - m_accum[i].w[SLICE_H] = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit - m_accum[i].w[SLICE_M] = (int16_t)(r >> 16); - m_accum[i].w[SLICE_L] = (uint16_t)r; + m_accum[i].w.h3 = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit + m_accum[i].w.h2 = (int16_t)(r >> 16); + m_accum[i].w.h = (uint16_t)r; - vres[i] = m_accum[i].w[SLICE_M]; + vres[i] = m_accum[i].w.h2; } WRITEBACK_RESULT(); break; @@ -737,11 +761,11 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)]; int32_t r = s1 * s2; - m_accum[i].w[SLICE_H] = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit - m_accum[i].w[SLICE_M] = (int16_t)(r >> 16); - m_accum[i].w[SLICE_L] = (uint16_t)(r); + m_accum[i].w.h3 = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit + m_accum[i].w.h2 = (int16_t)(r >> 16); + m_accum[i].w.h = (uint16_t)(r); - vres[i] = m_accum[i].w[SLICE_L]; + vres[i] = m_accum[i].w.h; } WRITEBACK_RESULT(); break; @@ -764,9 +788,9 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)]; int32_t r = s1 * s2; - m_accum[i].w[SLICE_H] = (int16_t)(r >> 16); - m_accum[i].w[SLICE_M] = (uint16_t)(r); - m_accum[i].w[SLICE_L] = 0; + m_accum[i].w.h3 = (int16_t)(r >> 16); + m_accum[i].w.h2 = (uint16_t)(r); + m_accum[i].w.h = 0; if (r < -32768) r = -32768; if (r > 32767) r = 32767; @@ -792,17 +816,17 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)]; int32_t r = s1 * s2; - uint64_t q = (uint64_t)(uint16_t)m_accum[i].w[SLICE_LL]; - q |= (((uint64_t)(uint16_t)m_accum[i].w[SLICE_L]) << 16); - q |= (((uint64_t)(uint16_t)m_accum[i].w[SLICE_M]) << 32); - q |= (((uint64_t)(uint16_t)m_accum[i].w[SLICE_H]) << 48); + uint64_t q = (uint64_t)(uint16_t)m_accum[i].w.l; + q |= (((uint64_t)(uint16_t)m_accum[i].w.h) << 16); + q |= (((uint64_t)(uint16_t)m_accum[i].w.h2) << 32); + q |= (((uint64_t)(uint16_t)m_accum[i].w.h3) << 48); q += (int64_t)(r) << 17; - m_accum[i].w[SLICE_LL] = (uint16_t)q; - m_accum[i].w[SLICE_L] = (uint16_t)(q >> 16); - m_accum[i].w[SLICE_M] = (uint16_t)(q >> 32); - m_accum[i].w[SLICE_H] = (uint16_t)(q >> 48); + m_accum[i].w.l = (uint16_t)q; + m_accum[i].w.h = (uint16_t)(q >> 16); + m_accum[i].w.h2 = (uint16_t)(q >> 32); + m_accum[i].w.h3 = (uint16_t)(q >> 48); vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff); } @@ -823,32 +847,32 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t s1 = m_v[VS1REG].s[i]; int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)]; int32_t r1 = s1 * s2; - uint32_t r2 = m_accum[i].w[SLICE_L] + ((uint16_t)r1 * 2); - uint32_t r3 = m_accum[i].w[SLICE_M] + (uint16_t)((r1 >> 16) * 2) + (uint16_t)(r2 >> 16); + uint32_t r2 = m_accum[i].w.h + ((uint16_t)r1 * 2); + uint32_t r3 = m_accum[i].w.h2 + (uint16_t)((r1 >> 16) * 2) + (uint16_t)(r2 >> 16); - m_accum[i].w[SLICE_L] = (uint16_t)r2; - m_accum[i].w[SLICE_M] = (uint16_t)r3; - m_accum[i].w[SLICE_H] += (uint16_t)(r3 >> 16) + (uint16_t)(r1 >> 31); + m_accum[i].w.h = (uint16_t)r2; + m_accum[i].w.h2 = (uint16_t)r3; + m_accum[i].w.h3 += (uint16_t)(r3 >> 16) + (uint16_t)(r1 >> 31); - if ((int16_t)m_accum[i].w[SLICE_H] < 0) + if ((int16_t)m_accum[i].w.h3 < 0) { vres[i] = 0; } else { - if (m_accum[i].w[SLICE_H] != 0) + if (m_accum[i].w.h3 != 0) { vres[i] = 0xffff; } else { - if ((int16_t)m_accum[i].w[SLICE_M] < 0) + if ((int16_t)m_accum[i].w.h2 < 0) { vres[i] = 0xffff; } else { - vres[i] = m_accum[i].w[SLICE_M]; + vres[i] = m_accum[i].w.h2; } } } @@ -873,12 +897,12 @@ void rsp_device::handle_vector_ops(uint32_t op) uint32_t s1 = m_v[VS1REG].w[i]; uint32_t s2 = m_v[VS2REG].w[VEC_EL_2(EL, i)]; uint32_t r1 = s1 * s2; - uint32_t r2 = m_accum[i].w[SLICE_L] + (r1 >> 16); - uint32_t r3 = m_accum[i].w[SLICE_M] + (r2 >> 16); + uint32_t r2 = m_accum[i].w.h + (r1 >> 16); + uint32_t r3 = m_accum[i].w.h2 + (r2 >> 16); - m_accum[i].w[SLICE_L] = (uint16_t)r2; - m_accum[i].w[SLICE_M] = (uint16_t)r3; - m_accum[i].w[SLICE_H] += (int16_t)(r3 >> 16); + m_accum[i].w.h = (uint16_t)r2; + m_accum[i].w.h2 = (uint16_t)r3; + m_accum[i].w.h3 += (int16_t)(r3 >> 16); vres[i] = SATURATE_ACCUM(i, 0, 0x0000, 0xffff); } @@ -902,14 +926,14 @@ void rsp_device::handle_vector_ops(uint32_t op) uint32_t s1 = m_v[VS1REG].s[i]; uint32_t s2 = m_v[VS2REG].w[VEC_EL_2(EL, i)]; // not sign-extended uint32_t r1 = s1 * s2; - uint32_t r2 = (uint16_t)m_accum[i].w[SLICE_L] + (uint16_t)(r1); - uint32_t r3 = (uint16_t)m_accum[i].w[SLICE_M] + (r1 >> 16) + (r2 >> 16); + uint32_t r2 = (uint16_t)m_accum[i].w.h + (uint16_t)(r1); + uint32_t r3 = (uint16_t)m_accum[i].w.h2 + (r1 >> 16) + (r2 >> 16); - m_accum[i].w[SLICE_L] = (uint16_t)r2; - m_accum[i].w[SLICE_M] = (uint16_t)r3; - m_accum[i].w[SLICE_H] += (uint16_t)(r3 >> 16); + m_accum[i].w.h = (uint16_t)r2; + m_accum[i].w.h2 = (uint16_t)r3; + m_accum[i].w.h3 += (uint16_t)(r3 >> 16); if ((int32_t)r1 < 0) - m_accum[i].w[SLICE_H] -= 1; + m_accum[i].w.h3 -= 1; vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff); } @@ -933,16 +957,16 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t s1 = m_v[VS1REG].w[i]; // not sign-extended int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)]; - uint64_t q = (uint64_t)m_accum[i].w[SLICE_LL]; - q |= (((uint64_t)m_accum[i].w[SLICE_L]) << 16); - q |= (((uint64_t)m_accum[i].w[SLICE_M]) << 32); - q |= (((uint64_t)m_accum[i].w[SLICE_H]) << 48); + uint64_t q = (uint64_t)m_accum[i].w.l; + q |= (((uint64_t)m_accum[i].w.h) << 16); + q |= (((uint64_t)m_accum[i].w.h2) << 32); + q |= (((uint64_t)m_accum[i].w.h3) << 48); q += (int64_t)(s1*s2) << 16; - m_accum[i].w[SLICE_LL] = (uint16_t)q; - m_accum[i].w[SLICE_L] = (uint16_t)(q >> 16); - m_accum[i].w[SLICE_M] = (uint16_t)(q >> 32); - m_accum[i].w[SLICE_H] = (uint16_t)(q >> 48); + m_accum[i].w.l = (uint16_t)q; + m_accum[i].w.h = (uint16_t)(q >> 16); + m_accum[i].w.h2 = (uint16_t)(q >> 32); + m_accum[i].w.h3 = (uint16_t)(q >> 48); vres[i] = SATURATE_ACCUM(i, 0, 0x0000, 0xffff); } @@ -967,12 +991,12 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t s1 = m_v[VS1REG].s[i]; int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)]; - int32_t accum = (uint32_t)(uint16_t)m_accum[i].w[SLICE_M]; - accum |= ((uint32_t)((uint16_t)m_accum[i].w[SLICE_H])) << 16; + int32_t accum = (uint32_t)(uint16_t)m_accum[i].w.h2; + accum |= ((uint32_t)((uint16_t)m_accum[i].w.h3)) << 16; accum += s1 * s2; - m_accum[i].w[SLICE_H] = (uint16_t)(accum >> 16); - m_accum[i].w[SLICE_M] = (uint16_t)accum; + m_accum[i].w.h3 = (uint16_t)(accum >> 16); + m_accum[i].w.h2 = (uint16_t)accum; vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff); } @@ -997,7 +1021,7 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)]; int32_t r = s1 + s2 + BIT(m_vcarry, i); - m_accum[i].w[SLICE_L] = (int16_t)r; + m_accum[i].w.h = (int16_t)r; if (r > 32767) r = 32767; if (r < -32768) r = -32768; @@ -1026,7 +1050,7 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t s2 = m_v[VS2REG].s[VEC_EL_2(EL, i)]; int32_t r = s1 - s2 - BIT(m_vcarry, i); - m_accum[i].w[SLICE_L] = (int16_t)r; + m_accum[i].w.h = (int16_t)r; if (r > 32767) r = 32767; if (r < -32768) r = -32768; @@ -1074,7 +1098,7 @@ void rsp_device::handle_vector_ops(uint32_t op) vres[i] = 0; } - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } WRITEBACK_RESULT(); break; @@ -1101,7 +1125,7 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t r = s1 + s2; vres[i] = (int16_t)r; - m_accum[i].w[SLICE_L] = (int16_t)r; + m_accum[i].w.h = (int16_t)r; if (r & 0xffff0000) { @@ -1133,7 +1157,7 @@ void rsp_device::handle_vector_ops(uint32_t op) int32_t r = s1 - s2; vres[i] = (int16_t)(r); - m_accum[i].w[SLICE_L] = (uint16_t)r; + m_accum[i].w.h = (uint16_t)r; if ((uint16_t)r != 0) { @@ -1163,7 +1187,7 @@ void rsp_device::handle_vector_ops(uint32_t op) { for (int i = 0; i < 8; i++) { - m_v[VDREG].w[i] = m_accum[i].w[SLICE_H]; + m_v[VDREG].w[i] = m_accum[i].w.h3; } break; } @@ -1171,7 +1195,7 @@ void rsp_device::handle_vector_ops(uint32_t op) { for (int i = 0; i < 8; i++) { - m_v[VDREG].w[i] = m_accum[i].w[SLICE_M]; + m_v[VDREG].w[i] = m_accum[i].w.h2; } break; } @@ -1179,7 +1203,7 @@ void rsp_device::handle_vector_ops(uint32_t op) { for (int i = 0; i < 8; i++) { - m_v[VDREG].w[i] = m_accum[i].w[SLICE_L]; + m_v[VDREG].w[i] = m_accum[i].w.h; } break; } @@ -1228,7 +1252,7 @@ void rsp_device::handle_vector_ops(uint32_t op) vres[i] = s2; } - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } m_vzero = 0; @@ -1264,7 +1288,7 @@ void rsp_device::handle_vector_ops(uint32_t op) { vres[i] = s2; } - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } m_vzero = 0; @@ -1301,7 +1325,7 @@ void rsp_device::handle_vector_ops(uint32_t op) vres[i] = s2; } - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } m_vzero = 0; @@ -1338,7 +1362,7 @@ void rsp_device::handle_vector_ops(uint32_t op) vres[i] = s2; } - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } m_vzero = 0; @@ -1367,11 +1391,11 @@ void rsp_device::handle_vector_ops(uint32_t op) { if (BIT(m_vcompare, i)) // vcc_lo { - m_accum[i].w[SLICE_L] = -(uint16_t)s2; + m_accum[i].w.h = -(uint16_t)s2; } else { - m_accum[i].w[SLICE_L] = s1; + m_accum[i].w.h = s1; } } else @@ -1380,12 +1404,12 @@ void rsp_device::handle_vector_ops(uint32_t op) { if (((uint32_t)(uint16_t)(s1) + (uint32_t)(uint16_t)(s2)) > 0x10000) { - m_accum[i].w[SLICE_L] = s1; + m_accum[i].w.h = s1; m_vcompare &= ~(1 << i); } else { - m_accum[i].w[SLICE_L] = -(uint16_t)s2; + m_accum[i].w.h = -(uint16_t)s2; m_vcompare |= 1 << i; } } @@ -1393,12 +1417,12 @@ void rsp_device::handle_vector_ops(uint32_t op) { if (((uint32_t)(uint16_t)(s1) + (uint32_t)(uint16_t)(s2)) != 0) { - m_accum[i].w[SLICE_L] = s1; + m_accum[i].w.h = s1; m_vcompare &= ~(1 << i); } else { - m_accum[i].w[SLICE_L] = -(uint16_t)s2; + m_accum[i].w.h = -(uint16_t)s2; m_vcompare |= 1 << i; } } @@ -1410,29 +1434,29 @@ void rsp_device::handle_vector_ops(uint32_t op) { if (BIT(m_vclip2, i)) // vcc_hi { - m_accum[i].w[SLICE_L] = s2; + m_accum[i].w.h = s2; } else { - m_accum[i].w[SLICE_L] = s1; + m_accum[i].w.h = s1; } } else { if (((int32_t)(uint16_t)s1 - (int32_t)(uint16_t)s2) >= 0) { - m_accum[i].w[SLICE_L] = s2; + m_accum[i].w.h = s2; m_vclip2 |= 1 << i; } else { - m_accum[i].w[SLICE_L] = s1; + m_accum[i].w.h = s1; m_vclip2 &= ~(1 << i); } } } - vres[i] = m_accum[i].w[SLICE_L]; + vres[i] = m_accum[i].w.h; } m_vzero = 0; @@ -1521,7 +1545,7 @@ void rsp_device::handle_vector_ops(uint32_t op) m_vclip1 |= 1 << i; } - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } WRITEBACK_RESULT(); break; @@ -1555,12 +1579,12 @@ void rsp_device::handle_vector_ops(uint32_t op) } if ((s1 + s2) <= 0) { - m_accum[i].w[SLICE_L] = ~(uint16_t)s2; + m_accum[i].w.h = ~(uint16_t)s2; m_vcompare |= 1 << i; } else { - m_accum[i].w[SLICE_L] = s1; + m_accum[i].w.h = s1; } } else @@ -1571,16 +1595,16 @@ void rsp_device::handle_vector_ops(uint32_t op) } if ((s1 - s2) >= 0) { - m_accum[i].w[SLICE_L] = s2; + m_accum[i].w.h = s2; m_vclip2 |= 1 << i; } else { - m_accum[i].w[SLICE_L] = s1; + m_accum[i].w.h = s1; } } - vres[i] = m_accum[i].w[SLICE_L]; + vres[i] = m_accum[i].w.h; } WRITEBACK_RESULT(); break; @@ -1606,7 +1630,7 @@ void rsp_device::handle_vector_ops(uint32_t op) vres[i] = m_v[VS2REG].s[VEC_EL_2(EL, i)]; } - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } WRITEBACK_RESULT(); break; @@ -1624,7 +1648,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { vres[i] = m_v[VS1REG].w[i] & m_v[VS2REG].w[VEC_EL_2(EL, i)]; - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } WRITEBACK_RESULT(); break; @@ -1642,7 +1666,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { vres[i] = ~(m_v[VS1REG].w[i] & m_v[VS2REG].w[VEC_EL_2(EL, i)]); - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } WRITEBACK_RESULT(); break; @@ -1660,7 +1684,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { vres[i] = m_v[VS1REG].w[i] | m_v[VS2REG].w[VEC_EL_2(EL, i)]; - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } WRITEBACK_RESULT(); break; @@ -1678,7 +1702,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { vres[i] = ~(m_v[VS1REG].w[i] | m_v[VS2REG].w[VEC_EL_2(EL, i)]); - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } WRITEBACK_RESULT(); break; @@ -1696,7 +1720,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { vres[i] = m_v[VS1REG].w[i] ^ m_v[VS2REG].w[VEC_EL_2(EL, i)]; - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } WRITEBACK_RESULT(); break; @@ -1714,7 +1738,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { vres[i] = ~(m_v[VS1REG].w[i] ^ m_v[VS2REG].w[VEC_EL_2(EL, i)]); - m_accum[i].w[SLICE_L] = vres[i]; + m_accum[i].w.h = vres[i]; } WRITEBACK_RESULT(); break; @@ -1737,7 +1761,7 @@ void rsp_device::handle_vector_ops(uint32_t op) vres[i] = 0; uint16_t e1 = m_v[VS1REG].w[i]; uint16_t e2 = m_v[VS2REG].w[VEC_EL_2(EL, i)]; - m_accum[i].w[SLICE_L] = e1 + e2; + m_accum[i].w.h = e1 + e2; } WRITEBACK_RESULT(); break; @@ -1796,7 +1820,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { - m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)]; + m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)]; } break; } @@ -1871,7 +1895,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { - m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)]; + m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)]; } break; } @@ -1890,7 +1914,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { - m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)]; + m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)]; } m_v[VDREG].s[VS1REG & 7] = (int16_t)(m_reciprocal_res >> 16); @@ -1909,7 +1933,7 @@ void rsp_device::handle_vector_ops(uint32_t op) m_v[VDREG].w[VS1REG & 7] = m_v[VS2REG].w[VEC_EL_2(EL, VS1REG & 7)]; for (int i = 0; i < 8; i++) { - m_accum[i].w[SLICE_L] = m_v[VS2REG].w[i]; + m_accum[i].w.h = m_v[VS2REG].w[i]; } break; } @@ -1969,7 +1993,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { - m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)]; + m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)]; } break; @@ -2048,7 +2072,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { - m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)]; + m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)]; } break; @@ -2068,7 +2092,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { - m_accum[i].w[SLICE_L] = m_v[VS2REG].w[VEC_EL_2(EL, i)]; + m_accum[i].w.h = m_v[VS2REG].w[VEC_EL_2(EL, i)]; } m_v[VDREG].s[VS1REG & 7] = (int16_t)(m_reciprocal_res >> 16); // store high part @@ -2103,7 +2127,7 @@ void rsp_device::handle_vector_ops(uint32_t op) vres[i] = 0; uint16_t e1 = m_v[VS1REG].w[i]; uint16_t e2 = m_v[VS2REG].w[VEC_EL_2(EL, i)]; - m_accum[i].w[SLICE_L] = e1 + e2; + m_accum[i].w.h = e1 + e2; } WRITEBACK_RESULT(); break; @@ -2123,7 +2147,7 @@ void rsp_device::handle_vector_ops(uint32_t op) for (int i = 0; i < 8; i++) { vres[i] = m_v[VS1REG].w[i]; - m_accum[i].w[SLICE_L] = 0; + m_accum[i].w.h = 0; } WRITEBACK_RESULT(); break; diff --git a/src/devices/cpu/rsp/rsp.h b/src/devices/cpu/rsp/rsp.h index 0007e96714c..4e7378af089 100644 --- a/src/devices/cpu/rsp/rsp.h +++ b/src/devices/cpu/rsp/rsp.h @@ -148,7 +148,7 @@ protected: memory_access<12, 2, 0, ENDIANNESS_BIG>::specific m_dmem; private: - union VECTOR_REG + union VECTOR_REG // PAIR128 { uint64_t d[2]; uint32_t l[4]; @@ -157,13 +157,6 @@ private: uint8_t b[16]; }; - union ACCUMULATOR_REG - { - uint64_t q; - uint32_t l[2]; - uint16_t w[4]; - }; - uint32_t m_debugger_temp; uint16_t m_pc_temp; uint16_t m_ppc_temp; @@ -188,26 +181,23 @@ private: // COP2 (vectors) uint16_t SATURATE_ACCUM(int accum, int slice, uint16_t negative, uint16_t positive); - uint16_t m_vres[8]; - VECTOR_REG m_v[32]; - ACCUMULATOR_REG m_accum[8]; - uint8_t m_vcarry; - uint8_t m_vcompare; - uint8_t m_vclip1; - uint8_t m_vzero; - uint8_t m_vclip2; - - int32_t m_reciprocal_res; - uint32_t m_reciprocal_high; - int32_t m_dp_allowed; - - void handle_cop2(uint32_t op); - void handle_lwc2(uint32_t op); - void handle_swc2(uint32_t op); - void handle_vector_ops(uint32_t op); - - uint32_t m_div_in; - uint32_t m_div_out; + uint16_t m_vres[8]; + VECTOR_REG m_v[32]; + PAIR64 m_accum[8]; + uint8_t m_vcarry; + uint8_t m_vcompare; + uint8_t m_vclip1; + uint8_t m_vzero; + uint8_t m_vclip2; + + int32_t m_reciprocal_res; + uint32_t m_reciprocal_high; + int32_t m_dp_allowed; + + void handle_cop2(uint32_t op); + void handle_lwc2(uint32_t op); + void handle_swc2(uint32_t op); + void handle_vector_ops(uint32_t op); }; DECLARE_DEVICE_TYPE(RSP, rsp_device) diff --git a/src/devices/cpu/z80/nsc800.cpp b/src/devices/cpu/z80/nsc800.cpp index d7af9a67fe2..e2c0bfd0087 100644 --- a/src/devices/cpu/z80/nsc800.cpp +++ b/src/devices/cpu/z80/nsc800.cpp @@ -54,17 +54,21 @@ void nsc800_device::execute_run() void nsc800_device::execute_set_input(int inputnum, int state) { + bool update_irq_attention = false; switch (inputnum) { case NSC800_RSTA: + update_irq_attention = true; m_nsc800_irq_state[0] = state; break; case NSC800_RSTB: + update_irq_attention = true; m_nsc800_irq_state[1] = state; break; case NSC800_RSTC: + update_irq_attention = true; m_nsc800_irq_state[2] = state; break; @@ -72,4 +76,12 @@ void nsc800_device::execute_set_input(int inputnum, int state) z80_device::execute_set_input(inputnum, state); break; } + + if (update_irq_attention) + { + if (m_nsc800_irq_state[0] != CLEAR_LINE || m_nsc800_irq_state[1] != CLEAR_LINE || m_nsc800_irq_state[2] != CLEAR_LINE) + set_service_attention<SA_NSC800_IRQ_ON, 1>(); + else + set_service_attention<SA_NSC800_IRQ_ON, 0>(); + } } diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp index ab4d79d5120..c95474999d5 100644 --- a/src/devices/cpu/z80/z80.cpp +++ b/src/devices/cpu/z80/z80.cpp @@ -50,6 +50,7 @@ void z80_device::halt() if (!m_halt) { m_halt = 1; + set_service_attention<SA_HALT, 1>(); m_halt_cb(1); } } @@ -62,6 +63,7 @@ void z80_device::leave_halt() if (m_halt) { m_halt = 0; + set_service_attention<SA_HALT, 0>(); m_halt_cb(0); } } @@ -468,7 +470,7 @@ void z80_device::block_io_interrupted_flags() void z80_device::ei() { m_iff1 = m_iff2 = 1; - m_after_ei = true; + set_service_attention<SA_AFTER_EI, 1>(); } void z80_device::set_f(u8 f) @@ -562,14 +564,12 @@ void z80_device::device_start() save_item(NAME(m_im)); save_item(NAME(m_i)); save_item(NAME(m_nmi_state)); - save_item(NAME(m_nmi_pending)); save_item(NAME(m_irq_state)); save_item(NAME(m_wait_state)); save_item(NAME(m_busrq_state)); save_item(NAME(m_busack_state)); - save_item(NAME(m_after_ei)); - save_item(NAME(m_after_ldair)); save_item(NAME(m_ea)); + save_item(NAME(m_service_attention)); save_item(NAME(m_tmp_irq_vector)); save_item(NAME(m_shared_addr.w)); save_item(NAME(m_shared_data.w)); @@ -602,14 +602,12 @@ void z80_device::device_start() m_im = 0; m_i = 0; m_nmi_state = 0; - m_nmi_pending = false; m_irq_state = 0; m_wait_state = 0; m_busrq_state = 0; m_busack_state = 0; - m_after_ei = false; - m_after_ldair = false; m_ea = 0; + m_service_attention = 0; m_rtemp = 0; space(AS_PROGRAM).cache(m_args); @@ -667,11 +665,9 @@ void z80_device::device_reset() m_i = 0; m_r = 0; m_r2 = 0; - m_nmi_pending = false; - m_after_ei = false; - m_after_ldair = false; m_iff1 = 0; m_iff2 = 0; + m_service_attention = 0; } /**************************************************************************** @@ -688,12 +684,18 @@ void z80_device::execute_set_input(int inputnum, int state) { case Z80_INPUT_LINE_BUSRQ: m_busrq_state = state; + if (state != CLEAR_LINE) + set_service_attention<SA_BUSRQ, 1>(); + else + set_service_attention<SA_BUSRQ, 0>(); break; case INPUT_LINE_NMI: // mark an NMI pending on the rising edge if (m_nmi_state == CLEAR_LINE && state != CLEAR_LINE) - m_nmi_pending = true; + { + set_service_attention<SA_NMI_PENDING, 1>(); + } m_nmi_state = state; break; @@ -702,6 +704,10 @@ void z80_device::execute_set_input(int inputnum, int state) m_irq_state = state; if (daisy_chain_present()) m_irq_state = (daisy_update_irq_state() == ASSERT_LINE) ? ASSERT_LINE : m_irq_state; + if (state != CLEAR_LINE) + set_service_attention<SA_IRQ_ON, 1>(); + else + set_service_attention<SA_IRQ_ON, 0>(); // the main execute loop will take the interrupt break; @@ -728,8 +734,9 @@ void z80_device::state_import(const device_state_entry &entry) case STATE_GENPC: m_prvpc = m_pc; m_ref = 0xffff00; - m_after_ei = false; - m_after_ldair = false; + set_service_attention<SA_AFTER_EI, 0>(); + if (HAS_LDAIR_QUIRK) + set_service_attention<SA_AFTER_LDAIR, 0>(); break; case Z80_R: diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h index ec111c3cd32..b40e697d81f 100644 --- a/src/devices/cpu/z80/z80.h +++ b/src/devices/cpu/z80/z80.h @@ -78,6 +78,8 @@ protected: void illegal_1(); void illegal_2(); u8 flags_szyxc(u16 value); + template <u8 Bit, bool State> void set_service_attention() { static_assert(Bit < 8, "out of range bit index"); if (State) m_service_attention |= (1 << Bit); else m_service_attention &= ~(1 << Bit); }; + template <u8 Bit> bool get_service_attention() { static_assert(Bit < 8, "out of range bit index"); return m_service_attention & (1 << Bit); }; void halt(); void leave_halt(); @@ -137,6 +139,16 @@ protected: devcb_write_line m_halt_cb; devcb_write_line m_busack_cb; + static constexpr u8 SA_BUSRQ = 0; + static constexpr u8 SA_BUSACK = 1; + static constexpr u8 SA_NMI_PENDING = 2; + static constexpr u8 SA_IRQ_ON = 3; + static constexpr u8 SA_HALT = 4; + static constexpr u8 SA_AFTER_EI = 5; + static constexpr u8 SA_AFTER_LDAIR = 6; + static constexpr u8 SA_NSC800_IRQ_ON = 7; + u8 m_service_attention; // bitmap for required handling in service step + PAIR16 m_prvpc; PAIR16 m_pc; PAIR16 m_sp; @@ -161,13 +173,10 @@ protected: u8 m_im; u8 m_i; u8 m_nmi_state; // nmi pin state - bool m_nmi_pending; // nmi pending u8 m_irq_state; // irq pin state int m_wait_state; // wait pin state int m_busrq_state; // bus request pin state u8 m_busack_state; // bus acknowledge pin state - bool m_after_ei; // are we in the EI shadow? - bool m_after_ldair; // same, but for LD A,I or LD A,R u16 m_ea; int m_icount; diff --git a/src/devices/cpu/z80/z80.lst b/src/devices/cpu/z80/z80.lst index 12bd39360ba..a31e651748b 100644 --- a/src/devices/cpu/z80/z80.lst +++ b/src/devices/cpu/z80/z80.lst @@ -206,10 +206,14 @@ macro r800:ld_r_a macro ld_a_r call nomreq_ir 1 - A = (m_r & 0x7f) | m_r2; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true; + A = (m_r & 0x7f) | m_r2; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); + if (HAS_LDAIR_QUIRK) + set_service_attention<SA_AFTER_LDAIR, 1>(); macro r800:ld_a_r - A = (m_r & 0x7f) | m_r2; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true; + A = (m_r & 0x7f) | m_r2; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); + if (HAS_LDAIR_QUIRK) + set_service_attention<SA_AFTER_LDAIR, 1>(); macro ld_i_a call nomreq_ir 1 @@ -220,10 +224,14 @@ macro r800:ld_i_a macro ld_a_i call nomreq_ir 1 - A = m_i; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true; + A = m_i; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); + if (HAS_LDAIR_QUIRK) + set_service_attention<SA_AFTER_LDAIR, 1>(); macro r800:ld_a_i - A = m_i; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true; + A = m_i; set_f((F & CF) | SZ[A] | (m_iff2 << 2)); + if (HAS_LDAIR_QUIRK) + set_service_attention<SA_AFTER_LDAIR, 1>(); macro rst addr TDAT = PC; @@ -531,8 +539,8 @@ macro r800:otdr PC -= 2; block_io_interrupted_flags(); } -macro jump %opcode - m_ref = 0x%opcode00; +macro jump %po + m_ref = 0x%po00; goto process; macro jump_prefixed %prefix @@ -542,10 +550,9 @@ macro jump_prefixed %prefix macro take_nmi // Check if processor was halted leave_halt(); - #if HAS_LDAIR_QUIRK + if (HAS_LDAIR_QUIRK) // reset parity flag after LD A,I or LD A,R - if (m_after_ldair) F &= ~PF; - #endif + if (get_service_attention<SA_AFTER_LDAIR>()) F &= ~PF; m_iff1 = 0; m_r++; + 5 @@ -553,7 +560,7 @@ macro take_nmi call wm16_sp PC = 0x0066; WZ = PC; - m_nmi_pending = false; + set_service_attention<SA_NMI_PENDING, 0>(); macro irqfetch { @@ -640,27 +647,26 @@ macro take_interrupt } } WZ = PC; - #if HAS_LDAIR_QUIRK + if (HAS_LDAIR_QUIRK) // reset parity flag after LD A,I or LD A,R - if (m_after_ldair) F &= ~PF; - #endif + if (get_service_attention<SA_AFTER_LDAIR>()) F &= ~PF; macro check_interrupts - if (m_nmi_pending) { + if (get_service_attention<SA_NMI_PENDING>()) { call take_nmi - } else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei) { + } else if (m_irq_state != CLEAR_LINE && m_iff1 && !get_service_attention<SA_AFTER_EI>()) { // SA_IRQ_ON call take_interrupt } macro z80n:check_interrupts - if (m_nmi_pending) { + if (get_service_attention<SA_NMI_PENDING>()) { if (m_stackless) { // on take_nmi m_out_nextreg_cb(0xc2, m_pc.b.l); m_out_nextreg_cb(0xc3, m_pc.b.h); } call take_nmi - } else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei) { + } else if (m_irq_state != CLEAR_LINE && m_iff1 && !get_service_attention<SA_AFTER_EI>()) { call take_interrupt } @@ -688,17 +694,16 @@ macro nsc800_take_interrupt ; } WZ = PC; - #if HAS_LDAIR_QUIRK + if (HAS_LDAIR_QUIRK) // reset parity flag after LD A,I or LD A,R - if (m_after_ldair) F &= ~PF; - #endif + if (get_service_attention<SA_AFTER_LDAIR>()) F &= ~PF; macro nsc800:check_interrupts - if (m_nmi_pending) { + if (get_service_attention<SA_NMI_PENDING>()) { call take_nmi - } else if ((m_nsc800_irq_state[0] != CLEAR_LINE || m_nsc800_irq_state[1] != CLEAR_LINE || m_nsc800_irq_state[2] != CLEAR_LINE) && m_iff1 && !m_after_ei) { + } else if (get_service_attention<SA_NSC800_IRQ_ON>() && m_iff1 && !get_service_attention<SA_AFTER_EI>()) { call nsc800_take_interrupt - } else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei) { + } else if (m_irq_state != CLEAR_LINE && m_iff1 && !get_service_attention<SA_AFTER_EI>()) { // SA_IRQ_ON call take_interrupt } @@ -707,35 +712,42 @@ macro nsc800:check_interrupts # ROP ########################################################## ffff - m_ref = 0xffff00; - if (m_icount <= 0) return; - if (m_busrq_state) { - if (!m_busack_state) { - m_busack_state = 1; - m_busack_cb(1); - } - if (m_icount > 0) - m_icount = 0; + if (m_icount <= 0) { + m_ref = 0xffff00; return; - } else if (m_busack_state) { - m_busack_state = 0; - m_busack_cb(0); } - call check_interrupts - m_after_ei = false; - m_after_ldair = false; - if (m_halt) { - debugger_wait_hook(); - call rop - PC--; - continue; - } else { - PRVPC = PC; - debugger_instruction_hook(PC); - call rop - m_ref = (0x00 << 16) | (TDAT8 << 8); - goto process; + if (m_service_attention) { + if (m_busrq_state) { // SA_BUSRQ + if (!m_busack_state) { + m_busack_state = 1; + set_service_attention<SA_BUSACK, 1>(); + m_busack_cb(1); + } + if (m_icount > 0) + m_icount = 0; + m_ref = 0xffff00; + return; + } else if (m_busack_state) { // SA_BUSACK + m_busack_state = 0; + set_service_attention<SA_BUSACK, 0>(); + m_busack_cb(0); + } + call check_interrupts + set_service_attention<SA_AFTER_EI, 0>(); // SA_AFTER_EI + if (HAS_LDAIR_QUIRK) + set_service_attention<SA_AFTER_LDAIR, 0>(); // SA_AFTER_LDAIR + if (m_halt) { // SA_HALT + debugger_wait_hook(); + call rop + PC--; + continue; + } } + PRVPC = PC; + debugger_instruction_hook(PC); + call rop + m_ref = (0x00 << 16) | (TDAT8 << 8); + goto process; ########################################################## diff --git a/src/devices/cpu/z80/z80make.py b/src/devices/cpu/z80/z80make.py index 0aa7ee1a55e..023cdfd29ba 100644 --- a/src/devices/cpu/z80/z80make.py +++ b/src/devices/cpu/z80/z80make.py @@ -31,6 +31,10 @@ class IndStr: def has_indent(self): return self.indent != '' + def strip_indent(self, n): + if self.indent != '': + self.indent = self.indent[n:] + def replace(self, new): self.str = new @@ -77,7 +81,7 @@ class Opcode: for i in range(0, len(self.source)): il = self.source[i] if not has_steps or not step_switch: - il.indent = "" + il.strip_indent(1) line = il.line() tokens = line.split() last_line = i + 1 == len(self.source) @@ -240,7 +244,7 @@ class OpcodeList: name = line_toc[1] arg = None if len(line_toc) > 2: - arg = line_toc[2] + arg = " ".join(line_toc[2:]) if name in self.macros: macro = self.macros[name] ([out.extend(self.pre_process(il)) for il in macro.apply(arg)]) @@ -260,21 +264,22 @@ class OpcodeList: for prefix in sorted(prefixes): is_rop = prefix == 'ff' + opc_switch = not is_rop if prefix_switch: print("case 0x%s:" % (prefix), file=f) print("{", file=f) - if not is_rop: + if opc_switch: print("\tswitch (u8(m_ref >> 8)) // opcode", file=f) print("\t{", file=f) for opc in self.opcode_info[prefix]: # reenter loop only process steps > 0 if not reenter or opc.with_steps(): - if not is_rop: + if opc_switch: print("\tcase 0x%s:" % (opc.code), file=f) opc.save_dasm(step_switch=reenter, f=f) print("\t\tcontinue;", file=f) print("", file=f) - if not is_rop: + if opc_switch: print("\t}", file=f) if prefix_switch: @@ -295,6 +300,7 @@ class OpcodeList: print("", file=f) print("bool interrupted = true;", file=f) print("while (u8(m_ref) != 0x00) {", file=f) + print("// slow re-enter", file=f) print("\t// workaround to simulate main loop behavior where continue statement relays on having it set after", file=f) print("\tif (!interrupted) {", file=f) print("\t\tm_ref = 0xffff00;", file=f) @@ -305,19 +311,17 @@ class OpcodeList: self.switch_prefix(self.opcode_info.keys(), reenter=True, f=f) print("", file=f) print('assert((void("switch statement above must cover all possible cases!"), false));', file=f) - print("}", file=f) - print("", file=f) + print("} // end: slow", file=f) print("if (m_ref != 0xffff00) goto process;", file=f) print("", file=f) - print("while (true) {", file=f) - print("", file=f) - print("\t\t// unwrapped ff prefix", file=f) + print("while (true) { // fast process", file=f) + print("\t\t// rop: unwrapped ff prefix", file=f) self.switch_prefix(['ff'], reenter=False, f=f) print("", file=f) print("process:", file=f) self.switch_prefix(self.opcode_info.keys() - ['ff'], reenter=False, f=f) - print("", file=f) - print("} // while (true)", file=f) + print("} // end: fast", file=f) + print('assert((void("unreachable!"), false));', file=f) def main(argv): if len(argv) != 3 and len(argv) != 4: diff --git a/src/devices/cpu/z80/z80n.h b/src/devices/cpu/z80/z80n.h index 8198412074c..d4d452955fd 100644 --- a/src/devices/cpu/z80/z80n.h +++ b/src/devices/cpu/z80/z80n.h @@ -20,7 +20,7 @@ public: bool nmi_stackless_r() { return m_stackless; } void nmi_stackless_w(bool data) { m_stackless = data; } - void nmi() { m_nmi_pending = true; } + void nmi() { set_service_attention<SA_NMI_PENDING, 1>(); } protected: virtual void device_start() override ATTR_COLD; diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index c9d91704cce..8d4d6cedf4d 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -33,7 +33,6 @@ #define LOG_TIMING (1U << 3) //#define LOG_MASK (LOG_GENERAL | LOG_DEV_CALLS | LOG_DEBUG) -//#define LOG_MASK (LOG_TIMING) #define LOG_MASK (0) #define LOGDEVCALLS(...) LOGMASKED(LOG_DEV_CALLS, __VA_ARGS__) @@ -815,11 +814,15 @@ void netlist_mame_stream_output_device::device_reset() void netlist_mame_stream_output_device::sound_update_fill(sound_stream &stream, int output) { - if (stream.samples() < m_buffer.size()) - osd_printf_warning("sound %s: samples %d less bufsize %d\n", name(), stream.samples(), m_buffer.size()); + int samples = m_buffer.size(); + if (stream.samples() < samples) + { + osd_printf_warning("sound %s: samples %d less bufsize %d\n", name(), stream.samples(), samples); + samples = stream.samples(); + } int sampindex; - for (sampindex = 0; sampindex < m_buffer.size(); sampindex++) + for (sampindex = 0; sampindex < samples; sampindex++) stream.put(output, sampindex, m_buffer[sampindex]); if (sampindex < stream.samples()) stream.fill(output, m_cur, sampindex); @@ -858,7 +861,7 @@ void netlist_mame_stream_output_device::process(netlist::netlist_time_ext tim, n int pos = (tim - m_last_buffer_time) / m_sample_time; //if (pos > m_bufsize) // throw emu_fatalerror("sound %s: pos %d exceeded bufsize %d\n", name().c_str(), pos, m_bufsize); - while (m_buffer.size() < pos ) + while (m_buffer.size() < pos) { m_buffer.push_back(static_cast<sound_stream::sample_t>(m_cur)); } diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp index 8c08af9a4c6..8db48046bc4 100644 --- a/src/frontend/mame/ui/info.cpp +++ b/src/frontend/mame/ui/info.cpp @@ -182,7 +182,7 @@ void get_system_warnings( std::set<std::add_pointer_t<device_type> > seen; for (device_t &device : device_enumerator(machine.root_device())) { - if ((device.type().emulation_flags() & device_t::flags::NOT_WORKING) && seen.insert(&device.type()).second) + if ((&machine.root_device() != &device) && (device.type().emulation_flags() & device_t::flags::NOT_WORKING) && seen.insert(&device.type()).second) { util::stream_format(buf, first ? _("%s") : _(", %s"), device.type().fullname()); first = false; @@ -281,7 +281,8 @@ machine_static_info::machine_static_info(const ui_options &options, machine_conf m_emulation_flags |= device.type().emulation_flags() & ~device_t::flags::NOT_WORKING; m_unemulated_features |= device.type().unemulated_features(); m_imperfect_features |= device.type().imperfect_features(); - m_has_nonworking_devices = m_has_nonworking_devices || (device.type().emulation_flags() & device_t::flags::NOT_WORKING); + if (&config.root_device() != &device) + m_has_nonworking_devices = m_has_nonworking_devices || (device.type().emulation_flags() & device_t::flags::NOT_WORKING); // look for BIOS options device_t const *const parent(device.owner()); diff --git a/src/mame/bmc/koftball.cpp b/src/mame/bmc/koftball.cpp index 56944d3e4f9..a29413b5391 100644 --- a/src/mame/bmc/koftball.cpp +++ b/src/mame/bmc/koftball.cpp @@ -41,6 +41,7 @@ ft5_v6_c4.u58 / #include "cpu/m68000/m68000.h" #include "machine/nvram.h" +#include "machine/ticket.h" #include "machine/timer.h" #include "sound/okim6295.h" #include "sound/ymopl.h" @@ -77,7 +78,8 @@ public: m_videoram(*this, "videoram%u", 0U), m_pixram(*this, "pixram"), m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette") + m_palette(*this, "palette"), + m_hopper(*this, "hopper") { } void jxzh(machine_config &config) ATTR_COLD; @@ -97,6 +99,8 @@ private: required_shared_ptr<u16> m_pixram; required_device<gfxdecode_device> m_gfxdecode; required_device<palette_device> m_palette; + optional_device<hopper_device> m_hopper; + tilemap_t *m_tilemap[4]{}; u16 m_prot_data = 0; u8 m_irq_enable = 0; @@ -107,6 +111,7 @@ private: u8 m_pixpal = 0; void irq_ack_w(u8 data); + void outputs_w(u8 data); u16 random_number_r(); u16 prot_r(); u16 kaimenhu_prot_r(); @@ -295,6 +300,14 @@ void koftball_state::irq_ack_w(u8 data) m_maincpu->set_input_line(i, CLEAR_LINE); } +void koftball_state::outputs_w(u8 data) +{ + m_hopper->motor_w(BIT(data, 0)); + machine().bookkeeping().coin_counter_w(0, BIT(data, 1)); // credits in + machine().bookkeeping().coin_counter_w(1, BIT(data, 4)); // credits paid out by hopper or key-out + // bit 7 always set? +} + // FIXME: merge video maps void koftball_state::koftball_mem(address_map &map) { @@ -353,7 +366,7 @@ void koftball_state::jxzh_mem(address_map &map) map(0x2a001a, 0x2a001d).nopw(); map(0x2a0000, 0x2a001f).r(FUNC(koftball_state::random_number_r)); map(0x2b0000, 0x2b0001).portr("DSW"); - map(0x2da000, 0x2da003).w("ymsnd", FUNC(ym2413_device::write)).umask16(0xff00); + map(0x2da000, 0x2da003).umask16(0xff00).w("ymsnd", FUNC(ym2413_device::write)); map(0x2db001, 0x2db001).w("ramdac", FUNC(ramdac_device::index_w)); map(0x2db002, 0x2db003).nopr(); // reads here during some scene changes @@ -362,7 +375,7 @@ void koftball_state::jxzh_mem(address_map &map) map(0x2dc000, 0x2dc000).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write)); map(0x2f0000, 0x2f0001).portr("INPUTS"); - map(0x300000, 0x300001).nopw(); + map(0x300001, 0x300001).w(FUNC(koftball_state::outputs_w)); map(0x320000, 0x320000).lw8(NAME([this] (u8 data) { m_gfx_ctrl = data; LOGGFX("GFX ctrl $320000 (layer enable) %02x\n", data); })); map(0x340000, 0x340001).r(FUNC(koftball_state::prot_r)); map(0x360000, 0x360001).w(FUNC(koftball_state::prot_w)); @@ -384,23 +397,23 @@ void koftball_state::ramdac_map(address_map &map) static INPUT_PORTS_START( koftball ) PORT_START("INPUTS") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BILL1 ) + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_POKER_HOLD4 ) // also decrease in sound test PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_POKER_HOLD2 ) // also increase in sound test PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_POKER_HOLD3 ) - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("unknown1") PORT_CODE(KEYCODE_A) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("unknown2") PORT_CODE(KEYCODE_S) + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_SERVICE_NO_TOGGLE( 0x1000, IP_ACTIVE_LOW ) // test mode enter - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("unknown3") PORT_CODE(KEYCODE_D) - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("unknown4") PORT_CODE(KEYCODE_F) - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("unknown5") PORT_CODE(KEYCODE_G) + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_START("DSW") PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:!8") @@ -453,75 +466,86 @@ static INPUT_PORTS_START( koftball ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) INPUT_PORTS_END -static INPUT_PORTS_START( jxzh ) +static INPUT_PORTS_START( kaimenhu ) PORT_START("INPUTS") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_MAHJONG_REACH ) PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_MAHJONG_PON ) PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_MAHJONG_KAN ) PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_MAHJONG_CHI ) PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_MAHJONG_RON ) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_MAHJONG_SCORE ) PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_MAHJONG_BET ) - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("hopper switch") PORT_CODE(KEYCODE_H) + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::line_r)) PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_SERVICE_NO_TOGGLE( 0x1000, IP_ACTIVE_LOW ) - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP) PORT_NAME("Change Tile / Double Up") + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) PORT_NAME("%p Mahjong Small / Right") + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_MAHJONG_BIG ) PORT_NAME("%p Mahjong Big / Left") + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP) PORT_NAME("%p Mahjong Double Up / Change Tile") PORT_START("DSW") - PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:!8") - PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:!7") - PORT_DIPSETTING( 0x0002, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:!6") - PORT_DIPSETTING( 0x0004, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:!5") - PORT_DIPSETTING( 0x0008, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:!4") - PORT_DIPSETTING( 0x0010, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:!3") - PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:!2") - PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:!1") - PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Service_Mode ) ) PORT_DIPLOCATION("SW2:!8") - PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:!7") - PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:!6") - PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:!5") - PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:!4") - PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:!3") - PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:!2") - PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:!1") - PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0001, 0x0001, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW1:8") + PORT_DIPSETTING( 0x0001, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0002, 0x0002, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW1:7") + PORT_DIPSETTING( 0x0002, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0004, 0x0004, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW1:6") + PORT_DIPSETTING( 0x0004, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0008, 0x0008, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW1:5") + PORT_DIPSETTING( 0x0008, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0010, 0x0010, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW1:4") + PORT_DIPSETTING( 0x0010, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0020, 0x0020, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING( 0x0020, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0040, 0x0040, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING( 0x0040, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0080, 0x0080, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING( 0x0080, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0100, 0x0100, DEF_STR(Service_Mode) ) PORT_DIPLOCATION("SW2:8") + PORT_DIPSETTING( 0x0100, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0200, 0x0200, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW2:7") + PORT_DIPSETTING( 0x0200, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0400, 0x0400, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW2:6") + PORT_DIPSETTING( 0x0400, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x0800, 0x0800, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW2:5") + PORT_DIPSETTING( 0x0800, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x1000, 0x1000, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW2:4") + PORT_DIPSETTING( 0x1000, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x2000, 0x2000, DEF_STR(Unknown) ) PORT_DIPLOCATION("SW2:3") + PORT_DIPSETTING( 0x2000, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x4000, 0x0000, "In-Game Music" ) PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING( 0x4000, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) + PORT_DIPNAME( 0x8000, 0x0000, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW2:1") + PORT_DIPSETTING( 0x8000, DEF_STR(Off) ) + PORT_DIPSETTING( 0x0000, DEF_STR(On) ) +INPUT_PORTS_END + +static INPUT_PORTS_START( jxzh ) + PORT_INCLUDE(kaimenhu) + + PORT_MODIFY("DSW") + PORT_DIPNAME( 0x0003, 0x0003, "Odds Rate" ) PORT_DIPLOCATION("SW1:8,7") + PORT_DIPSETTING( 0x0003, "1 2 3 4 6 8 10 15" ) + PORT_DIPSETTING( 0x0002, "1 2 4 8 12 16 24 32" ) + PORT_DIPSETTING( 0x0001, "1 2 3 5 8 15 30 50" ) + PORT_DIPSETTING( 0x0000, "1 2 3 5 10 25 50 100" ) INPUT_PORTS_END @@ -596,6 +620,8 @@ void koftball_state::jxzh(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &koftball_state::jxzh_mem); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + + HOPPER(config, m_hopper, attotime::from_msec(50)); } void koftball_state::kaimenhu(machine_config &config) @@ -745,4 +771,4 @@ void koftball_state::init_koftball() GAME( 1995, koftball, 0, koftball, koftball, koftball_state, init_koftball, ROT0, "BMC", "King of Football", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1996, jxzh, 0, jxzh, jxzh, koftball_state, empty_init, ROT0, "BMC", "Jinxiu Zhonghua", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1996, kaimenhu, jxzh, kaimenhu, jxzh, koftball_state, empty_init, ROT0, "BMC", "Kaimen Hu", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1996, kaimenhu, jxzh, kaimenhu, kaimenhu, koftball_state, empty_init, ROT0, "BMC", "Kaimen Hu", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/igs/igs011.cpp b/src/mame/igs/igs011.cpp index ec6c08faa8a..8513a663336 100644 --- a/src/mame/igs/igs011.cpp +++ b/src/mame/igs/igs011.cpp @@ -592,17 +592,14 @@ void igs011_state::igs011_blit_flags_w(offs_t offset, u16 data, u16 mem_mask) clear_pen = m_blitter.pen; } - const int xstart = (m_blitter.x & 0x1ff) - (m_blitter.x & 0x200); - const int ystart = (m_blitter.y & 0x0ff) - (m_blitter.y & 0x100); - - int xend, xinc; - int yend, yinc; - - if (flipx) { xend = xstart - (m_blitter.w & 0x1ff) - 1; xinc = -1; } - else { xend = xstart + (m_blitter.w & 0x1ff) + 1; xinc = 1; } - - if (flipy) { yend = ystart - (m_blitter.h & 0x0ff) - 1; yinc = -1; } - else { yend = ystart + (m_blitter.h & 0x0ff) + 1; yinc = 1; } + const int xstart = util::sext(m_blitter.x, 10); + const int ystart = util::sext(m_blitter.y, 9); + const int xsize = (m_blitter.w & 0x1ff) + 1; + const int ysize = (m_blitter.h & 0x0ff) + 1; + const int xend = flipx ? (xstart - xsize) : (xstart + xsize); + const int yend = flipy ? (ystart - ysize) : (ystart + ysize); + const int xinc = flipx ? -1 : 1; + const int yinc = flipy ? -1 : 1; for (int y = ystart; y != yend; y += yinc) { @@ -3397,7 +3394,7 @@ static INPUT_PORTS_START( lhb2 ) PORT_DIPSETTING( 0x02, "70%" ) PORT_DIPSETTING( 0x01, "74%" ) PORT_DIPSETTING( 0x00, "78%" ) - PORT_DIPNAME( 0x08, 0x00, "Odds Rate" ) PORT_DIPLOCATION("SW1:4") // 倍數? + PORT_DIPNAME( 0x08, 0x00, "Odds Rate" ) PORT_DIPLOCATION("SW1:4") // 倍數表 PORT_DIPSETTING( 0x00, "1,2,3,4,5,6,7,8" ) PORT_DIPSETTING( 0x08, "1,2,3,5,8,15,30,50" ) PORT_DIPNAME( 0x10, 0x00, "Maximum Bet" ) PORT_DIPLOCATION("SW1:5") // 最大押注 @@ -3408,9 +3405,9 @@ static INPUT_PORTS_START( lhb2 ) PORT_DIPSETTING( 0x40, "2" ) PORT_DIPSETTING( 0x20, "3" ) PORT_DIPSETTING( 0x00, "5" ) - PORT_DIPNAME( 0x80, 0x80, "Credit Timer" ) PORT_DIPLOCATION("SW1:8") // ??清除 (clears credits after timeout if you don't start a game) - PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) // ? - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) // ? + PORT_DIPNAME( 0x80, 0x80, "Credit Timer" ) PORT_DIPLOCATION("SW1:8") // 自動清除 (clears credits after timeout if you don't start a game) + PORT_DIPSETTING( 0x80, DEF_STR(Off) ) // ? + PORT_DIPSETTING( 0x00, DEF_STR(On) ) // ? PORT_START("DSW2") PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW2:1,2") // 投幣比率 @@ -3430,13 +3427,15 @@ static INPUT_PORTS_START( lhb2 ) PORT_DIPNAME( 0x20, 0x20, "Payout Mode" ) PORT_DIPLOCATION("SW2:6") // 退分方式 PORT_DIPSETTING( 0x20, "Key-Out" ) // 洗分 PORT_DIPSETTING( 0x00, "Return Coins" ) // 退幣 (doesn't seem to work properly) - PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW2:7" ) // ???? - PORT_DIPNAME( 0x80, 0x80, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8") // ??音? - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) // ? - PORT_DIPSETTING( 0x80, DEF_STR( On ) ) // ? + PORT_DIPNAME( 0x40, 0x40, "Auto Reach" ) PORT_DIPLOCATION("SW2:7") // 自動摸打 (automatically draws and discards tiles after reach) + PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // ? + PORT_DIPSETTING( 0x40, DEF_STR(On) ) // ? + PORT_DIPNAME( 0x80, 0x80, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW2:8") // 示範音樂 + PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // ? + PORT_DIPSETTING( 0x80, DEF_STR(On) ) // ? PORT_START("DSW3") - PORT_DIPNAME( 0x03, 0x03, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:1,2") // ??限? + PORT_DIPNAME( 0x03, 0x03, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:1,2") // 破台限制 PORT_DIPSETTING( 0x03, "500" ) PORT_DIPSETTING( 0x02, "1000" ) PORT_DIPSETTING( 0x01, "2000" ) @@ -3582,37 +3581,39 @@ INPUT_PORTS_END // basically same game as lhb2 and nkishusp but with joystick controls static INPUT_PORTS_START( tygn ) PORT_START("DSW1") - PORT_DIPNAME( 0x07, 0x07, "Pay Out (%)" ) PORT_DIPLOCATION("DSW1:1,2,3") - PORT_DIPSETTING( 0x07, "50" ) - PORT_DIPSETTING( 0x06, "54" ) - PORT_DIPSETTING( 0x05, "58" ) - PORT_DIPSETTING( 0x04, "62" ) - PORT_DIPSETTING( 0x03, "66" ) - PORT_DIPSETTING( 0x02, "70" ) - PORT_DIPSETTING( 0x01, "74" ) - PORT_DIPSETTING( 0x00, "78" ) - PORT_DIPNAME( 0x08, 0x08, "Minimum Bet" ) PORT_DIPLOCATION("DSW1:4") + PORT_DIPNAME( 0x07, 0x02, "Payout Rate" ) PORT_DIPLOCATION("SW1:1,2,3") // 機率調整 + PORT_DIPSETTING( 0x07, "50%" ) + PORT_DIPSETTING( 0x06, "54%" ) + PORT_DIPSETTING( 0x05, "58%" ) + PORT_DIPSETTING( 0x04, "62%" ) + PORT_DIPSETTING( 0x03, "66%" ) + PORT_DIPSETTING( 0x02, "70%" ) + PORT_DIPSETTING( 0x01, "74%" ) + PORT_DIPSETTING( 0x00, "78%" ) + PORT_DIPNAME( 0x08, 0x08, "Minimum Bet" ) PORT_DIPLOCATION("SW1:4") // 最小押注 PORT_DIPSETTING( 0x08, "1" ) PORT_DIPSETTING( 0x00, "2" ) - PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coinage ) ) PORT_DIPLOCATION("DSW1:5,6") - PORT_DIPSETTING( 0x00, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x30, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x20, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("DSW1:7") - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_DIPUNKNOWN( 0x80, 0x80 ) PORT_DIPLOCATION("DSW1:8") + PORT_DIPNAME( 0x30, 0x30, DEF_STR(Coinage) ) PORT_DIPLOCATION("SW1:5,6") // 投幣比率 + PORT_DIPSETTING( 0x00, DEF_STR(2C_1C) ) + PORT_DIPSETTING( 0x30, DEF_STR(1C_1C) ) + PORT_DIPSETTING( 0x20, DEF_STR(1C_2C) ) + PORT_DIPSETTING( 0x10, DEF_STR(1C_3C) ) + PORT_DIPNAME( 0x40, 0x40, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW1:7") // 示範音樂 + PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // ? + PORT_DIPSETTING( 0x40, DEF_STR(On) ) // ? + PORT_DIPNAME( 0x80, 0x80, "Credit Timer" ) PORT_DIPLOCATION("SW1:8") // 自動清除 (clears credits after timeout if you don't start a game) + PORT_DIPSETTING( 0x80, DEF_STR(Off) ) // ? + PORT_DIPSETTING( 0x00, DEF_STR(On) ) // ? PORT_START("DSW2") // not shown in test mode - PORT_DIPUNKNOWN( 0x01, 0x01 ) PORT_DIPLOCATION("DSW2:1") - PORT_DIPUNKNOWN( 0x02, 0x02 ) PORT_DIPLOCATION("DSW2:2") - PORT_DIPUNKNOWN( 0x04, 0x04 ) PORT_DIPLOCATION("DSW2:3") - PORT_DIPUNKNOWN( 0x08, 0x08 ) PORT_DIPLOCATION("DSW2:4") - PORT_DIPUNKNOWN( 0x10, 0x10 ) PORT_DIPLOCATION("DSW2:5") - PORT_DIPUNKNOWN( 0x20, 0x20 ) PORT_DIPLOCATION("DSW2:6") - PORT_DIPUNKNOWN( 0x40, 0x40 ) PORT_DIPLOCATION("DSW2:7") - PORT_DIPUNKNOWN( 0x80, 0x80 ) PORT_DIPLOCATION("DSW2:8") + PORT_DIPUNKNOWN( 0x01, 0x01 ) PORT_DIPLOCATION("SW2:1") + PORT_DIPUNKNOWN( 0x02, 0x02 ) PORT_DIPLOCATION("SW2:2") + PORT_DIPUNKNOWN( 0x04, 0x04 ) PORT_DIPLOCATION("SW2:3") + PORT_DIPUNKNOWN( 0x08, 0x08 ) PORT_DIPLOCATION("SW2:4") + PORT_DIPUNKNOWN( 0x10, 0x10 ) PORT_DIPLOCATION("SW2:5") + PORT_DIPUNKNOWN( 0x20, 0x20 ) PORT_DIPLOCATION("SW2:6") + PORT_DIPUNKNOWN( 0x40, 0x40 ) PORT_DIPLOCATION("SW2:7") + PORT_DIPUNKNOWN( 0x80, 0x80 ) PORT_DIPLOCATION("SW2:8") PORT_START("DSW3") // only 2 out of 4 DIP banks phisically present PORT_DIPNAME( 0xff, 0xff, DEF_STR( Unused ) ) @@ -5108,7 +5109,7 @@ GAME( 1995, dbc, lhb, lhb, lhb, igs011_state, i GAME( 1995, ryukobou, lhb, lhb, lhb, igs011_state, init_ryukobou, ROT0, "IGS / Alta", "Mahjong Ryukobou (Japan, V030J)", MACHINE_SUPPORTS_SAVE ) GAME( 1996, lhb2, 0, lhb2, lhb2, igs011_state, init_lhb2, ROT0, "IGS", "Lung Fu Bong II (Hong Kong, V185H)", MACHINE_SUPPORTS_SAVE ) GAME( 1996, tygn, lhb2, tygn, tygn, igs011_state, init_tygn, ROT0, "IGS", "Te Yi Gong Neng (China, V632C)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // ROM patches -GAME( 1996, lhb3, lhb2, nkishusp, nkishusp, igs011_state, init_lhb3, ROT0, "IGS", "Long Hu Bang III: Cuo Pai Gaoshou (China, V242C)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // ROM patches +GAME( 1996, lhb3, lhb2, nkishusp, lhb2, igs011_state, init_lhb3, ROT0, "IGS", "Long Hu Bang III: Cuo Pai Gaoshou (China, V242C)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // ROM patches GAME( 1996, xymg, 0, xymg, xymg, igs011_state, init_xymg, ROT0, "IGS", "Xingyun Manguan (China, V651C, set 1)", MACHINE_SUPPORTS_SAVE ) GAME( 1996, xymga, xymg, xymga, xymg, igs011_state, init_xymga, ROT0, "IGS", "Xingyun Manguan (China, V651C, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) // different encryption and without IGS003 GAME( 1996, wlcc, xymg, wlcc, wlcc, igs011_state, init_wlcc, ROT0, "IGS", "Wanli Changcheng (China, V638C)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/igs/igs_m027.cpp b/src/mame/igs/igs_m027.cpp index ef1e018c4e7..45a2f96fba3 100644 --- a/src/mame/igs/igs_m027.cpp +++ b/src/mame/igs/igs_m027.cpp @@ -76,11 +76,15 @@ small 猜小 cancel 放弃 + Known issues: + * ccly shows a black screen when it should show its bookeeping and input test modes + * klxyj102cn/klxyj104cn occasionally think the hopper is empty in "Joystick" mode - why? + TODO: * Communication for games that support linked mode * IGS025 protection for Chess Challenge II * Emulate necessary peripherals for Extra Draw (might not belong here) - * I/O for remaining games (klxyj102cn, klxyj104cn) + * I/O for remaining games */ #include "emu.h" @@ -752,49 +756,60 @@ INPUT_PORTS_START( jking02 ) PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW3:8" ) INPUT_PORTS_END -INPUT_PORTS_START( tct2p ) - // uses the kan/pon/chi/reach/ron buttons as the main controls in mahjong panel mode +INPUT_PORTS_START( klxyj ) + // Mahjong panel controls: + // Start Start Stop All Take Score + // Mahjong Bet Bet + // Mahjong A Stop 1 Double Up (twice winnings) + // Mahjong B Stop 2 + // Mahjong C Stop 3 Double Up (winnings) + // Mahjong D Stop 4 + // Mahjong E Double Up (half winnings) + // Mahjong K Show Odds Big + // Mahjong M Show Odds Small + // TODO: how do you show hidden credit/bets/winnings in mahjong panel mode? IGS_MAHJONG_MATRIX_CONDITIONAL("DSW2", 0x01, 0x00) PORT_START("PORTB") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SLOT_STOP2 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SLOT_STOP2 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SLOT_STOP1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SLOT_STOP3 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SLOT_STOP1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SLOT_STOP3 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_START("PORTC") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SLOT_STOP_ALL ) PORT_NAME("Show Odds") PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_READ_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::line_r)) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SLOT_STOP4 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Small / Half Gamble") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Bet / Double Up") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Big / Show Odds") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Start / Take Score") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_READ_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::line_r)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SLOT_STOP4 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_START("PLAYER") - PORT_BIT( 0x000ff, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x00100, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x1fe00, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x20000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0xc0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) - PORT_BIT( 0x0003f, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_CUSTOM_MEMBER(FUNC(igs_m027_state::kbd_ioport_r)) - PORT_BIT( 0x00040, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_READ_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::line_r)) - PORT_BIT( 0x00f80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) - PORT_BIT( 0x01000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) - PORT_BIT( 0x02000, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) - PORT_BIT( 0x1c000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) - PORT_BIT( 0x20000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) - PORT_BIT( 0xc0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x000ff, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x00100, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x0fe00, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x10000, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Show Credits") // hold to show credits/bets/wins when hidden + PORT_BIT( 0x20000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0xc0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x0003f, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_CUSTOM_MEMBER(FUNC(igs_m027_state::kbd_ioport_r)) + PORT_BIT( 0x00040, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_READ_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::line_r)) + PORT_BIT( 0x00f80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x01000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x02000, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x1c000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x20000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0xc0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_START("PPIB") PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_WRITE_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::motor_w)) @@ -807,6 +822,118 @@ INPUT_PORTS_START( tct2p ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MEMORY_RESET ) PORT_TOGGLE PORT_START("DSW1") + PORT_DIPNAME( 0x1f, 0x1f, "Satellite Machine No.") PORT_DIPLOCATION("SW1:1,2,3,4,5") // 副机编号 + SATELLITE_NO_SETTINGS + PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW1:6" ) + PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW1:7" ) + PORT_DIPNAME( 0x80, 0x80, "Link Mode" ) PORT_DIPLOCATION("SW1:8") // 连线模式 + PORT_DIPSETTING( 0x80, DEF_STR(Off) ) // 无 + PORT_DIPSETTING( 0x00, DEF_STR(On) ) // 有 + + PORT_START("DSW2") + PORT_DIPNAME( 0x01, 0x01, DEF_STR(Controls) ) PORT_DIPLOCATION("SW2:1") // 操作界面 + PORT_DIPSETTING( 0x01, DEF_STR(Joystick) ) // 揺杆 + PORT_DIPSETTING( 0x00, "Mahjong" ) // 麻雀键盘 + PORT_DIPNAME( 0x02, 0x02, "Hide Credits") PORT_DIPLOCATION("SW2:2") // 隐分功能 (hides credits/bets/wins, game plays normally) + PORT_DIPSETTING( 0x02, DEF_STR(Off) ) // 无 + PORT_DIPSETTING( 0x00, DEF_STR(On) ) // 有 + PORT_DIPNAME( 0x04, 0x04, "Number Type" ) PORT_DIPLOCATION("SW2:3") // 数字型态 + PORT_DIPSETTING( 0x04, "Numbers" ) // 数字 + PORT_DIPSETTING( 0x00, "Circle Tiles" ) // 筒子 + PORT_DIPNAME( 0x08, 0x00, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW2:4") // 示范音乐 + PORT_DIPSETTING( 0x08, DEF_STR(Off) ) // 无 + PORT_DIPSETTING( 0x00, DEF_STR(On) ) // 有 + PORT_DIPNAME( 0x10, 0x10, "Background Color Mode" ) PORT_DIPLOCATION("SW2:5") // 底色模式 + PORT_DIPSETTING( 0x10, "Monochrome" ) // 黑白 + PORT_DIPSETTING( 0x00, "Color" ) // 彩色 + PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW2:6" ) + PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW2:7" ) + PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW2:8" ) + + PORT_START("DSW3") + PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SW3:1" ) + PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW3:2" ) + PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW3:3" ) + PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW3:4" ) + PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW3:5" ) + PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW3:6" ) + PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW3:7" ) + PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW3:8" ) +INPUT_PORTS_END + +INPUT_PORTS_START( tct2p ) + // Mahjong panel controls: + // Start Start Stop All Take Score + // Mahjong Bet Bet + // Mahjong Kan Stop 1 + // Mahjong Pon Stop 2 + // Mahjong Chi Stop 3 + // Mahjong Reach Stop 4 + // Mahjong Ron Start Stop All Take Score + // Mahjong Double Up Double Up (winnings) + // Mahjong Big Big Double Up (twice winnings) + // Mahjong Small Small Double Up (half winnings) + // Mahjong A Double Up (twice winnings) + // Mahjong C Double Up (winnings) + // Mahjong E Double Up (half winnings) + // Mahjong K Show Odds Big + // Mahjong M Show Odds Small + // Mahjong N Deal + IGS_MAHJONG_MATRIX_CONDITIONAL("DSW2", 0x01, 0x00) + + PORT_START("PORTB") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SLOT_STOP2 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SLOT_STOP1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SLOT_STOP3 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + + PORT_START("PORTC") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Small / Show Odds") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Bet / Double Up") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Big") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_NAME("Start / Take Score") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_READ_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::line_r)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SLOT_STOP4 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + + PORT_START("PLAYER") + PORT_BIT( 0x000ff, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x00100, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x0fe00, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x10000, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0x20000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + PORT_BIT( 0xc0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) + + PORT_BIT( 0x0003f, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_CUSTOM_MEMBER(FUNC(igs_m027_state::kbd_ioport_r)) + PORT_BIT( 0x00040, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_READ_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::line_r)) + PORT_BIT( 0x00f80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x01000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x02000, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x1c000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0x20000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + PORT_BIT( 0xc0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) + + PORT_START("PPIB") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_WRITE_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::motor_w)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_WRITE_LINE_MEMBER(FUNC(igs_m027_state::counter_w<0>)) // payout/keyout + + PORT_START("PPIC") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OUTPUT ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_WRITE_LINE_DEVICE_MEMBER("hopper", FUNC(hopper_device::motor_w)) + + PORT_START("CLEARMEM") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MEMORY_RESET ) PORT_TOGGLE + + PORT_START("DSW1") PORT_DIPNAME( 0x1f, 0x1f, "Satellite Machine No.") PORT_DIPLOCATION("SW1:1,2,3,4,5") // 副机編号 SATELLITE_NO_SETTINGS PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW1:6" ) @@ -2530,6 +2657,7 @@ ROM_START( sdwx ) ROM_LOAD( "sp.u2", 0x00000, 0x80000, CRC(216b5418) SHA1(b7bc24ced0ccb5476c974420aa506c13b971fc9f) ) ROM_END +// 快乐西游记 (Kuàilè Xīyóu Jì) ROM_START( klxyj104cn ) ROM_REGION( 0x04000, "maincpu", 0 ) // Internal ROM of IGS027A ARM based MCU. Not dumped for this set, but it works. @@ -2548,6 +2676,7 @@ ROM_START( klxyj104cn ) ROM_LOAD( "w4201.u2", 0x00000, 0x100000, CRC(464f11ab) SHA1(56e45bd31f667fc30387fcd4c940a94819b7ef0f) ) ROM_END +// 快乐西游记 (Kuàilè Xīyóu Jì) ROM_START( klxyj102cn ) // IGS PCB-0351-05-FM. 1 82C55, 3 banks of 8 DIP switches ROM_REGION( 0x04000, "maincpu", 0 ) // Internal ROM of IGS027A ARM based MCU @@ -3427,7 +3556,7 @@ ROM_START( mgcs3 ) ROM_END /* -Tarzan Chuǎng Tiānguān 2 Jiāqiáng Bǎn +Tarzan Chuǎng Tiān Guān 2 Jiāqiáng Bǎn 泰山闯天关 2 加强版 IGS, 2003 @@ -3821,9 +3950,9 @@ GAME( 2004, lhzb4dhb, 0, lhzb4, lhzb4, igs_m027_stat GAME( 1999, lthyp, 0, lthyp, lthyp, igs_m027_state, init_slqz3, ROT0, "IGS", "Long Teng Hu Yao Duizhan Jiaqiang Ban (S104CN)", MACHINE_NODEVICE_LAN ) GAME( 2000, zhongguo, 0, zhongguo, zhongguo, igs_m027_state, init_zhongguo, ROT0, "IGS", "Zhongguo Chu Da D (V102C)", 0 ) GAMEL( 2001, jking02, 0, jking02, jking02, igs_m027_state, init_jking02, ROT0, "IGS", "Jungle King 2002 (V209US)", MACHINE_NODEVICE_LAN, layout_jking02 ) // shows V212US in bookkeeping menu -GAME( 2001, klxyj104cn, jking02, m027_1ppi<true>, base, igs_m027_state, init_klxyj, ROT0, "IGS", "Kuai Le Xi You Ji (V104CN)", MACHINE_NOT_WORKING | MACHINE_NODEVICE_LAN ) -GAME( 2001, klxyj102cn, jking02, m027_1ppi<true>, base, igs_m027_state, init_klxyj, ROT0, "IGS", "Kuai Le Xi You Ji (V102CN)", MACHINE_NOT_WORKING | MACHINE_NODEVICE_LAN ) -GAME( 2003, tct2p, 0, tct2p, tct2p, igs_m027_state, init_tct2p, ROT0, "IGS", "Tarzan Chuang Tianguan 2 Jiaqiang Ban (V306CN)", 0 ) +GAME( 2001, klxyj104cn, jking02, tct2p, klxyj, igs_m027_state, init_klxyj, ROT0, "IGS", "Kuaile Xiyou Ji (V104CN)", MACHINE_NOT_WORKING | MACHINE_NODEVICE_LAN ) +GAME( 2001, klxyj102cn, jking02, tct2p, klxyj, igs_m027_state, init_klxyj, ROT0, "IGS", "Kuaile Xiyou Ji (V102CN)", MACHINE_NOT_WORKING | MACHINE_NODEVICE_LAN ) +GAME( 2003, tct2p, 0, tct2p, tct2p, igs_m027_state, init_tct2p, ROT0, "IGS", "Tarzan Chuang Tian Guan 2 Jiaqiang Ban (V306CN)", 0 ) GAME( 2003, mgzz, 0, mgzz, mgzz101cn, igs_m027_state, init_mgzz, ROT0, "IGS", "Manguan Zhizun (V101CN)", 0 ) GAME( 2003, mgzz100cn, mgzz, mgzz, mgzz100cn, igs_m027_state, init_mgzz, ROT0, "IGS", "Manguan Zhizun (V100CN)", 0 ) GAME( 2007, mgcs3, 0, lhzb4, mgcs3, igs_m027_state, init_mgcs3, ROT0, "IGS", "Manguan Caishen 3 (V101CN)", 0 ) diff --git a/src/mame/misc/sshanghai.cpp b/src/mame/misc/sshanghai.cpp index 9a5eb3e6b74..9a215d83e33 100644 --- a/src/mame/misc/sshanghai.cpp +++ b/src/mame/misc/sshanghai.cpp @@ -6,14 +6,37 @@ Super Shanghai 2000. Super Shanghai 2000 - Wrestle Fiesta. + 3-reel 5-liner with an extra reel, plus a front game to hide the slots game. + + Rare stealth video slots machine platform based on a Z80 CPU and a AY-3-8910 for sound. + 5 DIP switches banks. + Driver by Roberto Fresca & Grull Osgo. - 3-reel 5-liner with an extra reel. - Rare video slots machine platform based on a Z80 CPU and a AY-3-8910 for sound. - 5 DIP switchs banks. +********************************************************************************************* + + Notes: + + This platform hosts various slot games featuring different themes, + including classic fruit symbols (7s, bells, plums, oranges, grapes, etc.), + Easter-themed graphics (eggs, rabbits), and fish-themed designs. - Unknown manufacturer. + To comply with local gambling restrictions, these games are concealed behind + a front-game interface. The system initially boots into a Pairs-style front-game. + Hidden input sequences allow switching between the slots game and the front-game. + Some machines further protect this mechanism with a 4-digit password, which can + be entered using the joystick or directional buttons and confirmed with the action button. + + The platform support games with three operational modes: + + * Pairs Mode (front-game only) + * Stealth Mode (hides the slots game) + * Direct Slots Mode (boots directly into the slots game) + + + If a set request password, use Right, Left, Up, Down, to change the code digits in order. + Action button to validate and switch to slots mode. ********************************************************************************************/ @@ -246,10 +269,10 @@ static INPUT_PORTS_START( ssh2000 ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_9) PORT_NAME("Clear/Reset") PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_CODE(KEYCODE_Z) PORT_NAME("Fire 1") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_CODE(KEYCODE_Z) PORT_NAME("Action") PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_0) PORT_NAME("Port Test") - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_CODE(KEYCODE_X) PORT_NAME("Fire 2") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_CODE(KEYCODE_C) PORT_NAME("Fire 3") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_CODE(KEYCODE_X) PORT_NAME("Switch to Slots (gambling game)") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_CODE(KEYCODE_C) PORT_NAME("Switch to Pairs (front Game)") PORT_START("IN1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) @@ -258,108 +281,109 @@ static INPUT_PORTS_START( ssh2000 ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_S) PORT_NAME("Test 2") PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2) PORT_NAME("Coin A") PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(2) PORT_NAME("Coin B") - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("Start (Automatic)") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("Start (Automatic Mode)") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_NAME("Bet / Stop / Up") PORT_START("DSWA") - PORT_DIPNAME( 0x03, 0x00, "Percentage" ) PORT_DIPLOCATION("DSWA:8,7") + PORT_DIPNAME( 0x03, 0x00, "Percentage" ) PORT_DIPLOCATION("DSWA:8,7") PORT_DIPSETTING( 0x00, "80%" ) PORT_DIPSETTING( 0x01, "75%" ) PORT_DIPSETTING( 0x02, "70%" ) PORT_DIPSETTING( 0x03, "65%" ) - PORT_DIPNAME( 0x04, 0x04, "Sprites" ) PORT_DIPLOCATION("DSWA:6") + PORT_DIPNAME( 0x04, 0x04, "Sprites" ) PORT_DIPLOCATION("DSWA:6") PORT_DIPSETTING( 0x04, "Fruits") PORT_DIPSETTING( 0x00, "Tiles") - PORT_DIPNAME( 0x08, 0x00, "Game Name" ) PORT_DIPLOCATION("DSWA:5") + PORT_DIPNAME( 0x08, 0x00, "Game Name" ) PORT_DIPLOCATION("DSWA:5") PORT_DIPSETTING( 0x08, "NAME 2") PORT_DIPSETTING( 0x00, "NAME 1") - PORT_DIPNAME( 0x10, 0x00, "Extra Take") PORT_DIPLOCATION("DSWA:4") + PORT_DIPNAME( 0x10, 0x00, "Extra Take") PORT_DIPLOCATION("DSWA:4") PORT_DIPSETTING( 0x10, "OFF: NO" ) PORT_DIPSETTING( 0x00, "ON: YES" ) - PORT_DIPNAME( 0x20, 0x00, "Demo Sound" ) PORT_DIPLOCATION("DSWA:3") + PORT_DIPNAME( 0x20, 0x00, "Demo Sound" ) PORT_DIPLOCATION("DSWA:3") PORT_DIPSETTING( 0x20, "OFF: NO" ) PORT_DIPSETTING( 0x00, "ON: YES" ) - PORT_DIPNAME( 0x40, 0x00, "Max. BET" ) PORT_DIPLOCATION("DSWA:2") + PORT_DIPNAME( 0x40, 0x00, "Max. BET" ) PORT_DIPLOCATION("DSWA:2") PORT_DIPSETTING( 0x40, "OFF: 9" ) PORT_DIPSETTING( 0x00, "ON: 5" ) - PORT_DIPNAME( 0x80, 0x00, "Demostration") PORT_DIPLOCATION("DSWA:1") + PORT_DIPNAME( 0x80, 0x00, "Demostration") PORT_DIPLOCATION("DSWA:1") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_START("DSWB") - PORT_DIPNAME( 0x0f, 0x0f, "Coinage A") PORT_DIPLOCATION("DSWB:8,7,6,5") + PORT_DIPNAME( 0x0f, 0x00, "Coinage A") PORT_DIPLOCATION("DSWB:8,7,6,5") PORT_DIPSETTING( 0x00, "1" ) - PORT_DIPSETTING( 0x1, "2" ) - PORT_DIPSETTING( 0x2, "5" ) - PORT_DIPSETTING( 0x3, "10" ) - PORT_DIPSETTING( 0x4, "20" ) - PORT_DIPSETTING( 0x5, "50" ) - PORT_DIPSETTING( 0x6, "100" ) - PORT_DIPSETTING( 0x7, "500" ) - PORT_DIPSETTING( 0x8, "1000" ) - PORT_DIPSETTING( 0x9, "4" ) - PORT_DIPSETTING( 0xa, "8" ) - PORT_DIPSETTING( 0xb, "20" ) - PORT_DIPSETTING( 0xc, "40" ) - PORT_DIPSETTING( 0xd, "200" ) - PORT_DIPSETTING( 0xe, "400" ) - PORT_DIPSETTING( 0xf, "10" ) - PORT_DIPNAME( 0xf0, 0xf0, "Coinage B") PORT_DIPLOCATION("DSWB:4,3,2,1") + PORT_DIPSETTING( 0x01, "2" ) + PORT_DIPSETTING( 0x09, "4" ) + PORT_DIPSETTING( 0x02, "5" ) + PORT_DIPSETTING( 0x0a, "8" ) + PORT_DIPSETTING( 0x03, "10" ) + PORT_DIPSETTING( 0x0f, "10" ) + PORT_DIPSETTING( 0x04, "20" ) + PORT_DIPSETTING( 0x0b, "20" ) + PORT_DIPSETTING( 0x0c, "40" ) + PORT_DIPSETTING( 0x05, "50" ) + PORT_DIPSETTING( 0x06, "100" ) + PORT_DIPSETTING( 0x0d, "200" ) + PORT_DIPSETTING( 0x0e, "400" ) + PORT_DIPSETTING( 0x07, "500" ) + PORT_DIPSETTING( 0x08, "1000" ) + PORT_DIPNAME( 0xf0, 0x00, "Coinage B") PORT_DIPLOCATION("DSWB:4,3,2,1") PORT_DIPSETTING( 0x00, "1" ) PORT_DIPSETTING( 0x10, "2" ) + PORT_DIPSETTING( 0x90, "4" ) PORT_DIPSETTING( 0x20, "5" ) + PORT_DIPSETTING( 0xa0, "8" ) PORT_DIPSETTING( 0x30, "10" ) + PORT_DIPSETTING( 0xf0, "10" ) PORT_DIPSETTING( 0x40, "20" ) - PORT_DIPSETTING( 0x50, "50" ) - PORT_DIPSETTING( 0x60, "100" ) - PORT_DIPSETTING( 0x70, "500" ) - PORT_DIPSETTING( 0x80, "1000" ) - PORT_DIPSETTING( 0x90, "4" ) - PORT_DIPSETTING( 0xa0, "8" ) PORT_DIPSETTING( 0xb0, "20" ) PORT_DIPSETTING( 0xc0, "40" ) + PORT_DIPSETTING( 0x50, "50" ) + PORT_DIPSETTING( 0x60, "100" ) PORT_DIPSETTING( 0xd0, "200" ) PORT_DIPSETTING( 0xe0, "400" ) - PORT_DIPSETTING( 0xf0, "10" ) + PORT_DIPSETTING( 0x70, "500" ) + PORT_DIPSETTING( 0x80, "1000" ) PORT_START("DSWC") - PORT_DIPNAME( 0x01, 0x01, "Found") PORT_DIPLOCATION("DSWC:8") + PORT_DIPNAME( 0x01, 0x00, "Found") PORT_DIPLOCATION("DSWC:8") PORT_DIPSETTING( 0x01, "Auto" ) PORT_DIPSETTING( 0x00, "Hand" ) - PORT_DIPNAME( 0x02, 0x02, "Found Pay" ) PORT_DIPLOCATION("DSWC:7") + PORT_DIPNAME( 0x02, 0x00, "Found Pay" ) PORT_DIPLOCATION("DSWC:7") PORT_DIPSETTING( 0x02, "By One" ) PORT_DIPSETTING( 0x00, "All" ) - PORT_DIPNAME( 0x04, 0x04, "Papas Pay" ) PORT_DIPLOCATION("DSWC:6") + PORT_DIPNAME( 0x04, 0x00, "Papas Pay" ) PORT_DIPLOCATION("DSWC:6") PORT_DIPSETTING( 0x04, "By One" ) PORT_DIPSETTING( 0x00, "All" ) - PORT_DIPNAME( 0x08, 0x08, "Flip Type" ) PORT_DIPLOCATION("DSWC:5") + PORT_DIPNAME( 0x08, 0x00, "Flip Type" ) PORT_DIPLOCATION("DSWC:5") PORT_DIPSETTING( 0x08, "on Tape" ) PORT_DIPSETTING( 0x00, "on Kare" ) - PORT_DIPNAME( 0xf0, 0xf0, "Coinage C") PORT_DIPLOCATION("DSWC:4,3,2,1") + PORT_DIPNAME( 0xf0, 0x00, "Coinage C") PORT_DIPLOCATION("DSWC:4,3,2,1") PORT_DIPSETTING( 0x00, "1" ) PORT_DIPSETTING( 0x10, "2" ) + PORT_DIPSETTING( 0x90, "4" ) PORT_DIPSETTING( 0x20, "5" ) + PORT_DIPSETTING( 0xa0, "8" ) PORT_DIPSETTING( 0x30, "10" ) + PORT_DIPSETTING( 0xf0, "10" ) PORT_DIPSETTING( 0x40, "20" ) - PORT_DIPSETTING( 0x50, "50" ) - PORT_DIPSETTING( 0x60, "100" ) - PORT_DIPSETTING( 0x70, "500" ) - PORT_DIPSETTING( 0x80, "1000" ) - PORT_DIPSETTING( 0x90, "4" ) - PORT_DIPSETTING( 0xa0, "8" ) PORT_DIPSETTING( 0xb0, "20" ) PORT_DIPSETTING( 0xc0, "40" ) + PORT_DIPSETTING( 0x50, "50" ) + PORT_DIPSETTING( 0x60, "100" ) PORT_DIPSETTING( 0xd0, "200" ) PORT_DIPSETTING( 0xe0, "400" ) - PORT_DIPSETTING( 0xf0, "10" ) + PORT_DIPSETTING( 0x70, "500" ) + PORT_DIPSETTING( 0x80, "1000" ) PORT_START("DSWD") - PORT_DIPNAME( 0x0f, 0x0f, "Credit Limit") PORT_DIPLOCATION("DSWD:8,7,6,5") + PORT_DIPNAME( 0x0f, 0x00, "Credit Limit") PORT_DIPLOCATION("DSWD:8,7,6,5") PORT_DIPSETTING( 0x00, " 5000" ) PORT_DIPSETTING( 0x01, " 7500" ) PORT_DIPSETTING( 0x02, "10000" ) PORT_DIPSETTING( 0x03, "15000" ) PORT_DIPSETTING( 0x04, "20000" ) + PORT_DIPSETTING( 0x0f, "20000" ) PORT_DIPSETTING( 0x05, "25000" ) PORT_DIPSETTING( 0x06, "30000" ) PORT_DIPSETTING( 0x07, "35000" ) @@ -370,21 +394,20 @@ static INPUT_PORTS_START( ssh2000 ) PORT_DIPSETTING( 0x0c, "70000" ) PORT_DIPSETTING( 0x0d, "80000" ) PORT_DIPSETTING( 0x0e, "90000" ) - PORT_DIPSETTING( 0x0f, "20000" ) - PORT_DIPNAME( 0x10, 0x10, "Swap Code" ) PORT_DIPLOCATION("DSWD:4") + PORT_DIPNAME( 0x10, 0x00, "Swap Code" ) PORT_DIPLOCATION("DSWD:4") PORT_DIPSETTING( 0x10, "Code 2" ) PORT_DIPSETTING( 0x00, "Code 1" ) - PORT_DIPNAME( 0x20, 0x20, "Return In" ) PORT_DIPLOCATION("DSWD:3") + PORT_DIPNAME( 0x20, 0x00, "Return In" ) PORT_DIPLOCATION("DSWD:3") PORT_DIPSETTING( 0x20, "Main" ) PORT_DIPSETTING( 0x00, "Amusement" ) - PORT_DIPNAME( 0x40, 0x40, "Must be Off" ) PORT_DIPLOCATION("DSWD:2") + PORT_DIPNAME( 0x40, 0x00, "Must be Off" ) PORT_DIPLOCATION("DSWD:2") PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) - PORT_DIPNAME( 0x80, 0x80, "Amusement" ) PORT_DIPLOCATION("DSWD:1") + PORT_DIPNAME( 0x80, 0x00, "Amusement" ) PORT_DIPLOCATION("DSWD:1") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_START("DSWE") - PORT_DIPNAME( 0x0f, 0x0f, "CoinIn Limit") PORT_DIPLOCATION("DSWE:8,7,6,5") + PORT_DIPNAME( 0x0f, 0x00, "CoinIn Limit") PORT_DIPLOCATION("DSWE:8,7,6,5") PORT_DIPSETTING( 0x00, " 1000" ) PORT_DIPSETTING( 0x01, " 2000" ) PORT_DIPSETTING( 0x02, " 3000" ) @@ -401,12 +424,12 @@ static INPUT_PORTS_START( ssh2000 ) PORT_DIPSETTING( 0x0d, "40000" ) PORT_DIPSETTING( 0x0e, "50000" ) PORT_DIPSETTING( 0x0f, " 5000" ) - PORT_DIPNAME( 0x30, 0x30, "Preset BONUS" ) PORT_DIPLOCATION("DSWE:4,3") + PORT_DIPNAME( 0x30, 0x00, "Preset BONUS" ) PORT_DIPLOCATION("DSWE:4,3") PORT_DIPSETTING( 0x00, "1000" ) PORT_DIPSETTING( 0x10, "2000" ) PORT_DIPSETTING( 0x20, "3000" ) PORT_DIPSETTING( 0x30, "4000" ) - PORT_DIPNAME( 0xc0, 0xc0, "Preset LEFT" ) PORT_DIPLOCATION("DSWE:2,1") + PORT_DIPNAME( 0xc0, 0x00, "Preset LEFT" ) PORT_DIPLOCATION("DSWE:2,1") PORT_DIPSETTING( 0x00, "1000" ) PORT_DIPSETTING( 0x40, "2000" ) PORT_DIPSETTING( 0x80, "3000" ) @@ -466,6 +489,7 @@ void ssh2000_state::ssh2000(machine_config &config) /* Super Shanghai 2000 (set 1) + No code to enter the game. type: SHG-47 version: 2000 @@ -510,6 +534,7 @@ ROM_END /* Super Shanghai 2000 (set 2) + Code 1234 to enter the game. type: SHG-47 version: 2000 @@ -545,6 +570,7 @@ ROM_END Super Shanghai 2000 Wrestle Fiesta. Main program 30% bonus by Vegas (red board) + No code to enter the game. type: SHG-47 version: 2000 |