diff options
492 files changed, 8687 insertions, 3304 deletions
diff --git a/cmake/Qt3rdPartyLibraryConfig.cmake.in b/cmake/Qt3rdPartyLibraryConfig.cmake.in index 9c51350821f..b91cd8a06c0 100644 --- a/cmake/Qt3rdPartyLibraryConfig.cmake.in +++ b/cmake/Qt3rdPartyLibraryConfig.cmake.in @@ -16,7 +16,10 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependenci include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake") endif() -if (NOT QT_NO_CREATE_TARGETS) +# Do the checks inside Targets.cmake even when the file is still being generated +include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@TargetsPrecheck.cmake") + +if(NOT __qt_@target@_skip_include_targets_file) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake") if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS) @@ -26,6 +29,7 @@ if (NOT QT_NO_CREATE_TARGETS) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessAliasTargets.cmake") endif() endif() + set(__qt_@target@_targets_file_included ON) endif() foreach(extra_cmake_include @extra_cmake_includes@) diff --git a/cmake/Qt3rdPartyLibraryHelpers.cmake b/cmake/Qt3rdPartyLibraryHelpers.cmake index 33bfc3e8348..fb41ded3150 100644 --- a/cmake/Qt3rdPartyLibraryHelpers.cmake +++ b/cmake/Qt3rdPartyLibraryHelpers.cmake @@ -283,6 +283,17 @@ function(qt_internal_add_3rdparty_library target) INSTALL_DESTINATION "${config_install_dir}" ) + qt_configure_file( + OUTPUT "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" + CONTENT +" +_qt_internal_should_include_targets( + TARGETS ${target} + NAMESPACE ${INSTALL_CMAKE_NAMESPACE}:: + OUT_VAR_SHOULD_SKIP __qt_${target}_skip_include_targets_file +) +") + write_basic_package_version_file( "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" VERSION ${PROJECT_VERSION} @@ -297,6 +308,7 @@ function(qt_internal_add_3rdparty_library target) "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" DESTINATION "${config_install_dir}" COMPONENT Devel ) diff --git a/cmake/QtAppHelpers.cmake b/cmake/QtAppHelpers.cmake index 00613275416..df2e70ffb0f 100644 --- a/cmake/QtAppHelpers.cmake +++ b/cmake/QtAppHelpers.cmake @@ -86,7 +86,6 @@ function(qt_internal_add_app target) ${arg_INCLUDE_DIRECTORIES} DEFINES ${arg_DEFINES} - ${deprecation_define} LIBRARIES ${arg_LIBRARIES} ${arg_PUBLIC_LIBRARIES} diff --git a/cmake/QtAutogenHelpers.cmake b/cmake/QtAutogenHelpers.cmake index 8aabb09e14a..b50dd0b2899 100644 --- a/cmake/QtAutogenHelpers.cmake +++ b/cmake/QtAutogenHelpers.cmake @@ -215,49 +215,3 @@ function(qt_make_output_file infile prefix suffix source_dir binary_dir result) set("${result}" "${outpath}/${prefix}${outfilename}${suffix}" PARENT_SCOPE) endfunction() -# Work around AUTOGEN issue when a library is added as a dependency more than once, and the autogen -# library dependency results in being discarded. To mitigate that, add all autogen dependencies -# manually, based on the passed in dependencies. -# CMake 4.0+ has a fix, so we don't need the extra logic. -# See https://gitlab.kitware.com/cmake/cmake/-/issues/26700 -function(qt_internal_work_around_autogen_discarded_dependencies target) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0 - OR QT_NO_AUTOGEN_DISCARDED_DEPENDENCIES_WORKAROUND) - return() - endif() - - set(libraries ${ARGN}) - set(final_libraries "") - - foreach(lib IN LISTS libraries) - # Skip non-target dependencies. - if(NOT TARGET "${lib}") - continue() - endif() - - # Resolve alias targets, because AUTOGEN_TARGET_DEPENDS doesn't seem to handle them. - _qt_internal_dealias_target(lib) - - # Skip imported targets, they don't have sync_headers targets. - get_target_property(imported "${lib}" IMPORTED) - if(imported) - continue() - endif() - - # Resolve Qt private modules to their public counterparts. - get_target_property(is_private_module "${lib}" _qt_is_private_module) - get_target_property(public_module_target "${lib}" _qt_public_module_target_name) - - if(is_private_module AND public_module_target) - set(lib "${public_module_target}") - endif() - - # Another TARGET check, just in case. - if(TARGET "${lib}") - list(APPEND final_libraries "${lib}") - endif() - endforeach() - if(final_libraries) - set_property(TARGET ${target} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS "${final_libraries}") - endif() -endfunction() diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index 029546fd65d..405b5e22635 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -217,6 +217,17 @@ configure_file( @ONLY ) +qt_configure_file( + OUTPUT "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}TargetsPrecheck.cmake" + CONTENT +" +_qt_internal_should_include_targets( + TARGETS ${__export_targets} + NAMESPACE ${INSTALL_CMAKE_NAMESPACE}:: + OUT_VAR_SHOULD_SKIP __qt_skip_include_targets_file +) +") + write_basic_package_version_file( "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigVersionImpl.cmake" VERSION ${PROJECT_VERSION} @@ -248,6 +259,7 @@ qt_install(FILES "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigExtras.cmake" "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigVersion.cmake" "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigVersionImpl.cmake" + "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}TargetsPrecheck.cmake" "${__GlobalConfig_build_dir}/QtInstallPaths.cmake" DESTINATION "${__GlobalConfig_install_dir}" COMPONENT Devel @@ -443,10 +455,19 @@ elseif(WASM) endif() # Install CI support files to libexec. -qt_path_join(__qt_libexec_install_dir "${QT_INSTALL_DIR}" "${INSTALL_LIBEXECDIR}") -qt_copy_or_install(FILES coin/instructions/qmake/ensure_pro_file.cmake - DESTINATION "${__qt_libexec_install_dir}") -qt_copy_or_install(PROGRAMS "util/testrunner/qt-testrunner.py" - DESTINATION "${__qt_libexec_install_dir}") -qt_copy_or_install(PROGRAMS "util/testrunner/sanitizer-testrunner.py" - DESTINATION "${__qt_libexec_install_dir}") +if(QT_INSTALL_CI_FILES) + qt_path_join(__qt_libexec_install_dir "${QT_INSTALL_DIR}" "${INSTALL_LIBEXECDIR}") + qt_copy_or_install(FILES coin/instructions/qmake/ensure_pro_file.cmake + DESTINATION "${__qt_libexec_install_dir}") + qt_copy_or_install(PROGRAMS "util/testrunner/qt-testrunner.py" + DESTINATION "${__qt_libexec_install_dir}") + qt_copy_or_install(PROGRAMS "util/testrunner/sanitizer-testrunner.py" + DESTINATION "${__qt_libexec_install_dir}") + qt_copy_or_install(PROGRAMS "util/json_schema/check_qt_module_json_schemas.py" + DESTINATION "${__qt_libexec_install_dir}") +endif() + +# Install json schemas for the users as well +qt_copy_or_install(FILES + "util/json_schema/modules.json" + DESTINATION "${INSTALL_QT_SHAREDIR}/json_schema/") diff --git a/cmake/QtBuildHelpers.cmake b/cmake/QtBuildHelpers.cmake index 60d66eb2353..1fb5c6350e1 100644 --- a/cmake/QtBuildHelpers.cmake +++ b/cmake/QtBuildHelpers.cmake @@ -429,6 +429,7 @@ macro(qt_internal_setup_build_and_global_variables) qt_internal_set_qt_source_tree_var() qt_internal_set_export_compile_commands() qt_internal_set_configure_from_ide() + qt_internal_set_ci_options() # Depends on qt_internal_set_configure_from_ide qt_internal_set_sync_headers_at_configure_time() diff --git a/cmake/QtBuildInternalsExtra.cmake.in b/cmake/QtBuildInternalsExtra.cmake.in index 8985f8178a9..32b9facfece 100644 --- a/cmake/QtBuildInternalsExtra.cmake.in +++ b/cmake/QtBuildInternalsExtra.cmake.in @@ -73,6 +73,10 @@ if(@FEATURE_developer_build@) set(FEATURE_developer_build ON CACHE BOOL "Developer build." FORCE) endif() +# Propagate CI files installation +set(QT_INSTALL_CI_FILES @QT_INSTALL_CI_FILES@ CACHE BOOL + "Install CI files for internal use only" FORCE) + # Propagate non-prefix builds. set(QT_WILL_INSTALL @QT_WILL_INSTALL@ CACHE BOOL "Boolean indicating if doing a Qt prefix build (vs non-prefix build)." FORCE) diff --git a/cmake/QtBuildOptionsHelpers.cmake b/cmake/QtBuildOptionsHelpers.cmake index a2f352c39c6..ccd054183d4 100644 --- a/cmake/QtBuildOptionsHelpers.cmake +++ b/cmake/QtBuildOptionsHelpers.cmake @@ -155,6 +155,19 @@ macro(qt_internal_set_configure_from_ide) endif() endmacro() +function(qt_internal_set_ci_options) + # Do not install CI only files except for + # - developer-builds + # - in coin CI + if(QT_FEATURE_developer_build OR DEFINED ENV{COIN_UNIQUE_JOB_ID}) + set(__QT_INSTALL_CI_FILES_default ON) + else() + set(__QT_INSTALL_CI_FILES_default OFF) + endif() + set(QT_INSTALL_CI_FILES ${__QT_INSTALL_CI_FILES_default} CACHE BOOL + "Install CI files for internal use only") +endfunction() + macro(qt_internal_set_sync_headers_at_configure_time) set(_qt_sync_headers_at_configure_time_default ${QT_INTERNAL_CONFIGURE_FROM_IDE}) diff --git a/cmake/QtBuildRepoHelpers.cmake b/cmake/QtBuildRepoHelpers.cmake index bca25233365..86107179475 100644 --- a/cmake/QtBuildRepoHelpers.cmake +++ b/cmake/QtBuildRepoHelpers.cmake @@ -11,6 +11,8 @@ macro(qt_internal_project_setup) # Check for the minimum CMake version. qt_internal_require_suitable_cmake_version() qt_internal_upgrade_cmake_policies() + # Make sure QT_INTERNAL_BUILD_STANDALONE_PARTS is defined as early as possible + qt_internal_setup_standalone_parts() endmacro() macro(qt_build_internals_set_up_private_api) @@ -817,6 +819,8 @@ macro(qt_build_tests) endif() endif() + qt_internal_add_default_tests() + if(NOT QT_SUPERBUILD) # In a super build, we don't want to finalize the batch blacklist at the end of each repo, # but rather once at the end of the top-level configuration. diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in index 2c34af97713..10b483c1e9b 100644 --- a/cmake/QtConfig.cmake.in +++ b/cmake/QtConfig.cmake.in @@ -19,7 +19,11 @@ __qt_internal_require_suitable_cmake_version_for_using_qt() get_filename_component(_qt_cmake_dir "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) set(_qt_@PROJECT_VERSION_MAJOR@_config_cmake_dir "${CMAKE_CURRENT_LIST_DIR}") -if (NOT QT_NO_CREATE_TARGETS) +# Do the checks inside Targets.cmake even when the file is still being generated +include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@TargetsPrecheck.cmake") + +# Create the targets unless we are generating the @INSTALL_CMAKE_NAMESPACE@Targets.cmake +if(NOT __qt_skip_include_targets_file) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@Targets.cmake") if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS) if(CMAKE_VERSION VERSION_LESS 3.18 OR QT_USE_OLD_VERSION_LESS_TARGETS) @@ -28,6 +32,7 @@ if (NOT QT_NO_CREATE_TARGETS) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@VersionlessAliasTargets.cmake") endif() endif() + set(__qt_targets_file_included ON) else() # For examples using `find_package(...)` inside their CMakeLists.txt files: # Make CMake's AUTOGEN detect this Qt version properly diff --git a/cmake/QtFeature.cmake b/cmake/QtFeature.cmake index 9cffa58229e..86b1201792d 100644 --- a/cmake/QtFeature.cmake +++ b/cmake/QtFeature.cmake @@ -1570,7 +1570,8 @@ function(qt_run_config_compile_test name) endif() if(arg_CXX_STANDARD) - if(${arg_CXX_STANDARD} LESS 23 OR ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.20") + if((${arg_CXX_STANDARD} LESS 23 OR ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.20") AND + (${arg_CXX_STANDARD} LESS 26 OR ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25")) set(CMAKE_CXX_STANDARD "${arg_CXX_STANDARD}") set(CMAKE_CXX_STANDARD_REQUIRED OFF) endif() diff --git a/cmake/QtFlagHandlingHelpers.cmake b/cmake/QtFlagHandlingHelpers.cmake index 1747e7c7197..67d6f37e36d 100644 --- a/cmake/QtFlagHandlingHelpers.cmake +++ b/cmake/QtFlagHandlingHelpers.cmake @@ -359,7 +359,9 @@ endfunction() function(qt_set_language_standards) ## Use the latest standard the compiler supports (same as qt_common.prf) - if (QT_FEATURE_cxx2b) + if (QT_FEATURE_cxx2c) + set(CMAKE_CXX_STANDARD 26 PARENT_SCOPE) + elseif (QT_FEATURE_cxx2b) set(CMAKE_CXX_STANDARD 23 PARENT_SCOPE) elseif (QT_FEATURE_cxx20) set(CMAKE_CXX_STANDARD 20 PARENT_SCOPE) diff --git a/cmake/QtFrameworkHelpers.cmake b/cmake/QtFrameworkHelpers.cmake index 1982937aaf8..7fac9bdb203 100644 --- a/cmake/QtFrameworkHelpers.cmake +++ b/cmake/QtFrameworkHelpers.cmake @@ -54,6 +54,12 @@ function(qt_internal_find_apple_system_framework out_var framework_name) # We might revisit this later. set(cache_var_name "${out_var}Internal") + if(QT_USE_VCPKG) + # vcpkg.cmake sets CMAKE_FIND_FRAMEWORK to LAST and this setting will find e.g. + # libnetwork.tbd instead of Network.framework. Force the default value here. + set(CMAKE_FIND_FRAMEWORK FIRST) + endif() + find_library(${cache_var_name} "${framework_name}") if(${cache_var_name} AND ${cache_var_name} MATCHES ".framework$") diff --git a/cmake/QtInternalTargets.cmake b/cmake/QtInternalTargets.cmake index a1f4cb7281c..1b0adccd5b5 100644 --- a/cmake/QtInternalTargets.cmake +++ b/cmake/QtInternalTargets.cmake @@ -94,6 +94,18 @@ function(qt_internal_set_warnings_are_errors_flags target target_scope) ${language_args} ) endif() + if(APPLE) + qt_internal_add_compiler_dependent_flags("${target}" ${target_scope} + COMPILERS CLANG AppleClang + CONDITIONS $<BOOL:$<TARGET_PROPERTY:UNITY_BUILD>> + OPTIONS + -Wno-error=nullability-completeness + COMMON_CONDITIONS + ${common_conditions} + LANGUAGES + OBJCXX + ) + endif() # Other options are gated at compile time that are not likely to change between different build # environments of other modules. if(ANDROID) diff --git a/cmake/QtModuleConfig.cmake.in b/cmake/QtModuleConfig.cmake.in index e3af0299c57..73e83d44e19 100644 --- a/cmake/QtModuleConfig.cmake.in +++ b/cmake/QtModuleConfig.cmake.in @@ -24,12 +24,16 @@ if(NOT DEFINED "@INSTALL_CMAKE_NAMESPACE@@target@_FOUND") set("@INSTALL_CMAKE_NAMESPACE@@target@_FOUND" TRUE) endif() -if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND) +# Do the checks inside Targets.cmake even when the file is still being generated +include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@TargetsPrecheck.cmake") + +if(NOT __qt_@target@_skip_include_targets_file AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake" OPTIONAL) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@ExtraProperties.cmake" OPTIONAL) + set(__qt_@target@_targets_file_included ON) endif() # Find the private module counterpart. @@ -80,7 +84,7 @@ if (@INSTALL_CMAKE_NAMESPACE@@target@_FOUND endif() unset(__qt_@target@_always_load_private_module) -if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND) +if(__qt_@target@_targets_file_included) # DEPRECATED # Provide old style variables for includes, compile definitions, etc. # These variables are deprecated and only provided on a best-effort basis to facilitate porting. @@ -210,9 +214,9 @@ else() set(@INSTALL_CMAKE_NAMESPACE@@target@_NOT_FOUND_MESSAGE "Target \"@QT_CMAKE_EXPORT_NAMESPACE@::@target@\" was not found.") - if(QT_NO_CREATE_TARGETS) + if(__qt_@target@_skip_include_targets_file) string(APPEND @INSTALL_CMAKE_NAMESPACE@@target@_NOT_FOUND_MESSAGE - "Possibly due to QT_NO_CREATE_TARGETS being set to TRUE and thus " + "Possibly due to __qt_@target@_skip_include_targets_file being set to TRUE and thus " "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake was not " "included to define the target.") endif() diff --git a/cmake/QtModuleConfigPrivate.cmake.in b/cmake/QtModuleConfigPrivate.cmake.in index 6c16eae2ef6..4846fc740ae 100644 --- a/cmake/QtModuleConfigPrivate.cmake.in +++ b/cmake/QtModuleConfigPrivate.cmake.in @@ -24,11 +24,15 @@ if(NOT __qt_@target@_always_load_private_module) _qt_internal_show_private_module_warning(@target_private@) endif() -if(NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND) +# Do the checks inside Targets.cmake even when the file is still being generated +include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@TargetsPrecheck.cmake") + +if(NOT __qt_@target_private@_skip_include_targets_file AND @INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@Targets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@AdditionalTargetInfo.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@ExtraProperties.cmake" OPTIONAL) + set(__qt_@target_private@_targets_file_included ON) endif() if(TARGET @QT_CMAKE_EXPORT_NAMESPACE@::@target_private@) @@ -45,9 +49,9 @@ else() set(@INSTALL_CMAKE_NAMESPACE@@target_private@_NOT_FOUND_MESSAGE "Target \"@QT_CMAKE_EXPORT_NAMESPACE@::@target_private@\" was not found.") - if(QT_NO_CREATE_TARGETS) + if(__qt_@target_private@_skip_include_targets_file) string(APPEND @INSTALL_CMAKE_NAMESPACE@@target_private@_NOT_FOUND_MESSAGE - "Possibly due to QT_NO_CREATE_TARGETS being set to TRUE and thus " + "Possibly due to __qt_@target_private@_skip_include_targets_file being set to TRUE and thus " "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@Targets.cmake was not " "included to define the target.") endif() diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake index ac27997461e..f7ab67455ce 100644 --- a/cmake/QtModuleHelpers.cmake +++ b/cmake/QtModuleHelpers.cmake @@ -627,7 +627,6 @@ function(qt_internal_add_module target) QT_DEPRECATED_WARNINGS QT_BUILDING_QT QT_BUILD_${module_define_infix}_LIB ### FIXME: use QT_BUILD_ADDON for Add-ons or remove if we don't have add-ons anymore - ${deprecation_define} ) list(APPEND arg_LIBRARIES Qt::PlatformModuleInternal) endif() @@ -1065,9 +1064,29 @@ function(qt_internal_write_basic_module_package target target_private) if(arg_PRIVATE) set(package_name "${INSTALL_CMAKE_NAMESPACE}${target_private}") set(module_config_input_file "QtModuleConfigPrivate.cmake.in") + qt_configure_file( + OUTPUT "${arg_CONFIG_BUILD_DIR}/${package_name}TargetsPrecheck.cmake" + CONTENT +" +_qt_internal_should_include_targets( + TARGETS ${target_private} + NAMESPACE ${INSTALL_CMAKE_NAMESPACE}:: + OUT_VAR_SHOULD_SKIP __qt_${target_private}_skip_include_targets_file +) +") else() set(package_name "${INSTALL_CMAKE_NAMESPACE}${target}") set(module_config_input_file "QtModuleConfig.cmake.in") + qt_configure_file( + OUTPUT "${arg_CONFIG_BUILD_DIR}/${package_name}TargetsPrecheck.cmake" + CONTENT +" +_qt_internal_should_include_targets( + TARGETS ${target} + NAMESPACE ${INSTALL_CMAKE_NAMESPACE}:: + OUT_VAR_SHOULD_SKIP __qt_${target}_skip_include_targets_file +) +") if(arg_FIND_PRIVATE_MODULE) set(always_load_private_module ON) endif() @@ -1111,6 +1130,7 @@ set(__qt_${target}_always_load_private_module ON) "${arg_CONFIG_BUILD_DIR}/${package_name}Config.cmake" "${arg_CONFIG_BUILD_DIR}/${package_name}ConfigVersion.cmake" "${arg_CONFIG_BUILD_DIR}/${package_name}ConfigVersionImpl.cmake" + "${arg_CONFIG_BUILD_DIR}/${package_name}TargetsPrecheck.cmake" DESTINATION "${arg_CONFIG_INSTALL_DIR}" COMPONENT Devel ) @@ -1434,6 +1454,7 @@ function(qt_internal_list_to_json_array out_var list_var) endfunction() # Generate a module description file based on the template in ModuleDescription.json.in +# Keep this in sync with `utils/json_schema/modules.json` function(qt_describe_module target) set(path_suffix "${INSTALL_DESCRIPTIONSDIR}") qt_path_join(build_dir ${QT_BUILD_DIR} ${path_suffix}) @@ -1533,8 +1554,9 @@ function(qt_describe_module target) endif() if(ANDROID) string(APPEND targets_information - "${indent5}\"api_version\": \"${QT_ANDROID_API_USED_FOR_JAVA}\", -${indent5}\"ndk_version\": \"${ANDROID_NDK_REVISION}\",\n") + "${indent5}\"api_version\": \"${QT_ANDROID_API_USED_FOR_JAVA}\",\n" + "${indent5}\"ndk_version\": \"${ANDROID_NDK_REVISION}\",\n" + "${indent5}\"android_platform\": \"${ANDROID_PLATFORM}\",\n") endif() string(APPEND targets_information "${indent5}\"architecture\": \"${architecture}\",\n") string(APPEND targets_information "${indent5}\"abi\": \"${TEST_arch_${architecture}_abi}\"\n") diff --git a/cmake/QtModuleToolsConfig.cmake.in b/cmake/QtModuleToolsConfig.cmake.in index ec447aa55b4..43b826c2060 100644 --- a/cmake/QtModuleToolsConfig.cmake.in +++ b/cmake/QtModuleToolsConfig.cmake.in @@ -18,12 +18,16 @@ if(NOT DEFINED "@INSTALL_CMAKE_NAMESPACE@@target@_FOUND") set("@INSTALL_CMAKE_NAMESPACE@@target@_FOUND" TRUE) endif() -if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND) +# Do the checks inside Targets.cmake even when the file is still being generated +include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@TargetsPrecheck.cmake") + +if(NOT __qt_@target@_skip_include_targets_file AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake") if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake") endif() + set(__qt_@target@_targets_file_included ON) endif() foreach(extra_cmake_include @extra_cmake_includes@) diff --git a/cmake/QtPluginConfig.cmake.in b/cmake/QtPluginConfig.cmake.in index 1ec7663ac6f..9b7ddc8ec7e 100644 --- a/cmake/QtPluginConfig.cmake.in +++ b/cmake/QtPluginConfig.cmake.in @@ -1,28 +1,16 @@ # Copyright (C) 2024 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -include_guard(DIRECTORY) - -if(DEFINED QT_REPO_DEPENDENCIES - AND NOT QT_INTERNAL_BUILD_STANDALONE_PARTS - AND NOT QT_BUILD_STANDALONE_TESTS) - # We're building a Qt repository. - # Skip this plugin if it has not been provided by one of this repo's dependencies. - string(TOLOWER "@PROJECT_NAME@" lower_case_project_name) - if(NOT lower_case_project_name IN_LIST QT_REPO_DEPENDENCIES) - return() - endif() -endif() - -@skip_internal_test_plugin@ - @PACKAGE_INIT@ cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_version@) include(CMakeFindDependencyMacro) -if (NOT QT_NO_CREATE_TARGETS) +# Do the checks inside Targets.cmake even when the file is still being generated +include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@TargetsPrecheck.cmake") + +if(NOT __qt_@target@_skip_include_targets_file) # Find required dependencies, if any. if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake") @@ -33,5 +21,6 @@ if (NOT QT_NO_CREATE_TARGETS) if(@target@_FOUND) include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake") + set(__qt_@target@_targets_file_included ON) endif() endif() diff --git a/cmake/QtPluginHelpers.cmake b/cmake/QtPluginHelpers.cmake index 66db5e29be1..0d129791804 100644 --- a/cmake/QtPluginHelpers.cmake +++ b/cmake/QtPluginHelpers.cmake @@ -304,7 +304,6 @@ function(qt_internal_add_plugin target) PUBLIC_LIBRARIES ${arg_PUBLIC_LIBRARIES} DEFINES ${arg_DEFINES} - ${deprecation_define} PUBLIC_DEFINES ${arg_PUBLIC_DEFINES} FEATURE_DEPENDENCIES ${arg_FEATURE_DEPENDENCIES} @@ -381,6 +380,7 @@ function(qt_internal_add_plugin target) # For test plugins we need to make sure plugins are not loaded from the Qt installation # when building standalone tests. + set(test_plugin_arg "") if(QT_INTERNAL_CONFIGURING_TESTS OR arg_TEST_PLUGIN) if(NOT arg_TEST_PLUGIN) message(WARNING "The installable test plugin ${target} is built as part of a test" @@ -388,13 +388,7 @@ function(qt_internal_add_plugin target) "\nThis warning will soon become an error." ) endif() - set(skip_internal_test_plugin -"if(QT_BUILD_STANDALONE_TESTS AND \"\${PROJECT_NAME}\" STREQUAL \"${PROJECT_NAME}\") - message(DEBUG \"Skipping loading ${target}Config.cmake during \" - \"standalone tests run of ${PROJECT_NAME}\") - return() -endif()" - ) + set(test_plugin_arg TEST_PLUGIN) endif() configure_package_config_file( @@ -402,6 +396,20 @@ endif()" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" INSTALL_DESTINATION "${config_install_dir}" ) + + qt_configure_file( + OUTPUT "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" + CONTENT +# TODO: Remove the CHECK_QT_NO_CREATE_TARGETS once a better approach is developed +" +_qt_internal_should_include_targets( + TARGETS ${target} + NAMESPACE ${INSTALL_CMAKE_NAMESPACE}:: + PROJECT_NAME ${PROJECT_NAME} + OUT_VAR_SHOULD_SKIP __qt_${target}_skip_include_targets_file + ${test_plugin_arg} +) +") write_basic_package_version_file( "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" VERSION ${PROJECT_VERSION} @@ -416,6 +424,7 @@ endif()" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" DESTINATION "${config_install_dir}" COMPONENT Devel ) diff --git a/cmake/QtPlugins.cmake.in b/cmake/QtPlugins.cmake.in index e668a4cbefe..a6ca60bbd12 100644 --- a/cmake/QtPlugins.cmake.in +++ b/cmake/QtPlugins.cmake.in @@ -9,6 +9,6 @@ if(NOT DEFINED QT_SKIP_AUTO_PLUGIN_INCLUSION) set(QT_SKIP_AUTO_PLUGIN_INCLUSION OFF) endif() -if(NOT QT_NO_CREATE_TARGETS AND NOT QT_SKIP_AUTO_PLUGIN_INCLUSION) +if(__qt_@QT_MODULE@_targets_file_included AND NOT QT_SKIP_AUTO_PLUGIN_INCLUSION) __qt_internal_include_plugin_packages(@QT_MODULE@) endif() diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake index 5d8e299023d..9f220f9d78b 100644 --- a/cmake/QtPostProcessHelpers.cmake +++ b/cmake/QtPostProcessHelpers.cmake @@ -881,6 +881,11 @@ function(qt_internal_generate_user_facing_tools_info) qt_path_join(tool_link_base_dir "${CMAKE_INSTALL_PREFIX}" "${INSTALL_PUBLICBINDIR}") get_property(user_facing_tool_targets GLOBAL PROPERTY QT_USER_FACING_TOOL_TARGETS) set(lines "") + set(cmake_install_script "${PROJECT_BINARY_DIR}/install_user_facing_tool_links.cmake") + set(cmake_install_script_content +"execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E make_directory + \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${INSTALL_PUBLICBINDIR}\") +") foreach(target ${user_facing_tool_targets}) get_target_property(filename ${target} OUTPUT_NAME) if(NOT filename) @@ -897,9 +902,17 @@ function(qt_internal_generate_user_facing_tools_info) qt_path_join(tool_link_path "${INSTALL_PUBLICBINDIR}" "${linkname}${PROJECT_VERSION_MAJOR}") _qt_internal_relative_path(tool_target_path BASE_DIRECTORY ${tool_link_base_dir}) list(APPEND lines "${tool_target_path} ${tool_link_path}") + string(APPEND cmake_install_script_content +"execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E create_symlink + \"${tool_target_path}\" \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${tool_link_path}\") +") endforeach() string(REPLACE ";" "\n" content "${lines}") string(APPEND content "\n") set(out_file "${PROJECT_BINARY_DIR}/user_facing_tool_links.txt") file(WRITE "${out_file}" "${content}") + qt_configure_file(OUTPUT "${cmake_install_script}" + CONTENT "${cmake_install_script_content}" + ) + install(SCRIPT ${cmake_install_script}) endfunction() diff --git a/cmake/QtPublicCMakeHelpers.cmake b/cmake/QtPublicCMakeHelpers.cmake index 1cb6e5a2412..6c2d54cfcbc 100644 --- a/cmake/QtPublicCMakeHelpers.cmake +++ b/cmake/QtPublicCMakeHelpers.cmake @@ -361,21 +361,44 @@ function(_qt_internal_add_phony_target_deferred target) endif() endfunction() +# Equivalent to the auto-generated `*Targets.cmake` multi-inclusion check +# # The helper function that checks if module was included multiple times, and has the inconsistent # set of targets that belong to the module. It's expected that either all 'targets' or none of them # will be written to the 'targets_not_defined' variable, if the module was not or was # searched before accordingly. -function(_qt_internal_check_multiple_inclusion targets_not_defined targets) +function(_qt_internal_check_multiple_inclusion targets_not_defined) + # Backport for the old syntax + if(ARGC EQUAL 2) + _qt_internal_check_multiple_inclusion(${targets_not_defined} + TARGETS ${ARGN} + ) + set(${targets_not_defined} "${${targets_not_defined}}" PARENT_SCOPE) + return() + endif() + + set(option_args "") + set(single_args + NAMESPACE + ) + set(multi_args + TARGETS + ) + cmake_parse_arguments(PARSE_ARGV 1 arg "${option_args}" "${single_args}" "${multi_args}") + + if(NOT arg_NAMESPACE) + set(arg_NAMESPACE Qt::) + endif() + set(targets_defined "") set(${targets_not_defined} "") set(expected_targets "") - foreach(expected_target ${targets}) + foreach(expected_target ${arg_TARGETS}) list(APPEND expected_targets ${expected_target}) - if(NOT TARGET Qt::${expected_target}) - list(APPEND ${targets_not_defined} ${expected_target}) - endif() - if(TARGET Qt::${expected_target}) + if(TARGET "${arg_NAMESPACE}${expected_target}") list(APPEND targets_defined ${expected_target}) + else() + list(APPEND ${targets_not_defined} ${expected_target}) endif() endforeach() if("${targets_defined}" STREQUAL "${expected_targets}") @@ -980,3 +1003,147 @@ function(_qt_internal_get_moc_compiler_flavor_flags out_var) set(${out_var} "${flags}" PARENT_SCOPE) endfunction() + +# Check if we should be including the `Targets.cmake` file +# +# Synopsis +# +# _qt_internal_should_include_targets( +# TARGETS <target1> ... +# NAMESPACE <str> +# OUT_VAR_SHOULD_SKIP <var> +# [PROJECT_NAME <str>] +# [TEST_PLUGIN] +# [CHECK_QT_NO_CREATE_TARGETS] +# ) +# +# Arguments +# +# `TARGETS` +# The targets added via `export(TARGETS ...)` +# +# `NAMESPACE` +# The `NAMESPACE` used in the `export` command. Make sure to include the `::` +# +# `OUT_VAR_SHOULD_SKIP` +# Output variable indicating if the `include(*Targets.cmake)` should be skipped +# +# `PROJECT_NAME` +# The original project that defined the current Config.cmake file at the time of the +# generation. For now only used for plugins. +# +# `TEST_PLUGIN` +# If the module is a TEST_PLUGIN, we do additional checks based on +# `QT_BUILD_STANDALONE_TESTS` +# +# `CHECK_QT_NO_CREATE_TARGETS` +# Whether to check `QT_NO_CREATE_TARGETS` as a compatibility step +function(_qt_internal_should_include_targets) + set(option_args + TEST_PLUGIN + CHECK_QT_NO_CREATE_TARGETS + ) + set(single_args + NAMESPACE + OUT_VAR_SHOULD_SKIP + PROJECT_NAME + ) + set(multi_args + TARGETS + ) + cmake_parse_arguments(PARSE_ARGV 0 arg "${option_args}" "${single_args}" "${multi_args}") + + # Check for required inputs + foreach(check_arg IN ITEMS NAMESPACE OUT_VAR_SHOULD_SKIP) + if(NOT arg_${check_arg}) + message(FATAL_ERROR "Missing input ${check_arg}") + endif() + endforeach() + + # Check for inputs that will be required in the future + foreach(check_arg IN ITEMS) + if(NOT arg_${check_arg}) + get_property(skip_warning GLOBAL + PROPERTY _qt_skip_warning__qt_internal_should_include_targets + ) + if(NOT skip_warning) + message(WARNING + "The current module was generated before ${check_arg} was introduced.\n" + "Consider reconfiguring the current module (see backtrace)." + ) + set_property(GLOBAL + PROPERTY _qt_skip_warning__qt_internal_should_include_targets ON + ) + endif() + endif() + endforeach() + + # Check for deprecated inputs, i.e. the Config.cmake were already created + # with a version of qtbase that removed the specific compatibilities + foreach(check_arg IN ITEMS ) + if(arg_${check_arg}) + get_property(skip_warning GLOBAL + PROPERTY _qt_skip_warning__qt_internal_should_include_targets + ) + if(NOT skip_warning) + message(WARNING + "The input ${check_arg} is deprecated and has no effect.\n" + "Consider reconfiguring the current module (see backtrace)." + ) + set_property(GLOBAL + PROPERTY _qt_skip_warning__qt_internal_should_include_targets ON + ) + endif() + endif() + endforeach() + + if(arg_PROJECT_NAME) + # Check if we are in a top-level build and which submodules will be included + if(NOT QT_INTERNAL_BUILD_STANDALONE_PARTS AND DEFINED Qt_SOURCE_DIR) + # All projects will be rebuilt so skip any include targets + set(${arg_OUT_VAR_SHOULD_SKIP} ON PARENT_SCOPE) + return() + endif() + + # Check if we are building the current project + if(NOT QT_INTERNAL_BUILD_STANDALONE_PARTS AND + PROJECT_NAME STREQUAL arg_PROJECT_NAME) + # We are currently building the project, so skip the include targets + set(${arg_OUT_VAR_SHOULD_SKIP} ON PARENT_SCOPE) + return() + endif() + + # Check if we are building the standalone tests + if(arg_TEST_PLUGIN AND QT_BUILD_STANDALONE_TESTS AND + PROJECT_NAME STREQUAL arg_PROJECT_NAME) + set(${arg_OUT_VAR_SHOULD_SKIP} ON PARENT_SCOPE) + return() + endif() + endif() + + # Compatibility using the old global `QT_NO_CREATE_TARGETS` + # TODO: Remove these once developers have reconfigured their project. + if(arg_CHECK_QT_NO_CREATE_TARGETS AND QT_NO_CREATE_TARGETS) + set(${arg_OUT_VAR_SHOULD_SKIP} ON PARENT_SCOPE) + return() + endif() + + # We might still be generating the Targets.cmake file, so we do the same + # checks as in the Targets.cmake, but with the targets that were defined + # in the current build tree. + _qt_internal_check_multiple_inclusion(tgt_not_defined + TARGETS ${arg_TARGETS} + NAMESPACE ${arg_NAMESPACE} + ) + + # In Targets.cmake, if there are no expected targets that are undefined, + # the script returns, otherwise it creates all expected targets. + if(NOT tgt_not_defined) + set(${arg_OUT_VAR_SHOULD_SKIP} ON PARENT_SCOPE) + return() + endif() + + # If no special setup is detected, use the normal logic, i.e. include + # the Targets.cmake + set(${arg_OUT_VAR_SHOULD_SKIP} OFF PARENT_SCOPE) +endfunction() diff --git a/cmake/QtPublicTargetHelpers.cmake b/cmake/QtPublicTargetHelpers.cmake index b62c5e6ae3d..27f7c3acf79 100644 --- a/cmake/QtPublicTargetHelpers.cmake +++ b/cmake/QtPublicTargetHelpers.cmake @@ -18,6 +18,84 @@ function(__qt_internal_strip_target_directory_scope_token target out_var) set("${out_var}" "${target}" PARENT_SCOPE) endfunction() +# Work around AUTOGEN issue when a library is added as a dependency more than once, and the autogen +# library dependency results in being discarded. To mitigate that, add all autogen dependencies +# manually, based on the passed in dependencies. +# CMake 4.0+ has a fix, so we don't need the extra logic. +# See https://gitlab.kitware.com/cmake/cmake/-/issues/26700 +function(_qt_internal_work_around_autogen_discarded_dependencies target) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0 + OR QT_NO_AUTOGEN_DISCARDED_DEPENDENCIES_WORKAROUND) + return() + endif() + + set(libraries ${ARGN}) + set(final_libraries "") + + foreach(lib IN LISTS libraries) + # Skip non-target dependencies. + if(NOT TARGET "${lib}") + continue() + endif() + + # Resolve alias targets, because AUTOGEN_TARGET_DEPENDS doesn't seem to handle them. + _qt_internal_dealias_target(lib) + + # Skip imported targets, they don't have sync_headers targets. + get_target_property(imported "${lib}" IMPORTED) + if(imported) + continue() + endif() + + # Resolve Qt private modules to their public counterparts. + get_target_property(is_private_module "${lib}" _qt_is_private_module) + get_target_property(public_module_target "${lib}" _qt_public_module_target_name) + + if(is_private_module AND public_module_target) + set(lib "${public_module_target}") + endif() + + # Another TARGET check, just in case. + if(TARGET "${lib}") + list(APPEND final_libraries "${lib}") + endif() + endforeach() + if(final_libraries) + _qt_internal_append_to_target_property_without_duplicates("${target}" + AUTOGEN_TARGET_DEPENDS ${final_libraries}) + endif() +endfunction() + +# This function is similar to _qt_internal_work_around_autogen_discarded_dependencies +# but it instead queries the libs to process from the target's LINK_LIBRARIES and +# INTERFACE_LINK_LIBRARIES. +# It only applies the logic while building Qt itself. +# It's meant to be used in public API like qt_finalize_target, so that the workaround is applied +# to examples that are built as part of the qt build tree. +function(_qt_internal_work_around_autogen_discarded_dependencies_from_target_libs target) + if(NOT QT_BUILDING_QT) + return() + endif() + + set(libraries "") + + get_target_property(link_libs "${target}" LINK_LIBRARIES) + if(link_libs) + list(APPEND libraries "${link_libs}") + endif() + get_target_property(interface_link_libs "${target}" INTERFACE_LINK_LIBRARIES) + + if(interface_link_libs) + list(APPEND libraries "${interface_link_libs}") + endif() + + if(NOT libraries) + return() + endif() + + _qt_internal_work_around_autogen_discarded_dependencies("${target}" ${libraries}) +endfunction() + # Tests if linker could resolve circular dependencies between object files and static libraries. function(__qt_internal_static_link_order_public_test result) # We could trust iOS linker diff --git a/cmake/QtPublicWasmToolchainHelpers.cmake b/cmake/QtPublicWasmToolchainHelpers.cmake index ecdca052113..32309ed05ba 100644 --- a/cmake/QtPublicWasmToolchainHelpers.cmake +++ b/cmake/QtPublicWasmToolchainHelpers.cmake @@ -53,7 +53,7 @@ endfunction() function(__qt_internal_get_emcc_recommended_version out_var) # This version of Qt needs this version of emscripten. - set(QT_EMCC_RECOMMENDED_VERSION "3.1.70") + set(QT_EMCC_RECOMMENDED_VERSION "4.0.7") set(${out_var} "${QT_EMCC_RECOMMENDED_VERSION}" PARENT_SCOPE) endfunction() diff --git a/cmake/QtTargetHelpers.cmake b/cmake/QtTargetHelpers.cmake index 25f6ec07046..cbf0df3b7f3 100644 --- a/cmake/QtTargetHelpers.cmake +++ b/cmake/QtTargetHelpers.cmake @@ -235,7 +235,7 @@ function(qt_internal_extend_target target) endif() set(all_libraries ${arg_LIBRARIES} ${arg_PUBLIC_LIBRARIES}) - qt_internal_work_around_autogen_discarded_dependencies(${target} ${all_libraries}) + _qt_internal_work_around_autogen_discarded_dependencies(${target} ${all_libraries}) if(QT_GENERATE_SBOM) set(sbom_args "") diff --git a/cmake/QtTestHelpers.cmake b/cmake/QtTestHelpers.cmake index cf8a085b26d..ad8a9d65c14 100644 --- a/cmake/QtTestHelpers.cmake +++ b/cmake/QtTestHelpers.cmake @@ -45,10 +45,6 @@ function(qt_internal_add_benchmark target) OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}" # avoid polluting bin directory ${exec_args} ) - qt_internal_extend_target(${target} - DEFINES - ${deprecation_define} - ) # Benchmarks on iOS must be app bundles. if(IOS) @@ -274,7 +270,7 @@ function(qt_internal_add_test_to_batch batch_name name) ${is_manual} OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/build_dir" SOURCES "${QT_CMAKE_DIR}/qbatchedtestrunner.in.cpp" - DEFINES QTEST_BATCH_TESTS ${deprecation_define} + DEFINES QTEST_BATCH_TESTS INCLUDE_DIRECTORIES ${private_includes} LIBRARIES ${QT_CMAKE_EXPORT_NAMESPACE}::Core ${QT_CMAKE_EXPORT_NAMESPACE}::Test @@ -555,7 +551,6 @@ function(qt_internal_add_test name) ${private_includes} DEFINES ${arg_DEFINES} - ${deprecation_define} LIBRARIES ${arg_LIBRARIES} ${arg_PUBLIC_LIBRARIES} @@ -1219,3 +1214,22 @@ function(qt_internal_add_test_finalizers target) qt_add_list_file_finalizer(_qt_internal_finalize_executable "${target}") endif() endfunction() + +# Collection of tests and targets added to all repos +function(qt_internal_add_default_tests) + # Check the installed json module files satisfy the schemas + # This is not made as a test to avoid downstream using it and carrying the python test + # dependencies + if(NOT TARGET check_qt_module_json_schemas) + qt_path_join(__check_qt_module_json_schemas_py + "${QT_STAGING_PREFIX}" + "${INSTALL_LIBEXECDIR}" + "check_qt_module_json_schemas.py" + ) + add_custom_target(check_qt_module_json_schemas + COMMAND python3 ${__check_qt_module_json_schemas_py} + "--install-prefix=${QT_STAGING_PREFIX}" + "--qt-sharedir=${INSTALL_QT_SHAREDIR}" + ) + endif() +endfunction() diff --git a/cmake/QtToolHelpers.cmake b/cmake/QtToolHelpers.cmake index a7e1842c04f..1954e6d85a2 100644 --- a/cmake/QtToolHelpers.cmake +++ b/cmake/QtToolHelpers.cmake @@ -140,7 +140,6 @@ function(qt_internal_add_tool target_name) ${arg_INCLUDE_DIRECTORIES} DEFINES ${arg_DEFINES} - ${deprecation_define} ${corelib} LIBRARIES ${arg_LIBRARIES} @@ -396,7 +395,9 @@ function(qt_export_tools module_name) set(first_tool_package_version "") - foreach(tool_name ${QT_KNOWN_MODULE_${module_name}_TOOLS}) + set(known_tools ${QT_KNOWN_MODULE_${module_name}_TOOLS}) + + foreach(tool_name IN LISTS known_tools) # Specific tools can have package dependencies. # e.g. qtwaylandscanner depends on WaylandScanner (non-qt package). get_target_property(extra_packages "${tool_name}" QT_EXTRA_PACKAGE_DEPENDENCIES) @@ -428,8 +429,9 @@ function(qt_export_tools module_name) if (QT_WILL_RENAME_TOOL_TARGETS) string(REGEX REPLACE "_native$" "" tool_name ${tool_name}) endif() + # `__qt_${target}_targets_file_included` is defined in the QtModuleToolsConfig.cmake.in set(extra_cmake_statements "${extra_cmake_statements} -if(NOT QT_NO_CREATE_TARGETS AND ${INSTALL_CMAKE_NAMESPACE}${target}_FOUND) +if(__qt_${target}_targets_file_included AND ${INSTALL_CMAKE_NAMESPACE}${target}_FOUND) __qt_internal_promote_target_to_global(${INSTALL_CMAKE_NAMESPACE}::${tool_name}) endif() ") @@ -488,6 +490,16 @@ endif() INSTALL_DESTINATION "${config_install_dir}" ) + qt_configure_file( + OUTPUT "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" + CONTENT +"_qt_internal_should_include_targets( + TARGETS ${known_tools} + NAMESPACE ${INSTALL_CMAKE_NAMESPACE}:: + OUT_VAR_SHOULD_SKIP __qt_${target}_skip_include_targets_file +) +") + # There might be Tools packages which don't have a corresponding real module_name target, like # WaylandScannerTools. # In that case we'll use the package version of the first tool that belongs to that package. @@ -523,6 +535,7 @@ endif() "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TargetsPrecheck.cmake" DESTINATION "${config_install_dir}" COMPONENT Devel ) @@ -686,6 +699,7 @@ function(qt_internal_find_tool out_var target_name tools_target) set(tools_package_name "${INSTALL_CMAKE_NAMESPACE}${tools_target}Tools") message(STATUS "Searching for tool '${full_name}' in package ${tools_package_name}.") + # TODO: Remove these once developers have reconfigured their project. # Create the tool targets, even if QT_NO_CREATE_TARGETS is set. # Otherwise targets like Qt6::moc are not available in a top-level cross-build. set(BACKUP_QT_NO_CREATE_TARGETS ${QT_NO_CREATE_TARGETS}) @@ -751,6 +765,7 @@ function(qt_internal_find_tool out_var target_name tools_target) # Restore backups. set(CMAKE_FIND_ROOT_PATH "${${tools_package_name}_BACKUP_CMAKE_FIND_ROOT_PATH}") set(CMAKE_PREFIX_PATH "${${tools_package_name}_BACKUP_CMAKE_PREFIX_PATH}") + # TODO: Remove these once developers have reconfigured their project. set(QT_NO_CREATE_TARGETS ${BACKUP_QT_NO_CREATE_TARGETS}) if(${${tools_package_name}_FOUND} AND TARGET ${full_name}) diff --git a/cmake/QtVersionlessAliasTargets.cmake.in b/cmake/QtVersionlessAliasTargets.cmake.in index fcf182941c0..29633e081b3 100644 --- a/cmake/QtVersionlessAliasTargets.cmake.in +++ b/cmake/QtVersionlessAliasTargets.cmake.in @@ -1,6 +1,6 @@ # Protect against multiple inclusion, which would fail when already imported targets are # added once more. -_qt_internal_check_multiple_inclusion(_targets_not_defined "@versionless_targets@") +_qt_internal_check_multiple_inclusion(_targets_not_defined TARGETS @versionless_targets@) _qt_internal_create_versionless_alias_targets("${_targets_not_defined}" @INSTALL_CMAKE_NAMESPACE@) diff --git a/cmake/QtVersionlessTargets.cmake.in b/cmake/QtVersionlessTargets.cmake.in index c809915e657..0b4bea003ad 100644 --- a/cmake/QtVersionlessTargets.cmake.in +++ b/cmake/QtVersionlessTargets.cmake.in @@ -1,6 +1,6 @@ # Protect against multiple inclusion, which would fail when already imported targets are # added once more. -_qt_internal_check_multiple_inclusion(_targets_not_defined "@versionless_targets@") +_qt_internal_check_multiple_inclusion(_targets_not_defined TARGETS @versionless_targets@) _qt_internal_create_versionless_targets("${_targets_not_defined}" @INSTALL_CMAKE_NAMESPACE@) diff --git a/coin/instructions/cmake_qtbase_build_instructions.yaml b/coin/instructions/cmake_qtbase_build_instructions.yaml index 4c79c41b005..056ddba8c7b 100644 --- a/coin/instructions/cmake_qtbase_build_instructions.yaml +++ b/coin/instructions/cmake_qtbase_build_instructions.yaml @@ -87,6 +87,11 @@ instructions: directory: "{{.InstallRoot}}/{{.AgentWorkingDir}}" maxTimeInSeconds: 1200 maxTimeBetweenOutput: 1200 + # Signal that qtbase should always build the doc tools (if all other requirements are met). + - type: EnvironmentVariable + variableName: QT_CI_BUILD_DOC_TOOLS + variableValue: "1" + - !include "{{qt/qtbase}}/coin_build_doc_tools_checked.yaml" - type: UploadArtifact archiveDirectory: "{{.InstallRoot}}/{{.AgentWorkingDir}}" transferType: UploadModuleBuildArtifact diff --git a/coin/instructions/cmake_run_ctest.yaml b/coin/instructions/cmake_run_ctest.yaml index 0c58a83b209..43963fc172b 100644 --- a/coin/instructions/cmake_run_ctest.yaml +++ b/coin/instructions/cmake_run_ctest.yaml @@ -151,6 +151,8 @@ instructions: userMessageOnFailure: > Failed to copy LastTest.log to testresults directory. executeOn: always + maxTimeInSeconds: 20 + maxTimeBetweenOutput: 20 - type: Group enable_if: condition: runtime diff --git a/coin/instructions/coin_build_doc_tools.yaml b/coin/instructions/coin_build_doc_tools.yaml index b1a5c51a3ed..783b86cf352 100644 --- a/coin/instructions/coin_build_doc_tools.yaml +++ b/coin/instructions/coin_build_doc_tools.yaml @@ -1,7 +1,8 @@ type: Group instructions: + # Build outside of qtbase source dir, to avoid REUSE missing license warnings for the built files. - type: SetBuildDirectory - directory: "{{.SourceDir}}" + directory: "{{.AgentWorkingDir}}" - type: ChangeDirectory directory: "{{.BuildDir}}" diff --git a/coin/instructions/coin_qtbase_build_template_v2.yaml b/coin/instructions/coin_qtbase_build_template_v2.yaml index 5bc615808e9..5e652e8eddd 100644 --- a/coin/instructions/coin_qtbase_build_template_v2.yaml +++ b/coin/instructions/coin_qtbase_build_template_v2.yaml @@ -73,9 +73,3 @@ instructions: condition: property property: features contains_value: "DebianPackaging" - - # Signal that qtbase should always build the doc tools (if all other requirements are met). - - type: EnvironmentVariable - variableName: QT_CI_BUILD_DOC_TOOLS - variableValue: "1" - - !include "{{qt/qtbase}}/coin_build_doc_tools_checked.yaml" diff --git a/coin/instructions/prepare_building_env.yaml b/coin/instructions/prepare_building_env.yaml index 8962d66ac11..20e7ef7f01c 100644 --- a/coin/instructions/prepare_building_env.yaml +++ b/coin/instructions/prepare_building_env.yaml @@ -769,3 +769,31 @@ instructions: condition: property property: host.os equals_value: Windows + - # Default value when not cross-compiling + type: EnvironmentVariable + variableName: TARGET_INSTALL_DIR + variableValue: "{{.InstallDir}}" + - type: Group + instructions: + - # Default value when cross-compiling + type: EnvironmentVariable + variableName: TARGET_INSTALL_DIR + variableValue: "{{.InstallDir}}{{.Env.CI_PATH_SEP}}target" + - type: EnvironmentVariable + variableName: TARGET_INSTALL_DIR + variableValue: "{{$android_artifact_path:=index .Env \"QT_CI_ARTIFACT_ID_PATH_Android-x86\"}}{{index .Env $android_artifact_path}}/install/target" + enable_if: + condition: and + conditions: + - condition: property + property: target.osVersion + equals_value: Android_ANY + - condition: property + property: target.arch + equals_value: Multi + enable_if: + # Only enable if cross-compiling + condition: property + property: target.osVersion + in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, QNX_800, WebAssembly, INTEGRITY, VxWorks] + diff --git a/coin/instructions/vxworks_test_env_setup.yaml b/coin/instructions/vxworks_test_env_setup.yaml index 9a7e326e047..9ff710fbc7f 100644 --- a/coin/instructions/vxworks_test_env_setup.yaml +++ b/coin/instructions/vxworks_test_env_setup.yaml @@ -64,7 +64,7 @@ instructions: env_vars["VXWORKS_CERTS_DIR"]="$WIND_CC_SYSROOT/certs" env_vars["HOME"]="/home/qt/work/vxworkshome" env_vars["QML_LOADERTHREAD_STACK_SIZE"]="131072" - env_vars["QTEST_FUNCTION_TIMEOUT"]="600000" + env_vars["QTEST_FUNCTION_TIMEOUT"]="1000000" env_vars["QT_PLUGIN_PATH"]="/home/qt/work/install/target/plugins" env_vars["QT_QPA_PLATFORM_PLUGIN_PATH"]="/home/qt/work/install/target/plugins/platforms" diff --git a/configure.cmake b/configure.cmake index 5831333e3ca..92fe4dba448 100644 --- a/configure.cmake +++ b/configure.cmake @@ -274,10 +274,10 @@ int main(void) ) qt_config_compile_test(cxx2b - LABEL "C++2b support" + LABEL "C++23 support" CODE "#if __cplusplus > 202002L -// Compiler claims to support C++2B, trust it +// Compiler claims to support C++23, trust it #else # error __cplusplus must be > 202002L (the value for C++20) #endif @@ -292,6 +292,25 @@ int main(void) CXX_STANDARD 23 ) +qt_config_compile_test(cxx2c + LABEL "C++2c support" + CODE +"#if __cplusplus > 202302L +// Compiler claims to support C++2c, trust it +#else +# error __cplusplus must be > 202302L (the value for C++23) +#endif + +int main(void) +{ + /* BEGIN TEST: */ + /* END TEST: */ + return 0; +} +" + CXX_STANDARD 26 +) + qt_config_compiler_supports_flag_test(optimize_debug LABEL "-Og support" FLAG "-Og" @@ -725,11 +744,17 @@ qt_feature("c++2a" PUBLIC ) qt_feature_config("c++2a" QMAKE_PUBLIC_QT_CONFIG) qt_feature("c++2b" PUBLIC - LABEL "C++2b" + LABEL "C++23" AUTODETECT OFF CONDITION QT_FEATURE_cxx20 AND (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") AND TEST_cxx2b ) qt_feature_config("c++2b" QMAKE_PUBLIC_QT_CONFIG) +qt_feature("c++2c" PUBLIC + LABEL "C++2c" + AUTODETECT OFF + CONDITION QT_FEATURE_cxx2b AND (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25") AND TEST_cxx2c +) +qt_feature_config("c++2c" QMAKE_PUBLIC_QT_CONFIG) set(__qt_ltcg_detected FALSE) if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) set(__qt_ltcg_detected TRUE) diff --git a/doc/global/macros.qdocconf b/doc/global/macros.qdocconf index e239174ca6d..87e8be30443 100644 --- a/doc/global/macros.qdocconf +++ b/doc/global/macros.qdocconf @@ -96,8 +96,8 @@ macro.AndroidMinVer = "9" macro.AndroidMaxVer = "15" macro.AndroidPlatformVer = "35" macro.AndroidBuildToolsVer = "35.0.1" -macro.GradleVer = "8.10" -macro.AGPVer = "8.6.0" +macro.GradleVer = "8.14.2" +macro.AGPVer = "8.10.1" macro.AAOSVer = "10 to 13" macro.beginfloatleft.HTML = "<div style=\"float: left; margin-right: 2em\">" diff --git a/examples/widgets/rhi/cuberhiwidget/examplewidget.cpp b/examples/widgets/rhi/cuberhiwidget/examplewidget.cpp index fe39d904dd5..2d16cc0ba2a 100644 --- a/examples/widgets/rhi/cuberhiwidget/examplewidget.cpp +++ b/examples/widgets/rhi/cuberhiwidget/examplewidget.cpp @@ -3,8 +3,10 @@ #include "examplewidget.h" #include "cube.h" + #include <QFile> #include <QPainter> +#include <QtGui/qquaternion.h> static const QSize CUBE_TEX_SIZE(512, 512); diff --git a/examples/widgets/widgets/windowflags/controllerwindow.cpp b/examples/widgets/widgets/windowflags/controllerwindow.cpp index 80d5f9e59b4..dc1145262b3 100644 --- a/examples/widgets/widgets/windowflags/controllerwindow.cpp +++ b/examples/widgets/widgets/windowflags/controllerwindow.cpp @@ -100,7 +100,7 @@ void ControllerWindow::updatePreview() if (pos.y() < 0) pos.setY(0); previewWindow->move(pos); - previewWindow->show(); + previewWindow->showNormal(); } //! [4] diff --git a/examples/widgets/widgets/windowflags/main.cpp b/examples/widgets/widgets/windowflags/main.cpp index b01716ddae1..93b5c2d5217 100644 --- a/examples/widgets/widgets/windowflags/main.cpp +++ b/examples/widgets/widgets/windowflags/main.cpp @@ -9,6 +9,6 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); ControllerWindow controller; - controller.show(); + controller.showNormal(); return app.exec(); } diff --git a/licenseRule.json b/licenseRule.json index e35e8ba7fd1..b40e225e347 100644 --- a/licenseRule.json +++ b/licenseRule.json @@ -119,7 +119,7 @@ "file type": "test", "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] }, - "ests/auto/testlib/selftests/": { + "tests/auto/testlib/selftests/(?!README)": { "comment": "Exception. Those are test files", "file type": "test", "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf index 6eb08a9d2fa..82c6173a037 100644 --- a/mkspecs/common/clang.conf +++ b/mkspecs/common/clang.conf @@ -36,11 +36,13 @@ QMAKE_CXXFLAGS_CXX14 = -std=c++1y QMAKE_CXXFLAGS_CXX1Z = -std=c++1z QMAKE_CXXFLAGS_CXX2A = -std=c++2a QMAKE_CXXFLAGS_CXX2B = -std=c++2b +QMAKE_CXXFLAGS_CXX2C = -std=c++2c QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11 QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++1y QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z QMAKE_CXXFLAGS_GNUCXX2A = -std=gnu++2a QMAKE_CXXFLAGS_GNUCXX2B = -std=gnu++2b +QMAKE_CXXFLAGS_GNUCXX2C = -std=gnu++2c QMAKE_LFLAGS_CXX11 = QMAKE_LFLAGS_CXX14 = diff --git a/mkspecs/common/g++-base.conf b/mkspecs/common/g++-base.conf index d392879f66d..e12e41506ae 100644 --- a/mkspecs/common/g++-base.conf +++ b/mkspecs/common/g++-base.conf @@ -34,11 +34,13 @@ QMAKE_CXXFLAGS_CXX14 = -std=c++1y QMAKE_CXXFLAGS_CXX1Z = -std=c++1z QMAKE_CXXFLAGS_CXX2A = -std=c++2a QMAKE_CXXFLAGS_CXX2B = -std=c++2b +QMAKE_CXXFLAGS_CXX2C = -std=c++2c QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11 QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++1y QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z QMAKE_CXXFLAGS_GNUCXX2A = -std=gnu++2a QMAKE_CXXFLAGS_GNUCXX2B = -std=gnu++2b +QMAKE_CXXFLAGS_GNUCXX2C = -std=gnu++2c QMAKE_LFLAGS_CXX11 = QMAKE_LFLAGS_CXX14 = QMAKE_LFLAGS_CXX1Z = diff --git a/mkspecs/common/msvc-version.conf b/mkspecs/common/msvc-version.conf index 303b341e9d7..0130542ddb9 100644 --- a/mkspecs/common/msvc-version.conf +++ b/mkspecs/common/msvc-version.conf @@ -121,6 +121,7 @@ greaterThan(QMAKE_MSC_VER, 1919) { MSVC_TOOLSET_VER = 142 QMAKE_CXXFLAGS_CXX2A = -std:c++latest QMAKE_CXXFLAGS_CXX2B = -std:c++latest + QMAKE_CXXFLAGS_CXX2C = -std:c++latest QMAKE_CXXFLAGS += -Zc:externConstexpr } diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index 2be446e41ec..cf48bfda07f 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -123,17 +123,19 @@ breakpad { c++17: CONFIG += c++1z c++20: CONFIG += c++2a -c++latest: CONFIG *= c++2b c++2a c++1z c++14 c++11 +c++23: CONFIG += c++2b +c++latest: CONFIG *= c++2c c++2b c++2a c++1z c++14 c++11 -!c++1z:!c++2a:!c++2b { +!c++1z:!c++2a:!c++2b:!c++2c { # Qt requires C++17 QT_COMPILER_STDCXX_no_L = $$replace(QT_COMPILER_STDCXX, "L$", "") !greaterThan(QT_COMPILER_STDCXX_no_L, 201402): CONFIG += c++1z } -c++1z|c++2a|c++2b { +c++1z|c++2a|c++2b|c++2c { # Disable special compiler flags for host builds !host_build|!cross_compile { - c++2b: cxxstd = CXX2B + c++2c: cxxstd = CXX2C + else:c++2b: cxxstd = CXX2B else:c++2a: cxxstd = CXX2A else: cxxstd = CXX1Z } else { diff --git a/mkspecs/features/wasm/emcc_ver.prf b/mkspecs/features/wasm/emcc_ver.prf index 2f801228797..bb59844c4d5 100644 --- a/mkspecs/features/wasm/emcc_ver.prf +++ b/mkspecs/features/wasm/emcc_ver.prf @@ -1,5 +1,5 @@ defineReplace(qtEmccRecommendedVersion) { - return (3.1.70) + return (4.0.7) } defineReplace(qtSystemEmccVersion) { diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 96036eba701..9c29b26fb82 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -804,7 +804,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString icon = fileFixify(var("ICON")); t << "@$(DEL_FILE) " << info_plist_out << "\n\t" - << "@plutil -convert xml1 -o - " << info_plist << " | " + << "@set -o pipefail && plutil -convert xml1 -o - " << info_plist << " | " << "sed "; for (const ProString &arg : std::as_const(commonSedArgs)) t << arg; @@ -837,7 +837,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if (!isShallowBundle) symlinks[bundle_dir + "Resources"] = "Versions/Current/Resources"; t << "@$(DEL_FILE) " << info_plist_out << "\n\t" - << "@plutil -convert xml1 -o - " << info_plist << " | " + << "@set -o pipefail && plutil -convert xml1 -o - " << info_plist << " | " << "sed "; for (const ProString &arg : std::as_const(commonSedArgs)) t << arg; diff --git a/qt_cmdline.cmake b/qt_cmdline.cmake index b0b3797d27e..8f68a40f3ff 100644 --- a/qt_cmdline.cmake +++ b/qt_cmdline.cmake @@ -174,12 +174,19 @@ function(qt_commandline_cxxstd arg val nextok) if(val MATCHES "(c\\+\\+)?(17|1z)") qtConfCommandlineDisableFeature(c++20) qtConfCommandlineDisableFeature(c++2b) + qtConfCommandlineDisableFeature(c++2c) elseif(val MATCHES "(c\\+\\+)?(20|2a)") qtConfCommandlineEnableFeature(c++20) qtConfCommandlineDisableFeature(c++2b) - elseif(val MATCHES "(c\\+\\+)?(2b)") + qtConfCommandlineDisableFeature(c++2c) + elseif(val MATCHES "(c\\+\\+)?(23|2b)") qtConfCommandlineEnableFeature(c++20) qtConfCommandlineEnableFeature(c++2b) + qtConfCommandlineDisableFeature(c++2c) + elseif(val MATCHES "(c\\+\\+)?(2c)") + qtConfCommandlineEnableFeature(c++20) + qtConfCommandlineEnableFeature(c++2b) + qtConfCommandlineEnableFeature(c++2c) else() qtConfAddError("Invalid argument '${val}' to command line parameter '${arg}'") endif() diff --git a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.jar b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.jar Binary files differindex a4b76b9530d..1b33c55baab 100644 --- a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.jar +++ b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.jar diff --git a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties index cea7a793a84..ff23a68d70f 100644 --- a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/3rdparty/gradle/gradlew b/src/3rdparty/gradle/gradlew index 057afac53f3..0f14772e0e5 100755 --- a/src/3rdparty/gradle/gradlew +++ b/src/3rdparty/gradle/gradlew @@ -114,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -205,7 +205,7 @@ fi DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/src/3rdparty/gradle/gradlew.bat b/src/3rdparty/gradle/gradlew.bat index 640d68685c1..8de1053a1f9 100644 --- a/src/3rdparty/gradle/gradlew.bat +++ b/src/3rdparty/gradle/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/3rdparty/gradle/qt_attribution.json b/src/3rdparty/gradle/qt_attribution.json index 19c9147c632..d2966e5c8b9 100644 --- a/src/3rdparty/gradle/qt_attribution.json +++ b/src/3rdparty/gradle/qt_attribution.json @@ -4,8 +4,8 @@ "QDocModule": "qtcore", "QtParts": ["tools"], "Homepage": "https://gradle.org", - "Version": "8.12", - "DownloadLocation": "https://github.com/gradle/gradle/releases/tag/v8.12.0", + "Version": "8.14.2", + "DownloadLocation": "https://github.com/gradle/gradle/releases/tag/v8.14.2", "PURL": "pkg:github/gradle/gradle@v$<VERSION>", "CPE": "cpe:2.3:a:gradle:gradle:$<VERSION>:*:*:*:*:*:*:*", "QtUsage": "Needed to create Android packages", diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 15219dbb4e0..90c766594e7 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,5 +1,5 @@ -libpng 1.6.48 - April 30, 2025 -============================== +libpng 1.6.49 - June 12, 2025 +============================= This is a public release of libpng, intended for use in production code. @@ -9,13 +9,13 @@ Files available for download Source files with LF line endings (for Unix/Linux): - * libpng-1.6.48.tar.xz (LZMA-compressed, recommended) - * libpng-1.6.48.tar.gz (deflate-compressed) + * libpng-1.6.49.tar.xz (LZMA-compressed, recommended) + * libpng-1.6.49.tar.gz (deflate-compressed) Source files with CRLF line endings (for Windows): - * lpng1648.7z (LZMA-compressed, recommended) - * lpng1648.zip (deflate-compressed) + * lpng1649.7z (LZMA-compressed, recommended) + * lpng1649.zip (deflate-compressed) Other information: @@ -25,17 +25,13 @@ Other information: * TRADEMARK.md -Changes from version 1.6.47 to version 1.6.48 +Changes from version 1.6.48 to version 1.6.49 --------------------------------------------- - * Fixed the floating-point version of the mDCv setter `png_set_mDCv`. - (Reported by Mohit Bakshi; fixed by John Bowler) - * Added #error directives to discourage the inclusion of private - libpng implementation header files in PNG-supporting applications. - * Added the CMake build option `PNG_LIBCONF_HEADER`, to be used as an - alternative to `DFA_XTRA`. - * Removed the Travis CI configuration files, with heartfelt thanks for - their generous support of our project over the past five years! + * Added SIMD-optimized code for the RISC-V Vector Extension (RVV). + (Contributed by Manfred Schlaegl, Dragos Tiselice and Filip Wasil) + * Added various fixes and improvements to the build scripts and to + the sample code. Send comments/corrections/commendations to png-mng-implement at lists.sf.net. diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index 557ff1b8c97..0c0fa6dc70b 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -6261,6 +6261,12 @@ Version 1.6.48 [April 30, 2025] Removed the Travis CI configuration files, with heartfelt thanks for their generous support of our project over the past five years! +Version 1.6.49 [June 12, 2025] + Added SIMD-optimized code for the RISC-V Vector Extension (RVV). + (Contributed by Manfred Schlaegl, Dragos Tiselice and Filip Wasil) + Added various fixes and improvements to the build scripts and to + the sample code. + Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement diff --git a/src/3rdparty/libpng/INSTALL b/src/3rdparty/libpng/INSTALL index df1a494468b..1557fbded48 100644 --- a/src/3rdparty/libpng/INSTALL +++ b/src/3rdparty/libpng/INSTALL @@ -136,7 +136,7 @@ Your directory structure should look like this: depcomp, install-sh, mkinstalldirs, test-pngtest.sh, etc. contrib arm-neon, conftest, examples, gregbook, libtests, pngminim, - pngminus, pngsuite, tools, visupng + pngminus, pngsuite, tools, visupng, riscv-rvv projects owatcom, visualc71, vstudio scripts @@ -289,6 +289,7 @@ such as one of --enable-mips-msa=yes --enable-intel-sse=yes --enable-powerpc-vsx=yes + --enable-riscv-rvv=yes or enable them all at once with @@ -301,6 +302,7 @@ or more of CPPFLAGS += "-DPNG_MIPS_MSA" CPPFLAGS += "-DPNG_INTEL_SSE" CPPFLAGS += "-DPNG_POWERPC_VSX" + CPPFLAGS += "-DPNG_RISCV_RVV" See for example scripts/makefile.linux-opt @@ -317,13 +319,15 @@ to disable a particular one, or via compiler-command options such as CPPFLAGS += "-DPNG_ARM_NEON_OPT=0, -DPNG_MIPS_MSA_OPT=0, - -DPNG_INTEL_SSE_OPT=0, -DPNG_POWERPC_VSX_OPT=0" + -DPNG_INTEL_SSE_OPT=0, -DPNG_POWERPC_VSX_OPT=0, + -DPNG_RISCV_RVV_OPT=0" If you are using cmake, hardware optimizations are "on" by default. To disable them, use cmake . -DPNG_ARM_NEON=no -DPNG_INTEL_SSE=no \ - -DPNG_MIPS_MSA=no -DPNG_POWERPC_VSX=no + -DPNG_MIPS_MSA=no -DPNG_POWERPC_VSX=no \ + -DPNG_RISCV_RVV=no or disable them all at once with diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index cbde7246ca2..9f2b2d0ed53 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.48 +README for libpng version 1.6.49 ================================ See the note about version numbers near the top of `png.h`. @@ -147,6 +147,7 @@ Files included in this distribution loongarch/ => Optimized code for LoongArch LSX mips/ => Optimized code for MIPS MSA and MIPS MMI powerpc/ => Optimized code for PowerPC VSX + riscv/ => Optimized code for the RISC-V platform ci/ => Scripts for continuous integration contrib/ => External contributions arm-neon/ => Optimized code for the ARM-NEON platform @@ -162,6 +163,7 @@ Files included in this distribution programs demonstrating the use of pngusr.dfa pngminus/ => Simple pnm2png and png2pnm programs pngsuite/ => Test images + riscv-rvv/ => Optimized code for the RISC-V Vector platform testpngs/ => Test images tools/ => Various tools visupng/ => VisualPng, a Windows viewer for PNG images diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index 940c2e2b513..f4e151f0c23 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -9,7 +9,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng version 1.6.36, December 2018, through 1.6.48 - April 2025 + libpng version 1.6.36, December 2018, through 1.6.49 - June 2025 Updated and distributed by Cosmin Truta Copyright (c) 2018-2025 Cosmin Truta diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index a9179ffbbdd..8a77b6db5f2 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -13,7 +13,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_48 Your_png_h_is_not_version_1_6_48; +typedef png_libpng_version_1_6_49 Your_png_h_is_not_version_1_6_49; /* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the * corresponding macro definitions. This causes a compile time failure if @@ -815,7 +815,7 @@ png_get_copyright(png_const_structrp png_ptr) return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.48" PNG_STRING_NEWLINE \ + "libpng version 1.6.49" PNG_STRING_NEWLINE \ "Copyright (c) 2018-2025 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index 665511c5547..f43e49c521a 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,6 +1,6 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.48 + * libpng version 1.6.49 * * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson @@ -14,7 +14,7 @@ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.48, April 2025: + * libpng versions 1.6.36, December 2018, through 1.6.49, June 2025: * Cosmin Truta * See also "Contributing Authors", below. */ @@ -238,7 +238,7 @@ * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.48 16 10648 16.so.16.48[.0] + * 1.6.49 16 10649 16.so.16.49[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for @@ -274,7 +274,7 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.48" +#define PNG_LIBPNG_VER_STRING "1.6.49" #define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" /* The versions of shared library builds should stay in sync, going forward */ @@ -285,7 +285,7 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 48 +#define PNG_LIBPNG_VER_RELEASE 49 /* This should be zero for a public release, or non-zero for a * development version. @@ -316,7 +316,7 @@ * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10648 /* 1.6.48 */ +#define PNG_LIBPNG_VER 10649 /* 1.6.49 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -426,7 +426,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_48; +typedef char* png_libpng_version_1_6_49; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * @@ -3303,26 +3303,45 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, * selected at run time. */ #ifdef PNG_SET_OPTION_SUPPORTED + +/* HARDWARE: ARM Neon SIMD instructions supported */ #ifdef PNG_ARM_NEON_API_SUPPORTED -# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ +# define PNG_ARM_NEON 0 #endif -#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ -#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ + +/* SOFTWARE: Force maximum window */ +#define PNG_MAXIMUM_INFLATE_WINDOW 2 + +/* SOFTWARE: Check ICC profile for sRGB */ +#define PNG_SKIP_sRGB_CHECK_PROFILE 4 + +/* HARDWARE: MIPS MSA SIMD instructions supported */ #ifdef PNG_MIPS_MSA_API_SUPPORTED -# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */ +# define PNG_MIPS_MSA 6 #endif + +/* SOFTWARE: Disable Adler32 check on IDAT */ #ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED -# define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */ +# define PNG_IGNORE_ADLER32 8 #endif + +/* HARDWARE: PowerPC VSX SIMD instructions supported */ #ifdef PNG_POWERPC_VSX_API_SUPPORTED -# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions - * supported */ +# define PNG_POWERPC_VSX 10 #endif + +/* HARDWARE: MIPS MMI SIMD instructions supported */ #ifdef PNG_MIPS_MMI_API_SUPPORTED -# define PNG_MIPS_MMI 12 /* HARDWARE: MIPS MMI SIMD instructions supported */ +# define PNG_MIPS_MMI 12 +#endif + +/* HARDWARE: RISC-V RVV SIMD instructions supported */ +#ifdef PNG_RISCV_RVV_API_SUPPORTED +# define PNG_RISCV_RVV 14 #endif -#define PNG_OPTION_NEXT 14 /* Next option - numbers must be even */ +/* Next option - numbers must be even */ +#define PNG_OPTION_NEXT 16 /* Return values: NOTE: there are four values and 'off' is *not* zero */ #define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index e46b0611190..e92a3b1eca4 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,6 +1,6 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.48 + * libpng version 1.6.49 * * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index c7634440de8..ea61c441ba6 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,6 +1,6 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.48 */ +/* libpng version 1.6.49 */ /* Copyright (c) 2018-2025 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h index a6f8d67d384..cb44a6aec8a 100644 --- a/src/3rdparty/libpng/pngpriv.h +++ b/src/3rdparty/libpng/pngpriv.h @@ -143,6 +143,24 @@ # endif #endif +#ifndef PNG_RISCV_RVV_OPT + /* RISCV_RVV optimizations are being controlled by the compiler settings, + * typically the target compiler will define __riscv but the rvv extension + * availability has to be explicitly stated. This is why if no + * PNG_RISCV_RVV_OPT was defined then a runtime check will be executed. + * + * To enable RISCV_RVV optimizations unconditionally, and compile the + * associated code, pass --enable-riscv-rvv=yes or --enable-riscv-rvv=on + * to configure or put -DPNG_RISCV_RVV_OPT=2 in CPPFLAGS. + */ + +# if defined(__riscv) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_RISCV_RVV_OPT 1 +# else +# define PNG_RISCV_RVV_OPT 0 +# endif +#endif + #if PNG_ARM_NEON_OPT > 0 /* NEON optimizations are to be at least considered by libpng, so enable the * callbacks to do this. @@ -288,6 +306,16 @@ # define PNG_LOONGARCH_LSX_IMPLEMENTATION 0 #endif +#if PNG_RISCV_RVV_OPT > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_rvv +# ifndef PNG_RISCV_RVV_IMPLEMENTATION + /* Use the intrinsics code by default. */ +# define PNG_RISCV_RVV_IMPLEMENTATION 1 +# endif +#else +# define PNG_RISCV_RVV_IMPLEMENTATION 0 +#endif + /* Is this a build of a DLL where compilation of the object modules requires * different preprocessor settings to those required for a simple library? If * so PNG_BUILD_DLL must be set. @@ -1522,6 +1550,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif +#if PNG_RISCV_RVV_OPT > 0 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + /* Choose the best filter to use and filter the row data */ PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); @@ -2134,6 +2179,11 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); #endif +# if PNG_RISCV_RVV_OPT > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_rvv, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +#endif + PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, png_const_charp key, png_bytep new_key), PNG_EMPTY); diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c index 4f55f6408b8..a0dbf2ae208 100644 --- a/src/3rdparty/libpng/pngread.c +++ b/src/3rdparty/libpng/pngread.c @@ -809,7 +809,8 @@ png_read_destroy(png_structrp png_ptr) #endif #if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_ARM_NEON_IMPLEMENTATION) + (defined(PNG_ARM_NEON_IMPLEMENTATION) || \ + defined(PNG_RISCV_RVV_IMPLEMENTATION)) png_free(png_ptr, png_ptr->riffled_palette); png_ptr->riffled_palette = NULL; #endif diff --git a/src/3rdparty/libpng/pngrtran.c b/src/3rdparty/libpng/pngrtran.c index 0fea13a418d..1809db70473 100644 --- a/src/3rdparty/libpng/pngrtran.c +++ b/src/3rdparty/libpng/pngrtran.c @@ -28,6 +28,12 @@ # endif #endif +#ifdef PNG_RISCV_RVV_IMPLEMENTATION +# if PNG_RISCV_RVV_IMPLEMENTATION == 1 +# define PNG_RISCV_RVV_INTRINSICS_AVAILABLE +# endif +#endif + #ifdef PNG_READ_SUPPORTED /* Set the action on getting a CRC error for an ancillary or critical chunk. */ diff --git a/src/3rdparty/libpng/pngstruct.h b/src/3rdparty/libpng/pngstruct.h index b17a54fe8f9..084422bc1e2 100644 --- a/src/3rdparty/libpng/pngstruct.h +++ b/src/3rdparty/libpng/pngstruct.h @@ -375,7 +375,8 @@ struct png_struct_def /* New member added in libpng-1.6.36 */ #if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_ARM_NEON_IMPLEMENTATION) + (defined(PNG_ARM_NEON_IMPLEMENTATION) || \ + defined(PNG_RISCV_RVV_IMPLEMENTATION)) png_bytep riffled_palette; /* buffer for accelerated palette expansion */ #endif diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index d300d9d9b52..49d0b6ca79f 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -7,8 +7,8 @@ "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", - "Version": "1.6.48", - "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.48.tar.xz", + "Version": "1.6.49", + "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.49.tar.xz", "PURL": "pkg:github/pnggroup/libpng@v$<VERSION>", "CPE": "cpe:2.3:a:libpng:libpng:$<VERSION>:*:*:*:*:*:*:*", diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 6572b106e0c..4d750224183 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -7,10 +7,10 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.50.1", + "Version": "3.50.2", "PURL": "pkg:github/sqlite/sqlite@version-$<VERSION>", "CPE": "cpe:2.3:a:sqlite:sqlite:$<VERSION>:*:*:*:*:*:*:*", - "DownloadLocation": "https://www.sqlite.org/2025/sqlite-amalgamation-3500100.zip", + "DownloadLocation": "https://www.sqlite.org/2025/sqlite-amalgamation-3500200.zip", "License": "SQLite Blessing", "LicenseId": "blessing", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 49a4256b0c0..0b071b2b6cc 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.50.1. By combining all the individual C code files into this +** version 3.50.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** b77dc5e0f596d2140d9ac682b2893ff65d3a with changes in files: +** 2af157d77fb1304a74176eaee7fbc7c7e932 with changes in files: ** ** */ @@ -465,9 +465,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.50.1" -#define SQLITE_VERSION_NUMBER 3050001 -#define SQLITE_SOURCE_ID "2025-06-06 14:52:32 b77dc5e0f596d2140d9ac682b2893ff65d3a4140aa86067a3efebe29dc914c95" +#define SQLITE_VERSION "3.50.2" +#define SQLITE_VERSION_NUMBER 3050002 +#define SQLITE_SOURCE_ID "2025-06-28 14:00:48 2af157d77fb1304a74176eaee7fbc7c7e932d946bf25325e9c26c91db19e3079" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -4398,7 +4398,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** database filename D with corresponding journal file J and WAL file W and -** with N URI parameters key/values pairs in the array P. The result from +** an array P of N URI Key/Value pairs. The result from ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that ** is safe to pass to routines like: ** <ul> @@ -5079,7 +5079,7 @@ typedef struct sqlite3_context sqlite3_context; ** METHOD: sqlite3_stmt ** ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, -** literals may be replaced by a [parameter] that matches one of following +** literals may be replaced by a [parameter] that matches one of the following ** templates: ** ** <ul> @@ -5124,7 +5124,7 @@ typedef struct sqlite3_context sqlite3_context; ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) -** found in first character, which is removed, or in the absence of a BOM +** found in the first character, which is removed, or in the absence of a BOM ** the byte order is the native byte order of the host ** machine for sqlite3_bind_text16() or the byte order specified in ** the 6th parameter for sqlite3_bind_text64().)^ @@ -5144,7 +5144,7 @@ typedef struct sqlite3_context sqlite3_context; ** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL -** terminated. If any NUL characters occurs at byte offsets less than +** terminated. If any NUL characters occur at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. @@ -5356,7 +5356,7 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and -** table column that is the origin of a particular result column in +** table column that is the origin of a particular result column in a ** [SELECT] statement. ** ^The name of the database or table or column can be returned as ** either a UTF-8 or UTF-16 string. ^The _database_ routines return @@ -5925,8 +5925,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be -** used inside of triggers, view, CHECK constraints, or other elements of -** the database schema. This flags is especially recommended for SQL +** used inside of triggers, views, CHECK constraints, or other elements of +** the database schema. This flag is especially recommended for SQL ** functions that have side effects or reveal internal application state. ** Without this flag, an attacker might be able to modify the schema of ** a database file to include invocations of the function with parameters @@ -5957,7 +5957,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or -** sqlite3_create_window_function() is not NULL, then it is destructor for +** sqlite3_create_window_function() is not NULL, then it is the destructor for ** the application data pointer. The destructor is invoked when the function ** is deleted, either by being overloaded or when the database connection ** closes.)^ ^The destructor is also invoked if the call to @@ -6357,7 +6357,7 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); ** METHOD: sqlite3_value ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] -** object D and returns a pointer to that copy. ^The [sqlite3_value] returned +** object V and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a ** memory allocation fails. ^If V is a [pointer value], then the result @@ -6395,7 +6395,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*); ** allocation error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is -** determined by the N parameter on first successful call. Changing the +** determined by the N parameter on the first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set @@ -6557,7 +6557,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi ** ** Security Warning: These interfaces should not be exposed in scripting ** languages or in other circumstances where it might be possible for an -** an attacker to invoke them. Any agent that can invoke these interfaces +** attacker to invoke them. Any agent that can invoke these interfaces ** can probably also take control of the process. ** ** Database connection client data is only available for SQLite @@ -6671,7 +6671,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would -** appear if the string where NUL terminated. If any NUL characters occur +** appear if the string were NUL terminated. If any NUL characters occur ** in the string at a byte offset that is less than the value of the 3rd ** parameter, then the resulting string will contain embedded NULs and the ** result of expressions operating on strings with embedded NULs is undefined. @@ -6729,7 +6729,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** string and preferably a string literal. The sqlite3_result_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** -** If these routines are called from within the different thread +** If these routines are called from within a different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ @@ -7135,7 +7135,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name -** for the N-th database on database connection D, or a NULL pointer of N is +** for the N-th database on database connection D, or a NULL pointer if N is ** out of range. An N value of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. @@ -7230,7 +7230,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); ** <dd>The SQLITE_TXN_READ state means that the database is currently ** in a read transaction. Content has been read from the database file ** but nothing in the database file has changed. The transaction state -** will advanced to SQLITE_TXN_WRITE if any changes occur and there are +** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are ** no other conflicting concurrent write transactions. The transaction ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or ** [COMMIT].</dd> @@ -7239,7 +7239,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); ** <dd>The SQLITE_TXN_WRITE state means that the database is currently ** in a write transaction. Content has been written to the database file ** but has not yet committed. The transaction state will change to -** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd> +** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd> */ #define SQLITE_TXN_NONE 0 #define SQLITE_TXN_READ 1 @@ -7520,7 +7520,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** CAPI3REF: Impose A Limit On Heap Size ** ** These interfaces impose limits on the amount of heap memory that will be -** by all database connections within a single process. +** used by all database connections within a single process. ** ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. @@ -7578,7 +7578,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** </ul>)^ ** ** The circumstances under which SQLite will enforce the heap limits may -** changes in future releases of SQLite. +** change in future releases of SQLite. */ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); @@ -7693,8 +7693,8 @@ SQLITE_API int sqlite3_table_column_metadata( ** ^The entry point is zProc. ** ^(zProc may be 0, in which case SQLite will try to come up with an ** entry point name on its own. It first tries "sqlite3_extension_init". -** If that does not work, it constructs a name "sqlite3_X_init" where the -** X is consists of the lower-case equivalent of all ASCII alphabetic +** If that does not work, it constructs a name "sqlite3_X_init" where +** X consists of the lower-case equivalent of all ASCII alphabetic ** characters in the filename from the last "/" to the first following ** "." and omitting any initial "lib".)^ ** ^The sqlite3_load_extension() interface returns @@ -7765,7 +7765,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** ^(Even though the function prototype shows that xEntryPoint() takes ** no arguments and returns void, SQLite invokes xEntryPoint() with three ** arguments and expects an integer result as if the signature of the -** entry point where as follows: +** entry point were as follows: ** ** <blockquote><pre> ** int xEntryPoint( @@ -7929,7 +7929,7 @@ struct sqlite3_module { ** virtual table and might not be checked again by the byte code.)^ ^(The ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag ** is left in its default setting of false, the constraint will always be -** checked separately in byte code. If the omit flag is change to true, then +** checked separately in byte code. If the omit flag is changed to true, then ** the constraint may or may not be checked in byte code. In other words, ** when the omit flag is true there is no guarantee that the constraint will ** not be checked again using byte code.)^ @@ -7955,7 +7955,7 @@ struct sqlite3_module { ** The xBestIndex method may optionally populate the idxFlags field with a ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] -** output to show the idxNum has hex instead of as decimal. Another flag is +** output to show the idxNum as hex instead of as decimal. Another flag is ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will ** return at most one row. ** @@ -8096,7 +8096,7 @@ struct sqlite3_index_info { ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through ** into the [xCreate] and [xConnect] methods of the virtual table module -** when a new virtual table is be being created or reinitialized. +** when a new virtual table is being created or reinitialized. ** ** ^The sqlite3_create_module_v2() interface has a fifth parameter which ** is a pointer to a destructor for the pClientData. ^SQLite will @@ -8261,7 +8261,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided ** the API is not misused, it is always safe to call [sqlite3_blob_close()] -** on *ppBlob after this function it returns. +** on *ppBlob after this function returns. ** ** This function fails with SQLITE_ERROR if any of the following are true: ** <ul> @@ -8381,7 +8381,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The -** incremental blob I/O routines can only read or overwriting existing +** incremental blob I/O routines can only read or overwrite existing ** blob content; they cannot change the size of a blob. ** ** This routine only works on a [BLOB handle] which has been created @@ -8531,7 +8531,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** routine returns NULL if it is unable to allocate the requested -** mutex. The argument to sqlite3_mutex_alloc() must one of these +** mutex. The argument to sqlite3_mutex_alloc() must be one of these ** integer constants: ** ** <ul> @@ -8764,7 +8764,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** -** ^This interface returns a pointer the [sqlite3_mutex] object that +** ^This interface returns a pointer to the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this @@ -8887,7 +8887,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords -** recognized by SQLite. Applications can uses these routines to determine +** recognized by SQLite. Applications can use these routines to determine ** whether or not a specific identifier needs to be escaped (for example, ** by enclosing in double-quotes) so as not to confuse the parser. ** @@ -9055,7 +9055,7 @@ SQLITE_API void sqlite3_str_reset(sqlite3_str*); ** content of the dynamic string under construction in X. The value ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** and might be freed or altered by any subsequent method on the same -** [sqlite3_str] object. Applications must not used the pointer returned +** [sqlite3_str] object. Applications must not use the pointer returned by ** [sqlite3_str_value(X)] after any subsequent method call on the same ** object. ^Applications may change the content of the string returned ** by [sqlite3_str_value(X)] as long as they do not write into any bytes @@ -9141,7 +9141,7 @@ SQLITE_API int sqlite3_status64( ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they -** where too large (they were larger than the "sz" parameter to +** were too large (they were larger than the "sz" parameter to ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because ** no space was left in the page cache.</dd>)^ ** @@ -9225,28 +9225,29 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> ** <dd>This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; -** the current value is always zero.)^ +** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt> -** <dd>This parameter returns the number malloc attempts that might have +** <dd>This parameter returns the number of malloc attempts that might have ** been satisfied using lookaside memory but failed due to the amount of ** memory requested being larger than the lookaside slot size. ** Only the high-water value is meaningful; -** the current value is always zero.)^ +** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt> -** <dd>This parameter returns the number malloc attempts that might have +** <dd>This parameter returns the number of malloc attempts that might have ** been satisfied using lookaside memory but failed due to all lookaside ** memory already being in use. ** Only the high-water value is meaningful; -** the current value is always zero.)^ +** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt> @@ -9255,10 +9256,10 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** memory used by that pager cache is divided evenly between the attached ** connections.)^ In other words, if none of the pager caches associated ** with the database connection are shared, this request returns the same -** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are +** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are ** shared, the value returned by this call will be smaller than that returned ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with -** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. +** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.</dd> ** ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap @@ -9268,6 +9269,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** schema memory is shared with other database connections due to ** [shared cache mode] being enabled. ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +** </dd> ** ** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap @@ -9304,7 +9306,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces -** additional overhead. This parameter can be used help identify +** additional overhead. This parameter can be used to help identify ** inefficiencies that can be resolved by increasing the cache size. ** </dd> ** @@ -9784,7 +9786,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically ** restarted by the next call to sqlite3_backup_step(). ^If the source -** database is modified by the using the same database connection as is used +** database is modified by using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** @@ -9801,7 +9803,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** and may not be used following a call to sqlite3_backup_finish(). ** ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no -** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() errors occurred, regardless of whether or not ** sqlite3_backup_step() completed. ** ^If an out-of-memory condition or IO error occurred during any prior ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then @@ -10871,7 +10873,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); ** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the -** [sqlite3_db_cacheflush(D)] interface invoked, any dirty +** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty ** pages in the pager-cache that are not currently in use are written out ** to disk. A dirty page may be in use if a database cursor created by an ** active SQL statement is reading from it, or if it is page 1 of a database @@ -15442,8 +15444,8 @@ typedef INT16_TYPE LogEst; ** assuming n is a signed integer type. UMXV(n) is similar for unsigned ** integer types. */ -#define SMXV(n) ((((i64)1)<<(sizeof(n)-1))-1) -#define UMXV(n) ((((i64)1)<<(sizeof(n)))-1) +#define SMXV(n) ((((i64)1)<<(sizeof(n)*8-1))-1) +#define UMXV(n) ((((i64)1)<<(sizeof(n)*8))-1) /* ** Round up a number to the next larger multiple of 8. This is used @@ -19254,7 +19256,7 @@ struct AggInfo { ** from source tables rather than from accumulators */ u8 useSortingIdx; /* In direct mode, reference the sorting index rather ** than the source table */ - u16 nSortingColumn; /* Number of columns in the sorting index */ + u32 nSortingColumn; /* Number of columns in the sorting index */ int sortingIdx; /* Cursor number of the sorting index */ int sortingIdxPTab; /* Cursor number of pseudo-table */ int iFirstReg; /* First register in range for aCol[] and aFunc[] */ @@ -19263,8 +19265,8 @@ struct AggInfo { Table *pTab; /* Source table */ Expr *pCExpr; /* The original expression */ int iTable; /* Cursor number of the source table */ - i16 iColumn; /* Column number within the source table */ - i16 iSorterColumn; /* Column number in the sorting index */ + int iColumn; /* Column number within the source table */ + int iSorterColumn; /* Column number in the sorting index */ } *aCol; int nColumn; /* Number of used entries in aCol[] */ int nAccumulator; /* Number of columns that show through to the output. @@ -54966,7 +54968,9 @@ bitvec_set_rehash: }else{ memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); memset(p->u.apSub, 0, sizeof(p->u.apSub)); - p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; + p->iDivisor = p->iSize/BITVEC_NPTR; + if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++; + if( p->iDivisor<BITVEC_NBIT ) p->iDivisor = BITVEC_NBIT; rc = sqlite3BitvecSet(p, i); for(j=0; j<BITVEC_NINT; j++){ if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); @@ -69654,6 +69658,7 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); } SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + pWal->iReCksum = 0; } return rc; } @@ -69701,6 +69706,9 @@ SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ walCleanupHash(pWal); } SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + if( pWal->iReCksum>pWal->hdr.mxFrame ){ + pWal->iReCksum = 0; + } } return rc; @@ -117346,7 +117354,9 @@ static void findOrCreateAggInfoColumn( ){ struct AggInfo_col *pCol; int k; + int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; + assert( mxTerm <= SMXV(i16) ); assert( pAggInfo->iFirstReg==0 ); pCol = pAggInfo->aCol; for(k=0; k<pAggInfo->nColumn; k++, pCol++){ @@ -117364,6 +117374,10 @@ static void findOrCreateAggInfoColumn( assert( pParse->db->mallocFailed ); return; } + if( k>mxTerm ){ + sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); + k = mxTerm; + } pCol = &pAggInfo->aCol[k]; assert( ExprUseYTab(pExpr) ); pCol->pTab = pExpr->y.pTab; @@ -117397,6 +117411,7 @@ fix_up_expr: if( pExpr->op==TK_COLUMN ){ pExpr->op = TK_AGG_COLUMN; } + assert( k <= SMXV(pExpr->iAgg) ); pExpr->iAgg = (i16)k; } @@ -117481,13 +117496,19 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ ** function that is already in the pAggInfo structure */ struct AggInfo_func *pItem = pAggInfo->aFunc; + int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; + assert( mxTerm <= SMXV(i16) ); for(i=0; i<pAggInfo->nFunc; i++, pItem++){ if( NEVER(pItem->pFExpr==pExpr) ) break; if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ break; } } - if( i>=pAggInfo->nFunc ){ + if( i>mxTerm ){ + sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); + i = mxTerm; + assert( i<pAggInfo->nFunc ); + }else if( i>=pAggInfo->nFunc ){ /* pExpr is original. Make a new entry in pAggInfo->aFunc[] */ u8 enc = ENC(pParse->db); @@ -117541,6 +117562,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ */ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pExpr, EP_NoReduce); + assert( i <= SMXV(pExpr->iAgg) ); pExpr->iAgg = (i16)i; pExpr->pAggInfo = pAggInfo; return WRC_Prune; @@ -131999,7 +132021,7 @@ static void concatFuncCore( int nSep, const char *zSep ){ - i64 j, k, n = 0; + i64 j, n = 0; int i; char *z; for(i=0; i<argc; i++){ @@ -132013,8 +132035,8 @@ static void concatFuncCore( } j = 0; for(i=0; i<argc; i++){ - k = sqlite3_value_bytes(argv[i]); - if( k>0 ){ + if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){ + int k = sqlite3_value_bytes(argv[i]); const char *v = (const char*)sqlite3_value_text(argv[i]); if( v!=0 ){ if( j>0 && nSep>0 ){ @@ -163433,30 +163455,42 @@ static void exprAnalyzeOrTerm( ** 1. The SQLITE_Transitive optimization must be enabled ** 2. Must be either an == or an IS operator ** 3. Not originating in the ON clause of an OUTER JOIN -** 4. The affinities of A and B must be compatible -** 5a. Both operands use the same collating sequence OR -** 5b. The overall collating sequence is BINARY +** 4. The operator is not IS or else the query does not contain RIGHT JOIN +** 5. The affinities of A and B must be compatible +** 6a. Both operands use the same collating sequence OR +** 6b. The overall collating sequence is BINARY ** If this routine returns TRUE, that means that the RHS can be substituted ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. ** This is an optimization. No harm comes from returning 0. But if 1 is ** returned when it should not be, then incorrect answers might result. */ -static int termIsEquivalence(Parse *pParse, Expr *pExpr){ +static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ char aff1, aff2; CollSeq *pColl; - if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; - if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; - if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; + if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ + if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ + if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ + assert( pSrc!=0 ); + if( pExpr->op==TK_IS + && pSrc->nSrc + && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 + ){ + return 0; /* (4) */ + } aff1 = sqlite3ExprAffinity(pExpr->pLeft); aff2 = sqlite3ExprAffinity(pExpr->pRight); if( aff1!=aff2 && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) ){ - return 0; + return 0; /* (5) */ } pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); - if( sqlite3IsBinary(pColl) ) return 1; - return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); + if( !sqlite3IsBinary(pColl) + && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) + ){ + return 0; /* (6) */ + } + return 1; } /* @@ -163721,8 +163755,8 @@ static void exprAnalyze( if( op==TK_IS ) pNew->wtFlags |= TERM_IS; pTerm = &pWC->a[idxTerm]; pTerm->wtFlags |= TERM_COPIED; - - if( termIsEquivalence(pParse, pDup) ){ + assert( pWInfo->pTabList!=0 ); + if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){ pTerm->eOperator |= WO_EQUIV; eExtraOp = WO_EQUIV; } @@ -184424,6 +184458,7 @@ SQLITE_API int sqlite3_setlk_timeout(sqlite3 *db, int ms, int flags){ #endif if( ms<-1 ) return SQLITE_RANGE; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3_mutex_enter(db->mutex); db->setlkTimeout = ms; db->setlkFlags = flags; sqlite3BtreeEnterAll(db); @@ -184435,6 +184470,7 @@ SQLITE_API int sqlite3_setlk_timeout(sqlite3 *db, int ms, int flags){ } } sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); #endif #if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) UNUSED_PARAMETER(db); @@ -257230,7 +257266,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2025-06-06 14:52:32 b77dc5e0f596d2140d9ac682b2893ff65d3a4140aa86067a3efebe29dc914c95", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2025-06-28 14:00:48 2af157d77fb1304a74176eaee7fbc7c7e932d946bf25325e9c26c91db19e3079", -1, SQLITE_TRANSIENT); } /* @@ -258045,6 +258081,7 @@ static int fts5StorageDeleteFromIndex( for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ if( pConfig->abUnindexed[iCol-1]==0 ){ sqlite3_value *pVal = 0; + sqlite3_value *pFree = 0; const char *pText = 0; int nText = 0; const char *pLoc = 0; @@ -258061,11 +258098,22 @@ static int fts5StorageDeleteFromIndex( if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); }else{ - pText = (const char*)sqlite3_value_text(pVal); - nText = sqlite3_value_bytes(pVal); - if( pConfig->bLocale && pSeek ){ - pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); - nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); + if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){ + /* Make a copy of the value to work with. This is because the call + ** to sqlite3_value_text() below forces the type of the value to + ** SQLITE_TEXT, and we may need to use it again later. */ + pFree = pVal = sqlite3_value_dup(pVal); + if( pVal==0 ){ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale && pSeek ){ + pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol); + nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); + } } } @@ -258081,6 +258129,7 @@ static int fts5StorageDeleteFromIndex( } sqlite3Fts5ClearLocale(pConfig); } + sqlite3_value_free(pFree); } } if( rc==SQLITE_OK && p->nTotalRow<1 ){ diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index dae02e66c20..f56dd8d86a2 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.50.1" -#define SQLITE_VERSION_NUMBER 3050001 -#define SQLITE_SOURCE_ID "2025-06-06 14:52:32 b77dc5e0f596d2140d9ac682b2893ff65d3a4140aa86067a3efebe29dc914c95" +#define SQLITE_VERSION "3.50.2" +#define SQLITE_VERSION_NUMBER 3050002 +#define SQLITE_SOURCE_ID "2025-06-28 14:00:48 2af157d77fb1304a74176eaee7fbc7c7e932d946bf25325e9c26c91db19e3079" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -4079,7 +4079,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of ** database filename D with corresponding journal file J and WAL file W and -** with N URI parameters key/values pairs in the array P. The result from +** an array P of N URI Key/Value pairs. The result from ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that ** is safe to pass to routines like: ** <ul> @@ -4760,7 +4760,7 @@ typedef struct sqlite3_context sqlite3_context; ** METHOD: sqlite3_stmt ** ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, -** literals may be replaced by a [parameter] that matches one of following +** literals may be replaced by a [parameter] that matches one of the following ** templates: ** ** <ul> @@ -4805,7 +4805,7 @@ typedef struct sqlite3_context sqlite3_context; ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) -** found in first character, which is removed, or in the absence of a BOM +** found in the first character, which is removed, or in the absence of a BOM ** the byte order is the native byte order of the host ** machine for sqlite3_bind_text16() or the byte order specified in ** the 6th parameter for sqlite3_bind_text64().)^ @@ -4825,7 +4825,7 @@ typedef struct sqlite3_context sqlite3_context; ** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL -** terminated. If any NUL characters occurs at byte offsets less than +** terminated. If any NUL characters occur at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. @@ -5037,7 +5037,7 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and -** table column that is the origin of a particular result column in +** table column that is the origin of a particular result column in a ** [SELECT] statement. ** ^The name of the database or table or column can be returned as ** either a UTF-8 or UTF-16 string. ^The _database_ routines return @@ -5606,8 +5606,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be -** used inside of triggers, view, CHECK constraints, or other elements of -** the database schema. This flags is especially recommended for SQL +** used inside of triggers, views, CHECK constraints, or other elements of +** the database schema. This flag is especially recommended for SQL ** functions that have side effects or reveal internal application state. ** Without this flag, an attacker might be able to modify the schema of ** a database file to include invocations of the function with parameters @@ -5638,7 +5638,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or -** sqlite3_create_window_function() is not NULL, then it is destructor for +** sqlite3_create_window_function() is not NULL, then it is the destructor for ** the application data pointer. The destructor is invoked when the function ** is deleted, either by being overloaded or when the database connection ** closes.)^ ^The destructor is also invoked if the call to @@ -6038,7 +6038,7 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); ** METHOD: sqlite3_value ** ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] -** object D and returns a pointer to that copy. ^The [sqlite3_value] returned +** object V and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a ** memory allocation fails. ^If V is a [pointer value], then the result @@ -6076,7 +6076,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*); ** allocation error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is -** determined by the N parameter on first successful call. Changing the +** determined by the N parameter on the first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set @@ -6238,7 +6238,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi ** ** Security Warning: These interfaces should not be exposed in scripting ** languages or in other circumstances where it might be possible for an -** an attacker to invoke them. Any agent that can invoke these interfaces +** attacker to invoke them. Any agent that can invoke these interfaces ** can probably also take control of the process. ** ** Database connection client data is only available for SQLite @@ -6352,7 +6352,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would -** appear if the string where NUL terminated. If any NUL characters occur +** appear if the string were NUL terminated. If any NUL characters occur ** in the string at a byte offset that is less than the value of the 3rd ** parameter, then the resulting string will contain embedded NULs and the ** result of expressions operating on strings with embedded NULs is undefined. @@ -6410,7 +6410,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** string and preferably a string literal. The sqlite3_result_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** -** If these routines are called from within the different thread +** If these routines are called from within a different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ @@ -6816,7 +6816,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** METHOD: sqlite3 ** ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name -** for the N-th database on database connection D, or a NULL pointer of N is +** for the N-th database on database connection D, or a NULL pointer if N is ** out of range. An N value of 0 means the main database file. An N of 1 is ** the "temp" schema. Larger values of N correspond to various ATTACH-ed ** databases. @@ -6911,7 +6911,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); ** <dd>The SQLITE_TXN_READ state means that the database is currently ** in a read transaction. Content has been read from the database file ** but nothing in the database file has changed. The transaction state -** will advanced to SQLITE_TXN_WRITE if any changes occur and there are +** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are ** no other conflicting concurrent write transactions. The transaction ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or ** [COMMIT].</dd> @@ -6920,7 +6920,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); ** <dd>The SQLITE_TXN_WRITE state means that the database is currently ** in a write transaction. Content has been written to the database file ** but has not yet committed. The transaction state will change to -** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd> +** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd> */ #define SQLITE_TXN_NONE 0 #define SQLITE_TXN_READ 1 @@ -7201,7 +7201,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** CAPI3REF: Impose A Limit On Heap Size ** ** These interfaces impose limits on the amount of heap memory that will be -** by all database connections within a single process. +** used by all database connections within a single process. ** ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. @@ -7259,7 +7259,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** </ul>)^ ** ** The circumstances under which SQLite will enforce the heap limits may -** changes in future releases of SQLite. +** change in future releases of SQLite. */ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); @@ -7374,8 +7374,8 @@ SQLITE_API int sqlite3_table_column_metadata( ** ^The entry point is zProc. ** ^(zProc may be 0, in which case SQLite will try to come up with an ** entry point name on its own. It first tries "sqlite3_extension_init". -** If that does not work, it constructs a name "sqlite3_X_init" where the -** X is consists of the lower-case equivalent of all ASCII alphabetic +** If that does not work, it constructs a name "sqlite3_X_init" where +** X consists of the lower-case equivalent of all ASCII alphabetic ** characters in the filename from the last "/" to the first following ** "." and omitting any initial "lib".)^ ** ^The sqlite3_load_extension() interface returns @@ -7446,7 +7446,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** ^(Even though the function prototype shows that xEntryPoint() takes ** no arguments and returns void, SQLite invokes xEntryPoint() with three ** arguments and expects an integer result as if the signature of the -** entry point where as follows: +** entry point were as follows: ** ** <blockquote><pre> ** int xEntryPoint( @@ -7610,7 +7610,7 @@ struct sqlite3_module { ** virtual table and might not be checked again by the byte code.)^ ^(The ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag ** is left in its default setting of false, the constraint will always be -** checked separately in byte code. If the omit flag is change to true, then +** checked separately in byte code. If the omit flag is changed to true, then ** the constraint may or may not be checked in byte code. In other words, ** when the omit flag is true there is no guarantee that the constraint will ** not be checked again using byte code.)^ @@ -7636,7 +7636,7 @@ struct sqlite3_module { ** The xBestIndex method may optionally populate the idxFlags field with a ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] -** output to show the idxNum has hex instead of as decimal. Another flag is +** output to show the idxNum as hex instead of as decimal. Another flag is ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will ** return at most one row. ** @@ -7777,7 +7777,7 @@ struct sqlite3_index_info { ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through ** into the [xCreate] and [xConnect] methods of the virtual table module -** when a new virtual table is be being created or reinitialized. +** when a new virtual table is being created or reinitialized. ** ** ^The sqlite3_create_module_v2() interface has a fifth parameter which ** is a pointer to a destructor for the pClientData. ^SQLite will @@ -7942,7 +7942,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided ** the API is not misused, it is always safe to call [sqlite3_blob_close()] -** on *ppBlob after this function it returns. +** on *ppBlob after this function returns. ** ** This function fails with SQLITE_ERROR if any of the following are true: ** <ul> @@ -8062,7 +8062,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The -** incremental blob I/O routines can only read or overwriting existing +** incremental blob I/O routines can only read or overwrite existing ** blob content; they cannot change the size of a blob. ** ** This routine only works on a [BLOB handle] which has been created @@ -8212,7 +8212,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** routine returns NULL if it is unable to allocate the requested -** mutex. The argument to sqlite3_mutex_alloc() must one of these +** mutex. The argument to sqlite3_mutex_alloc() must be one of these ** integer constants: ** ** <ul> @@ -8445,7 +8445,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** -** ^This interface returns a pointer the [sqlite3_mutex] object that +** ^This interface returns a pointer to the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this @@ -8568,7 +8568,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** CAPI3REF: SQL Keyword Checking ** ** These routines provide access to the set of SQL language keywords -** recognized by SQLite. Applications can uses these routines to determine +** recognized by SQLite. Applications can use these routines to determine ** whether or not a specific identifier needs to be escaped (for example, ** by enclosing in double-quotes) so as not to confuse the parser. ** @@ -8736,7 +8736,7 @@ SQLITE_API void sqlite3_str_reset(sqlite3_str*); ** content of the dynamic string under construction in X. The value ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** and might be freed or altered by any subsequent method on the same -** [sqlite3_str] object. Applications must not used the pointer returned +** [sqlite3_str] object. Applications must not use the pointer returned by ** [sqlite3_str_value(X)] after any subsequent method call on the same ** object. ^Applications may change the content of the string returned ** by [sqlite3_str_value(X)] as long as they do not write into any bytes @@ -8822,7 +8822,7 @@ SQLITE_API int sqlite3_status64( ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] ** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they -** where too large (they were larger than the "sz" parameter to +** were too large (they were larger than the "sz" parameter to ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because ** no space was left in the page cache.</dd>)^ ** @@ -8906,28 +8906,29 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt> ** <dd>This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; -** the current value is always zero.)^ +** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt> -** <dd>This parameter returns the number malloc attempts that might have +** <dd>This parameter returns the number of malloc attempts that might have ** been satisfied using lookaside memory but failed due to the amount of ** memory requested being larger than the lookaside slot size. ** Only the high-water value is meaningful; -** the current value is always zero.)^ +** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] ** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt> -** <dd>This parameter returns the number malloc attempts that might have +** <dd>This parameter returns the number of malloc attempts that might have ** been satisfied using lookaside memory but failed due to all lookaside ** memory already being in use. ** Only the high-water value is meaningful; -** the current value is always zero.)^ +** the current value is always zero.</dd>)^ ** ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt> @@ -8936,10 +8937,10 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** memory used by that pager cache is divided evenly between the attached ** connections.)^ In other words, if none of the pager caches associated ** with the database connection are shared, this request returns the same -** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are +** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are ** shared, the value returned by this call will be smaller than that returned ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with -** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. +** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.</dd> ** ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap @@ -8949,6 +8950,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** schema memory is shared with other database connections due to ** [shared cache mode] being enabled. ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +** </dd> ** ** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt> ** <dd>This parameter returns the approximate number of bytes of heap @@ -8985,7 +8987,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces -** additional overhead. This parameter can be used help identify +** additional overhead. This parameter can be used to help identify ** inefficiencies that can be resolved by increasing the cache size. ** </dd> ** @@ -9465,7 +9467,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically ** restarted by the next call to sqlite3_backup_step(). ^If the source -** database is modified by the using the same database connection as is used +** database is modified by using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** @@ -9482,7 +9484,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** and may not be used following a call to sqlite3_backup_finish(). ** ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no -** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() errors occurred, regardless of whether or not ** sqlite3_backup_step() completed. ** ^If an out-of-memory condition or IO error occurred during any prior ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then @@ -10552,7 +10554,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); ** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the -** [sqlite3_db_cacheflush(D)] interface invoked, any dirty +** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty ** pages in the pager-cache that are not currently in use are written out ** to disk. A dirty page may be in use if a database cursor created by an ** active SQL statement is reading from it, or if it is page 1 of a database diff --git a/src/3rdparty/sqlite/update_sqlite.sh b/src/3rdparty/sqlite/update_sqlite.sh index fb0fb8bbbc3..321e4c1a2e8 100755 --- a/src/3rdparty/sqlite/update_sqlite.sh +++ b/src/3rdparty/sqlite/update_sqlite.sh @@ -8,7 +8,7 @@ version_maj=3 version_min=50 -version_patch=1 +version_patch=2 year=2025 version=${version_maj}.${version_min}.${version_patch} diff --git a/src/3rdparty/wayland/protocols/pointer-warp/REUSE.toml b/src/3rdparty/wayland/protocols/pointer-warp/REUSE.toml new file mode 100644 index 00000000000..61332b79db6 --- /dev/null +++ b/src/3rdparty/wayland/protocols/pointer-warp/REUSE.toml @@ -0,0 +1,10 @@ +version = 1 + +[[annotations]] +path = "pointer-warp-v1.xml" +precedence = "closest" +SPDX-FileCopyrightText = ["Copyright © 2024 Neal Gompa", + "Copyright © 2024 Xaver Hugl", + "Copyright © 2024 Matthias Klumpp", + "Copyright © 2024 Vlad Zahorodnii"] +SPDX-License-Identifier = "MIT" diff --git a/src/3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml b/src/3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml new file mode 100644 index 00000000000..158dad83c5d --- /dev/null +++ b/src/3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="pointer_warp_v1"> + <copyright> + Copyright © 2024 Neal Gompa + Copyright © 2024 Xaver Hugl + Copyright © 2024 Matthias Klumpp + Copyright © 2024 Vlad Zahorodnii + + 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 (including the next + paragraph) 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. + </copyright> + + <interface name="wp_pointer_warp_v1" version="1"> + <description summary="reposition the pointer to a location on a surface"> + This global interface allows applications to request the pointer to be + moved to a position relative to a wl_surface. + + Note that if the desired behavior is to constrain the pointer to an area + or lock it to a position, this protocol does not provide a reliable way + to do that. The pointer constraint and pointer lock protocols should be + used for those use cases instead. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + </description> + + <request name="destroy" type="destructor"> + <description summary="destroy the warp manager"> + Destroy the pointer warp manager. + </description> + </request> + + <request name="warp_pointer"> + <description summary="reposition the pointer"> + Request the compositor to move the pointer to a surface-local position. + Whether or not the compositor honors the request is implementation defined, + but it should + - honor it if the surface has pointer focus, including + when it has an implicit pointer grab + - reject it if the enter serial is incorrect + - reject it if the requested position is outside of the surface + + Note that the enter serial is valid for any surface of the client, + and does not have to be from the surface the pointer is warped to. + + </description> + <arg name="surface" type="object" interface="wl_surface" + summary="surface to position the pointer on"/> + <arg name="pointer" type="object" interface="wl_pointer" + summary="the pointer that should be repositioned"/> + <arg name="x" type="fixed"/> + <arg name="y" type="fixed"/> + <arg name="serial" type="uint" summary="serial number of the enter event"/> + </request> + </interface> +</protocol> diff --git a/src/3rdparty/wayland/protocols/pointer-warp/qt_attribution.json b/src/3rdparty/wayland/protocols/pointer-warp/qt_attribution.json new file mode 100644 index 00000000000..83cd73c3570 --- /dev/null +++ b/src/3rdparty/wayland/protocols/pointer-warp/qt_attribution.json @@ -0,0 +1,17 @@ +[ + { + "Id": "wayland-pointer-warp-protocol", + "Name": "Wayland Pointer Warp Protocol", + "QDocModule": "qtwaylandcompositor", + "QtUsage": "Used in the Qt Wayland platform plugin", + "Files": "pointer-warp-v1.xml", + "Description": "", + "Homepage": "https://wayland.freedesktop.org", + "Version": "version 1", + "DownloadLocation": "https://cgit.freedesktop.org/wayland/wayland-protocols/plain/staging/pointer-warp/pointer-warp-v1.xml", + "LicenseId": "MIT", + "License": "MIT License", + "LicenseFile": "../MIT_LICENSE.txt", + "Copyright": "Copyright © 2024 Neal Gompa\nCopyright © 2024 Xaver Hugl\nCopyright © 2024 Matthias Klumpp\nCopyright © 2024 Vlad Zahorodnii" + } +] diff --git a/src/3rdparty/wayland/protocols/session-management/REUSE.toml b/src/3rdparty/wayland/protocols/session-management/REUSE.toml new file mode 100644 index 00000000000..585706d8fcd --- /dev/null +++ b/src/3rdparty/wayland/protocols/session-management/REUSE.toml @@ -0,0 +1,12 @@ +version = 1 + +[[annotations]] +path = "xx-session-management-v1.xml" +precedence = "closest" +SPDX-FileCopyrightText = [ + "Copyright 2018 Mike Blumenkrantz", + "Copyright 2018 Samsung Electronics Co., Ltd", + "Copyright 2018 Red Hat Inc." +] + +SPDX-License-Identifier = "MIT" diff --git a/src/3rdparty/wayland/protocols/session-management/qt_attribution.json b/src/3rdparty/wayland/protocols/session-management/qt_attribution.json new file mode 100644 index 00000000000..8539749f112 --- /dev/null +++ b/src/3rdparty/wayland/protocols/session-management/qt_attribution.json @@ -0,0 +1,17 @@ +[ + { + "Id": "wayland-session-management-protocol", + "Name": "Wayland Session Management Protocol", + "QDocModule": "qtwaylandcompositor", + "QtUsage": "Used in the Qt Wayland platform plugin.", + "Files": "xx-session-management-v1.xml", + "Description": "An extension to restore window positions", + "Homepage": "https://wayland.freedesktop.org", + "Version": "experimental V1", + "DownloadLocation": "https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/experimental/xx-session-management/xx-session-management-v1.xml?ref_type=heads", + "LicenseId": "MIT", + "License": "MIT License", + "LicenseFile": "../MIT_LICENSE.txt", + "Copyright": "Copyright 2018 Mike Blumenkrantz\nCopyright 2018 Samsung Electronics Co., Ltd\nCopyright 2018 Red Hat Inc." + } +] diff --git a/src/3rdparty/wayland/protocols/session-management/xx-session-management-v1.xml b/src/3rdparty/wayland/protocols/session-management/xx-session-management-v1.xml new file mode 100644 index 00000000000..42458d9291a --- /dev/null +++ b/src/3rdparty/wayland/protocols/session-management/xx-session-management-v1.xml @@ -0,0 +1,264 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="xx_session_management_v1"> + <copyright> + Copyright 2018 Mike Blumenkrantz + Copyright 2018 Samsung Electronics Co., Ltd + Copyright 2018 Red Hat Inc. + + 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 (including the next + paragraph) 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. + </copyright> + + <description summary="Protocol for managing application sessions"> + This description provides a high-level overview of the interplay between + the interfaces defined this protocol. For details, see the protocol + specification. + + The xx_session_manager protocol declares interfaces necessary to + allow clients to restore toplevel state from previous executions. The + xx_session_manager_v1.get_session request can be used to obtain a + xx_session_v1 resource representing the state of a set of toplevels. + + Clients may obtain the session string to use in future calls through + the xx_session_v1.created event. Compositors will use this string + as an identifiable token for future runs, possibly storing data about + the related toplevels in persistent storage. + + Toplevels are managed through the xx_session_v1.add_toplevel and + xx_session_toplevel_v1.remove pair of requests. Clients will explicitly + request a toplevel to be restored according to prior state through the + xx_session_v1.restore_toplevel request before the toplevel is mapped. + + Warning! The protocol described in this file is currently in the + experimental phase. Backwards incompatible major versions of the + protocol are to be expected. Exposing this protocol without an opt-in + mechanism is discouraged. + </description> + + <interface name="xx_session_manager_v1" version="1"> + <description summary="manage sessions for applications"> + The xx_session_manager interface defines base requests for creating and + managing a session for an application. Sessions persist across application + and compositor restarts unless explicitly destroyed. A session is created + for the purpose of maintaining an application's xdg_toplevel surfaces + across compositor or application restarts. The compositor should remember + as many states as possible for surfaces in a given session, but there is + no requirement for which states must be remembered. + </description> + + <enum name="error"> + <entry name="in_use" summary="a requested session is already in use" + value="1"/> + </enum> + + <enum name="reason"> + <description summary="reason for getting a session"> + The reason may determine in what way a session restores the window + management state of associated toplevels. + + For example newly launched applications might be launched on the active + workspace with restored size and position, while a recovered + applications might restore additional state such as active workspace and + stacking order. + </description> + <entry name="launch" value="1"> + <description summary="an app is newly launched"> + A new app instance is launched, for example from an app launcher. + </description> + </entry> + <entry name="recover" value="2"> + <description summary="an app recovered"> + A app instance is recovering from for example a compositor or app crash. + </description> + </entry> + <entry name="session_restore" value="3"> + <description summary="an app restored"> + A app instance is restored, for example part of a restored session, or + restored from having been temporarily terminated due to resource + constraints. + </description> + </entry> + </enum> + + <request name="destroy" type="destructor"> + <description summary="Destroy this object"> + This has no effect other than to destroy the xx_session_manager object. + </description> + </request> + + <request name="get_session"> + <description summary="create or restore a session"> + Create a session object corresponding to either an existing session + identified by the given session identifier string or a new session. + While the session object exists, the session is considered to be "in + use". + + If a identifier string represents a session that is currently actively + in use by the the same client, an 'in_use' error is raised. If some + other client is currently using the same session, the new session will + replace managing the associated state. + + NULL is passed to initiate a new session. If an id is passed which does + not represent a valid session, the compositor treats it as if NULL had + been passed. + + A client is allowed to have any number of in use sessions at the same + time. + </description> + <arg name="id" type="new_id" interface="xx_session_v1"/> + <arg name="reason" type="uint" enum="reason" + summary="reason for session"/> + <arg name="session" type="string" + summary="the session to restore" + allow-null="true"/> + </request> + </interface> + + <interface name="xx_session_v1" version="1"> + <description summary="A session for an application"> + A xx_session_v1 object represents a session for an application. While the + object exists, all surfaces which have been added to the session will + have states stored by the compositor which can be reapplied at a later + time. Two sessions cannot exist for the same identifier string. + + States for surfaces added to a session are automatically updated by the + compositor when they are changed. + + Surfaces which have been added to a session are automatically removed from + the session if xdg_toplevel.destroy is called for the surface. + </description> + + <enum name="error"> + <entry name="invalid_restore" + summary="restore cannot be performed after initial toplevel commit" + value="1"/> + <entry name="name_in_use" + summary="toplevel name is already in used" + value="2"/> + <entry name="already_mapped" + summary="toplevel was already mapped when restored" + value="3"/> + </enum> + + <request name="destroy" type="destructor"> + <description summary="Destroy the session"> + Destroy a session object, preserving the current state but not continuing + to make further updates if state changes occur. This makes the associated + xx_toplevel_session_v1 objects inert. + </description> + </request> + + <request name="remove" type="destructor"> + <description summary="Remove the session"> + Remove the session, making it no longer available for restoration. A + compositor should in response to this request remove the data related to + this session from its storage. + </description> + </request> + + <request name="add_toplevel"> + <description summary="add a new surface to the session"> + Attempt to add a given surface to the session. The passed name is used + to identify what window is being restored, and may be used store window + specific state within the session. + + Calling this with a toplevel that is already managed by the session with + the same associated will raise an in_use error. + </description> + <arg name="id" type="new_id" interface="xx_toplevel_session_v1"/> + <arg name="toplevel" type="object" interface="xdg_toplevel"/> + <arg name="name" type="string"/> + </request> + + <request name="restore_toplevel"> + <description summary="restore a surface state"> + Inform the compositor that the toplevel associated with the passed name + should have its window management state restored. + + Calling this with a toplevel that is already managed by the session with + the same associated will raise an in_use error. + + This request must be called prior to the first commit on the associated + wl_surface, otherwise an already_mapped error is raised. + + As part of the initial configure sequence, if the toplevel was + successfully restored, a xx_toplevel_session_v1.restored event is + emitted. See the xx_toplevel_session_v1.restored event for further + details. + </description> + <arg name="id" type="new_id" interface="xx_toplevel_session_v1"/> + <arg name="toplevel" type="object" interface="xdg_toplevel"/> + <arg name="name" type="string"/> + </request> + + <event name="created"> + <description summary="newly-created session id"> + Emitted at most once some time after getting a new session object. It + means that no previous state was restored, and a new session was created. + The passed id can be used to restore previous sessions. + </description> + <arg name="id" type="string"/> + </event> + + <event name="restored"> + <description summary="the session has been restored"> + Emitted at most once some time after getting a new session object. It + means that previous state was at least partially restored. The same id + can again be used to restore previous sessions. + </description> + </event> + + <event name="replaced"> + <description summary="the session has been restored"> + Emitted at most once, if the session was taken over by some other + client. When this happens, the session and all its toplevel session + objects become inert, and should be destroyed. + </description> + </event> + </interface> + + <interface name="xx_toplevel_session_v1" version="1"> + <request name="destroy" type="destructor"> + <description summary="Destroy the object"> + Destroy the object. This has no effect window management of the + associated toplevel. + </description> + </request> + + <request name="remove" type="destructor"> + <description summary="remove a surface from the session"> + Remove a specified surface from the session and render any corresponding + xx_toplevel_session_v1 object inert. The compositor should remove any + data related to the toplevel in the corresponding session from its internal + storage. + </description> + </request> + + <event name="restored"> + <description summary="a toplevel's session has been restored"> + The "restored" event is emitted prior to the first + xdg_toplevel.configure for the toplevel. It will only be emitted after + xx_session_v1.restore_toplevel, and the initial empty surface state has + been applied, and it indicates that the surface's session is being + restored with this configure event. + </description> + <arg name="surface" type="object" interface="xdg_toplevel"/> + </event> + </interface> +</protocol> diff --git a/src/android/jar/build.gradle b/src/android/jar/build.gradle index 2ab607b62ea..74ecff6b75f 100644 --- a/src/android/jar/build.gradle +++ b/src/android/jar/build.gradle @@ -7,7 +7,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.8.0' + classpath 'com.android.tools.build:gradle:8.10.1' } } diff --git a/src/android/jar/src/org/qtproject/qt/android/CursorHandle.java b/src/android/jar/src/org/qtproject/qt/android/CursorHandle.java index 41256cc64a1..0079135e518 100644 --- a/src/android/jar/src/org/qtproject/qt/android/CursorHandle.java +++ b/src/android/jar/src/org/qtproject/qt/android/CursorHandle.java @@ -108,8 +108,11 @@ class CursorHandle implements ViewTreeObserver.OnPreDrawListener Context context = m_layout.getContext(); int[] attrs = {m_attr}; Drawable drawable; - try (TypedArray a = context.getTheme().obtainStyledAttributes(attrs)) { + TypedArray a = context.getTheme().obtainStyledAttributes(attrs); + try { drawable = a.getDrawable(0); + } finally { + a.recycle(); } m_cursorView = new CursorView(context, this); @@ -189,6 +192,9 @@ class CursorHandle implements ViewTreeObserver.OnPreDrawListener int width() { + if (m_cursorView == null) + return 0; + return m_cursorView.getDrawable().getIntrinsicWidth(); } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java index 542d05627c9..61f8f4b8d53 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java @@ -28,10 +28,6 @@ class QtAccessibilityDelegate extends View.AccessibilityDelegate // all low positive ints should be fine. static final int INVALID_ID = 333; // half evil - // The platform might ask for the class implementing the "view". - // Pretend to be an inner class of the QtSurface. - private static final String DEFAULT_CLASS_NAME = "$VirtualChild"; - private View m_view = null; private AccessibilityManager m_manager; private QtLayout m_layout; @@ -247,7 +243,7 @@ class QtAccessibilityDelegate extends View.AccessibilityDelegate AccessibilityEvent.obtain(AccessibilityEvent.TYPE_ANNOUNCEMENT); event.setEnabled(true); - event.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME); + event.setClassName(getNodeForVirtualViewId(viewId).getClassName()); event.setContentDescription(value); @@ -323,7 +319,7 @@ class QtAccessibilityDelegate extends View.AccessibilityDelegate final AccessibilityEvent event = AccessibilityEvent.obtain(eventType); event.setEnabled(true); - event.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME); + event.setClassName(getNodeForVirtualViewId(virtualViewId).getClassName()); event.setContentDescription(QtNativeAccessibility.descriptionForAccessibleObject(virtualViewId)); if (event.getText().isEmpty() && TextUtils.isEmpty(event.getContentDescription())) @@ -419,7 +415,6 @@ class QtAccessibilityDelegate extends View.AccessibilityDelegate final AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(); - node.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME); node.setPackageName(m_view.getContext().getPackageName()); if (m_layout.getChildCount() == 0 || !QtNativeAccessibility.populateNode(virtualViewId, node)) { diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java index 59dd42a8e8b..7dd00358546 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java @@ -9,7 +9,6 @@ import android.app.Activity; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; -import android.content.res.TypedArray; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.Rect; @@ -26,7 +25,7 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.PopupMenu; -import android.graphics.Color; + import java.util.HashMap; class QtActivityDelegate extends QtActivityDelegateBase @@ -40,6 +39,7 @@ class QtActivityDelegate extends QtActivityDelegateBase private boolean m_splashScreenSticky = false; private boolean m_backendsRegistered = false; + private View m_dummyView = null; private final HashMap<Integer, View> m_nativeViews = new HashMap<>(); QtActivityDelegate(Activity activity) @@ -197,19 +197,6 @@ class QtActivityDelegate extends QtActivityDelegateBase ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); m_layout.addView(m_splashScreen); - - // Set DayNight theme as layout background so splash screen - // is not visible with opaque windows. - TypedArray typedArray = m_activity.getTheme().obtainStyledAttributes( - android.R.style.Theme_DeviceDefault_DayNight, - new int[]{ android.R.attr.colorBackground }); - try { - int backgroundColor = typedArray.getColor(0, 0); - Drawable background = new ColorDrawable(backgroundColor); - m_layout.setBackground(background); - } finally { - typedArray.recycle(); - } } } catch (Exception e) { e.printStackTrace(); @@ -381,9 +368,15 @@ class QtActivityDelegate extends QtActivityDelegateBase if (m_layout == null) return; + if (m_topLevelWindows.isEmpty()) { + if (m_dummyView != null) { + m_layout.removeView(m_dummyView); + m_dummyView = null; + } + } + m_layout.addView(window, m_topLevelWindows.size()); m_topLevelWindows.put(window.getId(), window); - window.setToDestroy(false); if (!m_splashScreenSticky) hideSplashScreen(); }); @@ -397,13 +390,13 @@ class QtActivityDelegate extends QtActivityDelegateBase if (m_topLevelWindows.containsKey(id)) { QtWindow window = m_topLevelWindows.remove(id); window.setOnApplyWindowInsetsListener(null); // Set in QtWindow for safe margins - if (window.isFrontmostVisibleWindow()) { - window.setToDestroy(true); - // Keep current shown window open during shutdown transition - m_layout.postDelayed(() -> { window.destroySurface(); }, 500); - } else if (m_layout != null) { - m_layout.removeView(window); - } + if (m_topLevelWindows.isEmpty()) { + // Keep last frame in stack until it is replaced to get correct + // shutdown transition + m_dummyView = window; + } else if (m_layout != null) { + m_layout.removeView(window); + } } }); } @@ -459,6 +452,11 @@ class QtActivityDelegate extends QtActivityDelegateBase return; QtNative.runAction(()-> { + if (m_dummyView != null) { + m_layout.removeView(m_dummyView); + m_dummyView = null; + } + if (m_nativeViews.containsKey(id)) m_layout.removeView(m_nativeViews.remove(id)); diff --git a/src/android/jar/src/org/qtproject/qt/android/QtWindow.java b/src/android/jar/src/org/qtproject/qt/android/QtWindow.java index 22d387945c1..e4f489a39da 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtWindow.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtWindow.java @@ -20,7 +20,6 @@ import android.view.WindowInsets; import android.os.Build; import java.util.HashMap; -import java.util.concurrent.atomic.AtomicBoolean; @SuppressLint("ViewConstructor") class QtWindow extends QtLayout implements QtSurfaceInterface { @@ -31,7 +30,6 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { private GestureDetector m_gestureDetector; private final QtEditText m_editText; private final QtInputConnection.QtInputConnectionListener m_inputConnectionListener; - private final AtomicBoolean m_canBeDestroyed = new AtomicBoolean(true); private static native void setSurface(int windowId, Surface surface); private static native void safeAreaMarginsChanged(Insets insets, int id); @@ -159,60 +157,6 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { QtNative.runAction(() -> setVisibility(visible ? View.VISIBLE : View.INVISIBLE)); } - // Use only for Qt for Android and not Qt Quick for Android - @UsedFromNativeCode - public void setToDestroy(boolean destroy) - { - m_canBeDestroyed.set(destroy); - } - - // Use only for Qt for Android and not Qt Quick for Android - private QtLayout getParentContainer() - { - if (!(getParent() instanceof QtLayout)) - return null; - return (QtLayout) getParent(); - } - - // Use only for Qt for Android and not Qt Quick for Android - public boolean isFrontmostVisibleWindow() - { - QtLayout parent = getParentContainer(); - if (getVisibility() != View.VISIBLE || parent == null ) - return false; - - for (int index = parent.indexOfChild(this) + 1; index < parent.getChildCount(); index ++) { - View child = parent.getChildAt(index); - if (child instanceof QtWindow && child.isShown()) - return false; - } - - return true; - } - - // Use only for Qt for Android and not Qt Quick for Android - @UsedFromNativeCode - public boolean isLastVisibleTopLevelWindow() - { - QtLayout parent = getParentContainer(); - if (getVisibility() != View.VISIBLE || parent == null) - return false; - - for (int index = parent.indexOfChild(this) - 1; index >= 0; index--) { - View child = parent.getChildAt(index); - if (child instanceof QtWindow) { - QtWindow childWindow = (QtWindow) child; - if (child.getVisibility() == View.VISIBLE && !childWindow.m_canBeDestroyed.get()) - return false; - } - } - - if (parent.getChildCount() > 1 && !isFrontmostVisibleWindow()) - return false; - - return true; - } - @Override public void onSurfaceChanged(Surface surface) { @@ -279,10 +223,10 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { void destroySurface() { QtNative.runAction(()-> { - if (m_surfaceContainer != null && m_canBeDestroyed.get()) { + if (m_surfaceContainer != null) { removeView(m_surfaceContainer); m_surfaceContainer = null; - } + } }, false); } diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle index 6f39acc58fa..6595cb5358f 100644 --- a/src/android/templates/build.gradle +++ b/src/android/templates/build.gradle @@ -6,7 +6,7 @@ buildscript { dependencies { //noinspection AndroidGradlePluginVersion - classpath 'com.android.tools.build:gradle:8.8.0' + classpath 'com.android.tools.build:gradle:8.10.1' } } diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 4f5ef6b193d..4d83bbf794e 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -77,6 +77,7 @@ qt_internal_add_module(Core global/qsysinfo.cpp global/qsysinfo.h global/qsystemdetection.h global/qtclasshelpermacros.h + global/qtclasshelper_p.h global/qtconfiginclude.h global/qtconfigmacros.h global/qtcoreglobal.h global/qtcoreglobal_p.h @@ -252,6 +253,7 @@ qt_internal_add_module(Core text/qvsnprintf.cpp thread/qatomic.h thread/qatomic_cxx11.h + thread/qatomicwait.cpp thread/qatomicwait_p.h thread/qbasicatomic.h thread/qgenericatomic.h thread/qlocking_p.h @@ -757,6 +759,7 @@ qt_internal_extend_target(Core CONDITION QT_FEATURE_thread SOURCES thread/qatomic.cpp thread/qfutex_p.h + thread/qlatch.cpp thread/qlatch_p.h thread/qmutex.cpp thread/qmutex_p.h thread/qreadwritelock.cpp thread/qreadwritelock_p.h thread/qthreadstorage.cpp thread/qthreadstorage_p.h diff --git a/src/corelib/Qt6CoreConfigExtras.cmake.in b/src/corelib/Qt6CoreConfigExtras.cmake.in index ce53b89a7b8..15405197a61 100644 --- a/src/corelib/Qt6CoreConfigExtras.cmake.in +++ b/src/corelib/Qt6CoreConfigExtras.cmake.in @@ -4,7 +4,7 @@ if(NOT DEFINED QT_DEFAULT_MAJOR_VERSION) set(QT_DEFAULT_MAJOR_VERSION 6) endif() -if (NOT QT_NO_CREATE_TARGETS) +if(__qt_Core_targets_file_included) set(__qt_core_target @QT_CMAKE_EXPORT_NAMESPACE@::Core) get_property(__qt_core_aliased_target TARGET ${__qt_core_target} PROPERTY ALIASED_TARGET) if(__qt_core_aliased_target) @@ -32,13 +32,13 @@ if(ANDROID_PLATFORM) include("${CMAKE_CURRENT_LIST_DIR}/@QT_CMAKE_EXPORT_NAMESPACE@AndroidMacros.cmake") _qt_internal_create_global_android_targets() _qt_internal_collect_default_android_abis() - if(NOT QT_NO_CREATE_TARGETS) + if(__qt_Core_targets_file_included) _qt_internal_add_android_executable_finalizer(${__qt_core_target}) endif() endif() if(QT_FEATURE_permissions AND APPLE) - if(NOT QT_NO_CREATE_TARGETS) + if(__qt_Core_targets_file_included) set_property(TARGET ${__qt_core_target} APPEND PROPERTY INTERFACE_QT_EXECUTABLE_FINALIZERS _qt_internal_darwin_permission_finalizer diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake index fd938f0b1c2..7b522f99abb 100644 --- a/src/corelib/Qt6CoreMacros.cmake +++ b/src/corelib/Qt6CoreMacros.cmake @@ -831,6 +831,8 @@ function(qt6_finalize_target target) endif() endif() + _qt_internal_work_around_autogen_discarded_dependencies_from_target_libs("${target}") + get_target_property(is_immediately_finalized "${target}" _qt_is_immediately_finalized) get_target_property(uses_automoc ${target} AUTOMOC) if(uses_automoc) @@ -3797,7 +3799,7 @@ function(qt6_generate_deploy_app_script) qt6_generate_deploy_script(${generate_args} CONTENT " qt6_deploy_runtime_dependencies( - EXECUTABLE $<TARGET_FILE_NAME:${arg_TARGET}>.app + EXECUTABLE \"$<TARGET_FILE_NAME:${arg_TARGET}>.app\" ${common_deploy_args}) ") @@ -3805,7 +3807,7 @@ ${common_deploy_args}) qt6_generate_deploy_script(${generate_args} CONTENT " qt6_deploy_runtime_dependencies( - EXECUTABLE $<TARGET_FILE:${arg_TARGET}> + EXECUTABLE \"$<TARGET_FILE:${arg_TARGET}>\" GENERATE_QT_CONF ${common_deploy_args}) ") @@ -3815,7 +3817,7 @@ ${common_deploy_args}) qt6_generate_deploy_script(${generate_args} CONTENT " qt6_deploy_runtime_dependencies( - EXECUTABLE $<TARGET_FILE:${arg_TARGET}> + EXECUTABLE \"$<TARGET_FILE:${arg_TARGET}>\" GENERATE_QT_CONF ${common_deploy_args}) ") diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 789b9aaef44..d74894e1e42 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -179,9 +179,9 @@ typedef QList<QAbstractAnimation*>::ConstIterator AnimationListConstIt; QUnifiedTimer::QUnifiedTimer() : QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL), - currentAnimationIdx(0), insideTick(false), insideRestart(false), consistentTiming(false), slowMode(false), + currentAnimationIdx(0), insideTick(false), insideRestart(false), consistentTiming(false), startTimersPending(false), stopTimerPending(false), allowNegativeDelta(false), - slowdownFactor(5.0f), profilerCallback(nullptr), + speedModifier(1), profilerCallback(nullptr), driverStartTime(0), temporalDrift(0) { time.invalidate(); @@ -265,9 +265,11 @@ void QUnifiedTimer::updateAnimationTimers() // ignore consistentTiming in case the pause timer is active qint64 delta = (consistentTiming && !pauseTimer.isActive()) ? timingInterval : totalElapsed - lastTick; - if (slowMode) { - if (slowdownFactor > 0) - delta = qRound(delta / slowdownFactor); + // Don't use qFuzzyCompare because this won't be set frequently enough + // that floating point error can accumulate. + if (speedModifier != 1) { + if (speedModifier > 0) + delta = qRound(delta / speedModifier); else delta = 0; } diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index cbe3f6339e7..d6c245f36f0 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -150,9 +150,9 @@ public: */ void setConsistentTiming(bool consistent) { consistentTiming = consistent; } - //these facilitate fine-tuning of complex animations - void setSlowModeEnabled(bool enabled) { slowMode = enabled; } - void setSlowdownFactor(qreal factor) { slowdownFactor = factor; } + // This facilitates both fine-tuning of complex animations by slowing them + // them down, and reducing execution time of auto tests by speeding them up. + void setSpeedModifier(qreal speed) { speedModifier = speed; } void installAnimationDriver(QAnimationDriver *driver); void uninstallAnimationDriver(QAnimationDriver *driver); @@ -194,15 +194,13 @@ private: bool insideTick; bool insideRestart; bool consistentTiming; - bool slowMode; bool startTimersPending; bool stopTimerPending; bool allowNegativeDelta; - // This factor will be used to divide the DEFAULT_TIMER_INTERVAL at each tick - // when slowMode is enabled. Setting it to 0 or higher than DEFAULT_TIMER_INTERVAL (16) - // stops all animations. - qreal slowdownFactor; + // This factor will be used to multiply the DEFAULT_TIMER_INTERVAL (16) at each tick + // if it's not equal to 1. Setting it to less than 1 / 16 (0.0625) stops all animations. + qreal speedModifier; QList<QAbstractAnimationTimer*> animationTimers, animationTimersToStart; QList<QAbstractAnimationTimer*> pausedAnimationTimers; diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index 8260d50fd3a..4285e39a542 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -1454,6 +1454,8 @@ void QFutureInterfaceBase::setContinuation(std::function<void(const QFutureInter } #endif // QT_CONFIG(future) +#include "qlockfile.h" // inlined API + #include "qlogging.h" QNoDebug QMessageLogger::noDebug() const noexcept @@ -1463,6 +1465,13 @@ QNoDebug QMessageLogger::noDebug() const noexcept #include "qmutex.h" // removed, previously-inline API +#include "qobject.h" + +bool QObject::doSetProperty(const char *name, const QVariant *lvalue, QVariant *rvalue) +{ + return doSetProperty(name, *lvalue, rvalue); +} + #include "qstring.h" // inlined API // #include "qotherheader.h" diff --git a/src/corelib/doc/snippets/CMakeLists.txt b/src/corelib/doc/snippets/CMakeLists.txt index e52c36ae8da..937433f2e21 100644 --- a/src/corelib/doc/snippets/CMakeLists.txt +++ b/src/corelib/doc/snippets/CMakeLists.txt @@ -2,7 +2,29 @@ # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause add_library(corelib_snippets OBJECT + customtype/customtypeexample.cpp + file/file.cpp + jni/src_qjniobject.cpp + process/process.cpp + qbytearraylist/main.cpp + qdir-listfiles/main.cpp + qdir-namefilters/main.cpp + qelapsedtimer/main.cpp + qloggingcategory/main.cpp + qmessageauthenticationcode/main.cpp + qmetatype/registerConverters.cpp + qprocess-environment/main.cpp qrangemodel/main.cpp + qstack/main.cpp + qstringlist/main.cpp + qstringlistmodel/main.cpp + qversionnumber/main.cpp + qxmlstreamwriter/main.cpp + settings/settings.cpp + sharedemployee/main.cpp + signalsandslots/signalsandslots.cpp + streaming/main.cpp + threads/threads.cpp ) target_link_libraries(corelib_snippets PRIVATE @@ -12,6 +34,23 @@ target_link_libraries(corelib_snippets PRIVATE qt_internal_extend_target(corelib_snippets CONDITION QT_FEATURE_widgets LIBRARIES Qt::Widgets + SOURCES + events/events.cpp + hellotrmain.cpp + fileinfo/main.cpp + pointer/pointer.cpp + qsortfilterproxymodel-details/main.cpp + qstring/main.cpp + qtcast/qtcast.cpp + settings/settings.cpp +) + +qt_internal_extend_target(corelib_snippets CONDITION QT_FEATURE_gui + LIBRARIES + Qt::Gui + SOURCES + buffer/buffer.cpp + qdebug/qdebugsnippet.cpp ) if ("${CMAKE_CXX_COMPILE_FEATURES}" MATCHES "cxx_std_23") @@ -19,3 +58,8 @@ if ("${CMAKE_CXX_COMPILE_FEATURES}" MATCHES "cxx_std_23") endif() set_target_properties(corelib_snippets PROPERTIES UNITY_BUILD OFF) + +add_subdirectory(eventfilters) +add_subdirectory(qmetaobject-invokable) +add_subdirectory(qmetaobject-revision) +add_subdirectory(qprocess) diff --git a/src/corelib/doc/snippets/buffer/buffer.cpp b/src/corelib/doc/snippets/buffer/buffer.cpp index 160c0327c32..ba40eba2c2f 100644 --- a/src/corelib/doc/snippets/buffer/buffer.cpp +++ b/src/corelib/doc/snippets/buffer/buffer.cpp @@ -1,7 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include <QApplication> #include <QBuffer> #include <QPalette> @@ -23,13 +22,14 @@ static void main_snippet() static void write_datastream_snippets() { + QPalette palette; //! [1] QByteArray byteArray; QBuffer buffer(&byteArray); buffer.open(QIODevice::WriteOnly); QDataStream out(&buffer); - out << QApplication::palette(); + out << palette; //! [1] } @@ -73,15 +73,3 @@ static void setBuffer_snippet() // byteArray == "abcdef" //! [4] } - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - main_snippet(); - bytearray_ptr_ctor_snippet(); - write_datastream_snippets(); - read_datastream_snippets(); - setBuffer_snippet(); - return 0; -} diff --git a/src/corelib/doc/snippets/eventfilters/CMakeLists.txt b/src/corelib/doc/snippets/eventfilters/CMakeLists.txt new file mode 100644 index 00000000000..ea381e425a5 --- /dev/null +++ b/src/corelib/doc/snippets/eventfilters/CMakeLists.txt @@ -0,0 +1,19 @@ +add_library(snippets_eventfilters OBJECT) + +target_link_libraries(snippets_eventfilters PRIVATE + Qt::Core +) + +qt_internal_extend_target(snippets_eventfilters CONDITION QT_FEATURE_widgets + LIBRARIES + Qt::Widgets + SOURCE + main.cpp +) + +qt_internal_extend_target(snippets_eventfilters CONDITION QT_FEATURE_gui + LIBRARIES + Qt::Gui + SOURCES + filterobject.cpp +) diff --git a/src/corelib/doc/snippets/events/events.cpp b/src/corelib/doc/snippets/events/events.cpp index faeb168d803..09bd1d299c9 100644 --- a/src/corelib/doc/snippets/events/events.cpp +++ b/src/corelib/doc/snippets/events/events.cpp @@ -54,7 +54,3 @@ bool MyWidget::event(QEvent *event) return QWidget::event(event); } //! [1] - -int main() -{ -} diff --git a/src/corelib/doc/snippets/file/file.cpp b/src/corelib/doc/snippets/file/file.cpp index d1244f4bf24..3fc03a0064c 100644 --- a/src/corelib/doc/snippets/file/file.cpp +++ b/src/corelib/doc/snippets/file/file.cpp @@ -78,9 +78,3 @@ static void readRegularEmptyFile_snippet() } //! [3] } - -int main() -{ - lineByLine_snippet(); - writeStream_snippet(); -} diff --git a/src/corelib/doc/snippets/hellotrmain.cpp b/src/corelib/doc/snippets/hellotrmain.cpp index 6f08a9761f2..5d6d71ea8f9 100644 --- a/src/corelib/doc/snippets/hellotrmain.cpp +++ b/src/corelib/doc/snippets/hellotrmain.cpp @@ -1,6 +1,9 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#include <QApplication> +#include <QTranslator> +#include <QPushButton> //! [0] // Required for using the '_L1' string literal. using namespace Qt::StringLiterals; @@ -21,4 +24,3 @@ int main(int argc, char *argv[]) return app.exec(); } //! [0] - diff --git a/src/corelib/doc/snippets/jni/src_qjniobject.cpp b/src/corelib/doc/snippets/jni/src_qjniobject.cpp index 6e66b51383e..ab1a1b5ca03 100644 --- a/src/corelib/doc/snippets/jni/src_qjniobject.cpp +++ b/src/corelib/doc/snippets/jni/src_qjniobject.cpp @@ -1,5 +1,12 @@ // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#include <QtCore/qglobal.h> +#include <QtCore/qdebug.h> + +#if defined(Q_QDOC) || defined(Q_OS_ANDROID) + +#include <QtCore/qjniobject.h> +#include <QtCore/qjnitypes.h> //! [QJniObject scope] void functionScope() @@ -11,7 +18,8 @@ void functionScope() myJString = string.object<jstring>(); } - // Ops! myJString is no longer valid. + // Ops! myJString is no longer valid. + QString myQtString = QJniObject(myJString).toString(); } //! [QJniObject scope] @@ -45,6 +53,7 @@ void foo() } //! [C++ native methods] +#if 0 // Java code //! [Java native methods] class FooJavaClass { @@ -61,3 +70,6 @@ private static native void callNativeTwo(int x); } //! [Java native methods] +#endif + +#endif diff --git a/src/corelib/doc/snippets/qdir-listfiles/main.cpp b/src/corelib/doc/snippets/qdir-listfiles/main.cpp index 236b32c73d0..d149a72e93a 100644 --- a/src/corelib/doc/snippets/qdir-listfiles/main.cpp +++ b/src/corelib/doc/snippets/qdir-listfiles/main.cpp @@ -4,6 +4,8 @@ //! [0] #include <QDir> #include <iostream> +#include <QCoreApplication> + int main(int argc, char *argv[]) { diff --git a/src/corelib/doc/snippets/code/qlogging/qlogging.cpp b/src/corelib/doc/snippets/qlogging/qlogging.cpp index e61eb70df30..e4c906884f3 100644 --- a/src/corelib/doc/snippets/code/qlogging/qlogging.cpp +++ b/src/corelib/doc/snippets/qlogging/qlogging.cpp @@ -3,7 +3,6 @@ #undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses -#include <QtGui> #include <QtDebug> #include <QQmlComponent> diff --git a/src/corelib/doc/snippets/qmetaobject-invokable/CMakeLists.txt b/src/corelib/doc/snippets/qmetaobject-invokable/CMakeLists.txt new file mode 100644 index 00000000000..76bb79951a3 --- /dev/null +++ b/src/corelib/doc/snippets/qmetaobject-invokable/CMakeLists.txt @@ -0,0 +1,17 @@ +if(NOT QT_FEATURE_widgets) + return() +endif() + +add_library(snippets_qmetaobject-invokable OBJECT) + +target_link_libraries(snippets_qmetaobject-invokable PRIVATE + Qt::Core +) + +qt_internal_extend_target(snippets_qmetaobject-invokable CONDITION QT_FEATURE_widgets + LIBRARIES + Qt::Widgets + SOURCES + main.cpp + window.cpp +) diff --git a/src/corelib/doc/snippets/qmetaobject-revision/CMakeLists.txt b/src/corelib/doc/snippets/qmetaobject-revision/CMakeLists.txt new file mode 100644 index 00000000000..0cadf9380b1 --- /dev/null +++ b/src/corelib/doc/snippets/qmetaobject-revision/CMakeLists.txt @@ -0,0 +1,17 @@ +if(NOT QT_FEATURE_widgets) + return() +endif() + +add_library(snippets_qmetaobject-revision OBJECT) + +target_link_libraries(snippets_qmetaobject-revision PRIVATE + Qt::Core +) + +qt_internal_extend_target(snippets_qmetaobject-revision CONDITION QT_FEATURE_widgets + LIBRARIES + Qt::Widgets + SOURCES + main.cpp + window.cpp +) diff --git a/src/corelib/doc/snippets/qmetatype/registerConverters.cpp b/src/corelib/doc/snippets/qmetatype/registerConverters.cpp index f53d04b7a60..dfe802ae1c2 100644 --- a/src/corelib/doc/snippets/qmetatype/registerConverters.cpp +++ b/src/corelib/doc/snippets/qmetatype/registerConverters.cpp @@ -5,6 +5,8 @@ #include <QMetaType> #include <QString> +using namespace Qt::Literals::StringLiterals; + int main() { //! [member] struct Coordinates { @@ -47,16 +49,22 @@ int main() { struct CustomStringType { const char *data() const {return nullptr;} }; + + struct CustomPointType{ + double x; + double y; + }; + //! [unaryfunc] QMetaType::registerConverter<CustomStringType, QString>([](const CustomStringType &str) { return QString::fromUtf8(str.data()); }); - QMetaType::registerConverter<QJsonValue, QPointF>( - [](const QJsonValue &value) -> std::optional<QPointF> { + QMetaType::registerConverter<QJsonValue, CustomPointType>( + [](const QJsonValue &value) -> std::optional<CustomPointType> { const auto object = value.toObject(); if (!object.contains("x") || !object.contains("y")) return std::nullopt; // The conversion fails if the required properties are missing - return QPointF{object["x"].toDouble(), object["y"].toDouble()}; + return CustomPointType{object["x"].toDouble(), object["y"].toDouble()}; }); //! [unaryfunc] } diff --git a/src/corelib/doc/snippets/qprocess/CMakeLists.txt b/src/corelib/doc/snippets/qprocess/CMakeLists.txt new file mode 100644 index 00000000000..d410d479f7f --- /dev/null +++ b/src/corelib/doc/snippets/qprocess/CMakeLists.txt @@ -0,0 +1,10 @@ +set(CMAKE_UNITY_BUILD OFF) + +add_library(snippets_qprocess OBJECT + qprocess-createprocessargumentsmodifier.cpp + qprocess-simpleexecution.cpp +) + +target_link_libraries(snippets_qprocess PRIVATE + Qt::Core +) diff --git a/src/corelib/doc/snippets/qprocess/qprocess-createprocessargumentsmodifier.cpp b/src/corelib/doc/snippets/qprocess/qprocess-createprocessargumentsmodifier.cpp index b084e99abda..10a89462e03 100644 --- a/src/corelib/doc/snippets/qprocess/qprocess-createprocessargumentsmodifier.cpp +++ b/src/corelib/doc/snippets/qprocess/qprocess-createprocessargumentsmodifier.cpp @@ -1,14 +1,14 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include <QCoreApplication> #include <QProcess> -#include <qt_windows.h> +#include <QtCore/qglobal.h> + +#ifdef Q_OS_WIN +#include <QtCore/qt_windows.h> int main(int argc, char *argv[]) { - QCoreApplication app(argc, argv); - //! [0] QProcess process; process.setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args) @@ -21,6 +21,5 @@ int main(int argc, char *argv[]) }); process.start("C:\\Windows\\System32\\cmd.exe", QStringList() << "/k" << "title" << "The Child Process"); //! [0] - - return app.exec(); } +#endif diff --git a/src/corelib/doc/snippets/qprocess/qprocess-simpleexecution.cpp b/src/corelib/doc/snippets/qprocess/qprocess-simpleexecution.cpp index 0715108754d..be8efee5e13 100644 --- a/src/corelib/doc/snippets/qprocess/qprocess-simpleexecution.cpp +++ b/src/corelib/doc/snippets/qprocess/qprocess-simpleexecution.cpp @@ -1,16 +1,15 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include <QApplication> -#include <QtGui> +#include <QtCore> int main(int argc, char *argv[]) { - QApplication app(argc, argv); + Q_UNUSED(argc) + Q_UNUSED(argv) //! [0] - QObject *parent; + QObject *parent = new QObject; //! [0] - parent = &app; //! [1] QString program = "./path/to/Qt/examples/widgets/analogclock"; @@ -24,6 +23,4 @@ int main(int argc, char *argv[]) QProcess *myProcess = new QProcess(parent); myProcess->start(program, arguments); //! [2] - - return app.exec(); } diff --git a/src/corelib/doc/snippets/qsignalmapper/CMakeLists.txt b/src/corelib/doc/snippets/qsignalmapper/CMakeLists.txt new file mode 100644 index 00000000000..086ddbf9c5e --- /dev/null +++ b/src/corelib/doc/snippets/qsignalmapper/CMakeLists.txt @@ -0,0 +1,18 @@ +if(NOT TARGET Qt::Widgets) + return() +endif() + +add_library(snippets_qsignalmapper OBJECT + buttonwidget.cpp +) + +add_compile_definitions(EXAMPLE_ONE) + +target_link_libraries(snippets_qsignalmapper PRIVATE + Qt::Core +) + +qt_internal_extend_target(snippets_qsignalmapper CONDITION QT_FEATURE_widgets + LIBRARIES + Qt::Widgets +) diff --git a/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp b/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp index e2e97fa11c0..1f9e53f1385 100644 --- a/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp +++ b/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp @@ -5,6 +5,7 @@ #include <QtWidgets> +#ifdef EXAMPLE_ONE //! [0] ButtonWidget::ButtonWidget(const QStringList &texts, QWidget *parent) : QWidget(parent) @@ -25,7 +26,7 @@ ButtonWidget::ButtonWidget(const QStringList &texts, QWidget *parent) this, &ButtonWidget::clicked); } //! [2] - +#else //! [3] ButtonWidget::ButtonWidget(const QStringList &texts, QWidget *parent) : QWidget(parent) @@ -39,3 +40,4 @@ ButtonWidget::ButtonWidget(const QStringList &texts, QWidget *parent) } } //! [3] +#endif diff --git a/src/corelib/doc/snippets/qsortfilterproxymodel-details/main.cpp b/src/corelib/doc/snippets/qsortfilterproxymodel-details/main.cpp index 962bece2076..52b5749ac0a 100644 --- a/src/corelib/doc/snippets/qsortfilterproxymodel-details/main.cpp +++ b/src/corelib/doc/snippets/qsortfilterproxymodel-details/main.cpp @@ -4,6 +4,8 @@ #include <QtGui> #include <QApplication> #include <QSortFilterProxyModel> +#include <QWidget> +#include <QTreeView> class MyItemModel : public QStandardItemModel { @@ -47,15 +49,7 @@ Widget::Widget(QWidget *parent) //! [4] proxyModel->sort(2, Qt::AscendingOrder); //! [4] //! [5] - proxyModel->setFilterRegularExpression(QRegularExpression("\.png", QRegularExpression::CaseInsensitiveOption)); + proxyModel->setFilterRegularExpression(QRegularExpression("\\.png", QRegularExpression::CaseInsensitiveOption)); proxyModel->setFilterKeyColumn(1); //! [5] } - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - Widget widget; - widget.show(); - return app.exec(); -} diff --git a/src/corelib/doc/snippets/qstack/main.cpp b/src/corelib/doc/snippets/qstack/main.cpp index f1f8e6a0fda..1380dbaf9f1 100644 --- a/src/corelib/doc/snippets/qstack/main.cpp +++ b/src/corelib/doc/snippets/qstack/main.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include <QtGui> +#include <QtCore> #include <iostream> using namespace std; diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp index 578c7ae53aa..736ce52b256 100644 --- a/src/corelib/doc/snippets/qstring/main.cpp +++ b/src/corelib/doc/snippets/qstring/main.cpp @@ -2,9 +2,11 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include <QtGui> -#include <QApplication> +#include <QWidget> #include <stdio.h> +using namespace Qt::Literals::StringLiterals; + class Widget : public QWidget { public: @@ -95,7 +97,7 @@ void Widget::constCharPointer() void Widget::constCharArray() { //! [1] - static const QChar data[4] = { 0x0055, 0x006e, 0x10e3, 0x03a3 }; + static const QChar data[4] = {QChar(0x0055), QChar(0x006e), QChar(0x10e3), QChar(0x03a3) }; QString str(data, 4); //! [1] } @@ -285,9 +287,9 @@ void Widget::compareSensitiveFunction() //! [16] //! [QtPrivate::compareStrings-QSV-QSV] - int x = QtPrivate::compareStrings(u"aUtO", u"AuTo", Qt::CaseInsensitive); // x == 0 - int y = QtPrivate::compareStrings(u"auto", u"Car", Qt::CaseSensitive); // y > 0 - int z = QtPrivate::compareStrings(u"auto", u"Car", Qt::CaseInsensitive); // z < 0 + int a = QtPrivate::compareStrings(u"aUtO", u"AuTo", Qt::CaseInsensitive); // a == 0 + int b = QtPrivate::compareStrings(u"auto", u"Car", Qt::CaseSensitive); // b > 0 + int c = QtPrivate::compareStrings(u"auto", u"Car", Qt::CaseInsensitive); // c < 0 //! [QtPrivate::compareStrings-QSV-QSV] } @@ -349,7 +351,7 @@ void Widget::fromRawDataFunction() 0x1009, 0x0020, 0x0020}; QString str = QString::fromRawData(unicode, std::size(unicode)); - if (str.contains(pattern) { + if (str.contains(pattern)) { // ... //! [22] //! [23] } @@ -374,7 +376,6 @@ void Widget::firstIndexOfFunction() QString str = "the minimum"; str.indexOf(QRegularExpression("m[aeiou]"), 0); // returns 4 - QString str = "the minimum"; QRegularExpressionMatch match; str.indexOf(QRegularExpression("m[aeiou]"), 0, &match); // returns 4 // match.captured() == mi @@ -424,7 +425,6 @@ void Widget::lastIndexOfFunction() QString str = "the minimum"; str.lastIndexOf(QRegularExpression("m[aeiou]")); // returns 8 - QString str = "the minimum"; QRegularExpressionMatch match; str.lastIndexOf(QRegularExpression("m[aeiou]"), -1, &match); // returns 8 // match.captured() == mu @@ -565,7 +565,7 @@ void Widget::resizeFunction() //! [46] QString t = "Hello"; - r.resize(t.size() + 10, 'X'); + t.resize(t.size() + 10, 'X'); // t == "HelloXXXXXXXXXX" //! [46] @@ -685,6 +685,7 @@ void Widget::splitFunction() void Widget::splitCaseSensitiveFunction() { + { //! [62] QString str = QStringLiteral("a,,b,c"); @@ -694,18 +695,23 @@ void Widget::splitCaseSensitiveFunction() QStringList list2 = str.split(u',', Qt::SkipEmptyParts); // list2: [ "a", "b", "c" ] //! [62] + } + { //! [62-empty] QString str = "abc"; auto parts = str.split(QString()); // parts: {"", "a", "b", "c", ""} //! [62-empty] + } + { //! [62-slashes] QString str = "/a/b/c/"; auto parts = str.split(u'/'); // parts: {"", "a", "b", "c", ""} //! [62-slashes] + } } void Widget::sprintfFunction() @@ -917,12 +923,3 @@ void Widget::sliceFunction() x.slice(4, 3); // x == "app" //! [slice97] } - - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - Widget widget; - widget.show(); - return app.exec(); -} diff --git a/src/corelib/doc/snippets/qstringlist/main.cpp b/src/corelib/doc/snippets/qstringlist/main.cpp index 1791faf5116..9e9e0441457 100644 --- a/src/corelib/doc/snippets/qstringlist/main.cpp +++ b/src/corelib/doc/snippets/qstringlist/main.cpp @@ -1,19 +1,12 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include <QtGui> -#include <iostream> +#include <QtCore> + using namespace std; using namespace Qt::StringLiterals; -class Widget : public QWidget -{ -public: - Widget(QWidget *parent = nullptr); -}; - -Widget::Widget(QWidget *parent) - : QWidget(parent) +void examples() { //! [0a] QStringList fonts = { "Arial", "Helvetica", "Times" }; @@ -110,11 +103,3 @@ Widget::Widget(QWidget *parent) //! [19] } } - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - Widget widget; - widget.show(); - return app.exec(); -} diff --git a/src/corelib/doc/snippets/qstringlistmodel/main.cpp b/src/corelib/doc/snippets/qstringlistmodel/main.cpp index b0d14e110e8..aba81619af2 100644 --- a/src/corelib/doc/snippets/qstringlistmodel/main.cpp +++ b/src/corelib/doc/snippets/qstringlistmodel/main.cpp @@ -1,16 +1,9 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include <QtGui> +#include <QtCore> -class Widget : public QWidget -{ -public: - Widget(QWidget *parent = nullptr); -}; - -Widget::Widget(QWidget *parent) - : QWidget(parent) +void example() { //! [0] QStringListModel *model = new QStringListModel(); @@ -19,11 +12,3 @@ Widget::Widget(QWidget *parent) model->setStringList(list); //! [0] } - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - Widget widget; - widget.show(); - return app.exec(); -} diff --git a/src/corelib/doc/snippets/qtcast/qtcast.cpp b/src/corelib/doc/snippets/qtcast/qtcast.cpp index 177446aff9c..cf7f722c30f 100644 --- a/src/corelib/doc/snippets/qtcast/qtcast.cpp +++ b/src/corelib/doc/snippets/qtcast/qtcast.cpp @@ -23,7 +23,7 @@ MyWidget::MyWidget() //! [3] QLabel *label = qobject_cast<QLabel *>(obj); //! [3] //! [4] - // label is 0 + // label is nullptr //! [4] //! [5] @@ -35,8 +35,3 @@ MyWidget::MyWidget() } //! [6] } - -int main() -{ - return 0; -} diff --git a/src/corelib/doc/snippets/qtcast/qtcast.h b/src/corelib/doc/snippets/qtcast/qtcast.h new file mode 100644 index 00000000000..faee1cdc09f --- /dev/null +++ b/src/corelib/doc/snippets/qtcast/qtcast.h @@ -0,0 +1,17 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef QTCAST_H +#define QTCAST_H + +#include <QWidget> + +class MyWidget : public QWidget +{ + Q_OBJECT + +public: + MyWidget(); +}; + +#endif diff --git a/src/corelib/doc/snippets/qversionnumber/main.cpp b/src/corelib/doc/snippets/qversionnumber/main.cpp index b78e14edf15..5897da54aae 100644 --- a/src/corelib/doc/snippets/qversionnumber/main.cpp +++ b/src/corelib/doc/snippets/qversionnumber/main.cpp @@ -39,16 +39,8 @@ void Object::isPrefixOf() //! [2] } -void QObject::parse() +void Object::parse() { - //! [3] - QString string("5.4.0-alpha"); - qsizetype suffixIndex; - QVersionNumber version = QVersionNumber::fromString(string, &suffixIndex); - // version is 5.4.0 - // suffixIndex is 5 - //! [3] - //! [3-latin1-1] QLatin1StringView string("5.4.0-alpha"); qsizetype suffixIndex; @@ -69,12 +61,3 @@ void Object::equivalent() // equal is false //! [4] } - -int main() -{ - Object::genericExample(); - Object::equalityExample(); - Object::isPrefixOf(); - Object::parse(); - Object::equivalent(); -} diff --git a/src/corelib/doc/snippets/settings/settings.cpp b/src/corelib/doc/snippets/settings/settings.cpp index c73b42b2a43..6f52e83fb2a 100644 --- a/src/corelib/doc/snippets/settings/settings.cpp +++ b/src/corelib/doc/snippets/settings/settings.cpp @@ -3,9 +3,6 @@ #include <QtGui> -QWidget *win; -QWidget *panel; - void snippet_ctor1() { //! [0] @@ -37,6 +34,16 @@ void snippet_ctor2() int margin = settings.value("editor/wrapMargin", 80).toInt(); //! [7] } +} + +#if __has_include(<QWidget>) +#include <QWidget> + +void snippet_ctor_widgets() +{ + QWidget *win; + QWidget *panel; + QSettings settings; //! [8] settings.setValue("mainwindow/size", win->size()); @@ -59,6 +66,7 @@ void snippet_ctor2() settings.endGroup(); //! [12] } +#endif void snippet_locations() { @@ -87,6 +95,9 @@ void snippet_locations() } } +#if __has_include(<QWidget>) +#include <QMainWindow> + class MainWindow : public QMainWindow { public: @@ -120,7 +131,7 @@ void MainWindow::readSettings() if (geometry.isEmpty()) setGeometry(200, 200, 400, 400); else - restoreGeometry(geometry) + restoreGeometry(geometry); settings.endGroup(); } //! [17] @@ -147,3 +158,4 @@ void MainWindow::closeEvent(QCloseEvent *event) } } //! [21] +#endif diff --git a/src/corelib/doc/src/cmake/qt_add_resources.qdoc b/src/corelib/doc/src/cmake/qt_add_resources.qdoc index 570272c6097..445e37e000a 100644 --- a/src/corelib/doc/src/cmake/qt_add_resources.qdoc +++ b/src/corelib/doc/src/cmake/qt_add_resources.qdoc @@ -111,5 +111,9 @@ resources linked into the final target. This especially affects static builds. There, the same resource name in different static libraries conflict in the consuming target. +In contrast to \l{qmake}'s \c{RESOURCES}, \c qt_add_resources does not +attempt to compile any QML or JavaScript files using \l{qmlcachegen}. Use +\l{qt_add_qml_module} for this. + \sa {qt6_add_big_resources}{qt_add_big_resources()} */ diff --git a/src/corelib/doc/src/qt6-changes.qdoc b/src/corelib/doc/src/qt6-changes.qdoc index 011568ef750..2c76f6b57c6 100644 --- a/src/corelib/doc/src/qt6-changes.qdoc +++ b/src/corelib/doc/src/qt6-changes.qdoc @@ -631,4 +631,10 @@ PUBLIC_LIBRARIES Qt::Core5Compat \endcode + + \section2 QTextStream + + Removed QTextStream::setCodec(). + Use QTextStream::setEncoding() with the new Encoding enum instead. + */ diff --git a/src/corelib/global/qflags.qdoc b/src/corelib/global/qflags.qdoc index 9d5fa181b20..5f7e68cdcff 100644 --- a/src/corelib/global/qflags.qdoc +++ b/src/corelib/global/qflags.qdoc @@ -471,8 +471,10 @@ \macro Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \relates QFlags - The Q_DECLARE_OPERATORS_FOR_FLAGS() macro declares global \c - operator|() functions for \a Flags, which is of type QFlags<T>. + The Q_DECLARE_OPERATORS_FOR_FLAGS() macro declares global + bitwise operator functions \c operator|(), \c operator&(), + \c operator^(), \c operator~() and their assignment forms: + &=, |=, and ^=. for \a Flags, which is of type QFlags<T>. See the QFlags documentation for details. diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 1ecec63aed4..d1fc672564f 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2021 The Qt Company Ltd. // Copyright (C) 2021 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:execute-external-code #include "qdir.h" #include "qstringlist.h" diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 8373f63b86c..55dadf4d6f9 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -379,7 +379,7 @@ using namespace QtPrivate; One example of direct use is to forward errors that stem from a scripting language, e.g. QML: - \snippet code/qlogging/qlogging.cpp 1 + \snippet qlogging/qlogging.cpp 1 \sa QMessageLogContext, qDebug(), qInfo(), qWarning(), qCritical(), qFatal() */ @@ -449,7 +449,7 @@ void QMessageLogger::info(const char *msg, ...) const This is a typedef for a pointer to a function with the following signature: - \snippet code/qlogging/qlogging.cpp 2 + \snippet qlogging/qlogging.cpp 2 The \c Q_DECLARE_LOGGING_CATEGORY macro generates a function declaration with this signature, and \c Q_LOGGING_CATEGORY generates its definition. diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp index 16b2b7ca408..8b153bcdb84 100644 --- a/src/corelib/global/qnumeric.cpp +++ b/src/corelib/global/qnumeric.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2019 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qnumeric.h" #include "qnumeric_p.h" diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h index 2c7110c97a6..bc2bbf9e53e 100644 --- a/src/corelib/global/qnumeric.h +++ b/src/corelib/global/qnumeric.h @@ -1,6 +1,7 @@ // Copyright (C) 2021 The Qt Company Ltd. // Copyright (C) 2025 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QNUMERIC_H #define QNUMERIC_H diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index fd742898f81..dab903f51fb 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2021 Intel Corporation. // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:cryptography // for rand_s #define _CRT_RAND_S diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index 5ac864e79ef..30599413d75 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -1,5 +1,6 @@ // Copyright (C) 2020 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:cryptography #ifndef QRANDOM_H #define QRANDOM_H diff --git a/src/corelib/global/qtclasshelper_p.h b/src/corelib/global/qtclasshelper_p.h new file mode 100644 index 00000000000..1e356726126 --- /dev/null +++ b/src/corelib/global/qtclasshelper_p.h @@ -0,0 +1,77 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default + +#ifndef QTCLASSHELPER_P_H +#define QTCLASSHELPER_P_H + +#include <QtCore/private/qglobal_p.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <type_traits> +#include <utility> + +QT_BEGIN_NAMESPACE + +/* + Helper for setters overloaded on lvalue/rvalue. If the setter is doing a + lot of work around the actual assignment, a common pattern is to create a + private helper method + + void doSetFoo(const Foo &lvalue, Foo *rvalue); + + and implement the two setters inline by calling that function: + + void setFoo(const Foo &f) { doSetFoo(f, nullptr); } + void setFoo(Foo &&f) { doSetFoo(f, &f); } + + Then, in doSetFoo(), when assigning the argument to the member, use this + function: + + q_choose_assign(m_foo, lvalue, rvalue); + + or, when appending to a container, + + q_choose_append(m_container, lvalue, rvalue); + + The functions mandate (in the C++ sense) that all arguments are the same + type, so they deduce each argument separately and then static_assert that + they're the same. If we need std::exchange()-like mixed types later, it's + easy to relax. For now, avoid being overly general. +*/ +template <typename T, typename U, typename V> +decltype(auto) q_choose_assign(T &var, const U &lvalue, V *rvalue) +{ + static_assert(std::is_same_v<T, U>, "all arguments must be of the same type"); + static_assert(std::is_same_v<U, V>, "all arguments must be of the same type"); + if (rvalue) + return var = std::move(*rvalue); + else + return var = lvalue; +} + +template <typename Container, typename U, typename V> +decltype(auto) q_choose_append(Container &c, const U &lvalue, V *rvalue) +{ + static_assert(std::is_same_v<typename Container::value_type, U>, "arguments must match container"); + static_assert(std::is_same_v<U, V>, "all arguments must be of the same type"); + if (rvalue) + c.push_back(std::move(*rvalue)); + else + c.push_back(lvalue); + return c.back(); +} + +QT_END_NAMESPACE + +#endif // QTCLASSHELPER_P_H diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp index 4ee29daa7a9..e95b1ae40b2 100644 --- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "private/qabstractfileengine_p.h" #include "private/qfsfileengine_p.h" diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp index 16abac48886..f7984409a0e 100644 --- a/src/corelib/io/qbuffer.cpp +++ b/src/corelib/io/qbuffer.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qbuffer.h" #include <QtCore/qmetaobject.h> diff --git a/src/corelib/io/qbuffer.h b/src/corelib/io/qbuffer.h index 4cbbfe7c52d..8dc36d92310 100644 --- a/src/corelib/io/qbuffer.h +++ b/src/corelib/io/qbuffer.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QBUFFER_H #define QBUFFER_H diff --git a/src/corelib/io/qdirentryinfo_p.h b/src/corelib/io/qdirentryinfo_p.h index 7ed5391ff04..8864255c425 100644 --- a/src/corelib/io/qdirentryinfo_p.h +++ b/src/corelib/io/qdirentryinfo_p.h @@ -148,7 +148,7 @@ private: QFileSystemEntry entry; QFileSystemMetaData metaData; - std::optional<QFileInfo> fileInfoOpt; + std::optional<QFileInfo> fileInfoOpt = std::nullopt; }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp index 3ce75bd3237..ee6a1859658 100644 --- a/src/corelib/io/qfiledevice.cpp +++ b/src/corelib/io/qfiledevice.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:trivial-parsing-only #include "qplatformdefs.h" #include "qfiledevice.h" diff --git a/src/corelib/io/qfiledevice.h b/src/corelib/io/qfiledevice.h index 52740257154..18ecd035122 100644 --- a/src/corelib/io/qfiledevice.h +++ b/src/corelib/io/qfiledevice.h @@ -1,5 +1,6 @@ // Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILEDEVICE_H #define QFILEDEVICE_H diff --git a/src/corelib/io/qfiledevice_p.h b/src/corelib/io/qfiledevice_p.h index b66e15db624..51df8966bff 100644 --- a/src/corelib/io/qfiledevice_p.h +++ b/src/corelib/io/qfiledevice_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILEDEVICE_P_H #define QFILEDEVICE_P_H diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 6f995fe082e..5a0be1d895e 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -893,6 +893,12 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM { Q_CHECK_FILE_NAME(entry, false); + // Detection of WasDeletedAttribute is imperfect: in general, if we can + // successfully stat() or access() a file, it hasn't been deleted (though + // there are exceptions, like /proc/XXX/fd/ entries on Linux). So we have + // to restore this flag in case we fail to stat() anything. + auto hadBeenDeleted = data.entryFlags & QFileSystemMetaData::WasDeletedAttribute; + #if defined(Q_OS_DARWIN) if (what & (QFileSystemMetaData::BundleType | QFileSystemMetaData::CaseSensitive)) { if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) @@ -1103,6 +1109,11 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM if (entryErrno != 0) { what &= ~QFileSystemMetaData::LinkType; // don't clear link: could be broken symlink data.clearFlags(what); + + // see comment at the top + data.entryFlags |= hadBeenDeleted; + data.knownFlagsMask |= hadBeenDeleted; + return false; } return true; diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index ac1691d30e8..8012a3b8c8b 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qfilesystementry_p.h" diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 8b5d506b0b2..615645ae90d 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILESYSTEMENTRY_P_H #define QFILESYSTEMENTRY_P_H diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index 064be4c2112..cd72f21acdf 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qfilesystemwatcher.h" #include "qfilesystemwatcher_p.h" diff --git a/src/corelib/io/qfilesystemwatcher.h b/src/corelib/io/qfilesystemwatcher.h index 668bc143b20..9523945435e 100644 --- a/src/corelib/io/qfilesystemwatcher.h +++ b/src/corelib/io/qfilesystemwatcher.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILESYSTEMWATCHER_H #define QFILESYSTEMWATCHER_H diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm index 0d9b84890ae..0f49d43bc02 100644 --- a/src/corelib/io/qfilesystemwatcher_fsevents.mm +++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include <qplatformdefs.h> diff --git a/src/corelib/io/qfilesystemwatcher_fsevents_p.h b/src/corelib/io/qfilesystemwatcher_fsevents_p.h index d6ce176a30f..2fc95a99931 100644 --- a/src/corelib/io/qfilesystemwatcher_fsevents_p.h +++ b/src/corelib/io/qfilesystemwatcher_fsevents_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILESYSTEMWATCHER_FSEVENTS_P_H #define QFILESYSTEMWATCHER_FSEVENTS_P_H diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index e60f6881109..4971b41c102 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qfilesystemwatcher.h" #include "qfilesystemwatcher_inotify_p.h" diff --git a/src/corelib/io/qfilesystemwatcher_inotify_p.h b/src/corelib/io/qfilesystemwatcher_inotify_p.h index 05f87df14c1..705fe71725a 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify_p.h +++ b/src/corelib/io/qfilesystemwatcher_inotify_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILESYSTEMWATCHER_INOTIFY_P_H #define QFILESYSTEMWATCHER_INOTIFY_P_H diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 7a9be337bf8..bc331c9dd2a 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include <qplatformdefs.h> diff --git a/src/corelib/io/qfilesystemwatcher_kqueue_p.h b/src/corelib/io/qfilesystemwatcher_kqueue_p.h index 05844d5be95..a460da6882e 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue_p.h +++ b/src/corelib/io/qfilesystemwatcher_kqueue_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILESYSTEMWATCHER_KQUEUE_P_H #define QFILESYSTEMWATCHER_KQUEUE_P_H diff --git a/src/corelib/io/qfilesystemwatcher_p.h b/src/corelib/io/qfilesystemwatcher_p.h index c34e3e2408f..79cf7443e37 100644 --- a/src/corelib/io/qfilesystemwatcher_p.h +++ b/src/corelib/io/qfilesystemwatcher_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILESYSTEMWATCHER_P_H #define QFILESYSTEMWATCHER_P_H diff --git a/src/corelib/io/qfilesystemwatcher_polling.cpp b/src/corelib/io/qfilesystemwatcher_polling.cpp index 5ec13a77f6c..ea374141563 100644 --- a/src/corelib/io/qfilesystemwatcher_polling.cpp +++ b/src/corelib/io/qfilesystemwatcher_polling.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qfilesystemwatcher_polling_p.h" diff --git a/src/corelib/io/qfilesystemwatcher_polling_p.h b/src/corelib/io/qfilesystemwatcher_polling_p.h index 80d7b7d1526..2ace2947be4 100644 --- a/src/corelib/io/qfilesystemwatcher_polling_p.h +++ b/src/corelib/io/qfilesystemwatcher_polling_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILESYSTEMWATCHER_POLLING_P_H #define QFILESYSTEMWATCHER_POLLING_P_H diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp index 5418265ba2c..3a2cb02c3d7 100644 --- a/src/corelib/io/qfilesystemwatcher_win.cpp +++ b/src/corelib/io/qfilesystemwatcher_win.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qfilesystemwatcher.h" #include "qfilesystemwatcher_win_p.h" diff --git a/src/corelib/io/qfilesystemwatcher_win_p.h b/src/corelib/io/qfilesystemwatcher_win_p.h index f6c6fd6c923..0687080b0ed 100644 --- a/src/corelib/io/qfilesystemwatcher_win_p.h +++ b/src/corelib/io/qfilesystemwatcher_win_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFILESYSTEMWATCHER_WIN_P_H #define QFILESYSTEMWATCHER_WIN_P_H diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index c45b7a58acd..acb9675c2de 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qfsfileengine_p.h" #include "qfsfileengine_iterator_p.h" diff --git a/src/corelib/io/qfsfileengine_iterator.cpp b/src/corelib/io/qfsfileengine_iterator.cpp index bdb2ecdafe7..409963724e5 100644 --- a/src/corelib/io/qfsfileengine_iterator.cpp +++ b/src/corelib/io/qfsfileengine_iterator.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qfsfileengine_iterator_p.h" #include "qfileinfo_p.h" diff --git a/src/corelib/io/qfsfileengine_iterator_p.h b/src/corelib/io/qfsfileengine_iterator_p.h index f3ffc336844..78c4b509666 100644 --- a/src/corelib/io/qfsfileengine_iterator_p.h +++ b/src/corelib/io/qfsfileengine_iterator_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFSFILEENGINE_ITERATOR_P_H #define QFSFILEENGINE_ITERATOR_P_H diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 837ec55b93a..d002fefa181 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QFSFILEENGINE_P_H #define QFSFILEENGINE_P_H diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index ec0ae9c8b11..abf5a0c7db4 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qplatformdefs.h" #include "private/qabstractfileengine_p.h" diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index c436d4cd26b..1575a2ec5bc 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qplatformdefs.h" #include "private/qabstractfileengine_p.h" diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 585a07158ea..9c1bb45dd2d 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:network-protocol //#define QIODEVICE_DEBUG @@ -1308,8 +1309,11 @@ QByteArray QIODevice::readAll() The newline character ('\\n') is included in the buffer. If a newline is not encountered before maxSize - 1 bytes are read, a - newline will not be inserted into the buffer. On windows newline - characters are replaced with '\\n'. + newline will not be inserted into the buffer. + + \note Newline translation(e.g., converting \r to \n) is performed + only when the device is opened for reading with QIODevice::Text + flag. Note that on sequential devices, data may not be immediately available, which may result in a partial line being returned. By calling the diff --git a/src/corelib/io/qiodevice.h b/src/corelib/io/qiodevice.h index 6bf7149e9af..263214ff012 100644 --- a/src/corelib/io/qiodevice.h +++ b/src/corelib/io/qiodevice.h @@ -1,5 +1,6 @@ // Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:header-decls-only #ifndef QIODEVICE_H #define QIODEVICE_H diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h index 151548fb04e..6a1a91e1dea 100644 --- a/src/corelib/io/qiodevice_p.h +++ b/src/corelib/io/qiodevice_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:network-protocol #ifndef QIODEVICE_P_H #define QIODEVICE_P_H diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index a15549217a0..fef20455732 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -2,6 +2,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2017 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qlockfile.h" #include "qlockfile_p.h" @@ -12,6 +13,13 @@ #include <QtCore/qdatetime.h> #include <QtCore/qfileinfo.h> +#include <qplatformdefs.h> + +#ifdef Q_OS_WIN +#include <io.h> +#include <qt_windows.h> +#endif + QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; @@ -126,6 +134,8 @@ QString QLockFile::fileName() const } /*! + \fn void QLockFile::setStaleLockTime(int staleLockTime) + Sets \a staleLockTime to be the time in milliseconds after which a lock file is considered stale. The default value is 30000, i.e. 30 seconds. @@ -146,10 +156,6 @@ QString QLockFile::fileName() const \sa staleLockTime() */ -void QLockFile::setStaleLockTime(int staleLockTime) -{ - setStaleLockTime(std::chrono::milliseconds{staleLockTime}); -} /*! \since 6.2 @@ -176,15 +182,13 @@ void QLockFile::setStaleLockTime(std::chrono::milliseconds staleLockTime) } /*! + \fn int QLockFile::staleLockTime() const + Returns the time in milliseconds after which a lock file is considered stale. \sa setStaleLockTime() */ -int QLockFile::staleLockTime() const -{ - return int(staleLockTimeAsDuration().count()); -} /*! \fn std::chrono::milliseconds QLockFile::staleLockTimeAsDuration() const \overload @@ -234,6 +238,8 @@ bool QLockFile::lock() } /*! + \fn bool QLockFile::tryLock(int timeout) + Attempts to create the lock file. This function returns \c true if the lock was obtained; otherwise it returns \c false. If another process (or another thread) has created the lock file already, this function will @@ -253,10 +259,6 @@ bool QLockFile::lock() \sa lock(), unlock() */ -bool QLockFile::tryLock(int timeout) -{ - return tryLock(std::chrono::milliseconds{ timeout }); -} /*! \overload @@ -374,6 +376,19 @@ bool QLockFile::getLockInfo(qint64 *pid, QString *hostname, QString *appname) co return true; } +QLockFilePrivate::QLockFilePrivate(const QString &fn) + : fileName(fn), +#ifdef Q_OS_WIN + fileHandle(INVALID_HANDLE_VALUE) +#else + fileHandle(-1) +#endif +{ +} + +QLockFilePrivate::~QLockFilePrivate() + = default; + QByteArray QLockFilePrivate::lockFileContents() const { // Use operator% from the fast builder to avoid multiple memory allocations. @@ -443,6 +458,19 @@ bool QLockFilePrivate::isApparentlyStale() const return staleLockTime > 0ms && abs(age) > staleLockTime; } +int QLockFilePrivate::getLockFileHandle(QLockFile *f) +{ + int fd; +#ifdef Q_OS_WIN + // Use of this function on Windows WILL leak a file descriptor. + fd = _open_osfhandle(intptr_t(f->d_func()->fileHandle), 0); +#else + fd = f->d_func()->fileHandle; +#endif + QT_LSEEK(fd, 0, SEEK_SET); + return fd; +} + /*! Attempts to forcefully remove an existing lock file. diff --git a/src/corelib/io/qlockfile.h b/src/corelib/io/qlockfile.h index af481ab59b0..29611e679d5 100644 --- a/src/corelib/io/qlockfile.h +++ b/src/corelib/io/qlockfile.h @@ -1,5 +1,6 @@ // Copyright (C) 2013 David Faure <faure+bluesystems@kde.org> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QLOCKFILE_H #define QLOCKFILE_H @@ -8,6 +9,7 @@ #include <QtCore/qscopedpointer.h> #include <chrono> +#include <memory> QT_BEGIN_NAMESPACE @@ -16,16 +18,19 @@ class QLockFilePrivate; class Q_CORE_EXPORT QLockFile { public: - QLockFile(const QString &fileName); + explicit QLockFile(const QString &fileName); ~QLockFile(); QString fileName() const; bool lock(); + QT_CORE_INLINE_SINCE(6, 10) bool tryLock(int timeout); void unlock(); + QT_CORE_INLINE_SINCE(6, 10) void setStaleLockTime(int); + QT_CORE_INLINE_SINCE(6, 10) int staleLockTime() const; bool tryLock(std::chrono::milliseconds timeout = std::chrono::milliseconds::zero()); @@ -45,14 +50,30 @@ public: }; LockError error() const; -protected: - QScopedPointer<QLockFilePrivate> d_ptr; - private: + std::unique_ptr<QLockFilePrivate> d_ptr; + Q_DECLARE_PRIVATE(QLockFile) Q_DISABLE_COPY(QLockFile) }; +#if QT_CORE_INLINE_IMPL_SINCE(6, 10) +bool QLockFile::tryLock(int timeout) +{ + return tryLock(std::chrono::milliseconds{timeout}); +} + +void QLockFile::setStaleLockTime(int staleLockTime) +{ + setStaleLockTime(std::chrono::milliseconds{staleLockTime}); +} + +int QLockFile::staleLockTime() const +{ + return int(staleLockTimeAsDuration().count()); +} +#endif // QT_CORE_INLINE_IMPL_SINCE(6, 10) + QT_END_NAMESPACE #endif // QLOCKFILE_H diff --git a/src/corelib/io/qlockfile_p.h b/src/corelib/io/qlockfile_p.h index 299b13b21a2..8758adfb71e 100644 --- a/src/corelib/io/qlockfile_p.h +++ b/src/corelib/io/qlockfile_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2013 David Faure <faure+bluesystems@kde.org> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QLOCKFILE_P_H #define QLOCKFILE_P_H @@ -19,22 +20,14 @@ #include <QtCore/qlockfile.h> #include <QtCore/qfile.h> -#include <qplatformdefs.h> - -#ifdef Q_OS_WIN -#include <io.h> -#include <qt_windows.h> -#endif - QT_BEGIN_NAMESPACE class QLockFilePrivate { public: - QLockFilePrivate(const QString &fn) - : fileName(fn) - { - } + explicit QLockFilePrivate(const QString &fn); + ~QLockFilePrivate(); + QLockFile::LockError tryLock_sys(); bool removeStaleLock(); QByteArray lockFileContents() const; @@ -49,27 +42,17 @@ public: QString fileName; #ifdef Q_OS_WIN - Qt::HANDLE fileHandle = INVALID_HANDLE_VALUE; + Qt::HANDLE fileHandle; #else - int fileHandle = -1; + int fileHandle; #endif std::chrono::milliseconds staleLockTime = std::chrono::seconds{30}; QLockFile::LockError lockError = QLockFile::NoError; bool isLocked = false; - static int getLockFileHandle(QLockFile *f) - { - int fd; -#ifdef Q_OS_WIN - // Use of this function on Windows WILL leak a file descriptor. - fd = _open_osfhandle(intptr_t(f->d_func()->fileHandle), 0); -#else - fd = f->d_func()->fileHandle; -#endif - QT_LSEEK(fd, 0, SEEK_SET); - return fd; - } + // used in tst_QLockFile: + Q_CORE_EXPORT static int getLockFileHandle(QLockFile *f); }; QT_END_NAMESPACE diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index 7565297496a..5704f65af37 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -2,6 +2,7 @@ // Copyright (C) 2017 Intel Corporation. // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "private/qlockfile_p.h" diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index b9d7721517f..fe9c54e4e07 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -2,6 +2,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2017 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "private/qlockfile_p.h" #include "private/qfilesystementry_p.h" diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 4ce2bf0c091..bb4d7e26725 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qloggingcategory.h" #include "qloggingcategory_p.h" diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h index 5a4ecf59e33..16e271e7f9e 100644 --- a/src/corelib/io/qloggingcategory.h +++ b/src/corelib/io/qloggingcategory.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QLOGGINGCATEGORY_H #define QLOGGINGCATEGORY_H diff --git a/src/corelib/io/qloggingcategory_p.h b/src/corelib/io/qloggingcategory_p.h index 46da266db0a..408ce862150 100644 --- a/src/corelib/io/qloggingcategory_p.h +++ b/src/corelib/io/qloggingcategory_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2025 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QLOGGINGCATEGORY_P_H #define QLOGGINGCATEGORY_P_H diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index 8279e1a3a27..e6e710377b8 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qloggingregistry_p.h" diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h index 1a6a7787df1..2d1301d668a 100644 --- a/src/corelib/io/qloggingregistry_p.h +++ b/src/corelib/io/qloggingregistry_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QLOGGINGREGISTRY_P_H #define QLOGGINGREGISTRY_P_H diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp index db286c763e3..ecd26d85bbd 100644 --- a/src/corelib/io/qnoncontiguousbytedevice.cpp +++ b/src/corelib/io/qnoncontiguousbytedevice.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qnoncontiguousbytedevice_p.h" #include <qbuffer.h> diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h index 3aa74290de3..31ed9857892 100644 --- a/src/corelib/io/qnoncontiguousbytedevice_p.h +++ b/src/corelib/io/qnoncontiguousbytedevice_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QNONCONTIGUOUSBYTEDEVICE_P_H #define QNONCONTIGUOUSBYTEDEVICE_P_H diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 0861379d1d6..235e5737289 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2019 The Qt Company Ltd. // Copyright (C) 2020 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qresource.h" #include "qresource_p.h" diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h index ca968b5180b..6b464de4f32 100644 --- a/src/corelib/io/qresource.h +++ b/src/corelib/io/qresource.h @@ -1,6 +1,7 @@ // Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2019 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QRESOURCE_H #define QRESOURCE_H diff --git a/src/corelib/io/qresource_iterator.cpp b/src/corelib/io/qresource_iterator.cpp index fdd5942fe47..630bc8bd82b 100644 --- a/src/corelib/io/qresource_iterator.cpp +++ b/src/corelib/io/qresource_iterator.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qresource.h" #include "qresource_iterator_p.h" diff --git a/src/corelib/io/qresource_iterator_p.h b/src/corelib/io/qresource_iterator_p.h index c4fd9f278db..5bfce5c104b 100644 --- a/src/corelib/io/qresource_iterator_p.h +++ b/src/corelib/io/qresource_iterator_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QRESOURCE_ITERATOR_P_H #define QRESOURCE_ITERATOR_P_H diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 018022b6d78..984ee546b81 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qsettings.h" #include "qsettings_p.h" diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h index 5d0356e8906..973ce2cee4b 100644 --- a/src/corelib/io/qsettings.h +++ b/src/corelib/io/qsettings.h @@ -1,5 +1,6 @@ // Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSETTINGS_H #define QSETTINGS_H diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp index 144ed59dc21..a2e76325969 100644 --- a/src/corelib/io/qsettings_mac.cpp +++ b/src/corelib/io/qsettings_mac.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qsettings.h" diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h index 4229abd8741..3561b0e2f24 100644 --- a/src/corelib/io/qsettings_p.h +++ b/src/corelib/io/qsettings_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSETTINGS_P_H #define QSETTINGS_P_H diff --git a/src/corelib/io/qsettings_wasm.cpp b/src/corelib/io/qsettings_wasm.cpp index 72045a2d519..32cd6b34444 100644 --- a/src/corelib/io/qsettings_wasm.cpp +++ b/src/corelib/io/qsettings_wasm.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:trusted-data-only #include "qsettings.h" #ifndef QT_NO_SETTINGS diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp index 230383ff2cd..5b11c748060 100644 --- a/src/corelib/io/qsettings_win.cpp +++ b/src/corelib/io/qsettings_win.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:trusted-data-only #include "qsettings.h" diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index be9ac52899a..6950ccfcbef 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:provides-trusted-directory-paths #include "qstandardpaths.h" diff --git a/src/corelib/io/qstandardpaths.h b/src/corelib/io/qstandardpaths.h index 56aa2b100c2..e32e4b3f0f1 100644 --- a/src/corelib/io/qstandardpaths.h +++ b/src/corelib/io/qstandardpaths.h @@ -1,5 +1,6 @@ // Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:header-decls-only #ifndef QSTANDARDPATHS_H #define QSTANDARDPATHS_H diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp index 3dbbfc1e1cf..c505ebefa75 100644 --- a/src/corelib/io/qstandardpaths_android.cpp +++ b/src/corelib/io/qstandardpaths_android.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:provides-trusted-directory-paths #include "qstandardpaths.h" diff --git a/src/corelib/io/qstandardpaths_haiku.cpp b/src/corelib/io/qstandardpaths_haiku.cpp index 93eba134f35..f473ebe633a 100644 --- a/src/corelib/io/qstandardpaths_haiku.cpp +++ b/src/corelib/io/qstandardpaths_haiku.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias Koenig <tobias.koenig@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:provides-trusted-directory-paths #include "qstandardpaths.h" diff --git a/src/corelib/io/qstandardpaths_mac.mm b/src/corelib/io/qstandardpaths_mac.mm index 2acbe927361..8958afc30ef 100644 --- a/src/corelib/io/qstandardpaths_mac.mm +++ b/src/corelib/io/qstandardpaths_mac.mm @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:provides-trusted-directory-paths #include "qstandardpaths.h" diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index 4fe8739bcc0..744505a9136 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2020 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:provides-trusted-directory-paths #include "qstandardpaths.h" #include <qdir.h> diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index 805ce65a5ac..c6471bf7917 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:provides-trusted-directory-paths #include "qstandardpaths.h" diff --git a/src/corelib/io/qstorageinfo.cpp b/src/corelib/io/qstorageinfo.cpp index 950af69ab82..aa7c67e8596 100644 --- a/src/corelib/io/qstorageinfo.cpp +++ b/src/corelib/io/qstorageinfo.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2022 The Qt Company Ltd. // Copyright (C) 2015 Ivan Komissarov <ABBAPOH@gmail.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qstorageinfo.h" #include "qstorageinfo_p.h" @@ -12,6 +13,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcStorageInfo, "qt.core.qstorageinfo", QtWarningMsg) QT_IMPL_METATYPE_EXTERN(QStorageInfo) +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QStorageInfoPrivate) /*! \class QStorageInfo @@ -75,7 +77,7 @@ QStorageInfo::QStorageInfo() \sa setPath() */ QStorageInfo::QStorageInfo(const QString &path) - : d(new QStorageInfoPrivate) + : QStorageInfo() { setPath(path); } @@ -85,39 +87,45 @@ QStorageInfo::QStorageInfo(const QString &path) containing the \a dir folder. */ QStorageInfo::QStorageInfo(const QDir &dir) - : d(new QStorageInfoPrivate) + : QStorageInfo(dir.absolutePath()) { - setPath(dir.absolutePath()); } /*! Constructs a new QStorageInfo object that is a copy of the \a other QStorageInfo object. */ QStorageInfo::QStorageInfo(const QStorageInfo &other) - : d(other.d) -{ -} + = default; + +/*! + \since 6.10 + \fn QStorageInfo::QStorageInfo(QStorageInfo &&other) + + Move-constructs a new QStorageInfo from \a other. + + The moved-from object \a other is placed in a partially-formed state, in + which the only valid operations are destruction and assignment of a new + value. +*/ /*! Destroys the QStorageInfo object and frees its resources. */ QStorageInfo::~QStorageInfo() -{ -} + = default; /*! Makes a copy of the QStorageInfo object \a other and assigns it to this QStorageInfo object. */ QStorageInfo &QStorageInfo::operator=(const QStorageInfo &other) -{ - d = other.d; - return *this; -} + = default; /*! \fn QStorageInfo &QStorageInfo::operator=(QStorageInfo &&other) - Assigns \a other to this QStorageInfo instance. + Move-assigns \a other to this QStorageInfo instance. + + The moved-from object \a other is placed in a valid, but unspecified state. */ /*! diff --git a/src/corelib/io/qstorageinfo.h b/src/corelib/io/qstorageinfo.h index 2d7c60ec915..846cfaf4f41 100644 --- a/src/corelib/io/qstorageinfo.h +++ b/src/corelib/io/qstorageinfo.h @@ -1,5 +1,6 @@ // Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSTORAGEINFO_H #define QSTORAGEINFO_H @@ -17,6 +18,7 @@ QT_BEGIN_NAMESPACE class QDebug; class QStorageInfoPrivate; +QT_DECLARE_QESDP_SPECIALIZATION_DTOR(QStorageInfoPrivate) class Q_CORE_EXPORT QStorageInfo { public: @@ -24,6 +26,7 @@ public: explicit QStorageInfo(const QString &path); explicit QStorageInfo(const QDir &dir); QStorageInfo(const QStorageInfo &other); + QStorageInfo(QStorageInfo &&) noexcept = default; ~QStorageInfo(); QStorageInfo &operator=(const QStorageInfo &other); diff --git a/src/corelib/io/qstorageinfo_linux.cpp b/src/corelib/io/qstorageinfo_linux.cpp index 00331a57127..f706650c637 100644 --- a/src/corelib/io/qstorageinfo_linux.cpp +++ b/src/corelib/io/qstorageinfo_linux.cpp @@ -3,6 +3,7 @@ // Copyright (C) 2016 Intel Corporation. // Copyright (C) 2023 Ahmad Samir <a.samirh78@gmail.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qstorageinfo_linux_p.h" diff --git a/src/corelib/io/qstorageinfo_linux_p.h b/src/corelib/io/qstorageinfo_linux_p.h index 8f92b9e9783..26a60dcbc13 100644 --- a/src/corelib/io/qstorageinfo_linux_p.h +++ b/src/corelib/io/qstorageinfo_linux_p.h @@ -3,6 +3,7 @@ // Copyright (C) 2016 Intel Corporation. // Copyright (C) 2023 Ahmad Samir <a.samirh78@gmail.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSTORAGEINFO_LINUX_P_H #define QSTORAGEINFO_LINUX_P_H diff --git a/src/corelib/io/qstorageinfo_mac.cpp b/src/corelib/io/qstorageinfo_mac.cpp index c6c0f501dab..acfa21d8146 100644 --- a/src/corelib/io/qstorageinfo_mac.cpp +++ b/src/corelib/io/qstorageinfo_mac.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qstorageinfo_p.h" diff --git a/src/corelib/io/qstorageinfo_p.h b/src/corelib/io/qstorageinfo_p.h index a917763fe36..0e3f81151e7 100644 --- a/src/corelib/io/qstorageinfo_p.h +++ b/src/corelib/io/qstorageinfo_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSTORAGEINFO_P_H #define QSTORAGEINFO_P_H diff --git a/src/corelib/io/qstorageinfo_stub.cpp b/src/corelib/io/qstorageinfo_stub.cpp index f2f7d2eb656..805b66b893c 100644 --- a/src/corelib/io/qstorageinfo_stub.cpp +++ b/src/corelib/io/qstorageinfo_stub.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qstorageinfo_p.h" diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 40580e3be17..34ba7b9682b 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -2,6 +2,7 @@ // Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com> // Copyright (C) 2016 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qstorageinfo_p.h" diff --git a/src/corelib/io/qstorageinfo_win.cpp b/src/corelib/io/qstorageinfo_win.cpp index 3582612508c..cbaf01848e2 100644 --- a/src/corelib/io/qstorageinfo_win.cpp +++ b/src/corelib/io/qstorageinfo_win.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qstorageinfo_p.h" diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index c1f01267949..73e25c85ddf 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2017 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qtemporaryfile.h" diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 565ce04c6ce..a4fbf69da8b 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3660,17 +3660,29 @@ QList<QUrl> QUrl::fromStringList(const QStringList &urls, ParsingMode mode) */ size_t qHash(const QUrl &url, size_t seed) noexcept { + QtPrivate::QHashCombineWithSeed hasher(seed); + + // non-commutative, we must hash the port first if (!url.d) - return qHash(-1, seed); // the hash of an unset port (-1) - - return qHash(url.d->scheme) ^ - qHash(url.d->userName) ^ - qHash(url.d->password) ^ - qHash(url.d->host) ^ - qHash(url.d->port, seed) ^ - qHash(url.d->path) ^ - qHash(url.d->query) ^ - qHash(url.d->fragment); + return hasher(0, -1); + size_t state = hasher(0, url.d->port); + + if (url.d->hasScheme()) + state = hasher(state, url.d->scheme); + if (url.d->hasUserInfo()) { + // see presentSections(), appendUserName(), etc. + state = hasher(state, url.d->userName); + state = hasher(state, url.d->password); + } + if (url.d->hasHost() || url.d->isLocalFile()) // for XDG compatibility + state = hasher(state, url.d->host); + if (url.d->hasPath()) + state = hasher(state, url.d->path); + if (url.d->hasQuery()) + state = hasher(state, url.d->query); + if (url.d->hasFragment()) + state = hasher(state, url.d->fragment); + return state; } static QUrl adjustFtpPath(QUrl url) diff --git a/src/corelib/ipc/qsharedmemory.cpp b/src/corelib/ipc/qsharedmemory.cpp index a2f6e42579e..7345753ce5b 100644 --- a/src/corelib/ipc/qsharedmemory.cpp +++ b/src/corelib/ipc/qsharedmemory.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qsharedmemory.h" #include "qsharedmemory_p.h" diff --git a/src/corelib/ipc/qsharedmemory.h b/src/corelib/ipc/qsharedmemory.h index ab448b15c16..eec7d82160c 100644 --- a/src/corelib/ipc/qsharedmemory.h +++ b/src/corelib/ipc/qsharedmemory.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSHAREDMEMORY_H #define QSHAREDMEMORY_H diff --git a/src/corelib/ipc/qsharedmemory_p.h b/src/corelib/ipc/qsharedmemory_p.h index 82cce8919ac..df0a6963598 100644 --- a/src/corelib/ipc/qsharedmemory_p.h +++ b/src/corelib/ipc/qsharedmemory_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSHAREDMEMORY_P_H #define QSHAREDMEMORY_P_H diff --git a/src/corelib/ipc/qsharedmemory_posix.cpp b/src/corelib/ipc/qsharedmemory_posix.cpp index 582c6628e19..fa215c3b538 100644 --- a/src/corelib/ipc/qsharedmemory_posix.cpp +++ b/src/corelib/ipc/qsharedmemory_posix.cpp @@ -2,6 +2,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias Koenig <tobias.koenig@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qsharedmemory.h" #include "qsharedmemory_p.h" diff --git a/src/corelib/ipc/qsharedmemory_systemv.cpp b/src/corelib/ipc/qsharedmemory_systemv.cpp index dc9de11091d..1777236bacc 100644 --- a/src/corelib/ipc/qsharedmemory_systemv.cpp +++ b/src/corelib/ipc/qsharedmemory_systemv.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qsharedmemory.h" #include "qsharedmemory_p.h" diff --git a/src/corelib/ipc/qsharedmemory_win.cpp b/src/corelib/ipc/qsharedmemory_win.cpp index 472f34f9a18..b46d0da0c8c 100644 --- a/src/corelib/ipc/qsharedmemory_win.cpp +++ b/src/corelib/ipc/qsharedmemory_win.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qsharedmemory.h" #include "qsharedmemory_p.h" diff --git a/src/corelib/ipc/qsystemsemaphore.cpp b/src/corelib/ipc/qsystemsemaphore.cpp index 24f4789f975..67e8c4bf757 100644 --- a/src/corelib/ipc/qsystemsemaphore.cpp +++ b/src/corelib/ipc/qsystemsemaphore.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qsystemsemaphore.h" #include "qsystemsemaphore_p.h" diff --git a/src/corelib/ipc/qsystemsemaphore.h b/src/corelib/ipc/qsystemsemaphore.h index 0981a7eecee..2d80955b85c 100644 --- a/src/corelib/ipc/qsystemsemaphore.h +++ b/src/corelib/ipc/qsystemsemaphore.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSYSTEMSEMAPHORE_H #define QSYSTEMSEMAPHORE_H diff --git a/src/corelib/ipc/qsystemsemaphore_p.h b/src/corelib/ipc/qsystemsemaphore_p.h index 788c4fb7844..5b4630a20a8 100644 --- a/src/corelib/ipc/qsystemsemaphore_p.h +++ b/src/corelib/ipc/qsystemsemaphore_p.h @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSYSTEMSEMAPHORE_P_H #define QSYSTEMSEMAPHORE_P_H diff --git a/src/corelib/ipc/qsystemsemaphore_posix.cpp b/src/corelib/ipc/qsystemsemaphore_posix.cpp index 7df9593513c..89a75048b4c 100644 --- a/src/corelib/ipc/qsystemsemaphore_posix.cpp +++ b/src/corelib/ipc/qsystemsemaphore_posix.cpp @@ -3,6 +3,7 @@ // Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias Koenig <tobias.koenig@kdab.com> // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qsystemsemaphore.h" #include "qsystemsemaphore_p.h" diff --git a/src/corelib/ipc/qsystemsemaphore_systemv.cpp b/src/corelib/ipc/qsystemsemaphore_systemv.cpp index e5d231d1d42..54e62c615cf 100644 --- a/src/corelib/ipc/qsystemsemaphore_systemv.cpp +++ b/src/corelib/ipc/qsystemsemaphore_systemv.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qsystemsemaphore.h" #include "qsystemsemaphore_p.h" diff --git a/src/corelib/ipc/qsystemsemaphore_win.cpp b/src/corelib/ipc/qsystemsemaphore_win.cpp index f42fecf71f6..a157dec0dd2 100644 --- a/src/corelib/ipc/qsystemsemaphore_win.cpp +++ b/src/corelib/ipc/qsystemsemaphore_win.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qsystemsemaphore.h" #include "qsystemsemaphore_p.h" diff --git a/src/corelib/ipc/qtipccommon.cpp b/src/corelib/ipc/qtipccommon.cpp index 355f6fbc602..e56046497c5 100644 --- a/src/corelib/ipc/qtipccommon.cpp +++ b/src/corelib/ipc/qtipccommon.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qtipccommon.h" #include "qtipccommon_p.h" diff --git a/src/corelib/ipc/qtipccommon.h b/src/corelib/ipc/qtipccommon.h index 658a426914f..375100f9837 100644 --- a/src/corelib/ipc/qtipccommon.h +++ b/src/corelib/ipc/qtipccommon.h @@ -1,5 +1,6 @@ // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QTIPCCOMMON_H #define QTIPCCOMMON_H diff --git a/src/corelib/ipc/qtipccommon_p.h b/src/corelib/ipc/qtipccommon_p.h index 8836cd64421..dc8619299fc 100644 --- a/src/corelib/ipc/qtipccommon_p.h +++ b/src/corelib/ipc/qtipccommon_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QTIPCCOMMON_P_H #define QTIPCCOMMON_P_H diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 604b4a19c69..f759f467cfc 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2022 The Qt Company Ltd. // Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qabstractitemmodel.h" #include <private/qabstractitemmodel_p.h> diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h index 5444bdc8f1f..8de9fee7f0a 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.h +++ b/src/corelib/itemmodels/qabstractitemmodel.h @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QABSTRACTITEMMODEL_H #define QABSTRACTITEMMODEL_H diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h index d22a0a50823..b52559de84c 100644 --- a/src/corelib/itemmodels/qabstractitemmodel_p.h +++ b/src/corelib/itemmodels/qabstractitemmodel_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QABSTRACTITEMMODEL_P_H #define QABSTRACTITEMMODEL_P_H diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index abdeefb4da6..3f843edeedb 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qabstractproxymodel.h" #include "qitemselectionmodel.h" diff --git a/src/corelib/itemmodels/qabstractproxymodel.h b/src/corelib/itemmodels/qabstractproxymodel.h index 8652f500df0..5ccad8c8388 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.h +++ b/src/corelib/itemmodels/qabstractproxymodel.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QABSTRACTPROXYMODEL_H #define QABSTRACTPROXYMODEL_H diff --git a/src/corelib/itemmodels/qabstractproxymodel_p.h b/src/corelib/itemmodels/qabstractproxymodel_p.h index d33666d00bb..68043fe8901 100644 --- a/src/corelib/itemmodels/qabstractproxymodel_p.h +++ b/src/corelib/itemmodels/qabstractproxymodel_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QABSTRACTPROXYMODEL_P_H #define QABSTRACTPROXYMODEL_P_H diff --git a/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp index a328a229f96..6d7b8f89b7b 100644 --- a/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp +++ b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qconcatenatetablesproxymodel.h" #include <private/qabstractitemmodel_p.h> diff --git a/src/corelib/itemmodels/qconcatenatetablesproxymodel.h b/src/corelib/itemmodels/qconcatenatetablesproxymodel.h index c432597dc16..94aa4cbe2cb 100644 --- a/src/corelib/itemmodels/qconcatenatetablesproxymodel.h +++ b/src/corelib/itemmodels/qconcatenatetablesproxymodel.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QCONCATENATEROWSPROXYMODEL_H #define QCONCATENATEROWSPROXYMODEL_H diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp index 1a97dd5b05d..c0a5f6bf17d 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.cpp +++ b/src/corelib/itemmodels/qidentityproxymodel.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qidentityproxymodel.h" #include "qidentityproxymodel_p.h" @@ -197,19 +198,7 @@ QModelIndex QIdentityProxyModel::mapToSource(const QModelIndex& proxyIndex) cons */ QModelIndexList QIdentityProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const { - Q_D(const QIdentityProxyModel); - Q_ASSERT(start.isValid() ? start.model() == this : true); - if (!d->model) - return QModelIndexList(); - - const QModelIndexList sourceList = d->model->match(mapToSource(start), role, value, hits, flags); - QModelIndexList::const_iterator it = sourceList.constBegin(); - const QModelIndexList::const_iterator end = sourceList.constEnd(); - QModelIndexList proxyList; - proxyList.reserve(sourceList.size()); - for ( ; it != end; ++it) - proxyList.append(mapFromSource(*it)); - return proxyList; + return QAbstractProxyModel::match(start, role, value, hits, flags); } /*! diff --git a/src/corelib/itemmodels/qidentityproxymodel.h b/src/corelib/itemmodels/qidentityproxymodel.h index af3534160a7..3520d6c5c28 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.h +++ b/src/corelib/itemmodels/qidentityproxymodel.h @@ -1,6 +1,6 @@ // Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - +// Qt-Security score:significant reason:default #ifndef QIDENTITYPROXYMODEL_H #define QIDENTITYPROXYMODEL_H diff --git a/src/corelib/itemmodels/qidentityproxymodel_p.h b/src/corelib/itemmodels/qidentityproxymodel_p.h index 9762110de21..a3edef2ad45 100644 --- a/src/corelib/itemmodels/qidentityproxymodel_p.h +++ b/src/corelib/itemmodels/qidentityproxymodel_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QIDENTITYPROXYMODEL_P_H #define QIDENTITYPROXYMODEL_P_H diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp index 3c84e8797d0..c57cddd22dd 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.cpp +++ b/src/corelib/itemmodels/qitemselectionmodel.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qitemselectionmodel.h" #include "qitemselectionmodel_p.h" diff --git a/src/corelib/itemmodels/qitemselectionmodel.h b/src/corelib/itemmodels/qitemselectionmodel.h index 9c4ac1177bb..230bc47f8fd 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.h +++ b/src/corelib/itemmodels/qitemselectionmodel.h @@ -1,5 +1,6 @@ // Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QITEMSELECTIONMODEL_H #define QITEMSELECTIONMODEL_H diff --git a/src/corelib/itemmodels/qitemselectionmodel_p.h b/src/corelib/itemmodels/qitemselectionmodel_p.h index 6f905c846c7..328ab9d15d5 100644 --- a/src/corelib/itemmodels/qitemselectionmodel_p.h +++ b/src/corelib/itemmodels/qitemselectionmodel_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QITEMSELECTIONMODEL_P_H #define QITEMSELECTIONMODEL_P_H diff --git a/src/corelib/itemmodels/qrangemodel.cpp b/src/corelib/itemmodels/qrangemodel.cpp index 2635846c58c..51043eb0e24 100644 --- a/src/corelib/itemmodels/qrangemodel.cpp +++ b/src/corelib/itemmodels/qrangemodel.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2025 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qrangemodel.h" #include <QtCore/qsize.h> @@ -233,10 +234,13 @@ QT_BEGIN_NAMESPACE itself. In addition, the row type needs be of a static size: either a gadget or QObject type, or a type that implements the {C++ tuple protocol}. - To represent such data as a tree, the row type has to implement a traversal - protocol that allows QRangeModel to navigate up and down the tree. - For any given row, the model needs to be able to retrieve the parent row, - and the span of children for any given row. + To represent such data as a tree, QRangeModel has to be able to traverse the + data structure: for any given row, the model needs to be able to retrieve + the parent row, and the optional span of children. These traversal functions + can be provided implicitly through the row type, or through an explicit + protocol type. + + \section2 Implicit tree traversal protocol \snippet qrangemodel/main.cpp tree_protocol_0 @@ -251,8 +255,8 @@ QT_BEGIN_NAMESPACE use a gadget. Each row item needs to maintain a pointer to the parent row, as well as an - optional range of child rows that is identical to the structure used for the - tree. + optional range of child rows. That range has to be identical to the range + structure used for the tree itself. Making the row type default constructible is optional, and allows the model to construct new row data elements, for instance in the insertRow() or @@ -297,7 +301,7 @@ QT_BEGIN_NAMESPACE \snippet qrangemodel/main.cpp tree_protocol_6 - \section3 Tree traversal protocol in a separate class + \section2 Tree traversal protocol in a separate class The tree traversal protocol can also be implemented in a separate class. @@ -352,16 +356,11 @@ QT_BEGIN_NAMESPACE constructed by moving tree-data with row-pointers into it, will take ownership of the data, and delete the row pointers in it's destructor. - \note This is not the case for tables and lists that use pointers as their - row type. QRangeModel will never allocate new rows in lists and tables - using operator new, and will never free any rows. - - Using pointers at rows comes with some memory allocation and management - overhead. However, when using rows through pointers the references to the - row items remain stable, even when they are moved around in the range, or - when the range reallocates. This can significantly reduce the cost of - making modifications to the model's structure when using insertRows(), - removeRows(), or moveRows(). + Using pointers as rows comes with some memory allocation and management + overhead. However, the references to the row items remain stable, even when + they are moved around in the range, or when the range reallocates. This can + significantly reduce the cost of making modifications to the model's + structure when using insertRows(), removeRows(), or moveRows(). Each choice has different performance and memory overhead trade-offs. The best option depends on the exact use case and data structure used. diff --git a/src/corelib/itemmodels/qrangemodel.h b/src/corelib/itemmodels/qrangemodel.h index afe5a81b56b..328966f26fd 100644 --- a/src/corelib/itemmodels/qrangemodel.h +++ b/src/corelib/itemmodels/qrangemodel.h @@ -1,5 +1,6 @@ // Copyright (C) 2025 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QRANGEMODEL_H #define QRANGEMODEL_H diff --git a/src/corelib/itemmodels/qrangemodel_impl.h b/src/corelib/itemmodels/qrangemodel_impl.h index d94a5944614..38378fdcc64 100644 --- a/src/corelib/itemmodels/qrangemodel_impl.h +++ b/src/corelib/itemmodels/qrangemodel_impl.h @@ -1,5 +1,6 @@ // Copyright (C) 2025 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QRANGEMODEL_IMPL_H #define QRANGEMODEL_IMPL_H @@ -67,7 +68,12 @@ namespace QRangeModelDetails // TODO: shouldn't we check is_smart_ptr && !is_copy_constructible && !is_copy_assignable // to support users-specific ptrs? template <typename T> - using is_any_unique_ptr = is_any_of<T, std::unique_ptr, QScopedPointer>; + using is_any_unique_ptr = is_any_of<T, +#ifndef QT_NO_SCOPED_POINTER + QScopedPointer, +#endif + std::unique_ptr + >; template <typename T> using is_any_shared_ptr = is_any_of<T, std::shared_ptr, QSharedPointer, @@ -946,7 +952,7 @@ public: if constexpr (multi_role::int_key) return std::as_const(value).find(Qt::ItemDataRole(role)); else - return std::as_const(value).find(roleNames().value(role)); + return std::as_const(value).find(itemModel().roleNames().value(role)); }(); if (it != value.cend()) { result = QRangeModelDetails::value(it); @@ -975,13 +981,20 @@ public: if constexpr (std::is_convertible_v<value_type, decltype(result)>) { result = value; } else { + const auto roleNames = [this]() -> QHash<int, QByteArray> { + Q_UNUSED(this); + if constexpr (!multi_role::int_key) + return itemModel().roleNames(); + else + return {}; + }(); for (auto it = std::cbegin(value); it != std::cend(value); ++it) { - int role = [this, key = QRangeModelDetails::key(it)]() { - Q_UNUSED(this); + const int role = [&roleNames, key = QRangeModelDetails::key(it)]() { + Q_UNUSED(roleNames); if constexpr (multi_role::int_key) return int(key); else - return roleNames().key(key.toUtf8(), -1); + return roleNames.key(key.toUtf8(), -1); }(); if (role != -1) @@ -993,7 +1006,7 @@ public: tried = true; using meta_type = QRangeModelDetails::wrapped_t<value_type>; const QMetaObject &mo = meta_type::staticMetaObject; - for (auto &&[role, roleName] : roleNames().asKeyValueRange()) { + for (auto &&[role, roleName] : itemModel().roleNames().asKeyValueRange()) { QVariant data; if constexpr (std::is_base_of_v<QObject, meta_type>) { if (value) @@ -1058,19 +1071,26 @@ public: Qt::ItemDataRole roleToSet = Qt::ItemDataRole(role); // If there is an entry for EditRole, overwrite that; otherwise, // set the entry for DisplayRole. + const auto roleNames = [this]() -> QHash<int, QByteArray> { + Q_UNUSED(this); + if constexpr (!multi_role::int_key) + return itemModel().roleNames(); + else + return {}; + }(); if (role == Qt::EditRole) { if constexpr (multi_role::int_key) { if (target.find(roleToSet) == target.end()) roleToSet = Qt::DisplayRole; } else { - if (target.find(roleNames().value(roleToSet)) == target.end()) + if (target.find(roleNames.value(roleToSet)) == target.end()) roleToSet = Qt::DisplayRole; } } if constexpr (multi_role::int_key) return write(target[roleToSet], data); else - return write(target[roleNames().value(roleToSet)], data); + return write(target[roleNames.value(roleToSet)], data); } else if (role == Qt::DisplayRole || role == Qt::EditRole) { return write(target, data); } @@ -1102,7 +1122,9 @@ public: if constexpr (multi_role()) { using key_type = typename value_type::key_type; tried = true; - const auto roleName = [map = roleNames()](int role) { return map.value(role); }; + const auto roleName = [map = itemModel().roleNames()](int role) { + return map.value(role); + }; // transactional: only update target if all values from data // can be stored. Storing never fails with int-keys. @@ -1142,8 +1164,9 @@ public: else // can't copy - targetCopy is now a pointer return &origin; }(target); + const auto roleNames = itemModel().roleNames(); for (auto &&[role, value] : data.asKeyValueRange()) { - const QByteArray roleName = roleNames().value(role); + const QByteArray roleName = roleNames.value(role); bool written = false; if constexpr (std::is_base_of_v<QObject, meta_type>) { if (targetCopy) @@ -1541,7 +1564,7 @@ protected: QMetaProperty roleProperty(int role) const { const QMetaObject *mo = &ItemType::staticMetaObject; - const QByteArray roleName = roleNames().value(role); + const QByteArray roleName = itemModel().roleNames().value(role); if (const int index = mo->indexOfProperty(roleName.data()); index >= 0) return mo->property(index); return {}; diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index c078fe06d0c..51436189629 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qsortfilterproxymodel.h" #include "qitemselectionmodel.h" diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h index e4a2d31636d..297242b3952 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.h +++ b/src/corelib/itemmodels/qsortfilterproxymodel.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSORTFILTERPROXYMODEL_H #define QSORTFILTERPROXYMODEL_H diff --git a/src/corelib/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp index 2c0cf2785c8..0882b722c80 100644 --- a/src/corelib/itemmodels/qstringlistmodel.cpp +++ b/src/corelib/itemmodels/qstringlistmodel.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default /* A simple model that uses a QStringList as its data source. diff --git a/src/corelib/itemmodels/qstringlistmodel.h b/src/corelib/itemmodels/qstringlistmodel.h index b93a9c71734..b45b5e16832 100644 --- a/src/corelib/itemmodels/qstringlistmodel.h +++ b/src/corelib/itemmodels/qstringlistmodel.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QSTRINGLISTMODEL_H #define QSTRINGLISTMODEL_H diff --git a/src/corelib/itemmodels/qtransposeproxymodel.cpp b/src/corelib/itemmodels/qtransposeproxymodel.cpp index 621b54782ef..9c80d5c6ed4 100644 --- a/src/corelib/itemmodels/qtransposeproxymodel.cpp +++ b/src/corelib/itemmodels/qtransposeproxymodel.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2018 Luca Beldi <v.ronin@yahoo.it> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #include "qtransposeproxymodel.h" #include <private/qtransposeproxymodel_p.h> diff --git a/src/corelib/itemmodels/qtransposeproxymodel.h b/src/corelib/itemmodels/qtransposeproxymodel.h index 67ce6f3befe..c219fb29884 100644 --- a/src/corelib/itemmodels/qtransposeproxymodel.h +++ b/src/corelib/itemmodels/qtransposeproxymodel.h @@ -1,5 +1,6 @@ // Copyright (C) 2018 Luca Beldi <v.ronin@yahoo.it> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QTRANSPOSEPROXYMODEL_H #define QTRANSPOSEPROXYMODEL_H diff --git a/src/corelib/itemmodels/qtransposeproxymodel_p.h b/src/corelib/itemmodels/qtransposeproxymodel_p.h index 2e0c09b95bf..abb7346d835 100644 --- a/src/corelib/itemmodels/qtransposeproxymodel_p.h +++ b/src/corelib/itemmodels/qtransposeproxymodel_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2018 Luca Beldi <v.ronin@yahoo.it> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QTRANSPOSEPROXYMODEL_P_H #define QTRANSPOSEPROXYMODEL_P_H diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 8f37d86c1bb..3b92c5f48f2 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1644,12 +1644,15 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) QThreadData *data = locker.threadData; + QT_WARNING_PUSH + QT_WARNING_DISABLE_DEPRECATED // compressEvent() // if this is one of the compressible events, do compression if (receiver->d_func()->postedEvents.loadAcquire() && self && self->compressEvent(event, receiver, &data->postEventList)) { Q_TRACE(QCoreApplication_postEvent_event_compressed, receiver, event); return; } + QT_WARNING_POP // delete the event on exceptions to protect against memory leaks till the event is // properly owned in the postEventList @@ -2186,7 +2189,7 @@ bool QCoreApplication::installTranslator(QTranslator *translationFile) QCoreApplicationPrivate *d = self->d_func(); { - QMutexLocker locker(&d->translateMutex); + QWriteLocker locker(&d->translateMutex); d->translators.prepend(translationFile); } @@ -2218,7 +2221,7 @@ bool QCoreApplication::removeTranslator(QTranslator *translationFile) if (!QCoreApplicationPrivate::checkInstance("removeTranslator")) return false; QCoreApplicationPrivate *d = self->d_func(); - QMutexLocker locker(&d->translateMutex); + QWriteLocker locker(&d->translateMutex); if (d->translators.removeAll(translationFile)) { #ifndef QT_NO_QOBJECT locker.unlock(); @@ -2303,7 +2306,7 @@ QString QCoreApplication::translate(const char *context, const char *sourceText, if (self) { QCoreApplicationPrivate *d = self->d_func(); - QMutexLocker locker(&d->translateMutex); + QReadLocker locker(&d->translateMutex); if (!d->translators.isEmpty()) { QList<QTranslator*>::ConstIterator it; QTranslator *translationFile; @@ -2329,23 +2332,13 @@ QString qtTrId(const char *id, int n) return QCoreApplication::translate(nullptr, id, nullptr, n); } -/*! - \internal - Returns a locked mutex handle if \a translator is registered in QCoreApplication, - and might be therefore queried for translations from other threads. - Returns an unlocked/dummy QMutexLocker otherwise. - */ -std::unique_lock<QMutex> QCoreApplicationPrivate::mutexLockerForTranslator(QTranslator *translator) +bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator) { if (!QCoreApplication::self) - return std::unique_lock<QMutex>(); - + return false; QCoreApplicationPrivate *d = QCoreApplication::self->d_func(); - std::unique_lock<QMutex> locker(d->translateMutex); - if (!d->translators.contains(translator)) - locker.unlock(); - - return locker; + QReadLocker locker(&d->translateMutex); + return d->translators.contains(translator); } #else diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 105bd7a291a..0c8e78170ee 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -211,6 +211,7 @@ protected: bool event(QEvent *) override; # if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + QT_DEPRECATED_VERSION_X_6_10("This feature will be removed in Qt 7") virtual bool compressEvent(QEvent *, QObject *receiver, QPostEventList *); # endif #endif // QT_NO_QOBJECT diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 4cb6254e98d..0027b1ad57f 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -30,12 +30,10 @@ #include "private/qcore_mac_p.h" #endif -#ifndef QT_NO_TRANSLATION -#include <mutex> -#endif - QT_BEGIN_NAMESPACE +typedef QList<QTranslator*> QTranslatorList; + class QAbstractEventDispatcher; #ifndef QT_NO_QOBJECT @@ -149,9 +147,9 @@ public: static bool is_app_closing; #endif #ifndef QT_NO_TRANSLATION - QList<QTranslator*> translators; - QMutex translateMutex; - static std::unique_lock<QMutex> mutexLockerForTranslator(QTranslator *translator); + QTranslatorList translators; + QReadWriteLock translateMutex; + static bool isTranslatorInstalled(QTranslator *translator); #endif static bool setuidAllowed; diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 795cc531114..2356611a5cf 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -17,7 +17,7 @@ #include <qthread.h> #include "private/qthread_p.h" #if QT_CONFIG(thread) -#include <qsemaphore.h> +#include "private/qlatch_p.h" #endif // for normalizeTypeInternal @@ -1748,9 +1748,9 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase * if (receiverInSameThread) qWarning("QMetaObject::invokeMethod: Dead lock detected"); - QSemaphore semaphore; - QCoreApplication::postEvent(object, new QMetaCallEvent(std::move(slot), nullptr, -1, argv, &semaphore)); - semaphore.acquire(); + QLatch latch(1); + QCoreApplication::postEvent(object, new QMetaCallEvent(std::move(slot), nullptr, -1, argv, &latch)); + latch.wait(); #endif // QT_CONFIG(thread) } else { qWarning("QMetaObject::invokeMethod: Unknown connection type"); @@ -2362,7 +2362,7 @@ QList<QByteArray> QMetaMethod::parameterNames() const \note In Qt 7, this function will return a null pointer for constructors. - \sa returnType(), QMetaType::type() + \sa returnType(), QMetaType::name() */ const char *QMetaMethod::typeName() const { @@ -2922,10 +2922,10 @@ auto QMetaMethodInvoker::invokeImpl(QMetaMethod self, void *target, return InvokeFailReason::DeadLockDetected; } - QSemaphore semaphore; + QLatch latch(1); QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction, - nullptr, -1, param, &semaphore)); - semaphore.acquire(); + nullptr, -1, param, &latch)); + latch.wait(); #endif // QT_CONFIG(thread) } return {}; diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index 60bcdedba13..7fe36d37bce 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -2080,6 +2080,17 @@ bool QMetaPropertyBuilder::isBindable() const else return false; } +/*! + Returns \c true if the property is required. + The default is \c false. + */ +bool QMetaPropertyBuilder::isRequired() const +{ + if (auto d = d_func()) + return d->flag(Bindable); + else + return false; +} /*! Sets this property to readable if \a value is true. @@ -2236,6 +2247,15 @@ void QMetaPropertyBuilder::setBindable(bool value) } /*! + Sets the\c REQUIRED flag on this property to \a value + */ +void QMetaPropertyBuilder::setRequired(bool value) +{ + if (auto d = d_func()) + d->setFlag(Required, value); +} + +/*! Returns the revision of this property. \sa setRevision() diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h index cf64e51c30c..36cd08d908c 100644 --- a/src/corelib/kernel/qmetaobjectbuilder_p.h +++ b/src/corelib/kernel/qmetaobjectbuilder_p.h @@ -216,6 +216,7 @@ public: bool isFinal() const; bool isAlias() const; bool isBindable() const; + bool isRequired() const; void setReadable(bool value); void setWritable(bool value); @@ -230,6 +231,7 @@ public: void setFinal(bool value); void setAlias(bool value); void setBindable(bool value); + void setRequired(bool value); int revision() const; void setRevision(int revision); diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 1242a40f185..45c947004f5 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -981,12 +981,6 @@ void QMetaType::unregisterMetaType(QMetaType type) than the QMetaType \a rhs, otherwise returns \c false. */ -/*! \internal */ -bool QMetaTypeModuleHelper::convert(const void *, int, void *, int) const -{ - return false; -} - static constexpr auto createStaticTypeToIdMap() { #define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \ @@ -1049,8 +1043,8 @@ static bool qIntegerConversionFromFPHelper(From from, To *to) return true; } -// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor): this is not a base class -static constexpr struct : QMetaTypeModuleHelper +namespace { +struct QCoreVariantHelper : QMetaTypeModuleHelper { template<typename T, typename LiteralWrapper = std::conditional_t<std::is_same_v<T, QString>, QLatin1StringView, const char *>> @@ -1060,7 +1054,8 @@ static constexpr struct : QMetaTypeModuleHelper return !(str.isEmpty() || str == LiteralWrapper("0") || str == LiteralWrapper("false")); } - const QtPrivate::QMetaTypeInterface *interfaceForType(int type) const override { + static const QtPrivate::QMetaTypeInterface *interfaceForType(int type) + { switch (type) { QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(QT_METATYPE_CONVERT_ID_TO_TYPE) QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_METATYPE_CONVERT_ID_TO_TYPE) @@ -1072,11 +1067,14 @@ static constexpr struct : QMetaTypeModuleHelper } } -#ifndef QT_BOOTSTRAPPED - bool convert(const void *from, int fromTypeId, void *to, int toTypeId) const override + static bool convert(const void *from, int fromTypeId, void *to, int toTypeId) { Q_ASSERT(fromTypeId != toTypeId); +#ifdef QT_BOOTSTRAPPED + Q_UNUSED(from); + Q_UNUSED(to); +#else // canConvert calls with two nullptr bool onlyCheck = (from == nullptr && to == nullptr); @@ -1747,26 +1745,28 @@ QT_WARNING_DISABLE_CLANG("-Wtautological-compare") QT_WARNING_POP } +#endif // !QT_BOOTSTRAPPED return false; } -#endif // !QT_BOOTSTRAPPED -} metatypeHelper = {}; +}; +} // unnamed namespace -Q_CONSTINIT Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper = nullptr; -Q_CONSTINIT Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeWidgetsHelper = nullptr; +Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeGuiHelper = {}; +Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeWidgetsHelper = {}; -static const QMetaTypeModuleHelper *qModuleHelperForType(int type) +#ifndef QT_BOOTSTRAPPED +static bool tryConvertBuiltinTypes(const void *from, int fromTypeId, void *to, int toTypeId) { + int type = qMax(fromTypeId, toTypeId); if (type <= QMetaType::LastCoreType) - return &metatypeHelper; + return QCoreVariantHelper::convert(from, fromTypeId, to, toTypeId); if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType) - return qMetaTypeGuiHelper; + return qMetaTypeGuiHelper.convert(from, fromTypeId, to, toTypeId); else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType) - return qMetaTypeWidgetsHelper; - return nullptr; + return qMetaTypeWidgetsHelper.convert(from, fromTypeId, to, toTypeId); + return false; } -#ifndef QT_BOOTSTRAPPED template<typename T, typename Key> class QMetaTypeFunctionRegistry { @@ -2471,10 +2471,8 @@ bool QMetaType::convert(QMetaType fromType, const void *from, QMetaType toType, int fromTypeId = fromType.id(); int toTypeId = toType.id(); - if (auto moduleHelper = qModuleHelperForType(qMax(fromTypeId, toTypeId))) { - if (moduleHelper->convert(from, fromTypeId, to, toTypeId)) - return true; - } + if (tryConvertBuiltinTypes(from, fromTypeId, to, toTypeId)) + return true; const auto f = customTypesConversionRegistry()->function({fromTypeId, toTypeId}); if (f) return (*f)(from, to); @@ -2676,10 +2674,9 @@ bool QMetaType::canConvert(QMetaType fromType, QMetaType toType) if (fromTypeId == toTypeId) return true; - if (auto moduleHelper = qModuleHelperForType(qMax(fromTypeId, toTypeId))) { - if (moduleHelper->convert(nullptr, fromTypeId, nullptr, toTypeId)) - return true; - } + if (tryConvertBuiltinTypes(nullptr, fromTypeId, nullptr, toTypeId)) + return true; + const ConverterFunction * const f = customTypesConversionRegistry()->function(std::make_pair(fromTypeId, toTypeId)); if (f) @@ -2879,8 +2876,12 @@ void QMetaType::registerNormalizedTypedef(const NS(QByteArray) & normalizedTypeN static const QtPrivate::QMetaTypeInterface *interfaceForStaticType(int typeId) { Q_ASSERT(typeId < QMetaType::User); - if (auto moduleHelper = qModuleHelperForType(typeId)) - return moduleHelper->interfaceForType(typeId); + if (typeId <= QMetaType::LastCoreType) + return QCoreVariantHelper::interfaceForType(typeId); + if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType) + return qMetaTypeGuiHelper.interfaceForType(typeId); + if (typeId >= QMetaType::FirstWidgetsType && typeId <= QMetaType::LastWidgetsType) + return qMetaTypeWidgetsHelper.interfaceForType(typeId); return nullptr; } @@ -2909,40 +2910,18 @@ bool QMetaType::isRegistered(int type) return interfaceForTypeNoWarning(type) != nullptr; } -namespace { -enum NormalizeTypeMode { - DontNormalizeType, - TryNormalizeType -}; -} -template <NormalizeTypeMode tryNormalizedType> static inline -const QtPrivate::QMetaTypeInterface *qMetaTypeTypeImpl(QByteArrayView name) +static const QtPrivate::QMetaTypeInterface *findMetaTypeByName(QByteArrayView name) { - if (name.isEmpty()) - return nullptr; - + Q_PRE(!name.isEmpty()); int type = qMetaTypeStaticType(name); if (type != QMetaType::UnknownType) { return interfaceForStaticType(type); #ifndef QT_BOOTSTRAPPED - } else { - QReadLocker locker(&customTypeRegistry()->lock); + } else if (customTypeRegistry.exists()) { + QReadLocker locker(&customTypeRegistry->lock); auto it = customTypeRegistry->aliases.constFind(name); if (it != customTypeRegistry->aliases.constEnd()) return it.value().data(); - -#ifndef QT_NO_QOBJECT - if (tryNormalizedType) { - const char *typeName = name.constData(); - const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName); - type = qMetaTypeStaticType(normalizedTypeName); - if (type == QMetaType::UnknownType) { - return customTypeRegistry->aliases.value(normalizedTypeName).data(); - } else { - return interfaceForStaticType(type); - } - } -#endif #endif } return nullptr; @@ -2969,7 +2948,9 @@ const QtPrivate::QMetaTypeInterface *qMetaTypeTypeImpl(QByteArrayView name) */ int qMetaTypeTypeInternal(QByteArrayView name) { - const QtPrivate::QMetaTypeInterface *iface = qMetaTypeTypeImpl<DontNormalizeType>(name); + const QtPrivate::QMetaTypeInterface *iface = nullptr; + if (!name.isEmpty()) + iface = findMetaTypeByName(name); return iface ? iface->typeId.loadRelaxed() : QMetaType::UnknownType; } @@ -3138,7 +3119,20 @@ QMetaType QMetaType::underlyingType() const */ QMetaType QMetaType::fromName(QByteArrayView typeName) { - return QMetaType(qMetaTypeTypeImpl<TryNormalizeType>(typeName)); + if (typeName.isEmpty()) + return QMetaType(); + + const QtPrivate::QMetaTypeInterface *iface = findMetaTypeByName(typeName); + if (iface) + return QMetaType(iface); + +#if !defined(QT_NO_QOBJECT) + const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName.constData()); + if (normalizedTypeName != typeName) + iface = findMetaTypeByName(normalizedTypeName); +#endif + + return QMetaType(iface); } /*! diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 0ec95c3bb99..d31566b4e95 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -2103,6 +2103,9 @@ public: while (begin != end && is_space(*(end - 1))) end--; + if (begin == end) + return len; + // Convert 'char const *' into 'const char *'. Start at index 1, // not 0, because 'const char *' is already OK. const char *cst = begin + 1; diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index c05bce5fc8f..b39e1de0be2 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -40,25 +40,29 @@ QT_BEGIN_NAMESPACE assign_and_return \ } -class Q_CORE_EXPORT QMetaTypeModuleHelper +struct QMetaTypeModuleHelper { - Q_DISABLE_COPY_MOVE(QMetaTypeModuleHelper) -protected: - QMetaTypeModuleHelper() = default; - ~QMetaTypeModuleHelper() = default; -public: - Q_WEAK_OVERLOAD // prevent it from entering the ABI and rendering constexpr useless static constexpr auto makePair(int from, int to) -> quint64 { return (quint64(from) << 32) + quint64(to); } - virtual const QtPrivate::QMetaTypeInterface *interfaceForType(int) const = 0; - virtual bool convert(const void *, int, void *, int) const; + static const QtPrivate::QMetaTypeInterface *interfaceForType_dummy(int) + { + return nullptr; + } + + static bool convert_dummy(const void *, int, void *, int) + { + return false; + } + + decltype(&interfaceForType_dummy) interfaceForType = &interfaceForType_dummy; + decltype(&convert_dummy) convert = &convert_dummy; }; -extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper; -extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeWidgetsHelper; +extern Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeGuiHelper; +extern Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeWidgetsHelper; namespace QtMetaTypePrivate { template<typename T> diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 0d2ec8efd7a..888c71f5a49 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -8,6 +8,7 @@ #include "qobject_p_p.h" #include "qmetaobject_p.h" +#include <QtCore/private/qtclasshelper_p.h> #include "qabstracteventdispatcher.h" #include "qabstracteventdispatcher_p.h" #include "qcoreapplication.h" @@ -26,7 +27,7 @@ #include <qscopeguard.h> #include <qset.h> #if QT_CONFIG(thread) -#include <qsemaphore.h> +#include <private/qlatch_p.h> #endif #include <private/qorderedmutexlocker_p.h> @@ -475,8 +476,8 @@ void QObjectPrivate::reinitBindingStorageAfterThreadMove() QAbstractMetaCallEvent::~QAbstractMetaCallEvent() { #if QT_CONFIG(thread) - if (semaphore_) - semaphore_->release(); + if (latch) + latch->countDown(); #endif } @@ -505,8 +506,8 @@ inline void QMetaCallEvent::allocArgs() QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction, const QObject *sender, int signalId, - void **args, QSemaphore *semaphore) - : QAbstractMetaCallEvent(sender, signalId, semaphore), + void **args, QLatch *latch) + : QAbstractMetaCallEvent(sender, signalId, latch), d({nullptr, args, callFunction, 0, method_offset, method_relative}), prealloc_() { @@ -520,8 +521,8 @@ QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, */ QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, const QObject *sender, int signalId, - void **args, QSemaphore *semaphore) - : QAbstractMetaCallEvent(sender, signalId, semaphore), + void **args, QLatch *latch) + : QAbstractMetaCallEvent(sender, signalId, latch), d({QtPrivate::SlotObjUniquePtr{slotO}, args, nullptr, 0, 0, ushort(-1)}), prealloc_() { @@ -537,8 +538,8 @@ QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, */ QMetaCallEvent::QMetaCallEvent(QtPrivate::SlotObjUniquePtr slotO, const QObject *sender, int signalId, - void **args, QSemaphore *semaphore) - : QAbstractMetaCallEvent(sender, signalId, semaphore), + void **args, QLatch *latch) + : QAbstractMetaCallEvent(sender, signalId, latch), d{std::move(slotO), args, nullptr, 0, 0, ushort(-1)}, prealloc_() { @@ -3911,7 +3912,7 @@ void QMetaObject::connectSlotsByName(QObject *o) /*! \fn template<typename PointerToMemberFunction> QMetaObject::Connection QMetaObject::connect( - const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type) + const QObject *sender, const QMetaMethod &signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type) \threadsafe \overload connect() @@ -3936,13 +3937,15 @@ void QMetaObject::connectSlotsByName(QObject *o) conversions and type checking are not handled by this function. Overloaded slots need to be explicitly be resolved with help of \l qOverload. + \a signal needs to be the meta-method of a signal, otherwise an + invalid connection will be returned. \sa QObject::connect(), QObject::disconnect() */ /*! - \fn template<typename PointerToMemberFunction, typename Functor> QMetaObject::Connection QMetaObject::connect( - const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type) + \fn template<typename Functor> QMetaObject::Connection QMetaObject::connect( + const QObject *sender, const QMetaMethod &signal, const QObject *context, Functor functor, Qt::ConnectionType type) \threadsafe \overload connect() @@ -3966,6 +3969,8 @@ void QMetaObject::connectSlotsByName(QObject *o) conversions and type checking are not handled by this function. Overloaded functors need to be explicitly be resolved with help of \l qOverload. + \a signal needs to be the meta-method of a signal, otherwise an + invalid connection will be returned. The connection will automatically disconnect if the sender or the context is destroyed. @@ -4193,18 +4198,18 @@ void doActivate(QObject *sender, int signal_index, void **argv) if (c->isSingleShot && !QObjectPrivate::removeConnection(c)) continue; - QSemaphore semaphore; + QLatch latch(1); { QMutexLocker locker(signalSlotLock(receiver)); if (!c->isSingleShot && !c->receiver.loadAcquire()) continue; QMetaCallEvent *ev = c->isSlotObject ? - new QMetaCallEvent(c->slotObj, sender, signal_index, argv, &semaphore) : + new QMetaCallEvent(c->slotObj, sender, signal_index, argv, &latch) : new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, - sender, signal_index, argv, &semaphore); + sender, signal_index, argv, &latch); QCoreApplication::postEvent(receiver, ev); } - semaphore.acquire(); + latch.wait(); continue; #endif } @@ -4370,10 +4375,9 @@ int QObjectPrivate::signalIndex(const char *signalName, \overload setProperty */ -bool QObject::doSetProperty(const char *name, const QVariant *lvalue, QVariant *rvalue) +bool QObject::doSetProperty(const char *name, const QVariant &value, QVariant *rvalue) { Q_D(QObject); - const auto &value =*lvalue; const QMetaObject *meta = metaObject(); if (!name || !meta) return false; @@ -4392,18 +4396,12 @@ bool QObject::doSetProperty(const char *name, const QVariant *lvalue, QVariant * } else { if (idx == -1) { d->extraData->propertyNames.append(name); - if (rvalue) - d->extraData->propertyValues.append(std::move(*rvalue)); - else - d->extraData->propertyValues.append(*lvalue); + q_choose_append(d->extraData->propertyValues, value, rvalue); } else { if (value.userType() == d->extraData->propertyValues.at(idx).userType() && value == d->extraData->propertyValues.at(idx)) return false; - if (rvalue) - d->extraData->propertyValues[idx] = std::move(*rvalue); - else - d->extraData->propertyValues[idx] = *lvalue; + q_choose_assign(d->extraData->propertyValues[idx], value, rvalue); } } @@ -4418,7 +4416,7 @@ bool QObject::doSetProperty(const char *name, const QVariant *lvalue, QVariant * qWarning("%s::setProperty: Property \"%s\" invalid," " read-only or does not exist", metaObject()->className(), name); #endif - return rvalue ? p.write(this, std::move(*rvalue)) : p.write(this, *lvalue); + return rvalue ? p.write(this, std::move(*rvalue)) : p.write(this, value); } /*! diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 813ccdb6735..8c2cd74281e 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -387,7 +387,10 @@ protected: private: void doSetObjectName(const QString &name); +#if QT_CORE_REMOVED_SINCE(6, 10) bool doSetProperty(const char *name, const QVariant *lvalue, QVariant *rvalue); +#endif + bool doSetProperty(const char *name, const QVariant &value, QVariant *rvalue); Q_DISABLE_COPY(QObject) @@ -409,12 +412,12 @@ inline QMetaObject::Connection QObject::connect(const QObject *asender, const ch #if QT_CORE_INLINE_IMPL_SINCE(6, 6) bool QObject::setProperty(const char *name, const QVariant &value) { - return doSetProperty(name, &value, nullptr); + return doSetProperty(name, value, nullptr); } #endif // inline since 6.6 bool QObject::setProperty(const char *name, QVariant &&value) { - return doSetProperty(name, &value, &value); + return doSetProperty(name, value, &value); } template <class T> diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 20c454506ab..dca9c1af932 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -328,16 +328,13 @@ bool QObjectPrivate::disconnect(const typename QtPrivate::FunctionPointer< Func1 &SignalType::Object::staticMetaObject); } -class QSemaphore; +class QLatch; class Q_CORE_EXPORT QAbstractMetaCallEvent : public QEvent { public: - QAbstractMetaCallEvent(const QObject *sender, int signalId, QSemaphore *semaphore = nullptr) - : QEvent(MetaCall), signalId_(signalId), sender_(sender) -#if QT_CONFIG(thread) - , semaphore_(semaphore) -#endif - { Q_UNUSED(semaphore); } + QAbstractMetaCallEvent(const QObject *sender, int signalId, QLatch *latch = nullptr) + : QEvent(MetaCall), signalId_(signalId), sender_(sender), latch(latch) + {} ~QAbstractMetaCallEvent(); virtual void placeMetaCall(QObject *object) = 0; @@ -348,25 +345,23 @@ public: private: int signalId_; const QObject *sender_; -#if QT_CONFIG(thread) - QSemaphore *semaphore_; -#endif + QLatch *latch; }; class Q_CORE_EXPORT QMetaCallEvent : public QAbstractMetaCallEvent { public: - // blocking queued with semaphore - args always owned by caller + // blocking queued with latch - args always owned by caller QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction, const QObject *sender, int signalId, - void **args, QSemaphore *semaphore); + void **args, QLatch *latch); QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId, - void **args, QSemaphore *semaphore); + void **args, QLatch *latch); QMetaCallEvent(QtPrivate::SlotObjUniquePtr slotObj, const QObject *sender, int signalId, - void **args, QSemaphore *semaphore); + void **args, QLatch *latch); // queued - args allocated by event, copied by caller QMetaCallEvent(ushort method_offset, ushort method_relative, diff --git a/src/corelib/kernel/qobject_p_p.h b/src/corelib/kernel/qobject_p_p.h index 1b05f20b827..fdc0f1e8392 100644 --- a/src/corelib/kernel/qobject_p_p.h +++ b/src/corelib/kernel/qobject_p_p.h @@ -143,7 +143,7 @@ struct QObjectPrivate::ConnectionData QAtomicPointer<SignalVector> signalVector; Connection *senders = nullptr; Sender *currentSender = nullptr; // object currently activating the object - std::atomic<TaggedSignalVector> orphaned = {}; + std::atomic<TaggedSignalVector> orphaned = {nullptr}; ~ConnectionData() { diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index b369d2ed8f7..79dcd82f0c5 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -294,9 +294,9 @@ struct Q_CORE_EXPORT QMetaObject #ifdef Q_QDOC template<typename PointerToMemberFunction> - static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection); - template<typename PointerToMemberFunction, typename Functor> - static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection); + static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection); + template<typename Functor> + static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection); #else template <typename Func> static inline Connection diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index 384253265be..7368af2df6e 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -1385,6 +1385,7 @@ QString QPropertyBindingError::description() const /*! \fn template <typename T> template <typename Functor> QPropertyBinding<T> QProperty<T>::setBinding(Functor f) \overload + \since 6.0 Associates the value of this property with the provided functor \a f and returns the previously associated binding. The property's value is set to the @@ -1442,6 +1443,7 @@ QString QPropertyBindingError::description() const /*! \fn template <typename T> template <typename Functor> QPropertyChangeHandler<T, Functor> QProperty<T>::subscribe(Functor f) + \since 6.0 Subscribes the given functor \a f as a callback that is called immediately and whenever the value of the property changes in the future. On each value @@ -1459,6 +1461,7 @@ QString QPropertyBindingError::description() const /*! \fn template <typename T> template <typename Functor> QPropertyNotifier QProperty<T>::addNotifier(Functor f) + \since 6.2 Subscribes the given functor \a f as a callback that is called whenever the value of the property changes. @@ -1948,6 +1951,7 @@ QString QPropertyBindingError::description() const \brief The QPropertyNotifier class controls the lifecycle of change callback installed on a QProperty. \ingroup tools + \since 6.2 QPropertyNotifier is created when registering a callback on a QProperty to listen to changes to the property's value, using QProperty::addNotifier. As diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index f4e7942e947..a3c4e109adf 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -299,7 +299,7 @@ public: auto This = static_cast<QPropertyChangeHandler<Functor>*>(self); This->m_handler(); }) - , m_handler(handler) + , m_handler(std::move(handler)) { } @@ -310,7 +310,7 @@ public: auto This = static_cast<QPropertyChangeHandler<Functor>*>(self); This->m_handler(); }) - , m_handler(handler) + , m_handler(std::move(handler)) { setSource(property); } @@ -329,7 +329,7 @@ public: auto This = static_cast<QPropertyNotifier *>(self); This->m_handler(); }) - , m_handler(handler) + , m_handler(std::move(handler)) { } @@ -341,7 +341,7 @@ public: auto This = static_cast<QPropertyNotifier *>(self); This->m_handler(); }) - , m_handler(handler) + , m_handler(std::move(handler)) { setSource(property); } @@ -516,7 +516,7 @@ public: QPropertyChangeHandler<Functor> onValueChanged(Functor f) { static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); - return QPropertyChangeHandler<Functor>(*this, f); + return QPropertyChangeHandler<Functor>(*this, std::move(f)); } template<typename Functor> @@ -524,14 +524,14 @@ public: { static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); f(); - return onValueChanged(f); + return onValueChanged(std::move(f)); } template<typename Functor> QPropertyNotifier addNotifier(Functor f) { static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); - return QPropertyNotifier(*this, f); + return QPropertyNotifier(*this, std::move(f)); } const QtPrivate::QPropertyBindingData &bindingData() const { return d; } @@ -785,7 +785,7 @@ public: template<typename Functor> QPropertyChangeHandler<Functor> onValueChanged(Functor f) const { - QPropertyChangeHandler<Functor> handler(f); + QPropertyChangeHandler<Functor> handler(std::move(f)); observe(&handler); return handler; } @@ -794,13 +794,13 @@ public: QPropertyChangeHandler<Functor> subscribe(Functor f) const { f(); - return onValueChanged(f); + return onValueChanged(std::move(f)); } template<typename Functor> QPropertyNotifier addNotifier(Functor f) { - QPropertyNotifier handler(f); + QPropertyNotifier handler(std::move(f)); observe(&handler); return handler; } @@ -1046,19 +1046,19 @@ public: template<typename Functor> QPropertyChangeHandler<Functor> onValueChanged(Functor f) { - return QBindable<T>(aliasedProperty(), iface).onValueChanged(f); + return QBindable<T>(aliasedProperty(), iface).onValueChanged(std::move(f)); } template<typename Functor> QPropertyChangeHandler<Functor> subscribe(Functor f) { - return QBindable<T>(aliasedProperty(), iface).subscribe(f); + return QBindable<T>(aliasedProperty(), iface).subscribe(std::move(f)); } template<typename Functor> QPropertyNotifier addNotifier(Functor f) { - return QBindable<T>(aliasedProperty(), iface).addNotifier(f); + return QBindable<T>(aliasedProperty(), iface).addNotifier(std::move(f)); } bool isValid() const @@ -1238,7 +1238,7 @@ public: QPropertyChangeHandler<Functor> onValueChanged(Functor f) { static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); - return QPropertyChangeHandler<Functor>(*this, f); + return QPropertyChangeHandler<Functor>(*this, std::move(f)); } template<typename Functor> @@ -1246,14 +1246,14 @@ public: { static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); f(); - return onValueChanged(f); + return onValueChanged(std::move(f)); } template<typename Functor> QPropertyNotifier addNotifier(Functor f) { static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); - return QPropertyNotifier(*this, f); + return QPropertyNotifier(*this, std::move(f)); } const QtPrivate::QPropertyBindingData &bindingData() const @@ -1386,7 +1386,7 @@ public: QPropertyChangeHandler<Functor> onValueChanged(Functor f) { static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); - return QPropertyChangeHandler<Functor>(*this, f); + return QPropertyChangeHandler<Functor>(*this, std::move(f)); } template<typename Functor> @@ -1394,14 +1394,14 @@ public: { static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); f(); - return onValueChanged(f); + return onValueChanged(std::move(f)); } template<typename Functor> QPropertyNotifier addNotifier(Functor f) { static_assert(std::is_invocable_v<Functor>, "Functor callback must be callable without any parameters"); - return QPropertyNotifier(*this, f); + return QPropertyNotifier(*this, std::move(f)); } QtPrivate::QPropertyBindingData &bindingData() const diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 47483dc6470..8e655ae9cd6 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -463,12 +463,6 @@ bool QTranslator::load(const QString & filename, const QString & directory, const QString & suffix) { Q_D(QTranslator); - - std::unique_lock locker = QCoreApplicationPrivate::mutexLockerForTranslator(this); - if (locker.owns_lock()) - QCoreApplication::postEvent(QCoreApplication::instance(), - new QEvent(QEvent::LanguageChange)); - d->clear(); QString prefix; @@ -744,12 +738,6 @@ bool QTranslator::load(const QLocale & locale, const QString & suffix) { Q_D(QTranslator); - - std::unique_lock locker = QCoreApplicationPrivate::mutexLockerForTranslator(this); - if (locker.owns_lock()) - QCoreApplication::postEvent(QCoreApplication::instance(), - new QEvent(QEvent::LanguageChange)); - d->clear(); return d->load_translation(locale, filename, prefix, directory, suffix); } @@ -769,12 +757,6 @@ bool QTranslator::load(const QLocale & locale, bool QTranslator::load(const uchar *data, int len, const QString &directory) { Q_D(QTranslator); - - std::unique_lock locker = QCoreApplicationPrivate::mutexLockerForTranslator(this); - if (locker.owns_lock()) - QCoreApplication::postEvent(QCoreApplication::instance(), - new QEvent(QEvent::LanguageChange)); - d->clear(); if (!data || len < MagicLength || memcmp(data, magic, MagicLength)) @@ -1048,6 +1030,7 @@ searchDependencies: void QTranslatorPrivate::clear() { + Q_Q(QTranslator); if (unmapPointer && unmapLength) { #if defined(QT_USE_MMAP) if (used_mmap) { @@ -1075,9 +1058,15 @@ void QTranslatorPrivate::clear() language.clear(); filePath.clear(); + + if (QCoreApplicationPrivate::isTranslatorInstalled(q)) + QCoreApplication::postEvent(QCoreApplication::instance(), + new QEvent(QEvent::LanguageChange)); } /*! + \threadsafe + Returns the translation for the key (\a context, \a sourceText, \a disambiguation). If none is found, also tries (\a context, \a sourceText, ""). If that still fails, returns a null string. diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 3a2dcb4a12d..e91797a3ffe 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -321,11 +321,6 @@ static QVariant::Private clonePrivate(const QVariant::Private &other) \compares equality - Because C++ forbids unions from including types that have - non-default constructors or destructors, most interesting Qt - classes cannot be used in unions. Without QVariant, this would be - a problem for QObject::property() and for database work, etc. - A QVariant object holds a single value of a single typeId() at a time. (Some types are multi-valued, for example a string list.) You can find out what type, T, the variant holds, convert it to a diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index 339ee6dc8f9..06dc614c352 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include <qplatformdefs.h> // always first diff --git a/src/corelib/mimetypes/qmimedatabase.h b/src/corelib/mimetypes/qmimedatabase.h index acf1edff27c..b70e207e940 100644 --- a/src/corelib/mimetypes/qmimedatabase.h +++ b/src/corelib/mimetypes/qmimedatabase.h @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QMIMEDATABASE_H #define QMIMEDATABASE_H diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h index cb28f0b7910..ea90b746339 100644 --- a/src/corelib/mimetypes/qmimedatabase_p.h +++ b/src/corelib/mimetypes/qmimedatabase_p.h @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QMIMEDATABASE_P_H #define QMIMEDATABASE_P_H diff --git a/src/corelib/mimetypes/qmimeglobpattern_p.h b/src/corelib/mimetypes/qmimeglobpattern_p.h index 309e45bd5c3..27e9d377fa5 100644 --- a/src/corelib/mimetypes/qmimeglobpattern_p.h +++ b/src/corelib/mimetypes/qmimeglobpattern_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QMIMEGLOBPATTERN_P_H #define QMIMEGLOBPATTERN_P_H diff --git a/src/corelib/mimetypes/qmimemagicrule_p.h b/src/corelib/mimetypes/qmimemagicrule_p.h index bd1b72d1138..2b400e66ada 100644 --- a/src/corelib/mimetypes/qmimemagicrule_p.h +++ b/src/corelib/mimetypes/qmimemagicrule_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QMIMEMAGICRULE_P_H #define QMIMEMAGICRULE_P_H diff --git a/src/corelib/mimetypes/qmimemagicrulematcher.cpp b/src/corelib/mimetypes/qmimemagicrulematcher.cpp index 24a12ee5613..95a0bef5cb3 100644 --- a/src/corelib/mimetypes/qmimemagicrulematcher.cpp +++ b/src/corelib/mimetypes/qmimemagicrulematcher.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #define QT_NO_CAST_FROM_ASCII diff --git a/src/corelib/mimetypes/qmimemagicrulematcher_p.h b/src/corelib/mimetypes/qmimemagicrulematcher_p.h index 02bc73150e7..f1f1a1c8bc3 100644 --- a/src/corelib/mimetypes/qmimemagicrulematcher_p.h +++ b/src/corelib/mimetypes/qmimemagicrulematcher_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QMIMEMAGICRULEMATCHER_P_H #define QMIMEMAGICRULEMATCHER_P_H diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h index b81831f1403..aede727d710 100644 --- a/src/corelib/mimetypes/qmimeprovider_p.h +++ b/src/corelib/mimetypes/qmimeprovider_p.h @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QMIMEPROVIDER_P_H #define QMIMEPROVIDER_P_H diff --git a/src/corelib/mimetypes/qmimetype.h b/src/corelib/mimetypes/qmimetype.h index 508a5cfb53a..fe0d1166af8 100644 --- a/src/corelib/mimetypes/qmimetype.h +++ b/src/corelib/mimetypes/qmimetype.h @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2015 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QMIMETYPE_H #define QMIMETYPE_H diff --git a/src/corelib/mimetypes/qmimetype_p.h b/src/corelib/mimetypes/qmimetype_p.h index 1ce5a835677..db8f2e81ac9 100644 --- a/src/corelib/mimetypes/qmimetype_p.h +++ b/src/corelib/mimetypes/qmimetype_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default #ifndef QMIMETYPE_P_H #define QMIMETYPE_P_H diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp index 1f5a86d11bb..f580103194b 100644 --- a/src/corelib/mimetypes/qmimetypeparser.cpp +++ b/src/corelib/mimetypes/qmimetypeparser.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:trusted-data-only #define QT_NO_CAST_FROM_ASCII diff --git a/src/corelib/mimetypes/qmimetypeparser_p.h b/src/corelib/mimetypes/qmimetypeparser_p.h index 34e588ccf85..845a0e46b7d 100644 --- a/src/corelib/mimetypes/qmimetypeparser_p.h +++ b/src/corelib/mimetypes/qmimetypeparser_p.h @@ -1,6 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - +// Qt-Security score:significant reason:default #ifndef QMIMETYPEPARSER_P_H #define QMIMETYPEPARSER_P_H diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index 70429bfa6f4..835f2d97f3e 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -396,7 +396,7 @@ QFactoryLoader::~QFactoryLoader() #if QT_CONFIG(library) for (qsizetype i = 0; i < d->loadedLibraries.size(); ++i) { if (d->loadedLibraries.at(i)) { - auto &plugin = d->libraries.at(i); + auto &plugin = d->libraries[i]; delete plugin->inst.data(); plugin->unload(); } @@ -470,7 +470,7 @@ void QFactoryLoader::setExtraSearchPath(const QString &path) // must re-scan everything for (qsizetype i = 0; i < d->loadedLibraries.size(); ++i) { if (d->loadedLibraries.at(i)) { - auto &plugin = d->libraries.at(i); + auto &plugin = d->libraries[i]; delete plugin->inst.data(); } } @@ -490,8 +490,10 @@ QFactoryLoader::MetaDataList QFactoryLoader::metaData() const QList<QPluginParsedMetaData> metaData; #if QT_CONFIG(library) QMutexLocker locker(&d->mutex); + metaData.reserve(qsizetype(d->libraries.size())); for (const auto &library : d->libraries) metaData.append(library->metaData); + locker.unlock(); #endif QLatin1StringView iid(d->iid.constData(), d->iid.size()); @@ -514,10 +516,12 @@ QList<QCborArray> QFactoryLoader::metaDataKeys() const QList<QCborArray> metaData; #if QT_CONFIG(library) QMutexLocker locker(&d->mutex); + metaData.reserve(qsizetype(d->libraries.size())); for (const auto &library : d->libraries) { const QCborValue md = library->metaData.value(QtPluginMetaDataKeys::MetaData); metaData.append(md["Keys"_L1].toArray()); } + locker.unlock(); #endif QLatin1StringView iid(d->iid.constData(), d->iid.size()); diff --git a/src/corelib/serialization/qcborarray.cpp b/src/corelib/serialization/qcborarray.cpp index e00b7a4571f..9a566b999b4 100644 --- a/src/corelib/serialization/qcborarray.cpp +++ b/src/corelib/serialization/qcborarray.cpp @@ -98,6 +98,17 @@ QCborArray::QCborArray(const QCborArray &other) noexcept } /*! + \fn QCborArray::QCborArray(QCborArray &&other) + \since 6.10 + + Move-constructor. + + The moved-from object \a other is placed in the default-constructed state. + + \sa QCborArray::QCborArray() +*/ + +/*! \fn QCborArray::QCborArray(std::initializer_list<QCborValue> args) Initializes this QCborArray from the C++ brace-enclosed list found in \a @@ -126,6 +137,15 @@ QCborArray &QCborArray::operator=(const QCborArray &other) noexcept } /*! + \fn QCborArray &QCborArray::operator=(QCborArray &&other) + \since 6.10 + + Move-assignment operator. + + The moved-from object \a other is placed in a valid, but unspecified state. +*/ + +/*! \fn void QCborArray::swap(QCborArray &other) \memberswap{array} */ diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h index 481f316f33e..208d5bcc9a1 100644 --- a/src/corelib/serialization/qcborarray.h +++ b/src/corelib/serialization/qcborarray.h @@ -1,5 +1,6 @@ // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QCBORARRAY_H #define QCBORARRAY_H @@ -203,7 +204,9 @@ public: QCborArray() noexcept; QCborArray(const QCborArray &other) noexcept; + QCborArray(QCborArray &&other) noexcept = default; QCborArray &operator=(const QCborArray &other) noexcept; + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QCborArray) QCborArray(std::initializer_list<QCborValue> args) : QCborArray() { diff --git a/src/corelib/serialization/qcborcommon.cpp b/src/corelib/serialization/qcborcommon.cpp index b3d4f70aa26..a6c74a67294 100644 --- a/src/corelib/serialization/qcborcommon.cpp +++ b/src/corelib/serialization/qcborcommon.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2018 Intel Corporation. // Copyright (C) 2019 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #define CBOR_NO_ENCODER_API #define CBOR_NO_PARSER_API diff --git a/src/corelib/serialization/qcborcommon.h b/src/corelib/serialization/qcborcommon.h index 4c52e8bfa48..5183a90937f 100644 --- a/src/corelib/serialization/qcborcommon.h +++ b/src/corelib/serialization/qcborcommon.h @@ -1,11 +1,13 @@ // Copyright (C) 2018 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QCBORCOMMON_H #define QCBORCOMMON_H #include <QtCore/qobjectdefs.h> #include <QtCore/qmetatype.h> +#include <QtCore/qshareddata.h> #if 0 #pragma qt_class(QtCborCommon) @@ -21,6 +23,9 @@ QT_BEGIN_NAMESPACE class QDebug; +class QCborContainerPrivate; +QT_DECLARE_QESDP_SPECIALIZATION_DTOR(QCborContainerPrivate) // defined in qcborvalue.cpp + enum class QCborSimpleType : quint8 { False = 20, True = 21, diff --git a/src/corelib/serialization/qcbordiagnostic.cpp b/src/corelib/serialization/qcbordiagnostic.cpp index e89afc48273..5bfdee5035c 100644 --- a/src/corelib/serialization/qcbordiagnostic.cpp +++ b/src/corelib/serialization/qcbordiagnostic.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2018 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qcborvalue.h" #include "qcborvalue_p.h" diff --git a/src/corelib/serialization/qcbormap.cpp b/src/corelib/serialization/qcbormap.cpp index 6166775c8ce..e6075dcfc36 100644 --- a/src/corelib/serialization/qcbormap.cpp +++ b/src/corelib/serialization/qcbormap.cpp @@ -276,6 +276,17 @@ QCborMap::QCborMap(const QCborMap &other) noexcept } /*! + \fn QCborMap::QCborMap(QCborMap &&other) + \since 6.10 + + Move-constructor. + + The moved-from object \a other is placed in the default-constructed state. + + \sa QCborMap::QCborMap() +*/ + +/*! \fn QCborMap::QCborMap(std::initializer_list<value_type> args) Constructs a QCborMap with items from a brace-initialization list found in @@ -309,6 +320,15 @@ QCborMap &QCborMap::operator=(const QCborMap &other) noexcept } /*! + \fn QCborMap &QCborMap::operator=(QCborMap &&other) + \since 6.10 + + Move-assignment operator. + + The moved-from object \a other is placed in a valid, but unspecified state. +*/ + +/*! \fn void QCborMap::swap(QCborMap &other) \memberswap{map} */ diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h index a5dc0925370..e2945621451 100644 --- a/src/corelib/serialization/qcbormap.h +++ b/src/corelib/serialization/qcbormap.h @@ -1,5 +1,6 @@ // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QCBORMAP_H #define QCBORMAP_H @@ -238,7 +239,9 @@ public: QCborMap() noexcept; QCborMap(const QCborMap &other) noexcept; + QCborMap(QCborMap &&other) noexcept = default; QCborMap &operator=(const QCborMap &other) noexcept; + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QCborMap) QCborMap(std::initializer_list<value_type> args) : QCborMap() { diff --git a/src/corelib/serialization/qcborstreamreader.cpp b/src/corelib/serialization/qcborstreamreader.cpp index c8ea1fbe6cd..df142a6da5f 100644 --- a/src/corelib/serialization/qcborstreamreader.cpp +++ b/src/corelib/serialization/qcborstreamreader.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2020 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qcborstreamreader.h" diff --git a/src/corelib/serialization/qcborstreamreader.h b/src/corelib/serialization/qcborstreamreader.h index c57db6a1bad..d042aa6bdf9 100644 --- a/src/corelib/serialization/qcborstreamreader.h +++ b/src/corelib/serialization/qcborstreamreader.h @@ -1,5 +1,6 @@ // Copyright (C) 2018 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QCBORSTREAMREADER_H #define QCBORSTREAMREADER_H diff --git a/src/corelib/serialization/qcborstreamwriter.cpp b/src/corelib/serialization/qcborstreamwriter.cpp index 07e62ed4cf4..c8309222fd1 100644 --- a/src/corelib/serialization/qcborstreamwriter.cpp +++ b/src/corelib/serialization/qcborstreamwriter.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2018 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qcborstreamwriter.h" diff --git a/src/corelib/serialization/qcborstreamwriter.h b/src/corelib/serialization/qcborstreamwriter.h index be072564e28..f9dba8e49cb 100644 --- a/src/corelib/serialization/qcborstreamwriter.h +++ b/src/corelib/serialization/qcborstreamwriter.h @@ -1,5 +1,6 @@ // Copyright (C) 2018 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QCBORSTREAMWRITER_H #define QCBORSTREAMWRITER_H diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index fed1811af22..5b7ec705079 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qcborvalue.h" #include "qcborvalue_p.h" @@ -27,6 +28,8 @@ QT_BEGIN_NAMESPACE +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QCborContainerPrivate) + // Worst case memory allocation for a corrupt stream: 256 MB for 32-bit, 1 GB for 64-bit static constexpr quint64 MaxAcceptableMemoryUse = (sizeof(void*) == 4 ? 256 : 1024) * 1024 * 1024; diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h index 04c391eb69f..febd9bafc30 100644 --- a/src/corelib/serialization/qcborvalue.h +++ b/src/corelib/serialization/qcborvalue.h @@ -1,5 +1,6 @@ // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QCBORVALUE_H #define QCBORVALUE_H diff --git a/src/corelib/serialization/qcborvalue_p.h b/src/corelib/serialization/qcborvalue_p.h index 7027cb7431d..ba2f461cf3a 100644 --- a/src/corelib/serialization/qcborvalue_p.h +++ b/src/corelib/serialization/qcborvalue_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2020 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QCBORVALUE_P_H #define QCBORVALUE_P_H diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h index 5a5b6926be3..c77b81bc271 100644 --- a/src/corelib/serialization/qjson_p.h +++ b/src/corelib/serialization/qjson_p.h @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QJSON_P_H #define QJSON_P_H diff --git a/src/corelib/serialization/qjsonarray.cpp b/src/corelib/serialization/qjsonarray.cpp index 402076eb814..ec376212701 100644 --- a/src/corelib/serialization/qjsonarray.cpp +++ b/src/corelib/serialization/qjsonarray.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include <qjsonobject.h> #include <qjsonvalue.h> diff --git a/src/corelib/serialization/qjsonarray.h b/src/corelib/serialization/qjsonarray.h index aaaf76cdbbe..0ddd7d1956b 100644 --- a/src/corelib/serialization/qjsonarray.h +++ b/src/corelib/serialization/qjsonarray.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QJSONARRAY_H #define QJSONARRAY_H diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp index 0f72dc3031a..40937194423 100644 --- a/src/corelib/serialization/qjsoncbor.cpp +++ b/src/corelib/serialization/qjsoncbor.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2020 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include "qcborvalue.h" #include "qcborvalue_p.h" diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp index ef012b7154a..7288ebf65eb 100644 --- a/src/corelib/serialization/qjsondocument.cpp +++ b/src/corelib/serialization/qjsondocument.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include <qjsondocument.h> #include <qjsonobject.h> diff --git a/src/corelib/serialization/qjsondocument.h b/src/corelib/serialization/qjsondocument.h index 6f8a46772fb..8c3163299b0 100644 --- a/src/corelib/serialization/qjsondocument.h +++ b/src/corelib/serialization/qjsondocument.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QJSONDOCUMENT_H #define QJSONDOCUMENT_H diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index 60b2cb3bd0f..6c70d6db855 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include <qjsonobject.h> #include <qjsonvalue.h> diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h index 8ad13b3c409..09988088663 100644 --- a/src/corelib/serialization/qjsonobject.h +++ b/src/corelib/serialization/qjsonobject.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QJSONOBJECT_H #define QJSONOBJECT_H diff --git a/src/corelib/serialization/qjsonparseerror.h b/src/corelib/serialization/qjsonparseerror.h index 9b72ce79020..803b04c53b6 100644 --- a/src/corelib/serialization/qjsonparseerror.h +++ b/src/corelib/serialization/qjsonparseerror.h @@ -1,5 +1,6 @@ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:header-decls-only #ifndef QJSONPARSEERROR_H #define QJSONPARSEERROR_H diff --git a/src/corelib/serialization/qjsonparser.cpp b/src/corelib/serialization/qjsonparser.cpp index c571777a23b..35e0372fb08 100644 --- a/src/corelib/serialization/qjsonparser.cpp +++ b/src/corelib/serialization/qjsonparser.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2021 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QT_BOOTSTRAPPED #include <qcoreapplication.h> diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp index 5d2e71b903d..f72eee1d864 100644 --- a/src/corelib/serialization/qjsonvalue.cpp +++ b/src/corelib/serialization/qjsonvalue.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2022 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include <qjsonobject.h> #include <qjsonvalue.h> diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h index cb56f38b1a4..d163552b0e6 100644 --- a/src/corelib/serialization/qjsonvalue.h +++ b/src/corelib/serialization/qjsonvalue.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #ifndef QJSONVALUE_H #define QJSONVALUE_H diff --git a/src/corelib/serialization/qjsonwriter.cpp b/src/corelib/serialization/qjsonwriter.cpp index b12b1435b2a..5bb9a6621ca 100644 --- a/src/corelib/serialization/qjsonwriter.cpp +++ b/src/corelib/serialization/qjsonwriter.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include <cmath> #include <qlocale.h> diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp index 9f0b8417aea..5e0eff698f9 100644 --- a/src/corelib/serialization/qtextstream.cpp +++ b/src/corelib/serialization/qtextstream.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser //#define QTEXTSTREAM_DEBUG @@ -2931,6 +2932,7 @@ QTextStream &bom(QTextStream &stream) /*! + \since 6.0 Sets the encoding for this stream to \a encoding. The encoding is used for decoding any data that is read from the assigned device, and for encoding any data that is written. By default, diff --git a/src/corelib/serialization/qtextstream.h b/src/corelib/serialization/qtextstream.h index 2b4caf549c7..e60be06d3cf 100644 --- a/src/corelib/serialization/qtextstream.h +++ b/src/corelib/serialization/qtextstream.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:header-decls-only #ifndef QTEXTSTREAM_H #define QTEXTSTREAM_H diff --git a/src/corelib/serialization/qtextstream_p.h b/src/corelib/serialization/qtextstream_p.h index d7e70200f95..7227c29c8fe 100644 --- a/src/corelib/serialization/qtextstream_p.h +++ b/src/corelib/serialization/qtextstream_p.h @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:header-decls-only #ifndef QTEXTSTREAM_P_H #define QTEXTSTREAM_P_H diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index ad9e1089bfe..b4751d1324f 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -1081,10 +1081,12 @@ void QXmlStreamReaderPrivate::parseEntity(const QString &value) inline void QXmlStreamReaderPrivate::reallocateStack() { stack_size <<= 1; - sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value))); - Q_CHECK_PTR(sym_stack); - state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int))); - Q_CHECK_PTR(state_stack); + void *p = realloc(sym_stack, stack_size * sizeof(Value)); + Q_CHECK_PTR(p); + sym_stack = static_cast<Value*>(p); + p = realloc(state_stack, stack_size * sizeof(int)); + Q_CHECK_PTR(p); + state_stack = static_cast<int*>(p); } @@ -2036,7 +2038,7 @@ void QXmlStreamReaderPrivate::startDocument() // unspecified (i.e. System) encoding. QString buf = decoder(QByteArrayView(rawReadBuffer).first(nbytesread)); if (!decoder.hasError()) - readBuffer = buf; + readBuffer = std::move(buf); } } } diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h index 4bba6bcc765..bd8770200db 100644 --- a/src/corelib/serialization/qxmlstream_p.h +++ b/src/corelib/serialization/qxmlstream_p.h @@ -140,8 +140,8 @@ public: if (tos + extraCapacity + 1 > cap) { cap = qMax(tos + extraCapacity + 1, cap << 1 ); void *ptr = realloc(static_cast<void *>(data), cap * sizeof(T)); + Q_CHECK_PTR(ptr); data = reinterpret_cast<T *>(ptr); - Q_CHECK_PTR(data); } } diff --git a/src/corelib/serialization/qxmlutils.cpp b/src/corelib/serialization/qxmlutils.cpp index e6fae7c173f..f84b27dc88d 100644 --- a/src/corelib/serialization/qxmlutils.cpp +++ b/src/corelib/serialization/qxmlutils.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include <qstring.h> diff --git a/src/corelib/serialization/qxmlutils_p.h b/src/corelib/serialization/qxmlutils_p.h index 0ad17589799..8489d50c108 100644 --- a/src/corelib/serialization/qxmlutils_p.h +++ b/src/corelib/serialization/qxmlutils_p.h @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:header-decls-only #ifndef QXMLUTILS_P_H #define QXMLUTILS_P_H diff --git a/src/corelib/text/qanystringview.cpp b/src/corelib/text/qanystringview.cpp index c8e5daaf089..7bf8a3fa1fd 100644 --- a/src/corelib/text/qanystringview.cpp +++ b/src/corelib/text/qanystringview.cpp @@ -47,6 +47,43 @@ QT_BEGIN_NAMESPACE outlives the QAnyStringView on all code paths, lest the string view ends up referencing deleted data. + For example, + + \code + QAnyStringView str = funcReturningQString(); // return value is a temp + \endcode + + would leave \c{str} referencing the deleted temporary (which constitutes + undefined behavior). This is particularly true for the single-character + constructors: + + \code + QAnyStringView ch = u' '; // u' ' is a temporary + // oops, ch references deleted temporary + \endcode + + In both cases, the solution is to "pin" the temporary to an lvalue and only + then create a QAnyStringView from it: + + \code + const auto r = funcReturningQString(); + QAnyStringView str = r; // ok, `r` outlives `str` + const auto sp = u' '; + QAnyStringView ch = sp; // ok, `sp` outlives `ch` + \endcode + + However, using QAnyStringView as the interface type that it is intended to + be is \e{always} safe, provided the called function's documentation is not + asking for a longer lifetime: + + \code + void func(QAnyStringView s); + func(u' '); + func(functionReturningQString()); + \endcode + + This is why QAnyStringView supports these conversions in the first place. + When used as an interface type, QAnyStringView allows a single function to accept a wide variety of string data sources. One function accepting QAnyStringView thus replaces five function @@ -95,6 +132,19 @@ QT_BEGIN_NAMESPACE presented as a QLatin1StringView) while the 16-bit character types are interpreted as UTF-16 data in host byte order (the same as QString). + The following character types are only supported by the single-character + constructor: + + \list + \li \c QLatin1Char + \li \c QChar::SpecialCharacter + \li \c wchar_t (where it's a 32-bit type, i.e. Unix) (since 6.10) + \li \c char32_t + \endlist + + These character types are internally decomposed into a UTF-16 + sequence (using QChar::fromUcs4() for the last). + \section2 Sizes and Sub-Strings All sizes and positions in QAnyStringView functions are in the @@ -186,6 +236,69 @@ QT_BEGIN_NAMESPACE */ /*! + \fn template <typename Char, QAnyStringView::if_compatible_char<Char>> QAnyStringView::QAnyStringView(const Char &ch) + + Constructs a string view on the single character \a ch. The length is usually + \c{1} (but see below). + + In general, you must assume that a QAnyStringView thus created will start + to reference stale data at the end of the + \l{https://en.cppreference.com/w/cpp/language/expressions#Full-expressions}{full-expression}, + when temporaries are deleted. That means that using it to pass a single + character to a QAnyStringView-taking function is ok and safe (as long as + the function documentation doesn't ask for a lifetime longer than the + initial call): + + \code + int to_int(QAnyStringView); + int res = to_int(u'9'); // OK, data stays around for the duration of the call + \endcode + + But keeping the object around longer is undefined behavior: + + \code + QAnyStringView ch = u'9'; + int res = to_int(ch); // (silent) ERROR: ch references deleted data + \endcode + + If you need this, prefer + + \code + const auto nine = u'9'; + QAnyStringView ch(nine); // ok, references `nine`, which outlives `ch` + int res = to_int(ch); // 9 + \endcode + + The above is true for all directly supported \l{Compatible Character Types}. + + If \a ch is not one of these types, but merely converts to QChar, e.g. + QChar::SpecialCharacter or QLatin1Char, the QAnyStringView will bind to a + temporary object that will have been deleted at the end of the full + expression, just like in the second example. + + If \a ch cannot be represented in a single UTF-16 code unit (e.g. because + it's a \c{char32_t} value), this constructor decomposes \a ch into two + UFT-16 code units. The resulting QAnyStringView will have a size() of \c{2} + in that case, and the temporary buffer in which the decomposition is stored + is deleted at the end of the full-expression, similar to + + \code + [](char32_t ch, auto &&tmp = QChar::fromUcs4(ch)) { + return QAnyStringView(tmp); + } + \endcode + + The equivalent safe version in this case would be + + \code + const auto decomposed = QChar::fromUcs4(ch); + QAnyStringView ch(decomposed); + \endcode + + \sa QChar::fromUcs4(), {Compatible Character Types} +*/ + +/*! \fn template <typename Char, size_t N> QAnyStringView::QAnyStringView(const Char (&string)[N]) Constructs a string view on the character string literal \a string. diff --git a/src/corelib/text/qanystringview.h b/src/corelib/text/qanystringview.h index 4b89fa6edbf..079cf751af1 100644 --- a/src/corelib/text/qanystringview.h +++ b/src/corelib/text/qanystringview.h @@ -25,6 +25,11 @@ struct wrapped { using type = Result; }; template <typename Tag, typename Result> using wrapped_t = typename wrapped<Tag, Result>::type; +template <typename Char> +struct is_compatible_utf32_char : std::false_type {}; +template <> struct is_compatible_utf32_char<char32_t> : std::true_type {}; +template <> struct is_compatible_utf32_char<wchar_t> : std::bool_constant<sizeof(wchar_t) == 4> {}; + } // namespace QtPrivate class QAnyStringView @@ -60,6 +65,11 @@ private: }; template <typename Char> + using if_compatible_utf32_char = std::enable_if_t< + QtPrivate::is_compatible_utf32_char<Char>::value + , bool>; + + template <typename Char> using is_compatible_char = std::disjunction< QtPrivate::IsCompatibleCharType<Char>, QtPrivate::IsCompatibleChar8Type<Char> @@ -220,7 +230,7 @@ public: constexpr QAnyStringView(Char ch, QCharContainer &&capacity = QCharContainer()) noexcept : QAnyStringView{&(capacity.ch = ch), 1} {} template <typename Char, typename Container = decltype(QChar::fromUcs4(U'x')), - std::enable_if_t<std::is_same_v<Char, char32_t>, bool> = true> + if_compatible_utf32_char<Char> = true> constexpr QAnyStringView(Char c, Container &&capacity = {}) noexcept : QAnyStringView(capacity = QChar::fromUcs4(c)) {} diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index d518a2f28f2..91550056101 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -1889,6 +1889,15 @@ QByteArray::QByteArray(qsizetype size, Qt::Initialization) } /*! + \fn QByteArray::QByteArray(QByteArrayView v) + \since 6.8 + + Constructs a byte array initialized with the byte array view's data. + + The QByteArray will be null if and only if \a v is null. +*/ + +/*! Sets the size of the byte array to \a size bytes. If \a size is greater than the current size, the byte array is @@ -4924,7 +4933,7 @@ QByteArray QByteArray::fromEcmaUint8Array(emscripten::val uint8array) \since 6.5 \ingroup platform-type-conversions - \sa toEcmaUint8Array() + \sa fromEcmaUint8Array() */ emscripten::val QByteArray::toEcmaUint8Array() { diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index abba4b12fb2..9d0631f832d 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -2376,6 +2376,18 @@ void qtWarnAboutInvalidRegularExpression(const QString &pattern, const char *whe \sa fromLatin1(), fromLocal8Bit(), fromUtf8() */ +/*! + \fn QString::QString(QStringView sv) + + Constructs a string initialized with the string view's data. + + The QString will be null if and only if \a sv is null. + + \since 6.8 + + \sa fromUtf16() +*/ + /* //! [from-std-string] Returns a copy of the \a str string. The given string is assumed to be diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 09cfbdfe94d..e4f06835bd1 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -66,9 +66,6 @@ template <> struct treat_as_integral_arg<unsigned short> : std::true_type {}; template <> struct treat_as_integral_arg< signed short> : std::true_type {}; template <> struct treat_as_integral_arg<unsigned char> : std::true_type {}; template <> struct treat_as_integral_arg< signed char> : std::true_type {}; -// QTBUG-126054, keep until we can fix it for all platforms, not just Windows -// (where wchar_t does convert to QAnyStringView): -template <> struct treat_as_integral_arg<wchar_t> : std::true_type {}; } // Qt 4.x compatibility diff --git a/src/corelib/text/qstringalgorithms_p.h b/src/corelib/text/qstringalgorithms_p.h index a017ec58d49..c873858c59b 100644 --- a/src/corelib/text/qstringalgorithms_p.h +++ b/src/corelib/text/qstringalgorithms_p.h @@ -149,7 +149,10 @@ template <typename StringType> struct QStringAlgorithms return src.size() + adjust; } - static inline void replace_detaching(StringType &src, qsizetype bsize, + // Instead of detaching, i.e. copying the whole data array then performing the + // replacement, create a new buffer, copy `src` and `after` to it and swap it + // with `src`. + static inline void replace_into_copy(StringType &src, qsizetype bsize, ViewType after, QSpan<const qsizetype> indices, qsizetype newlen) { @@ -237,7 +240,7 @@ template <typename StringType> struct QStringAlgorithms // Instead of detaching (which would copy the whole data array) then // performing the replacement, allocate a new string and copy the data // over from `src` and `after` as needed. - replace_detaching(src, bsize, after, indices, newlen); + replace_into_copy(src, bsize, after, indices, newlen); return; } diff --git a/src/corelib/text/qstringlist.cpp b/src/corelib/text/qstringlist.cpp index bb9cf2f0c9f..e6f85849f27 100644 --- a/src/corelib/text/qstringlist.cpp +++ b/src/corelib/text/qstringlist.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE \reentrant - QStringList inherits from QList<QString>. Like QList, QStringList is + QStringList is actually just a QList<QString>. Like QList, QStringList is \l{implicitly shared}. It provides fast index-based access as well as fast insertions and removals. Passing string lists as value parameters is both fast and safe. diff --git a/src/corelib/text/qutf8stringview.qdoc b/src/corelib/text/qutf8stringview.qdoc index 6261927f682..fea4ae97761 100644 --- a/src/corelib/text/qutf8stringview.qdoc +++ b/src/corelib/text/qutf8stringview.qdoc @@ -108,7 +108,7 @@ QBasicUtf8StringView. Please do not use the template class's name in your source code. - \sa QAnyStringView, QUtf8StringView, QString + \sa QAnyStringView, QStringView, QLatin1StringView, QString */ /*! diff --git a/src/corelib/thread/qatomicwait.cpp b/src/corelib/thread/qatomicwait.cpp new file mode 100644 index 00000000000..25ca771643b --- /dev/null +++ b/src/corelib/thread/qatomicwait.cpp @@ -0,0 +1,178 @@ +// Copyright (C) 2025 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qatomicwait_p.h" + +#include <qendian.h> +#include "qfutex_p.h" +#include "qwaitcondition_p.h" + +#include <array> +#include <condition_variable> +#include <mutex> + +QT_BEGIN_NAMESPACE + +/* + * Implementation details: + * + * Normally, a call from atomic_notify_one() or atomic_notify_all() corresponds + * to a call to cond.notify_one() or cond.notify_all(). This simple + * implementation would require that we keep a distinct wait condition variable + * per atomic variable, of which there could be an arbitrary number. + * + * Instead, we have a limited set of std::condition_variable, which are + * selected based on the address of the variable being waited/notified on. + * Because multiple, distinct variables could be sharing the same condition + * variable, we need to perform a cond.notify_all() call in case the lock is + * contended by waiters to more than one address, as we can't be sure which one + * would be woken up by the cond.notify_one() call. + * + * We recover some of the performance of notifying a single waker by also + * storing the address of the variable that was being waited on. If it matches + * the address of the variable being notified, we can perform a notify_one() + * call. This also allows us to avoid any system call in case no waiter has yet + * joined the queue. In case of contention, we store a sentinel address + * instead, indicating there are waiters to multiple variables. The last waiter + * to leave a wait queue is responsible for resetting the watched address back + * to nullptr. + * + * Performance details: + * + * This implementation is designed for systems where neither the Standard + * Library's own std::atomic_wait nor operating system futexes are available + * (read: usually, not the systems Qt is used most frequently on). Therefore, + * it's designed for simplicity, not performance. Simplifications applied + * include: + * - the total number of possible condition variables + * - the hashing algorithm to select a condition variable (simple XOR) + * - no attempt to wait for a variable change before calling cond.wait() + * (no spinning, no HW-assisted wait) + * + * Other limitations: + * + * We only support 8-, 16-, 32- and 64-bit variables and we require bit-exact + * comparisons for all bits. This means we do not support objects with padding + * bits or without unique representations. + */ + +namespace { +struct QAtomicWaitLocks +{ + // Sentinel address used to indicate this Lock is being used by waiters to + // multiple addresses, implying we must make a notify_all() call. + static void *contendedWatchAddress() { return reinterpret_cast<void *>(-1); } + + struct Lock { + alignas(QtPrivate::IdealMutexAlignment) std::mutex mutex; + alignas(QtPrivate::IdealMutexAlignment) std::condition_variable cond; + + // Can assume values: + // - nullptr: no waiter is waiting + // - contendedWatchAddress(): waiters to distinct addresses + // - any other value: all waiters are waiting on the same address + const void *watchedAddress = nullptr; + qsizetype watcherCount = 0; + }; + + static constexpr int LockCount = 16; + std::array<Lock, LockCount> locks; + + int indexFor(const void *ptr) + { + static_assert((LockCount & (LockCount - 1)) == 0, "LockCount is not a power of two"); + + quintptr value = quintptr(ptr) / sizeof(int); + quintptr idx = value % LockCount; +#ifndef QATOMICWAIT_USE_FALLBACK + // XOR some higher bits too to avoid hashing collisions + // (we don't do it in the unit test because we *want* those collisions) + idx ^= (value / LockCount) % LockCount; + idx ^= (value / LockCount / LockCount) % LockCount; +#endif + return int(idx); + } + + Lock &lockFor(const void *ptr) { return locks[indexFor(ptr)]; } +}; +} // unnamed namespace + +static inline void checkFutexUse() +{ +#if !defined(QATOMICWAIT_USE_FALLBACK) + if (QtFutex::futexAvailable()) { + // This will disable the code and data on systems where futexes are + // always available (currently: FreeBSD, Linux, Windows). + qFatal("Implementation should have used futex!"); + } +#endif +} + +static QAtomicWaitLocks &atomicLocks() noexcept +{ + checkFutexUse(); + + static QAtomicWaitLocks global {}; + return global; +} + +template <typename T> static bool isEqual(const void *address, const void *old) +{ + auto atomic = static_cast<const std::atomic<T> *>(address); + auto expected = static_cast<const T *>(old); + return atomic->load(std::memory_order_relaxed) == *expected; +} + +static bool isEqual(const void *address, const void *old, qsizetype size) noexcept +{ + switch (size) { + case 1: return isEqual<quint8 >(address, old); + case 2: return isEqual<quint16>(address, old); + case 4: return isEqual<quint32>(address, old); + case 8: return isEqual<quint64>(address, old); + } + Q_UNREACHABLE_RETURN(false); +} + +void QtPrivate::_q_atomicWait(const void *address, const void *old, qsizetype size) noexcept +{ + auto &locker = atomicLocks().lockFor(address); + + // NOT noexcept; we'll terminate if locking the mutex fails + std::unique_lock lock(locker.mutex); + + // is the value still current? + if (!isEqual(address, old, size)) + return; // no, failed to wait + + if (locker.watchedAddress && locker.watchedAddress != address) + locker.watchedAddress = QAtomicWaitLocks::contendedWatchAddress(); + else + locker.watchedAddress = address; + ++locker.watcherCount; + + do { + locker.cond.wait(lock); + } while (isEqual(address, old, size)); + + if (--locker.watcherCount == 0) + locker.watchedAddress = nullptr; +} + +void QtPrivate::_q_atomicWake(void *address, WakeMode mode) noexcept +{ + auto &locker = atomicLocks().lockFor(address); + + // NOT noexcept; we'll terminate if locking the mutex fails + std::unique_lock lock(locker.mutex); + + // can we wake just one? + if (mode == WakeMode::One && locker.watchedAddress == address) + locker.cond.notify_one(); + else if (locker.watchedAddress != nullptr) + locker.cond.notify_all(); + else + qt_noop(); // no one was waiting +} + +QT_END_NAMESPACE diff --git a/src/corelib/thread/qatomicwait_p.h b/src/corelib/thread/qatomicwait_p.h new file mode 100644 index 00000000000..9a25e56863c --- /dev/null +++ b/src/corelib/thread/qatomicwait_p.h @@ -0,0 +1,84 @@ +// Copyright (C) 2025 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QATOMICWAIT_P_H +#define QATOMICWAIT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an implementation +// detail. This header file may change from version to version without notice, +// or even be removed. +// +// We mean it. +// + +#include "qbasicatomic.h" +#include <private/qglobal_p.h> + +QT_BEGIN_NAMESPACE + +namespace QtPrivate { +enum class WakeMode { One = 1, All = -1 }; + +#ifdef QATOMICWAIT_USE_FALLBACK +# define Q_ATOMICWAIT_EXPORT /* being linked into the unit test */ +#else +# define Q_ATOMICWAIT_EXPORT Q_CORE_EXPORT +#endif + +Q_ATOMICWAIT_EXPORT void _q_atomicWait(const void *address, const void *old, qsizetype size) noexcept; +Q_ATOMICWAIT_EXPORT void _q_atomicWake(void *address, WakeMode) noexcept; + +#undef Q_ATOMICWAIT_EXPORT +} + +namespace QtFallbackAtomicWait { +// C++20- & C23-like API +template <typename T> std::enable_if_t<std::has_unique_object_representations_v<T>> +atomic_wait_explicit(const std::atomic<T> *atomic, T old, std::memory_order mo) noexcept +{ + Q_ASSERT(mo == std::memory_order_relaxed || mo == std::memory_order_acquire + || mo == std::memory_order_seq_cst); + QtPrivate::_q_atomicWait(atomic, &old, sizeof(T)); + std::atomic_thread_fence(mo); +} + +template <typename T> std::enable_if_t<std::has_unique_object_representations_v<T>> +atomic_wait(const std::atomic<T> *atomic, T old) noexcept +{ + atomic_wait_explicit(atomic, old, std::memory_order_seq_cst); +} + +template <typename T> std::enable_if_t<std::has_unique_object_representations_v<T>> +atomic_notify_one(std::atomic<T> *atomic) +{ + QtPrivate::_q_atomicWake(atomic, QtPrivate::WakeMode::One); +} + +template <typename T> std::enable_if_t<std::has_unique_object_representations_v<T>> +atomic_notify_all(std::atomic<T> *atomic) +{ + QtPrivate::_q_atomicWake(atomic, QtPrivate::WakeMode::All); +} +} // namespace QtFallbackAtomicWait + +namespace q20 { +#ifdef __cpp_lib_atomic_wait +using std::atomic_wait; +using std::atomic_wait_explicit; +using std::atomic_notify_all; +using std::atomic_notify_one; +#else +using QtFallbackAtomicWait::atomic_wait; +using QtFallbackAtomicWait::atomic_wait_explicit; +using QtFallbackAtomicWait::atomic_notify_all; +using QtFallbackAtomicWait::atomic_notify_one; +#endif +} // namespace QtNativeAtomicWait + +QT_END_NAMESPACE + +#endif // QATOMICWAIT_P_H diff --git a/src/corelib/thread/qlatch.cpp b/src/corelib/thread/qlatch.cpp new file mode 100644 index 00000000000..0b4863267c0 --- /dev/null +++ b/src/corelib/thread/qlatch.cpp @@ -0,0 +1,228 @@ +// Copyright (C) 2025 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qlatch_p.h" + +#include "qatomicwait_p.h" +#include "qfutex_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QtFutex; + +#if defined(QATOMICWAIT_USE_FALLBACK) +static constexpr bool ForcedFallbackAtomicWait = true; +namespace atomicwait = QtFallbackAtomicWait; +#else +static constexpr bool ForcedFallbackAtomicWait = false; +namespace atomicwait = q20; +#endif + +/*! + \class QLatch + \internal + + Implements the same API as \c std::latch (C++20), allowing a single + synchronization between threads. + + \section2 Typical uses + \section3 Waiting for threaded work to finish + + For this use-case, one or more threads perform some work, which needs to + finish before the caller thread can proceed. For this, each worker thread + calls countDown() once they have finished their work, while the caller + thread suspends execution by calling wait(). + + The operation is best seen in: + \code + QLatch latch(segments); + int y = 0; + for (int i = 0; i < segments; ++i) { + int yn = (data->height - y) / (segments - i); + threadPool->start([&, y, yn]() { + convertSegment(y, y + yn); + latch.countDown(); + }); + y += yn; + } + latch.wait(); + \endcode + + Or, for a single thread: + \code + QLatch latch(1); + QMetaObject::invokeMethod(object, [&]() { + doSomething(); + latch.countDown(); + }, Qt::QueuedConnection); + latch.wait(); + \endcode + + In fact, the above is exactly what Qt::BlockingQueued connection does. + + \section3 Synchronizing execution + + For this use-case, multiple threads must reach a particular state before + any of them may proceed. In this case, all of them call arriveAndWait(), + causing all but the last one of them to suspend execution until that last + one also arrives. + + \code + QLatch latch(n); + for (int i = 0; i < n; ++i) { + threadPool->start([] { + latch.arriveAndWait(); + doStressfulWork(); + }); + } + \endcode + + \section2 Differences from \c std::latch + + \list + \li Uses \c{int} in the API instead of \c{ptrdiff_t} (note that the max() + is the same as libstdc++'s on Linux). + \li count_down() is not \c{const} (libstdc++ implementation is). + \endlist + + \omit + \section2 Implementation details + + countDown() must call wakeUp() if the latch counter reaches zero and there + are threads waiting to be woken up. Or, conversely, countDown() needs to do + nothing after decrementing if the latch counter is still non-zero or there + are no waiters. Therefore, we choose the bits so that a non-zero + \c{counter} member implies no action required. + + \endomit +*/ + +/*! + \fn QLatch::QLatch(int expected) noexcept + + Initializes the QLatch to indicate that countDown() will be called \a + expected times. You probably want to pass a value greater than zero. +*/ + +/*! + \fn int QLatch::pending() noexcept + \internal + + Returns the counter. + + Don't use; for the unit test only. +*/ + +/*! + \fn void QLatch::countDown(int n) noexcept + \fn void QLatch::count_down(int n) noexcept + + Decrements the internal counter by \a n. If the internal counter drops to + zero after this operation, any threads currently waiting will be woken up. + If \a n is greater than the value of the internal counter or is negative, + the behavior is undefined. + + This function does not block and may be used to notify waiters that this + thread has reached a particular point and they may proceed. To synchronize + all threads so they all resume work at the same time, use arriveAndWait(). + + This function implements release memory ordering. + + \sa arriveAndWait(), wait() +*/ + +/*! + \fn bool QLatch::tryWait() const noexcept + \fn void QLatch::try_wait() const noexcept + + Returns true if the internal counter in this latch has dropped to zero, + false otherwise. This function does not block. + + This function implements acquire memory ordering. + + \sa wait(), countDown() +*/ + +/*! + \fn void QLatch::wait() noexcept + + Waits for the internal counter in this latch to drop to zero. + + This function implements acquire memory ordering. + + \sa tryWait(), arriveAndWait(), countDown() +*/ + +/*! + \fn void QLatch::arriveAndWait(int n) noexcept + \fn void QLatch::arrive_and_wait(int n) noexcept + + This function decrements the internal counter by \a n. If the counter + remains non-zero after this operation, it suspends the current thread until + it does become zero. Otherwise it wakes all other current waiters. + + This function is useful to synchronize multiple threads so they may start + some execution at (nearly) exactly the same time. + + This function is exactly equivalent to: + \code + countDown(n); + wait(); + \endcode + + This function implements acquire-and-release memory ordering. + + \sa countDown(), wait() +*/ + +/*! + \fn int QLatch::max() noexcept + + Returns the maximum number that can be passed to the constructor. +*/ + +void QLatch::waitInternal(int current) noexcept +{ + // mark that there is a waiter -> clear the bit that there are no waiters + if (current & NoWaiters) { +#if __has_builtin(__atomic_and_fetch) + // Modern GCC and Clang are able to generate loop-free code for this + // operation on x86-64, ARMv8.1 and RISC-V. + if (__atomic_and_fetch(reinterpret_cast<int *>(&counter._q_value), ~NoWaiters, + int(std::memory_order_relaxed)) == 0) + return; +#else + // Do it in two steps, which is usually better than a compare_exchange + // loop. This is not exactly the same as above (it's not atomic!) but + // is correct for our purposes because the counter never changes from 0 + // once it reaches that. + counter.fetchAndAndRelaxed(~NoWaiters); + if (counter.loadRelaxed() == 0) + return; // no need to wait! +#endif + } + current &= ~NoWaiters; + + auto waitLoop = [&](auto waiter) { + do { + waiter(current); + } while ((current = counter.loadAcquire()) != 0); + }; + + if (futexAvailable() && !ForcedFallbackAtomicWait) + waitLoop([&](int current) { futexWait(counter, current); }); + else + waitLoop([&](int current) { + atomicwait::atomic_wait_explicit(&counter._q_value, current, std::memory_order_relaxed); + }); +} + +void QLatch::wakeUp() noexcept +{ + if (futexAvailable() && !ForcedFallbackAtomicWait) + futexWakeAll(counter); + else + atomicwait::atomic_notify_all(&counter._q_value); +} + +QT_END_NAMESPACE diff --git a/src/corelib/thread/qlatch_p.h b/src/corelib/thread/qlatch_p.h new file mode 100644 index 00000000000..95890f7519d --- /dev/null +++ b/src/corelib/thread/qlatch_p.h @@ -0,0 +1,96 @@ +// Copyright (C) 2024 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QLATCH_P_H +#define QLATCH_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an implementation +// detail. This header file may change from version to version without notice, +// or even be removed. +// +// We mean it. +// + +#include <QtCore/qbasicatomic.h> +#include <QtCore/qtsan_impl.h> + +#include <private/qglobal_p.h> + +#include <limits> + +QT_BEGIN_NAMESPACE + +class QLatch +{ +public: + constexpr explicit QLatch(int expected) noexcept + : counter(expected | NoWaiters) + {} + + int pending() const noexcept + { + return (counter.loadAcquire() & CounterMask); + } + + void countDown(int n = 1) noexcept + { + QtTsan::latchCountDown(&counter); + if (counter.fetchAndSubRelease(n) == n) // addAndFetch(n) == 0 + wakeUp(); + } + + bool tryWait() const noexcept + { + if (pending() != 0) + return false; + QtTsan::latchWait(&counter); + return true; + } + + void wait() noexcept // not const + { + if (int current = counter.loadAcquire(); (current & CounterMask) != 0) { + waitInternal(current); + QtTsan::latchWait(&counter); + } + } + + void arriveAndWait(int n = 1) noexcept + { + countDown(n); + wait(); + } + + // API compatible with C++20: + static constexpr int max() noexcept { return std::numeric_limits<int>::max(); } + void count_down(int n = 1) noexcept { countDown(n); } + bool try_wait() const noexcept { return tryWait(); } + void arrive_and_wait(int n = 1) noexcept { arriveAndWait(n); } + +private: + static constexpr int NoWaitersBit = 31; + static constexpr int NoWaiters = 1 << NoWaitersBit; + static constexpr int CounterMask = ~NoWaiters; + QBasicAtomicInt counter; + + Q_DISABLE_COPY_MOVE(QLatch) + +#ifdef QATOMICWAIT_USE_FALLBACK +# define Q_LATCH_EXPORT /* being linked into the unit test */ +#else +# define Q_LATCH_EXPORT Q_CORE_EXPORT +#endif + + void Q_LATCH_EXPORT waitInternal(int current) noexcept; + void Q_LATCH_EXPORT wakeUp() noexcept; + +#undef Q_LATCH_EXPORT +}; + +QT_END_NAMESPACE + +#endif // QLATCH_P_H diff --git a/src/corelib/thread/qtsan_impl.h b/src/corelib/thread/qtsan_impl.h index b28d65e65f4..2d1cb2c1bdb 100644 --- a/src/corelib/thread/qtsan_impl.h +++ b/src/corelib/thread/qtsan_impl.h @@ -33,6 +33,16 @@ inline void futexRelease(void *addr, void *addr2 = nullptr) ::__tsan_release(addr); } +inline void latchWait(const void *addr) +{ + ::__tsan_acquire(const_cast<void *>(addr)); +} + +inline void latchCountDown(void *addr) +{ + ::__tsan_release(addr); +} + inline void mutexPreLock(void *addr, unsigned flags) { ::__tsan_mutex_pre_lock(addr, flags); @@ -61,6 +71,8 @@ enum : unsigned { #else inline void futexAcquire(void *, void * = nullptr) {} inline void futexRelease(void *, void * = nullptr) {} +inline void latchCountDown(void *) {} +inline void latchWait(const void *) {} enum : unsigned { MutexWriteReentrant, diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index b85c252cd30..43b16cd0f4f 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -405,13 +405,16 @@ static int fromOffsetString(QStringView offsetString, bool *valid) noexcept \section2 Range of Valid Dates - Dates are stored internally as a Julian Day number, an integer count of - every day in a contiguous range, with 24 November 4714 BCE in the Gregorian - calendar being Julian Day 0 (1 January 4713 BCE in the Julian calendar). - As well as being an efficient and accurate way of storing an absolute date, - it is suitable for converting a date into other calendar systems such as - Hebrew, Islamic or Chinese. The Julian Day number can be obtained using - QDate::toJulianDay() and can be set using QDate::fromJulianDay(). + Dates are stored internally as a modified Julian Day number, an integer + count of every day in a contiguous range, with 24 November 4714 BCE in the + Gregorian calendar being Julian Day 0 (1 January 4713 BCE in the Julian + calendar). As well as being an efficient and accurate way of storing an + absolute date, it is suitable for converting a date into other calendar + systems such as Hebrew, Islamic or Chinese. For the purposes of QDate, + Julian Days are delimited at midnight and, for those of QDateTime, in the + zone used by the datetime. (This departs from the formal definition, which + delimits Julian Days at UTC noon.) The Julian Day number can be obtained + using QDate::toJulianDay() and can be set using QDate::fromJulianDay(). The range of Julian Day numbers that QDate can represent is, for technical reasons, limited to between -784350574879 and 784354017364, which means from @@ -3655,16 +3658,16 @@ QDateTime::Data QDateTimePrivate::create(QDate toDate, QTime toTime, const QTime \section1 Remarks - \note QDateTime does not account for leap seconds. + QDateTime does not account for leap seconds. - \note All conversion to and from string formats is done using the C locale. + All conversions to and from string formats are done using the C locale. For localized conversions, see QLocale. - \note There is no year 0 in the Gregorian calendar. Dates in that year are + There is no year 0 in the Gregorian calendar. Dates in that year are considered invalid. The year -1 is the year "1 before Christ" or "1 before common era." The day before 1 January 1 CE is 31 December 1 BCE. - \note Using local time (the default) or a specified time zone implies a need + Using local time (the default) or a specified time zone implies a need to resolve any issues around \l {Timezone transitions}{transitions}. As a result, operations on such QDateTime instances (notably including constructing them) may be more expensive than the equivalent when using UTC diff --git a/src/corelib/time/qtimezonelocale_data_p.h b/src/corelib/time/qtimezonelocale_data_p.h index 9afb12406c0..9e179369254 100644 --- a/src/corelib/time/qtimezonelocale_data_p.h +++ b/src/corelib/time/qtimezonelocale_data_p.h @@ -58,7 +58,7 @@ namespace QtTimeZoneLocale { // GENERATED PART STARTS HERE /* - This part of the file was generated on 2025-06-17 from the + This part of the file was generated on 2025-07-01 from the Common Locale Data Repository v47 http://www.unicode.org/cldr/ @@ -49804,7 +49804,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 5130, 88357, 11, }, // Africa/Dar_es_Salaam { 687, 5043, 88368, 6, }, // Africa/Djibouti { 687, 5243, 88374, 5, }, // Africa/Douala - { 687, 5166, 221031, 9, }, // Africa/El_Aaiun + { 687, 5166, 88379, 8, }, // Africa/El_Aaiun { 687, 6853, 88387, 9, }, // Africa/Freetown { 687, 4906, 88396, 7, }, // Africa/Gaborone { 687, 5015, 88403, 5, }, // Africa/Harare @@ -49925,7 +49925,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 5897, 89278, 7, }, // America/Marigot { 687, 5805, 89285, 9, }, // America/Martinique { 687, 8184, 89294, 9, }, // America/Matamoros - { 687, 2917, 221040, 8, }, // America/Mazatlan + { 687, 2917, 221031, 8, }, // America/Mazatlan { 687, 8202, 89312, 8, }, // America/Menominee { 687, 8220, 31158, 6, }, // America/Merida { 687, 8235, 89320, 12, }, // America/Metlakatla @@ -50012,7 +50012,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 4540, 89984, 7, }, // Asia/Damascus { 687, 1093, 89991, 4, }, // Asia/Dhaka { 687, 6192, 89995, 4, }, // Asia/Dili - { 687, 3596, 221048, 3, }, // Asia/Dubai + { 687, 3596, 221039, 3, }, // Asia/Dubai { 687, 6159, 90003, 7, }, // Asia/Dushanbe { 687, 8636, 90010, 11, }, // Asia/Famagusta { 687, 8651, 90021, 5, }, // Asia/Gaza @@ -50024,7 +50024,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 7006, 90073, 7, }, // Asia/Jakarta { 687, 6992, 31943, 7, }, // Asia/Jayapura { 687, 1290, 90080, 6, }, // Asia/Jerusalem - { 687, 3560, 221051, 4, }, // Asia/Kabul + { 687, 3560, 221042, 4, }, // Asia/Kabul { 687, 4316, 90091, 7, }, // Asia/Kamchatka { 687, 4239, 31972, 5, }, // Asia/Karachi { 687, 1185, 90098, 8, }, // Asia/Kathmandu @@ -50080,7 +50080,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 1395, 90429, 5, }, // Atlantic/Faroe { 687, 8736, 90434, 5, }, // Atlantic/Madeira { 687, 2748, 90439, 9, }, // Atlantic/Reykjavik - { 687, 7272, 221055, 13, }, // Atlantic/South_Georgia + { 687, 7272, 221046, 13, }, // Atlantic/South_Georgia { 687, 6821, 90463, 11, }, // Atlantic/St_Helena { 687, 6644, 90474, 7, }, // Atlantic/Stanley { 687, 1670, 90481, 6, }, // Australia/Adelaide @@ -50094,7 +50094,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 1727, 90537, 8, }, // Australia/Melbourne { 687, 1762, 90545, 4, }, // Australia/Perth { 687, 1463, 32494, 5, }, // Australia/Sydney - { 687, 6441, 221068, 9, }, // Europe/Amsterdam + { 687, 6441, 221059, 9, }, // Europe/Amsterdam { 687, 6216, 90559, 6, }, // Europe/Andorra { 687, 3620, 90565, 10, }, // Europe/Astrakhan { 687, 2300, 90575, 5, }, // Europe/Athens @@ -50128,7 +50128,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 6410, 90773, 6, }, // Europe/Monaco { 687, 3537, 90779, 6, }, // Europe/Moscow { 687, 6458, 90785, 5, }, // Europe/Oslo - { 687, 4284, 221077, 4, }, // Europe/Paris + { 687, 4284, 221068, 4, }, // Europe/Paris { 687, 6424, 90790, 10, }, // Europe/Podgorica { 687, 6275, 90800, 5, }, // Europe/Prague { 687, 8837, 90805, 4, }, // Europe/Riga @@ -50154,7 +50154,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 6540, 90946, 9, }, // Europe/Zurich { 687, 5078, 90955, 11, }, // Indian/Antananarivo { 687, 6947, 90966, 5, }, // Indian/Chagos - { 687, 6046, 221081, 8, }, // Indian/Christmas + { 687, 6046, 221072, 8, }, // Indian/Christmas { 687, 6063, 90978, 5, }, // Indian/Cocos { 687, 5029, 90983, 6, }, // Indian/Comoro { 687, 6661, 90989, 7, }, // Indian/Kerguelen @@ -50177,7 +50177,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 6696, 91094, 7, }, // Pacific/Gambier { 687, 3822, 91101, 10, }, // Pacific/Guadalcanal { 687, 6018, 31112, 4, }, // Pacific/Guam - { 687, 3049, 221089, 5, }, // Pacific/Kanton + { 687, 3049, 221080, 5, }, // Pacific/Kanton { 687, 3998, 33132, 10, }, // Pacific/Kiritimati { 687, 7019, 91126, 6, }, // Pacific/Kosrae { 687, 2842, 91132, 10, }, // Pacific/Kwajalein @@ -50188,7 +50188,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 687, 7132, 91165, 4, }, // Pacific/Niue { 687, 4168, 91169, 7, }, // Pacific/Norfolk { 687, 7098, 91176, 6, }, // Pacific/Noumea - { 687, 3126, 221094, 9, }, // Pacific/Pago_Pago + { 687, 3126, 221085, 9, }, // Pacific/Pago_Pago { 687, 7155, 91191, 4, }, // Pacific/Palau { 687, 7194, 33210, 8, }, // Pacific/Pitcairn { 687, 3096, 91195, 6, }, // Pacific/Pohnpei @@ -50203,650 +50203,650 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 688, 6788, 195501, 6, }, // Africa/Abidjan Venetian/Latin/Italy { 688, 6760, 74129, 4, }, // Africa/Accra { 688, 5059, 35821, 10, }, // Africa/Addis_Ababa - { 688, 7420, 221103, 6, }, // Africa/Algiers - { 688, 14, 221109, 6, }, // Africa/Asmara - { 688, 5257, 221115, 6, }, // Africa/Bangui - { 688, 7435, 221121, 5, }, // Africa/Bissau - { 688, 4922, 221126, 9, }, // Africa/Bujumbura + { 688, 7420, 221094, 6, }, // Africa/Algiers + { 688, 14, 221100, 6, }, // Africa/Asmara + { 688, 5257, 221106, 6, }, // Africa/Bangui + { 688, 7435, 221112, 5, }, // Africa/Bissau + { 688, 4922, 221117, 9, }, // Africa/Bujumbura { 688, 2320, 161877, 8, }, // Africa/Cairo - { 688, 4117, 221135, 10, }, // Africa/Casablanca + { 688, 4117, 221126, 10, }, // Africa/Casablanca { 688, 7449, 166781, 5, }, // Africa/Ceuta { 688, 6773, 157976, 7, }, // Africa/Conakry { 688, 5130, 21354, 12, }, // Africa/Dar_es_Salaam { 688, 5043, 158501, 6, }, // Africa/Djibouti { 688, 5243, 21372, 5, }, // Africa/Douala { 688, 5166, 6393, 7, }, // Africa/El_Aaiun - { 688, 5151, 221145, 7, }, // Africa/Kampala + { 688, 5151, 221136, 7, }, // Africa/Kampala { 688, 4524, 157994, 6, }, // Africa/Khartoum { 688, 6869, 20418, 4, }, // Africa/Lome - { 688, 4939, 221152, 10, }, // Africa/Lubumbashi - { 688, 5197, 221162, 6, }, // Africa/Maseru - { 688, 5182, 221168, 7, }, // Africa/Mbabane - { 688, 5113, 221175, 8, }, // Africa/Mogadishu + { 688, 4939, 221143, 10, }, // Africa/Lubumbashi + { 688, 5197, 221153, 6, }, // Africa/Maseru + { 688, 5182, 221159, 7, }, // Africa/Mbabane + { 688, 5113, 221166, 8, }, // Africa/Mogadishu { 688, 5271, 195575, 6, }, // Africa/Ndjamena { 688, 6803, 147724, 8, }, // Africa/Nouakchott - { 688, 6727, 221183, 8, }, // Africa/Ouagadougou + { 688, 6727, 221174, 8, }, // Africa/Ouagadougou { 688, 5225, 26542, 10, }, // Africa/Porto-Novo - { 688, 4435, 221191, 15, }, // Africa/Sao_Tome + { 688, 4435, 221182, 15, }, // Africa/Sao_Tome { 688, 2866, 164486, 7, }, // Africa/Tripoli - { 688, 6554, 221206, 6, }, // Africa/Tunis + { 688, 6554, 221197, 6, }, // Africa/Tunis { 688, 5607, 4775, 7, }, // America/Anguilla - { 688, 270, 221212, 7, }, // America/Argentina/Cordoba - { 688, 7489, 221219, 11, }, // America/Argentina/Rio_Gallegos + { 688, 270, 221203, 7, }, // America/Argentina/Cordoba + { 688, 7489, 221210, 11, }, // America/Argentina/Rio_Gallegos { 688, 4252, 6592, 8, }, // America/Asuncion { 688, 237, 22, 8, }, // America/Atikokan - { 688, 7623, 221230, 16, }, // America/Bahia_Banderas + { 688, 7623, 221221, 16, }, // America/Bahia_Banderas { 688, 4361, 44161, 6, }, // America/Bogota - { 688, 7735, 221246, 12, }, // America/Campo_Grande + { 688, 7735, 221237, 12, }, // America/Campo_Grande { 688, 3868, 33314, 6, }, // America/Cancun { 688, 4345, 147758, 6, }, // America/Cayenne { 688, 5496, 44173, 6, }, // America/Cayman { 688, 7774, 60, 6, }, // America/Ciudad_Juarez - { 688, 3791, 221258, 6, }, // America/Cuiaba + { 688, 3791, 221249, 6, }, // America/Cuiaba { 688, 5723, 66, 7, }, // America/Curacao - { 688, 805, 221264, 6, }, // America/Denver - { 688, 5739, 221270, 8, }, // America/Dominica + { 688, 805, 221255, 6, }, // America/Denver + { 688, 5739, 221261, 8, }, // America/Dominica { 688, 7869, 26580, 8, }, // America/Eirunepe { 688, 5770, 20519, 7, }, // America/Grenada { 688, 5786, 95109, 9, }, // America/Guadeloupe { 688, 2281, 95118, 7, }, // America/Havana - { 688, 348, 221278, 12, }, // America/Indiana/Indianapolis - { 688, 481, 221290, 14, }, // America/Indiana/Knox - { 688, 7961, 221304, 17, }, // America/Indiana/Marengo - { 688, 7985, 221321, 20, }, // America/Indiana/Petersburg - { 688, 8012, 221341, 19, }, // America/Indiana/Tell_City - { 688, 8038, 221360, 15, }, // America/Indiana/Vevay - { 688, 8060, 221375, 19, }, // America/Indiana/Vincennes - { 688, 8086, 221394, 17, }, // America/Indiana/Winamac - { 688, 2799, 221411, 7, }, // America/Jamaica - { 688, 8125, 221418, 21, }, // America/Kentucky/Monticello - { 688, 3239, 221439, 11, }, // America/Los_Angeles + { 688, 348, 221269, 12, }, // America/Indiana/Indianapolis + { 688, 481, 221281, 14, }, // America/Indiana/Knox + { 688, 7961, 221295, 17, }, // America/Indiana/Marengo + { 688, 7985, 221312, 20, }, // America/Indiana/Petersburg + { 688, 8012, 221332, 19, }, // America/Indiana/Tell_City + { 688, 8038, 221351, 15, }, // America/Indiana/Vevay + { 688, 8060, 221366, 19, }, // America/Indiana/Vincennes + { 688, 8086, 221385, 17, }, // America/Indiana/Winamac + { 688, 2799, 221402, 7, }, // America/Jamaica + { 688, 8125, 221409, 21, }, // America/Kentucky/Monticello + { 688, 3239, 221430, 11, }, // America/Los_Angeles { 688, 5932, 207, 22, }, // America/Lower_Princes { 688, 8153, 26588, 6, }, // America/Maceio - { 688, 5805, 221450, 9, }, // America/Martinique + { 688, 5805, 221441, 9, }, // America/Martinique { 688, 8220, 229, 6, }, // America/Merida - { 688, 2949, 221459, 16, }, // America/Mexico_City - { 688, 4391, 221475, 8, }, // America/Miquelon + { 688, 2949, 221450, 16, }, // America/Mexico_City + { 688, 4391, 221466, 8, }, // America/Miquelon { 688, 8270, 21944, 8, }, // America/Monterrey { 688, 5824, 7172, 9, }, // America/Montserrat { 688, 1850, 235, 19, }, // America/Noronha - { 688, 8301, 221483, 20, }, // America/North_Dakota/Beulah - { 688, 8329, 221503, 20, }, // America/North_Dakota/Center - { 688, 8357, 221523, 23, }, // America/North_Dakota/New_Salem + { 688, 8301, 221474, 20, }, // America/North_Dakota/Beulah + { 688, 8329, 221494, 20, }, // America/North_Dakota/Center + { 688, 8357, 221514, 23, }, // America/North_Dakota/New_Salem { 688, 393, 317, 4, }, // America/Nuuk { 688, 2356, 164613, 6, }, // America/Panama - { 688, 3945, 221546, 14, }, // America/Port-au-Prince - { 688, 5954, 221560, 15, }, // America/Port_of_Spain + { 688, 3945, 221537, 14, }, // America/Port-au-Prince + { 688, 5954, 221551, 15, }, // America/Port_of_Spain { 688, 5843, 95222, 9, }, // America/Puerto_Rico - { 688, 1878, 221575, 8, }, // America/Sao_Paulo + { 688, 1878, 221566, 8, }, // America/Sao_Paulo { 688, 6899, 321, 16, }, // America/Scoresbysund - { 688, 8508, 221583, 13, }, // America/St_Barthelemy - { 688, 2061, 221596, 8, }, // America/St_Johns - { 688, 5863, 221604, 12, }, // America/St_Kitts - { 688, 5880, 221616, 8, }, // America/St_Lucia - { 688, 855, 221197, 9, }, // America/St_Thomas - { 688, 5913, 221624, 11, }, // America/St_Vincent + { 688, 8508, 221574, 13, }, // America/St_Barthelemy + { 688, 2061, 221587, 8, }, // America/St_Johns + { 688, 5863, 221595, 12, }, // America/St_Kitts + { 688, 5880, 221607, 8, }, // America/St_Lucia + { 688, 855, 221188, 9, }, // America/St_Thomas + { 688, 5913, 221615, 11, }, // America/St_Vincent { 688, 5688, 148000, 7, }, // America/Tortola { 688, 6133, 400, 16, }, // Antarctica/DumontDUrville - { 688, 8568, 221635, 15, }, // Antarctica/Macquarie + { 688, 8568, 221626, 15, }, // Antarctica/Macquarie { 688, 5395, 7594, 6, }, // Asia/Almaty { 688, 3968, 5605, 4, }, // Asia/Amman - { 688, 5511, 221650, 6, }, // Asia/Anadyr - { 688, 5523, 221656, 5, }, // Asia/Aqtau + { 688, 5511, 221641, 6, }, // Asia/Anadyr + { 688, 5523, 221647, 5, }, // Asia/Aqtau { 688, 5368, 7606, 6, }, // Asia/Aqtobe - { 688, 964, 221661, 7, }, // Asia/Ashgabat - { 688, 8624, 221668, 6, }, // Asia/Atyrau + { 688, 964, 221652, 7, }, // Asia/Ashgabat + { 688, 8624, 221659, 6, }, // Asia/Atyrau { 688, 3607, 4162, 6, }, // Asia/Baghdad { 688, 5534, 63955, 6, }, // Asia/Bahrain { 688, 3778, 91536, 6, }, // Asia/Bishkek { 688, 5989, 20751, 6, }, // Asia/Brunei { 688, 4601, 93254, 4, }, // Asia/Chita - { 688, 4511, 221674, 7, }, // Asia/Colombo + { 688, 4511, 221665, 7, }, // Asia/Colombo { 688, 4540, 74438, 7, }, // Asia/Damascus { 688, 1093, 158496, 4, }, // Asia/Dhaka - { 688, 3596, 221681, 5, }, // Asia/Dubai - { 688, 6159, 221686, 7, }, // Asia/Dushanbe + { 688, 3596, 221672, 5, }, // Asia/Dubai + { 688, 6159, 221677, 7, }, // Asia/Dushanbe { 688, 8636, 95258, 9, }, // Asia/Famagusta { 688, 1259, 432, 11, }, // Asia/Ho_Chi_Minh { 688, 1290, 123559, 10, }, // Asia/Jerusalem { 688, 4316, 162180, 9, }, // Asia/Kamchatka - { 688, 1185, 221693, 8, }, // Asia/Kathmandu - { 688, 8661, 221701, 7, }, // Asia/Khandyga + { 688, 1185, 221684, 8, }, // Asia/Kathmandu + { 688, 8661, 221692, 7, }, // Asia/Khandyga { 688, 992, 20838, 7, }, // Asia/Kolkata - { 688, 4197, 221708, 11, }, // Asia/Krasnoyarsk - { 688, 4859, 221719, 12, }, // Asia/Kuala_Lumpur - { 688, 1211, 221731, 5, }, // Asia/Macau + { 688, 4197, 221699, 11, }, // Asia/Krasnoyarsk + { 688, 4859, 221710, 12, }, // Asia/Kuala_Lumpur + { 688, 1211, 221722, 5, }, // Asia/Macau { 688, 1349, 7736, 7, }, // Asia/Makassar { 688, 6920, 20857, 7, }, // Asia/Muscat - { 688, 8675, 221736, 13, }, // Asia/Novokuznetsk + { 688, 8675, 221727, 13, }, // Asia/Novokuznetsk { 688, 7145, 65240, 5, }, // Asia/Oral { 688, 6961, 22518, 8, }, // Asia/Phnom_Penh { 688, 5559, 73150, 5, }, // Asia/Qatar - { 688, 8708, 221749, 8, }, // Asia/Qostanay + { 688, 8708, 221740, 8, }, // Asia/Qostanay { 688, 4269, 7778, 9, }, // Asia/Qyzylorda { 688, 3584, 7787, 4, }, // Asia/Riyadh { 688, 4408, 158282, 7, }, // Asia/Sakhalin { 688, 7245, 20886, 10, }, // Asia/Samarkand { 688, 3279, 7798, 4, }, // Asia/Seoul - { 688, 1053, 221757, 8, }, // Asia/Shanghai - { 688, 4297, 221765, 13, }, // Asia/Srednekolymsk + { 688, 1053, 221748, 8, }, // Asia/Shanghai + { 688, 4297, 221756, 13, }, // Asia/Srednekolymsk { 688, 3263, 177683, 6, }, // Asia/Taipei { 688, 4781, 91755, 7, }, // Asia/Tashkent { 688, 3915, 220114, 7, }, // Asia/Tbilisi { 688, 2772, 7842, 7, }, // Asia/Tehran - { 688, 1317, 221778, 5, }, // Asia/Thimphu - { 688, 1021, 221783, 10, }, // Asia/Ulaanbaatar + { 688, 1317, 221769, 5, }, // Asia/Thimphu + { 688, 1021, 221774, 10, }, // Asia/Ulaanbaatar { 688, 1159, 202026, 7, }, // Asia/Urumqi - { 688, 8722, 221793, 9, }, // Asia/Ust-Nera + { 688, 8722, 221784, 9, }, // Asia/Ust-Nera { 688, 6977, 26939, 8, }, // Asia/Vientiane { 688, 1235, 477, 6, }, // Asia/Yangon - { 688, 3883, 221802, 14, }, // Asia/Yekaterinburg - { 688, 3747, 221816, 7, }, // Asia/Yerevan - { 688, 3663, 221823, 11, }, // Atlantic/Azores - { 688, 6628, 221834, 13, }, // Atlantic/Canary - { 688, 3727, 221847, 9, }, // Atlantic/Cape_Verde - { 688, 1395, 221856, 11, }, // Atlantic/Faroe - { 688, 8736, 221867, 13, }, // Atlantic/Madeira - { 688, 2748, 221880, 8, }, // Atlantic/Reykjavik - { 688, 7272, 221888, 16, }, // Atlantic/South_Georgia - { 688, 6821, 221904, 14, }, // Atlantic/St_Helena - { 688, 1670, 221918, 8, }, // Australia/Adelaide - { 688, 1635, 221926, 8, }, // Australia/Brisbane - { 688, 1547, 221934, 15, }, // Australia/Lord_Howe - { 688, 6441, 221949, 9, }, // Europe/Amsterdam + { 688, 3883, 221793, 14, }, // Asia/Yekaterinburg + { 688, 3747, 221807, 7, }, // Asia/Yerevan + { 688, 3663, 221814, 11, }, // Atlantic/Azores + { 688, 6628, 221825, 13, }, // Atlantic/Canary + { 688, 3727, 221838, 9, }, // Atlantic/Cape_Verde + { 688, 1395, 221847, 11, }, // Atlantic/Faroe + { 688, 8736, 221858, 13, }, // Atlantic/Madeira + { 688, 2748, 221871, 8, }, // Atlantic/Reykjavik + { 688, 7272, 221879, 16, }, // Atlantic/South_Georgia + { 688, 6821, 221895, 14, }, // Atlantic/St_Helena + { 688, 1670, 221909, 8, }, // Australia/Adelaide + { 688, 1635, 221917, 8, }, // Australia/Brisbane + { 688, 1547, 221925, 15, }, // Australia/Lord_Howe + { 688, 6441, 221940, 9, }, // Europe/Amsterdam { 688, 6216, 33638, 6, }, // Europe/Andorra { 688, 3620, 33644, 8, }, // Europe/Astrakhan { 688, 2300, 5911, 5, }, // Europe/Athens { 688, 6336, 58906, 8, }, // Europe/Belgrade - { 688, 6488, 221958, 10, }, // Europe/Bratislava + { 688, 6488, 221949, 10, }, // Europe/Bratislava { 688, 2167, 27022, 6, }, // Europe/Brussels { 688, 3928, 21073, 8, }, // Europe/Bucharest { 688, 8772, 27037, 8, }, // Europe/Busingen { 688, 6289, 95331, 10, }, // Europe/Copenhagen - { 688, 6307, 221968, 9, }, // Europe/Gibraltar - { 688, 8804, 221977, 12, }, // Europe/Isle_of_Man + { 688, 6307, 221959, 9, }, // Europe/Gibraltar + { 688, 8804, 221968, 12, }, // Europe/Isle_of_Man { 688, 1130, 164893, 8, }, // Europe/Istanbul { 688, 3979, 63006, 12, }, // Europe/Kaliningrad { 688, 2527, 8148, 4, }, // Europe/Kyiv { 688, 3213, 157721, 7, }, // Europe/Lisbon - { 688, 6506, 221989, 8, }, // Europe/Ljubljana + { 688, 6506, 221980, 8, }, // Europe/Ljubljana { 688, 2501, 95370, 6, }, // Europe/London - { 688, 6365, 221997, 10, }, // Europe/Luxembourg + { 688, 6365, 221988, 10, }, // Europe/Luxembourg { 688, 6410, 44570, 6, }, // Europe/Monaco { 688, 3537, 95387, 5, }, // Europe/Moscow - { 688, 6458, 222007, 4, }, // Europe/Oslo - { 688, 4284, 222011, 6, }, // Europe/Paris + { 688, 6458, 221998, 4, }, // Europe/Oslo + { 688, 4284, 222002, 6, }, // Europe/Paris { 688, 6424, 196828, 9, }, // Europe/Podgorica { 688, 6275, 21185, 5, }, // Europe/Prague { 688, 6324, 6064, 4, }, // Europe/Rome { 688, 6470, 65868, 9, }, // Europe/San_Marino - { 688, 8849, 222017, 11, }, // Europe/Simferopol - { 688, 6523, 222028, 8, }, // Europe/Stockholm + { 688, 8849, 222008, 11, }, // Europe/Simferopol + { 688, 6523, 222019, 8, }, // Europe/Stockholm { 688, 8867, 8250, 5, }, // Europe/Tallinn { 688, 6202, 21213, 6, }, // Europe/Tirane - { 688, 8882, 222036, 8, }, // Europe/Ulyanovsk - { 688, 6567, 222044, 7, }, // Europe/Vatican + { 688, 8882, 222027, 8, }, // Europe/Ulyanovsk + { 688, 6567, 222035, 7, }, // Europe/Vatican { 688, 6231, 21230, 5, }, // Europe/Vienna { 688, 4727, 63187, 10, }, // Europe/Volgograd { 688, 3190, 95436, 8, }, // Europe/Warsaw { 688, 6540, 95452, 6, }, // Europe/Zurich - { 688, 6947, 222051, 6, }, // Indian/Chagos - { 688, 6046, 222057, 15, }, // Indian/Christmas - { 688, 6063, 222072, 11, }, // Indian/Cocos - { 688, 5029, 222083, 12, }, // Indian/Comoro + { 688, 6947, 222042, 6, }, // Indian/Chagos + { 688, 6046, 222048, 15, }, // Indian/Christmas + { 688, 6063, 222063, 11, }, // Indian/Cocos + { 688, 5029, 222074, 12, }, // Indian/Comoro { 688, 7260, 27115, 4, }, // Indian/Mahe - { 688, 7050, 222095, 13, }, // Indian/Maldives - { 688, 4069, 222108, 14, }, // Indian/Mauritius - { 688, 5098, 222122, 12, }, // Indian/Mayotte - { 688, 7211, 222134, 13, }, // Indian/Reunion - { 688, 3706, 222147, 18, }, // Pacific/Bougainville - { 688, 3015, 222165, 12, }, // Pacific/Chatham - { 688, 3157, 222177, 11, }, // Pacific/Chuuk - { 688, 2237, 222188, 15, }, // Pacific/Easter - { 688, 7360, 222203, 11, }, // Pacific/Efate - { 688, 7327, 222214, 13, }, // Pacific/Fakaofo - { 688, 7343, 222227, 14, }, // Pacific/Funafuti + { 688, 7050, 222086, 13, }, // Indian/Maldives + { 688, 4069, 222099, 14, }, // Indian/Mauritius + { 688, 5098, 222113, 12, }, // Indian/Mayotte + { 688, 7211, 222125, 13, }, // Indian/Reunion + { 688, 3706, 222138, 18, }, // Pacific/Bougainville + { 688, 3015, 222156, 12, }, // Pacific/Chatham + { 688, 3157, 222168, 11, }, // Pacific/Chuuk + { 688, 2237, 222179, 15, }, // Pacific/Easter + { 688, 7360, 222194, 11, }, // Pacific/Efate + { 688, 7327, 222205, 13, }, // Pacific/Fakaofo + { 688, 7343, 222218, 14, }, // Pacific/Funafuti { 688, 6678, 167332, 9, }, // Pacific/Galapagos - { 688, 6696, 222241, 13, }, // Pacific/Gambier - { 688, 3822, 222254, 17, }, // Pacific/Guadalcanal - { 688, 3049, 222271, 12, }, // Pacific/Kanton - { 688, 3998, 222283, 16, }, // Pacific/Kiritimati - { 688, 7019, 222299, 12, }, // Pacific/Kosrae - { 688, 2842, 222311, 15, }, // Pacific/Kwajalein - { 688, 4051, 222326, 14, }, // Pacific/Marquesas - { 688, 8914, 222340, 12, }, // Pacific/Midway - { 688, 7084, 222352, 11, }, // Pacific/Nauru - { 688, 7132, 222363, 10, }, // Pacific/Niue - { 688, 4168, 222373, 13, }, // Pacific/Norfolk + { 688, 6696, 222232, 13, }, // Pacific/Gambier + { 688, 3822, 222245, 17, }, // Pacific/Guadalcanal + { 688, 3049, 222262, 12, }, // Pacific/Kanton + { 688, 3998, 222274, 16, }, // Pacific/Kiritimati + { 688, 7019, 222290, 12, }, // Pacific/Kosrae + { 688, 2842, 222302, 15, }, // Pacific/Kwajalein + { 688, 4051, 222317, 14, }, // Pacific/Marquesas + { 688, 8914, 222331, 12, }, // Pacific/Midway + { 688, 7084, 222343, 11, }, // Pacific/Nauru + { 688, 7132, 222354, 10, }, // Pacific/Niue + { 688, 4168, 222364, 13, }, // Pacific/Norfolk { 688, 7098, 4628, 6, }, // Pacific/Noumea { 688, 3126, 135456, 11, }, // Pacific/Pago_Pago - { 688, 7155, 222386, 5, }, // Pacific/Palau - { 688, 7194, 222391, 14, }, // Pacific/Pitcairn - { 688, 3096, 222405, 12, }, // Pacific/Pohnpei - { 688, 4807, 222417, 13, }, // Pacific/Port_Moresby - { 688, 6076, 222430, 15, }, // Pacific/Rarotonga - { 688, 6031, 222445, 12, }, // Pacific/Saipan - { 688, 7312, 222457, 11, }, // Pacific/Tahiti - { 688, 6712, 222468, 13, }, // Pacific/Tarawa - { 688, 4583, 222481, 15, }, // Pacific/Tongatapu - { 688, 7392, 222496, 10, }, // Pacific/Wake - { 688, 7405, 222506, 12, }, // Pacific/Wallis - { 689, 6788, 222518, 7, }, // Africa/Abidjan Kuvi/Latin/India - { 689, 6760, 222525, 4, }, // Africa/Accra - { 689, 5059, 222529, 10, }, // Africa/Addis_Ababa - { 689, 7420, 222539, 7, }, // Africa/Algiers - { 689, 14, 222546, 6, }, // Africa/Asmara - { 689, 44, 222552, 6, }, // Africa/Bamako - { 689, 5257, 222558, 6, }, // Africa/Bangui - { 689, 6746, 222564, 6, }, // Africa/Banjul - { 689, 7435, 222570, 6, }, // Africa/Bissau - { 689, 4957, 222576, 8, }, // Africa/Blantyre - { 689, 5287, 222584, 9, }, // Africa/Brazzaville - { 689, 4922, 222593, 9, }, // Africa/Bujumbura - { 689, 2320, 222602, 5, }, // Africa/Cairo - { 689, 4117, 222607, 10, }, // Africa/Casablanca - { 689, 7449, 222617, 5, }, // Africa/Ceuta - { 689, 6773, 222622, 7, }, // Africa/Conakry - { 689, 6840, 222629, 4, }, // Africa/Dakar - { 689, 5130, 222633, 13, }, // Africa/Dar_es_Salaam + { 688, 7155, 222377, 5, }, // Pacific/Palau + { 688, 7194, 222382, 14, }, // Pacific/Pitcairn + { 688, 3096, 222396, 12, }, // Pacific/Pohnpei + { 688, 4807, 222408, 13, }, // Pacific/Port_Moresby + { 688, 6076, 222421, 15, }, // Pacific/Rarotonga + { 688, 6031, 222436, 12, }, // Pacific/Saipan + { 688, 7312, 222448, 11, }, // Pacific/Tahiti + { 688, 6712, 222459, 13, }, // Pacific/Tarawa + { 688, 4583, 222472, 15, }, // Pacific/Tongatapu + { 688, 7392, 222487, 10, }, // Pacific/Wake + { 688, 7405, 222497, 12, }, // Pacific/Wallis + { 689, 6788, 222509, 7, }, // Africa/Abidjan Kuvi/Latin/India + { 689, 6760, 222516, 4, }, // Africa/Accra + { 689, 5059, 222520, 10, }, // Africa/Addis_Ababa + { 689, 7420, 222530, 7, }, // Africa/Algiers + { 689, 14, 222537, 6, }, // Africa/Asmara + { 689, 44, 222543, 6, }, // Africa/Bamako + { 689, 5257, 222549, 6, }, // Africa/Bangui + { 689, 6746, 222555, 6, }, // Africa/Banjul + { 689, 7435, 222561, 6, }, // Africa/Bissau + { 689, 4957, 222567, 8, }, // Africa/Blantyre + { 689, 5287, 222575, 9, }, // Africa/Brazzaville + { 689, 4922, 222584, 9, }, // Africa/Bujumbura + { 689, 2320, 222593, 5, }, // Africa/Cairo + { 689, 4117, 222598, 10, }, // Africa/Casablanca + { 689, 7449, 222608, 5, }, // Africa/Ceuta + { 689, 6773, 222613, 7, }, // Africa/Conakry + { 689, 6840, 222620, 4, }, // Africa/Dakar + { 689, 5130, 222624, 13, }, // Africa/Dar_es_Salaam { 689, 5043, 26493, 6, }, // Africa/Djibouti - { 689, 5243, 222646, 5, }, // Africa/Douala - { 689, 5166, 222651, 9, }, // Africa/El_Aaiun - { 689, 6853, 222660, 7, }, // Africa/Freetown - { 689, 4906, 222667, 7, }, // Africa/Gaborone - { 689, 5015, 222674, 5, }, // Africa/Harare - { 689, 4479, 222679, 12, }, // Africa/Johannesburg - { 689, 4499, 222691, 4, }, // Africa/Juba - { 689, 5151, 222695, 6, }, // Africa/Kampala - { 689, 4524, 222701, 7, }, // Africa/Khartoum - { 689, 4973, 222708, 6, }, // Africa/Kigali - { 689, 5306, 222714, 7, }, // Africa/Kinshasa - { 689, 4744, 222721, 5, }, // Africa/Lagos - { 689, 5336, 222726, 9, }, // Africa/Libreville + { 689, 5243, 222637, 5, }, // Africa/Douala + { 689, 5166, 222642, 9, }, // Africa/El_Aaiun + { 689, 6853, 222651, 7, }, // Africa/Freetown + { 689, 4906, 222658, 7, }, // Africa/Gaborone + { 689, 5015, 222665, 5, }, // Africa/Harare + { 689, 4479, 222670, 12, }, // Africa/Johannesburg + { 689, 4499, 222682, 4, }, // Africa/Juba + { 689, 5151, 222686, 6, }, // Africa/Kampala + { 689, 4524, 222692, 7, }, // Africa/Khartoum + { 689, 4973, 222699, 6, }, // Africa/Kigali + { 689, 5306, 222705, 7, }, // Africa/Kinshasa + { 689, 4744, 222712, 5, }, // Africa/Lagos + { 689, 5336, 222717, 9, }, // Africa/Libreville { 689, 6869, 4087, 3, }, // Africa/Lome - { 689, 5211, 222735, 6, }, // Africa/Luanda - { 689, 4939, 222741, 9, }, // Africa/Lubumbashi - { 689, 5001, 222750, 6, }, // Africa/Lusaka - { 689, 5322, 222756, 6, }, // Africa/Malabo - { 689, 4987, 222762, 6, }, // Africa/Maputo - { 689, 5197, 222768, 6, }, // Africa/Maseru - { 689, 5182, 222774, 7, }, // Africa/Mbabane - { 689, 5113, 222781, 8, }, // Africa/Mogadishu - { 689, 7034, 222789, 8, }, // Africa/Monrovia - { 689, 3853, 222797, 7, }, // Africa/Nairobi - { 689, 5271, 222804, 7, }, // Africa/Ndjamena - { 689, 5354, 222811, 6, }, // Africa/Niamey - { 689, 6803, 222817, 6, }, // Africa/Nouakchott - { 689, 6727, 222823, 7, }, // Africa/Ouagadougou - { 689, 5225, 222830, 10, }, // Africa/Porto-Novo - { 689, 4435, 222840, 7, }, // Africa/Sao_Tome - { 689, 2866, 222847, 7, }, // Africa/Tripoli - { 689, 6554, 222854, 5, }, // Africa/Tunis - { 689, 4152, 222859, 7, }, // Africa/Windhoek - { 689, 132, 222866, 4, }, // America/Adak - { 689, 3346, 222870, 7, }, // America/Anchorage - { 689, 5607, 222877, 8, }, // America/Anguilla - { 689, 5624, 222885, 7, }, // America/Antigua - { 689, 4554, 222892, 9, }, // America/Araguaina - { 689, 166, 222901, 13, }, // America/Argentina/Buenos_Aires - { 689, 91, 222914, 9, }, // America/Argentina/Catamarca - { 689, 270, 222923, 7, }, // America/Argentina/Cordoba - { 689, 441, 222930, 5, }, // America/Argentina/Jujuy - { 689, 7462, 222935, 8, }, // America/Argentina/La_Rioja - { 689, 565, 222943, 7, }, // America/Argentina/Mendoza - { 689, 7489, 222950, 13, }, // America/Argentina/Rio_Gallegos - { 689, 7520, 222963, 5, }, // America/Argentina/Salta - { 689, 7544, 222968, 8, }, // America/Argentina/San_Juan - { 689, 5580, 222976, 8, }, // America/Argentina/San_Luis - { 689, 7571, 222984, 6, }, // America/Argentina/Tucuman - { 689, 7597, 222990, 7, }, // America/Argentina/Ushuaia - { 689, 5640, 222997, 5, }, // America/Aruba - { 689, 4252, 223002, 8, }, // America/Asuncion - { 689, 237, 223010, 8, }, // America/Atikokan - { 689, 3679, 223018, 5, }, // America/Bahia - { 689, 7623, 223023, 13, }, // America/Bahia_Banderas - { 689, 5654, 223036, 8, }, // America/Barbados - { 689, 7646, 223044, 5, }, // America/Belem - { 689, 5407, 223049, 5, }, // America/Belize - { 689, 7660, 223054, 12, }, // America/Blanc-Sablon - { 689, 7681, 223066, 9, }, // America/Boa_Vista - { 689, 4361, 223075, 6, }, // America/Bogota - { 689, 7699, 223081, 5, }, // America/Boise - { 689, 7713, 223086, 10, }, // America/Cambridge_Bay - { 689, 7735, 223096, 12, }, // America/Campo_Grande - { 689, 3868, 223108, 6, }, // America/Cancun - { 689, 4694, 223114, 7, }, // America/Caracas - { 689, 4345, 223121, 5, }, // America/Cayenne - { 689, 5496, 223126, 6, }, // America/Cayman - { 689, 2260, 223132, 6, }, // America/Chicago - { 689, 7756, 223138, 9, }, // America/Chihuahua + { 689, 5211, 222726, 6, }, // Africa/Luanda + { 689, 4939, 222732, 9, }, // Africa/Lubumbashi + { 689, 5001, 222741, 6, }, // Africa/Lusaka + { 689, 5322, 222747, 6, }, // Africa/Malabo + { 689, 4987, 222753, 6, }, // Africa/Maputo + { 689, 5197, 222759, 6, }, // Africa/Maseru + { 689, 5182, 222765, 7, }, // Africa/Mbabane + { 689, 5113, 222772, 8, }, // Africa/Mogadishu + { 689, 7034, 222780, 8, }, // Africa/Monrovia + { 689, 3853, 222788, 7, }, // Africa/Nairobi + { 689, 5271, 222795, 7, }, // Africa/Ndjamena + { 689, 5354, 222802, 6, }, // Africa/Niamey + { 689, 6803, 222808, 6, }, // Africa/Nouakchott + { 689, 6727, 222814, 7, }, // Africa/Ouagadougou + { 689, 5225, 222821, 10, }, // Africa/Porto-Novo + { 689, 4435, 222831, 7, }, // Africa/Sao_Tome + { 689, 2866, 222838, 7, }, // Africa/Tripoli + { 689, 6554, 222845, 5, }, // Africa/Tunis + { 689, 4152, 222850, 7, }, // Africa/Windhoek + { 689, 132, 222857, 4, }, // America/Adak + { 689, 3346, 222861, 7, }, // America/Anchorage + { 689, 5607, 222868, 8, }, // America/Anguilla + { 689, 5624, 222876, 7, }, // America/Antigua + { 689, 4554, 222883, 9, }, // America/Araguaina + { 689, 166, 222892, 13, }, // America/Argentina/Buenos_Aires + { 689, 91, 222905, 9, }, // America/Argentina/Catamarca + { 689, 270, 222914, 7, }, // America/Argentina/Cordoba + { 689, 441, 222921, 5, }, // America/Argentina/Jujuy + { 689, 7462, 222926, 8, }, // America/Argentina/La_Rioja + { 689, 565, 222934, 7, }, // America/Argentina/Mendoza + { 689, 7489, 222941, 13, }, // America/Argentina/Rio_Gallegos + { 689, 7520, 222954, 5, }, // America/Argentina/Salta + { 689, 7544, 222959, 8, }, // America/Argentina/San_Juan + { 689, 5580, 222967, 8, }, // America/Argentina/San_Luis + { 689, 7571, 222975, 6, }, // America/Argentina/Tucuman + { 689, 7597, 222981, 7, }, // America/Argentina/Ushuaia + { 689, 5640, 222988, 5, }, // America/Aruba + { 689, 4252, 222993, 8, }, // America/Asuncion + { 689, 237, 223001, 8, }, // America/Atikokan + { 689, 3679, 223009, 5, }, // America/Bahia + { 689, 7623, 223014, 13, }, // America/Bahia_Banderas + { 689, 5654, 223027, 8, }, // America/Barbados + { 689, 7646, 223035, 5, }, // America/Belem + { 689, 5407, 223040, 5, }, // America/Belize + { 689, 7660, 223045, 12, }, // America/Blanc-Sablon + { 689, 7681, 223057, 9, }, // America/Boa_Vista + { 689, 4361, 223066, 6, }, // America/Bogota + { 689, 7699, 223072, 5, }, // America/Boise + { 689, 7713, 223077, 10, }, // America/Cambridge_Bay + { 689, 7735, 223087, 12, }, // America/Campo_Grande + { 689, 3868, 223099, 6, }, // America/Cancun + { 689, 4694, 223105, 7, }, // America/Caracas + { 689, 4345, 223112, 5, }, // America/Cayenne + { 689, 5496, 223117, 6, }, // America/Cayman + { 689, 2260, 223123, 6, }, // America/Chicago + { 689, 7756, 223129, 9, }, // America/Chihuahua { 689, 7774, 53, 13, }, // America/Ciudad_Juarez - { 689, 5422, 223147, 10, }, // America/Costa_Rica - { 689, 7796, 223157, 7, }, // America/Creston - { 689, 3791, 223164, 6, }, // America/Cuiaba - { 689, 5723, 223170, 7, }, // America/Curacao - { 689, 7812, 223177, 11, }, // America/Danmarkshavn - { 689, 7833, 223188, 5, }, // America/Dawson - { 689, 7848, 223193, 11, }, // America/Dawson_Creek - { 689, 805, 223204, 6, }, // America/Denver - { 689, 3465, 223210, 7, }, // America/Detroit - { 689, 5739, 223217, 8, }, // America/Dominica - { 689, 893, 223225, 8, }, // America/Edmonton - { 689, 7869, 223233, 8, }, // America/Eirunepe - { 689, 5441, 223241, 11, }, // America/El_Salvador - { 689, 7886, 223252, 11, }, // America/Fort_Nelson - { 689, 7906, 223263, 9, }, // America/Fortaleza - { 689, 7924, 223272, 8, }, // America/Glace_Bay - { 689, 6881, 223280, 7, }, // America/Goose_Bay - { 689, 4612, 223287, 10, }, // America/Grand_Turk - { 689, 5770, 223297, 7, }, // America/Grenada - { 689, 5786, 223304, 10, }, // America/Guadeloupe - { 689, 3760, 223314, 9, }, // America/Guatemala - { 689, 4841, 223323, 8, }, // America/Guayaquil - { 689, 6932, 223331, 6, }, // America/Guyana - { 689, 1939, 223337, 8, }, // America/Halifax - { 689, 2281, 223345, 6, }, // America/Havana + { 689, 5422, 223138, 10, }, // America/Costa_Rica + { 689, 7796, 223148, 7, }, // America/Creston + { 689, 3791, 223155, 6, }, // America/Cuiaba + { 689, 5723, 223161, 7, }, // America/Curacao + { 689, 7812, 223168, 11, }, // America/Danmarkshavn + { 689, 7833, 223179, 5, }, // America/Dawson + { 689, 7848, 223184, 11, }, // America/Dawson_Creek + { 689, 805, 223195, 6, }, // America/Denver + { 689, 3465, 223201, 7, }, // America/Detroit + { 689, 5739, 223208, 8, }, // America/Dominica + { 689, 893, 223216, 8, }, // America/Edmonton + { 689, 7869, 223224, 8, }, // America/Eirunepe + { 689, 5441, 223232, 11, }, // America/El_Salvador + { 689, 7886, 223243, 11, }, // America/Fort_Nelson + { 689, 7906, 223254, 9, }, // America/Fortaleza + { 689, 7924, 223263, 8, }, // America/Glace_Bay + { 689, 6881, 223271, 7, }, // America/Goose_Bay + { 689, 4612, 223278, 10, }, // America/Grand_Turk + { 689, 5770, 223288, 7, }, // America/Grenada + { 689, 5786, 223295, 10, }, // America/Guadeloupe + { 689, 3760, 223305, 9, }, // America/Guatemala + { 689, 4841, 223314, 8, }, // America/Guayaquil + { 689, 6932, 223322, 6, }, // America/Guyana + { 689, 1939, 223328, 8, }, // America/Halifax + { 689, 2281, 223336, 6, }, // America/Havana { 689, 7942, 6920, 8, }, // America/Hermosillo - { 689, 348, 223351, 12, }, // America/Indiana/Indianapolis - { 689, 481, 223363, 14, }, // America/Indiana/Knox - { 689, 7961, 223377, 17, }, // America/Indiana/Marengo - { 689, 7985, 223394, 20, }, // America/Indiana/Petersburg - { 689, 8012, 223414, 19, }, // America/Indiana/Tell_City - { 689, 8038, 223433, 14, }, // America/Indiana/Vevay - { 689, 8060, 223447, 17, }, // America/Indiana/Vincennes - { 689, 8086, 223464, 17, }, // America/Indiana/Winamac - { 689, 8110, 223481, 6, }, // America/Inuvik - { 689, 660, 223487, 7, }, // America/Iqaluit - { 689, 2799, 223494, 7, }, // America/Jamaica - { 689, 5380, 223501, 5, }, // America/Juneau - { 689, 521, 223506, 9, }, // America/Kentucky/Louisville - { 689, 8125, 223515, 19, }, // America/Kentucky/Monticello - { 689, 5704, 223534, 10, }, // America/Kralendijk - { 689, 4376, 223544, 6, }, // America/La_Paz + { 689, 348, 223342, 12, }, // America/Indiana/Indianapolis + { 689, 481, 223354, 14, }, // America/Indiana/Knox + { 689, 7961, 223368, 17, }, // America/Indiana/Marengo + { 689, 7985, 223385, 20, }, // America/Indiana/Petersburg + { 689, 8012, 223405, 19, }, // America/Indiana/Tell_City + { 689, 8038, 223424, 14, }, // America/Indiana/Vevay + { 689, 8060, 223438, 17, }, // America/Indiana/Vincennes + { 689, 8086, 223455, 17, }, // America/Indiana/Winamac + { 689, 8110, 223472, 6, }, // America/Inuvik + { 689, 660, 223478, 7, }, // America/Iqaluit + { 689, 2799, 223485, 7, }, // America/Jamaica + { 689, 5380, 223492, 5, }, // America/Juneau + { 689, 521, 223497, 9, }, // America/Kentucky/Louisville + { 689, 8125, 223506, 19, }, // America/Kentucky/Monticello + { 689, 5704, 223525, 10, }, // America/Kralendijk + { 689, 4376, 223535, 6, }, // America/La_Paz { 689, 7169, 157373, 4, }, // America/Lima - { 689, 3239, 223550, 11, }, // America/Los_Angeles - { 689, 5932, 223561, 21, }, // America/Lower_Princes - { 689, 8153, 223582, 5, }, // America/Maceio - { 689, 8168, 223587, 7, }, // America/Managua - { 689, 1908, 223594, 6, }, // America/Manaus - { 689, 5897, 223600, 7, }, // America/Marigot - { 689, 5805, 223607, 8, }, // America/Martinique - { 689, 8184, 223615, 9, }, // America/Matamoros - { 689, 2917, 223624, 8, }, // America/Mazatlan - { 689, 8202, 223632, 8, }, // America/Menominee - { 689, 8220, 223640, 6, }, // America/Merida - { 689, 8235, 223646, 10, }, // America/Metlakatla - { 689, 2949, 223656, 12, }, // America/Mexico_City - { 689, 4391, 223668, 7, }, // America/Miquelon - { 689, 8254, 223675, 7, }, // America/Moncton - { 689, 8270, 223682, 8, }, // America/Monterrey - { 689, 4098, 223690, 10, }, // America/Montevideo - { 689, 5824, 223700, 10, }, // America/Montserrat - { 689, 5481, 223710, 5, }, // America/Nassau - { 689, 2379, 223715, 9, }, // America/New_York + { 689, 3239, 223541, 11, }, // America/Los_Angeles + { 689, 5932, 223552, 21, }, // America/Lower_Princes + { 689, 8153, 223573, 5, }, // America/Maceio + { 689, 8168, 223578, 7, }, // America/Managua + { 689, 1908, 223585, 6, }, // America/Manaus + { 689, 5897, 223591, 7, }, // America/Marigot + { 689, 5805, 223598, 8, }, // America/Martinique + { 689, 8184, 223606, 9, }, // America/Matamoros + { 689, 2917, 223615, 8, }, // America/Mazatlan + { 689, 8202, 223623, 8, }, // America/Menominee + { 689, 8220, 223631, 6, }, // America/Merida + { 689, 8235, 223637, 10, }, // America/Metlakatla + { 689, 2949, 223647, 12, }, // America/Mexico_City + { 689, 4391, 223659, 7, }, // America/Miquelon + { 689, 8254, 223666, 7, }, // America/Moncton + { 689, 8270, 223673, 8, }, // America/Monterrey + { 689, 4098, 223681, 10, }, // America/Montevideo + { 689, 5824, 223691, 10, }, // America/Montserrat + { 689, 5481, 223701, 5, }, // America/Nassau + { 689, 2379, 223706, 9, }, // America/New_York { 689, 8288, 7120, 3, }, // America/Nome - { 689, 1850, 223724, 7, }, // America/Noronha - { 689, 8301, 223731, 20, }, // America/North_Dakota/Beulah - { 689, 8329, 223751, 19, }, // America/North_Dakota/Center - { 689, 8357, 223770, 23, }, // America/North_Dakota/New_Salem - { 689, 393, 223793, 3, }, // America/Nuuk - { 689, 8388, 223796, 7, }, // America/Ojinaga - { 689, 2356, 223803, 6, }, // America/Panama - { 689, 6173, 223809, 10, }, // America/Paramaribo - { 689, 2973, 223819, 6, }, // America/Phoenix - { 689, 3945, 223825, 14, }, // America/Port-au-Prince - { 689, 5954, 223839, 13, }, // America/Port_of_Spain - { 689, 8404, 223852, 11, }, // America/Porto_Velho - { 689, 5843, 223863, 11, }, // America/Puerto_Rico - { 689, 4030, 223874, 12, }, // America/Punta_Arenas - { 689, 8424, 223886, 13, }, // America/Rankin_Inlet - { 689, 8445, 223899, 6, }, // America/Recife - { 689, 1995, 223905, 6, }, // America/Regina - { 689, 8460, 223911, 8, }, // America/Resolute - { 689, 695, 223919, 10, }, // America/Rio_Branco - { 689, 8477, 223929, 6, }, // America/Santarem - { 689, 2201, 223935, 8, }, // America/Santiago - { 689, 6111, 223943, 13, }, // America/Santo_Domingo - { 689, 1878, 223956, 9, }, // America/Sao_Paulo - { 689, 6899, 223965, 11, }, // America/Scoresbysund - { 689, 8494, 223976, 5, }, // America/Sitka - { 689, 8508, 223981, 14, }, // America/St_Barthelemy - { 689, 2061, 223995, 9, }, // America/St_Johns - { 689, 5863, 224004, 10, }, // America/St_Kitts - { 689, 5880, 224014, 10, }, // America/St_Lucia - { 689, 855, 224024, 10, }, // America/St_Thomas - { 689, 5913, 224034, 12, }, // America/St_Vincent - { 689, 8530, 224046, 13, }, // America/Swift_Current - { 689, 5461, 224059, 4, }, // America/Tegucigalpa - { 689, 5756, 224063, 4, }, // America/Thule - { 689, 313, 224067, 7, }, // America/Tijuana - { 689, 608, 224074, 7, }, // America/Toronto - { 689, 5688, 224081, 7, }, // America/Tortola - { 689, 2093, 224088, 8, }, // America/Vancouver - { 689, 2144, 224096, 9, }, // America/Whitehorse - { 689, 734, 224105, 8, }, // America/Winnipeg - { 689, 8552, 224113, 7, }, // America/Yakutat - { 689, 6001, 224120, 5, }, // Antarctica/Casey - { 689, 6094, 224125, 5, }, // Antarctica/Davis - { 689, 6133, 224130, 17, }, // Antarctica/DumontDUrville - { 689, 8568, 224147, 7, }, // Antarctica/Macquarie - { 689, 7066, 224154, 6, }, // Antarctica/Mawson - { 689, 7113, 224160, 9, }, // Antarctica/McMurdo - { 689, 8589, 224169, 6, }, // Antarctica/Palmer - { 689, 7226, 224175, 6, }, // Antarctica/Rothera - { 689, 7295, 224181, 5, }, // Antarctica/Syowa - { 689, 8607, 224186, 5, }, // Antarctica/Troll - { 689, 7374, 224191, 6, }, // Antarctica/Vostok - { 689, 1429, 224197, 10, }, // Arctic/Longyearbyen - { 689, 5570, 224207, 4, }, // Asia/Aden - { 689, 5395, 224211, 6, }, // Asia/Almaty - { 689, 3968, 224217, 5, }, // Asia/Amman - { 689, 5511, 224222, 6, }, // Asia/Anadyr - { 689, 5523, 224228, 5, }, // Asia/Aqtau - { 689, 5368, 224233, 7, }, // Asia/Aqtobe - { 689, 964, 224240, 7, }, // Asia/Ashgabat - { 689, 8624, 224247, 6, }, // Asia/Atyrau - { 689, 3607, 224253, 6, }, // Asia/Baghdad - { 689, 5534, 224259, 7, }, // Asia/Bahrain - { 689, 3653, 224266, 4, }, // Asia/Baku - { 689, 4466, 224270, 7, }, // Asia/Bangkok - { 689, 3571, 224277, 7, }, // Asia/Barnaul - { 689, 4086, 224284, 6, }, // Asia/Beirut - { 689, 3778, 224290, 6, }, // Asia/Bishkek - { 689, 5989, 224296, 6, }, // Asia/Brunei - { 689, 4601, 224302, 4, }, // Asia/Chita - { 689, 4511, 224306, 7, }, // Asia/Colombo - { 689, 4540, 224313, 8, }, // Asia/Damascus - { 689, 1093, 222867, 4, }, // Asia/Dhaka - { 689, 6192, 224321, 4, }, // Asia/Dili - { 689, 3596, 224325, 5, }, // Asia/Dubai - { 689, 6159, 224330, 7, }, // Asia/Dushanbe - { 689, 8636, 224337, 9, }, // Asia/Famagusta - { 689, 8651, 224346, 4, }, // Asia/Gaza - { 689, 4795, 224350, 6, }, // Asia/Hebron - { 689, 1259, 224356, 15, }, // Asia/Ho_Chi_Minh - { 689, 2704, 224371, 9, }, // Asia/Hong_Kong + { 689, 1850, 223715, 7, }, // America/Noronha + { 689, 8301, 223722, 20, }, // America/North_Dakota/Beulah + { 689, 8329, 223742, 19, }, // America/North_Dakota/Center + { 689, 8357, 223761, 23, }, // America/North_Dakota/New_Salem + { 689, 393, 223784, 3, }, // America/Nuuk + { 689, 8388, 223787, 7, }, // America/Ojinaga + { 689, 2356, 223794, 6, }, // America/Panama + { 689, 6173, 223800, 10, }, // America/Paramaribo + { 689, 2973, 223810, 6, }, // America/Phoenix + { 689, 3945, 223816, 14, }, // America/Port-au-Prince + { 689, 5954, 223830, 13, }, // America/Port_of_Spain + { 689, 8404, 223843, 11, }, // America/Porto_Velho + { 689, 5843, 223854, 11, }, // America/Puerto_Rico + { 689, 4030, 223865, 12, }, // America/Punta_Arenas + { 689, 8424, 223877, 13, }, // America/Rankin_Inlet + { 689, 8445, 223890, 6, }, // America/Recife + { 689, 1995, 223896, 6, }, // America/Regina + { 689, 8460, 223902, 8, }, // America/Resolute + { 689, 695, 223910, 10, }, // America/Rio_Branco + { 689, 8477, 223920, 6, }, // America/Santarem + { 689, 2201, 223926, 8, }, // America/Santiago + { 689, 6111, 223934, 13, }, // America/Santo_Domingo + { 689, 1878, 223947, 9, }, // America/Sao_Paulo + { 689, 6899, 223956, 11, }, // America/Scoresbysund + { 689, 8494, 223967, 5, }, // America/Sitka + { 689, 8508, 223972, 14, }, // America/St_Barthelemy + { 689, 2061, 223986, 9, }, // America/St_Johns + { 689, 5863, 223995, 10, }, // America/St_Kitts + { 689, 5880, 224005, 10, }, // America/St_Lucia + { 689, 855, 224015, 10, }, // America/St_Thomas + { 689, 5913, 224025, 12, }, // America/St_Vincent + { 689, 8530, 224037, 13, }, // America/Swift_Current + { 689, 5461, 224050, 4, }, // America/Tegucigalpa + { 689, 5756, 224054, 4, }, // America/Thule + { 689, 313, 224058, 7, }, // America/Tijuana + { 689, 608, 224065, 7, }, // America/Toronto + { 689, 5688, 224072, 7, }, // America/Tortola + { 689, 2093, 224079, 8, }, // America/Vancouver + { 689, 2144, 224087, 9, }, // America/Whitehorse + { 689, 734, 224096, 8, }, // America/Winnipeg + { 689, 8552, 224104, 7, }, // America/Yakutat + { 689, 6001, 224111, 5, }, // Antarctica/Casey + { 689, 6094, 224116, 5, }, // Antarctica/Davis + { 689, 6133, 224121, 17, }, // Antarctica/DumontDUrville + { 689, 8568, 224138, 7, }, // Antarctica/Macquarie + { 689, 7066, 224145, 6, }, // Antarctica/Mawson + { 689, 7113, 224151, 9, }, // Antarctica/McMurdo + { 689, 8589, 224160, 6, }, // Antarctica/Palmer + { 689, 7226, 224166, 6, }, // Antarctica/Rothera + { 689, 7295, 224172, 5, }, // Antarctica/Syowa + { 689, 8607, 224177, 5, }, // Antarctica/Troll + { 689, 7374, 224182, 6, }, // Antarctica/Vostok + { 689, 1429, 224188, 10, }, // Arctic/Longyearbyen + { 689, 5570, 224198, 4, }, // Asia/Aden + { 689, 5395, 224202, 6, }, // Asia/Almaty + { 689, 3968, 224208, 5, }, // Asia/Amman + { 689, 5511, 224213, 6, }, // Asia/Anadyr + { 689, 5523, 224219, 5, }, // Asia/Aqtau + { 689, 5368, 224224, 7, }, // Asia/Aqtobe + { 689, 964, 224231, 7, }, // Asia/Ashgabat + { 689, 8624, 224238, 6, }, // Asia/Atyrau + { 689, 3607, 224244, 6, }, // Asia/Baghdad + { 689, 5534, 224250, 7, }, // Asia/Bahrain + { 689, 3653, 224257, 4, }, // Asia/Baku + { 689, 4466, 224261, 7, }, // Asia/Bangkok + { 689, 3571, 224268, 7, }, // Asia/Barnaul + { 689, 4086, 224275, 6, }, // Asia/Beirut + { 689, 3778, 224281, 6, }, // Asia/Bishkek + { 689, 5989, 224287, 6, }, // Asia/Brunei + { 689, 4601, 224293, 4, }, // Asia/Chita + { 689, 4511, 224297, 7, }, // Asia/Colombo + { 689, 4540, 224304, 8, }, // Asia/Damascus + { 689, 1093, 222858, 4, }, // Asia/Dhaka + { 689, 6192, 224312, 4, }, // Asia/Dili + { 689, 3596, 224316, 5, }, // Asia/Dubai + { 689, 6159, 224321, 7, }, // Asia/Dushanbe + { 689, 8636, 224328, 9, }, // Asia/Famagusta + { 689, 8651, 224337, 4, }, // Asia/Gaza + { 689, 4795, 224341, 6, }, // Asia/Hebron + { 689, 1259, 224347, 15, }, // Asia/Ho_Chi_Minh + { 689, 2704, 224362, 9, }, // Asia/Hong_Kong { 689, 4771, 26836, 4, }, // Asia/Hovd - { 689, 4184, 224380, 7, }, // Asia/Irkutsk + { 689, 4184, 224371, 7, }, // Asia/Irkutsk { 689, 7006, 4248, 7, }, // Asia/Jakarta - { 689, 6992, 224387, 8, }, // Asia/Jayapura - { 689, 1290, 224395, 9, }, // Asia/Jerusalem - { 689, 3560, 224404, 5, }, // Asia/Kabul - { 689, 4316, 224409, 8, }, // Asia/Kamchatka - { 689, 4239, 224417, 6, }, // Asia/Karachi - { 689, 1185, 224423, 8, }, // Asia/Kathmandu - { 689, 8661, 224431, 7, }, // Asia/Khandyga - { 689, 992, 224438, 7, }, // Asia/Kolkata - { 689, 4197, 224445, 11, }, // Asia/Krasnoyarsk - { 689, 4859, 224456, 12, }, // Asia/Kuala_Lumpur - { 689, 5976, 224468, 6, }, // Asia/Kuching - { 689, 5547, 224474, 6, }, // Asia/Kuwait - { 689, 1211, 224480, 4, }, // Asia/Macau - { 689, 4017, 224484, 7, }, // Asia/Magadan - { 689, 1349, 224491, 7, }, // Asia/Makassar - { 689, 7182, 224498, 6, }, // Asia/Manila - { 689, 6920, 224504, 6, }, // Asia/Muscat - { 689, 2554, 224510, 8, }, // Asia/Nicosia - { 689, 8675, 224518, 12, }, // Asia/Novokuznetsk - { 689, 4135, 224530, 11, }, // Asia/Novosibirsk + { 689, 6992, 224378, 8, }, // Asia/Jayapura + { 689, 1290, 224386, 9, }, // Asia/Jerusalem + { 689, 3560, 224395, 5, }, // Asia/Kabul + { 689, 4316, 224400, 8, }, // Asia/Kamchatka + { 689, 4239, 224408, 6, }, // Asia/Karachi + { 689, 1185, 224414, 8, }, // Asia/Kathmandu + { 689, 8661, 224422, 7, }, // Asia/Khandyga + { 689, 992, 224429, 7, }, // Asia/Kolkata + { 689, 4197, 224436, 11, }, // Asia/Krasnoyarsk + { 689, 4859, 224447, 12, }, // Asia/Kuala_Lumpur + { 689, 5976, 224459, 6, }, // Asia/Kuching + { 689, 5547, 224465, 6, }, // Asia/Kuwait + { 689, 1211, 224471, 4, }, // Asia/Macau + { 689, 4017, 224475, 7, }, // Asia/Magadan + { 689, 1349, 224482, 7, }, // Asia/Makassar + { 689, 7182, 224489, 6, }, // Asia/Manila + { 689, 6920, 224495, 6, }, // Asia/Muscat + { 689, 2554, 224501, 8, }, // Asia/Nicosia + { 689, 8675, 224509, 12, }, // Asia/Novokuznetsk + { 689, 4135, 224521, 11, }, // Asia/Novosibirsk { 689, 4229, 123801, 4, }, // Asia/Omsk { 689, 7145, 91266, 4, }, // Asia/Oral - { 689, 6961, 224541, 9, }, // Asia/Phnom_Penh - { 689, 8693, 224550, 9, }, // Asia/Pontianak - { 689, 4214, 224559, 9, }, // Asia/Pyongyang + { 689, 6961, 224532, 9, }, // Asia/Phnom_Penh + { 689, 8693, 224541, 9, }, // Asia/Pontianak + { 689, 4214, 224550, 9, }, // Asia/Pyongyang { 689, 5559, 210375, 5, }, // Asia/Qatar - { 689, 8708, 224568, 7, }, // Asia/Qostanay - { 689, 4269, 224575, 8, }, // Asia/Qyzylorda - { 689, 3584, 224583, 5, }, // Asia/Riyadh - { 689, 4408, 224588, 7, }, // Asia/Sakhalin - { 689, 7245, 224595, 9, }, // Asia/Samarkand - { 689, 3279, 224604, 4, }, // Asia/Seoul - { 689, 1053, 224608, 6, }, // Asia/Shanghai - { 689, 3300, 224614, 8, }, // Asia/Singapore - { 689, 4297, 224622, 13, }, // Asia/Srednekolymsk - { 689, 3263, 224635, 6, }, // Asia/Taipei - { 689, 4781, 224641, 7, }, // Asia/Tashkent - { 689, 3915, 224648, 7, }, // Asia/Tbilisi - { 689, 2772, 224655, 6, }, // Asia/Tehran - { 689, 1317, 224661, 6, }, // Asia/Thimphu - { 689, 2821, 224667, 5, }, // Asia/Tokyo - { 689, 4572, 224672, 5, }, // Asia/Tomsk - { 689, 1021, 224677, 9, }, // Asia/Ulaanbaatar - { 689, 1159, 224686, 6, }, // Asia/Urumqi - { 689, 8722, 224692, 9, }, // Asia/Ust-Nera - { 689, 6977, 224701, 9, }, // Asia/Vientiane - { 689, 4710, 224710, 11, }, // Asia/Vladivostok - { 689, 4828, 224721, 7, }, // Asia/Yakutsk - { 689, 1235, 224728, 6, }, // Asia/Yangon - { 689, 3883, 224734, 13, }, // Asia/Yekaterinburg - { 689, 3747, 224747, 7, }, // Asia/Yerevan - { 689, 3663, 224754, 6, }, // Atlantic/Azores - { 689, 5671, 224760, 7, }, // Atlantic/Bermuda - { 689, 6628, 224767, 6, }, // Atlantic/Canary - { 689, 3727, 224773, 9, }, // Atlantic/Cape_Verde - { 689, 1395, 224782, 4, }, // Atlantic/Faroe - { 689, 8736, 224786, 7, }, // Atlantic/Madeira - { 689, 2748, 224793, 9, }, // Atlantic/Reykjavik - { 689, 7272, 224802, 11, }, // Atlantic/South_Georgia - { 689, 6821, 224813, 11, }, // Atlantic/St_Helena - { 689, 6644, 224824, 6, }, // Atlantic/Stanley - { 689, 1670, 224830, 8, }, // Australia/Adelaide - { 689, 1635, 224838, 8, }, // Australia/Brisbane - { 689, 1799, 224846, 11, }, // Australia/Broken_Hill - { 689, 1583, 224857, 6, }, // Australia/Darwin - { 689, 3637, 224863, 5, }, // Australia/Eucla - { 689, 1516, 224868, 6, }, // Australia/Hobart - { 689, 8753, 224874, 9, }, // Australia/Lindeman - { 689, 1547, 224883, 9, }, // Australia/Lord_Howe - { 689, 1727, 224892, 8, }, // Australia/Melbourne - { 689, 1762, 224900, 4, }, // Australia/Perth - { 689, 1463, 224904, 5, }, // Australia/Sydney - { 689, 6441, 224909, 9, }, // Europe/Amsterdam - { 689, 6216, 224918, 7, }, // Europe/Andorra - { 689, 3620, 224925, 9, }, // Europe/Astrakhan - { 689, 2300, 224934, 5, }, // Europe/Athens - { 689, 6336, 224939, 8, }, // Europe/Belgrade - { 689, 4757, 224947, 6, }, // Europe/Berlin - { 689, 6488, 224953, 10, }, // Europe/Bratislava - { 689, 2167, 224963, 8, }, // Europe/Brussels - { 689, 3928, 224971, 8, }, // Europe/Bucharest - { 689, 3806, 224979, 8, }, // Europe/Budapest - { 689, 8772, 224987, 8, }, // Europe/Busingen - { 689, 2583, 224995, 7, }, // Europe/Chisinau - { 689, 6289, 225002, 10, }, // Europe/Copenhagen - { 689, 2338, 225012, 5, }, // Europe/Dublin - { 689, 6307, 225017, 9, }, // Europe/Gibraltar - { 689, 8788, 225026, 6, }, // Europe/Guernsey - { 689, 6612, 225032, 8, }, // Europe/Helsinki - { 689, 8804, 225040, 11, }, // Europe/Isle_of_Man - { 689, 1130, 225051, 8, }, // Europe/Istanbul - { 689, 8823, 225059, 5, }, // Europe/Jersey - { 689, 3979, 225064, 11, }, // Europe/Kaliningrad - { 689, 8929, 225075, 5, }, // Europe/Kirov - { 689, 2527, 225080, 4, }, // Europe/Kyiv - { 689, 3213, 225084, 6, }, // Europe/Lisbon - { 689, 6506, 225090, 9, }, // Europe/Ljubljana - { 689, 2501, 225099, 4, }, // Europe/London - { 689, 6365, 225103, 8, }, // Europe/Luxembourg - { 689, 4892, 225111, 6, }, // Europe/Madrid - { 689, 6397, 225117, 5, }, // Europe/Malta - { 689, 6582, 225122, 8, }, // Europe/Mariehamn - { 689, 3693, 225130, 5, }, // Europe/Minsk - { 689, 6410, 225135, 6, }, // Europe/Monaco - { 689, 3537, 225141, 5, }, // Europe/Moscow - { 689, 6458, 225146, 4, }, // Europe/Oslo - { 689, 4284, 225150, 5, }, // Europe/Paris - { 689, 6424, 225155, 9, }, // Europe/Podgorica - { 689, 6275, 225164, 4, }, // Europe/Prague - { 689, 8837, 225168, 4, }, // Europe/Riga + { 689, 8708, 224559, 7, }, // Asia/Qostanay + { 689, 4269, 224566, 8, }, // Asia/Qyzylorda + { 689, 3584, 224574, 5, }, // Asia/Riyadh + { 689, 4408, 224579, 7, }, // Asia/Sakhalin + { 689, 7245, 224586, 9, }, // Asia/Samarkand + { 689, 3279, 224595, 4, }, // Asia/Seoul + { 689, 1053, 224599, 6, }, // Asia/Shanghai + { 689, 3300, 224605, 8, }, // Asia/Singapore + { 689, 4297, 224613, 13, }, // Asia/Srednekolymsk + { 689, 3263, 224626, 6, }, // Asia/Taipei + { 689, 4781, 224632, 7, }, // Asia/Tashkent + { 689, 3915, 224639, 7, }, // Asia/Tbilisi + { 689, 2772, 224646, 6, }, // Asia/Tehran + { 689, 1317, 224652, 6, }, // Asia/Thimphu + { 689, 2821, 224658, 5, }, // Asia/Tokyo + { 689, 4572, 224663, 5, }, // Asia/Tomsk + { 689, 1021, 224668, 9, }, // Asia/Ulaanbaatar + { 689, 1159, 224677, 6, }, // Asia/Urumqi + { 689, 8722, 224683, 9, }, // Asia/Ust-Nera + { 689, 6977, 224692, 9, }, // Asia/Vientiane + { 689, 4710, 224701, 11, }, // Asia/Vladivostok + { 689, 4828, 224712, 7, }, // Asia/Yakutsk + { 689, 1235, 224719, 6, }, // Asia/Yangon + { 689, 3883, 224725, 13, }, // Asia/Yekaterinburg + { 689, 3747, 224738, 7, }, // Asia/Yerevan + { 689, 3663, 224745, 6, }, // Atlantic/Azores + { 689, 5671, 224751, 7, }, // Atlantic/Bermuda + { 689, 6628, 224758, 6, }, // Atlantic/Canary + { 689, 3727, 224764, 9, }, // Atlantic/Cape_Verde + { 689, 1395, 224773, 4, }, // Atlantic/Faroe + { 689, 8736, 224777, 7, }, // Atlantic/Madeira + { 689, 2748, 224784, 9, }, // Atlantic/Reykjavik + { 689, 7272, 224793, 11, }, // Atlantic/South_Georgia + { 689, 6821, 224804, 11, }, // Atlantic/St_Helena + { 689, 6644, 224815, 6, }, // Atlantic/Stanley + { 689, 1670, 224821, 8, }, // Australia/Adelaide + { 689, 1635, 224829, 8, }, // Australia/Brisbane + { 689, 1799, 224837, 11, }, // Australia/Broken_Hill + { 689, 1583, 224848, 6, }, // Australia/Darwin + { 689, 3637, 224854, 5, }, // Australia/Eucla + { 689, 1516, 224859, 6, }, // Australia/Hobart + { 689, 8753, 224865, 9, }, // Australia/Lindeman + { 689, 1547, 224874, 9, }, // Australia/Lord_Howe + { 689, 1727, 224883, 8, }, // Australia/Melbourne + { 689, 1762, 224891, 4, }, // Australia/Perth + { 689, 1463, 224895, 5, }, // Australia/Sydney + { 689, 6441, 224900, 9, }, // Europe/Amsterdam + { 689, 6216, 224909, 7, }, // Europe/Andorra + { 689, 3620, 224916, 9, }, // Europe/Astrakhan + { 689, 2300, 224925, 5, }, // Europe/Athens + { 689, 6336, 224930, 8, }, // Europe/Belgrade + { 689, 4757, 224938, 6, }, // Europe/Berlin + { 689, 6488, 224944, 10, }, // Europe/Bratislava + { 689, 2167, 224954, 8, }, // Europe/Brussels + { 689, 3928, 224962, 8, }, // Europe/Bucharest + { 689, 3806, 224970, 8, }, // Europe/Budapest + { 689, 8772, 224978, 8, }, // Europe/Busingen + { 689, 2583, 224986, 7, }, // Europe/Chisinau + { 689, 6289, 224993, 10, }, // Europe/Copenhagen + { 689, 2338, 225003, 5, }, // Europe/Dublin + { 689, 6307, 225008, 9, }, // Europe/Gibraltar + { 689, 8788, 225017, 6, }, // Europe/Guernsey + { 689, 6612, 225023, 8, }, // Europe/Helsinki + { 689, 8804, 225031, 11, }, // Europe/Isle_of_Man + { 689, 1130, 225042, 8, }, // Europe/Istanbul + { 689, 8823, 225050, 5, }, // Europe/Jersey + { 689, 3979, 225055, 11, }, // Europe/Kaliningrad + { 689, 8929, 225066, 5, }, // Europe/Kirov + { 689, 2527, 225071, 4, }, // Europe/Kyiv + { 689, 3213, 225075, 6, }, // Europe/Lisbon + { 689, 6506, 225081, 9, }, // Europe/Ljubljana + { 689, 2501, 225090, 4, }, // Europe/London + { 689, 6365, 225094, 8, }, // Europe/Luxembourg + { 689, 4892, 225102, 6, }, // Europe/Madrid + { 689, 6397, 225108, 5, }, // Europe/Malta + { 689, 6582, 225113, 8, }, // Europe/Mariehamn + { 689, 3693, 225121, 5, }, // Europe/Minsk + { 689, 6410, 225126, 6, }, // Europe/Monaco + { 689, 3537, 225132, 5, }, // Europe/Moscow + { 689, 6458, 225137, 4, }, // Europe/Oslo + { 689, 4284, 225141, 5, }, // Europe/Paris + { 689, 6424, 225146, 9, }, // Europe/Podgorica + { 689, 6275, 225155, 4, }, // Europe/Prague + { 689, 8837, 225159, 4, }, // Europe/Riga { 689, 6324, 27088, 3, }, // Europe/Rome - { 689, 4331, 225172, 6, }, // Europe/Samara - { 689, 6470, 225178, 10, }, // Europe/San_Marino - { 689, 6245, 225188, 8, }, // Europe/Sarajevo - { 689, 4451, 225196, 7, }, // Europe/Saratov - { 689, 8849, 225203, 10, }, // Europe/Simferopol - { 689, 6383, 225213, 5, }, // Europe/Skopje - { 689, 6599, 225218, 6, }, // Europe/Sofia - { 689, 6523, 225224, 7, }, // Europe/Stockholm - { 689, 8867, 225231, 5, }, // Europe/Tallinn - { 689, 6202, 225236, 6, }, // Europe/Tirane - { 689, 8882, 225242, 9, }, // Europe/Ulyanovsk - { 689, 6352, 225251, 5, }, // Europe/Vaduz - { 689, 6567, 225256, 7, }, // Europe/Vatican - { 689, 6231, 225263, 6, }, // Europe/Vienna - { 689, 8899, 225269, 7, }, // Europe/Vilnius - { 689, 4727, 225276, 9, }, // Europe/Volgograd - { 689, 3190, 225285, 5, }, // Europe/Warsaw - { 689, 6261, 225290, 11, }, // Europe/Zagreb - { 689, 6540, 225301, 5, }, // Europe/Zurich - { 689, 5078, 225306, 9, }, // Indian/Antananarivo - { 689, 6947, 225315, 6, }, // Indian/Chagos - { 689, 6046, 225321, 8, }, // Indian/Christmas - { 689, 6063, 225329, 5, }, // Indian/Cocos - { 689, 5029, 225334, 6, }, // Indian/Comoro - { 689, 6661, 225340, 9, }, // Indian/Kerguelen - { 689, 7260, 225349, 4, }, // Indian/Mahe - { 689, 7050, 225353, 8, }, // Indian/Maldives - { 689, 4069, 225361, 9, }, // Indian/Mauritius - { 689, 5098, 225370, 5, }, // Indian/Mayotte - { 689, 7211, 225375, 7, }, // Indian/Reunion - { 689, 4422, 225382, 4, }, // Pacific/Apia - { 689, 932, 225386, 6, }, // Pacific/Auckland - { 689, 3706, 225392, 10, }, // Pacific/Bougainville - { 689, 3015, 225402, 5, }, // Pacific/Chatham - { 689, 3157, 225407, 3, }, // Pacific/Chuuk - { 689, 2237, 225410, 5, }, // Pacific/Easter - { 689, 7360, 225415, 5, }, // Pacific/Efate - { 689, 7327, 225420, 7, }, // Pacific/Fakaofo - { 689, 3902, 225427, 4, }, // Pacific/Fiji - { 689, 7343, 225431, 8, }, // Pacific/Funafuti - { 689, 6678, 225439, 9, }, // Pacific/Galapagos - { 689, 6696, 225448, 7, }, // Pacific/Gambier - { 689, 3822, 225455, 11, }, // Pacific/Guadalcanal - { 689, 6018, 223591, 4, }, // Pacific/Guam - { 689, 3049, 225466, 6, }, // Pacific/Kanton - { 689, 3998, 225472, 10, }, // Pacific/Kiritimati - { 689, 7019, 225482, 6, }, // Pacific/Kosrae - { 689, 2842, 225488, 9, }, // Pacific/Kwajalein - { 689, 4877, 225497, 6, }, // Pacific/Majuro - { 689, 4051, 225503, 8, }, // Pacific/Marquesas - { 689, 8914, 225511, 6, }, // Pacific/Midway - { 689, 7084, 225517, 5, }, // Pacific/Nauru - { 689, 7132, 225522, 4, }, // Pacific/Niue - { 689, 4168, 225526, 6, }, // Pacific/Norfolk - { 689, 7098, 225532, 5, }, // Pacific/Noumea - { 689, 3126, 225537, 11, }, // Pacific/Pago_Pago - { 689, 7155, 225548, 5, }, // Pacific/Palau - { 689, 7194, 225553, 7, }, // Pacific/Pitcairn - { 689, 3096, 225560, 6, }, // Pacific/Pohnpei - { 689, 4807, 225566, 12, }, // Pacific/Port_Moresby - { 689, 6076, 225578, 9, }, // Pacific/Rarotonga - { 689, 6031, 225587, 6, }, // Pacific/Saipan - { 689, 7312, 225593, 6, }, // Pacific/Tahiti - { 689, 6712, 225599, 6, }, // Pacific/Tarawa - { 689, 4583, 225605, 9, }, // Pacific/Tongatapu - { 689, 7392, 225614, 3, }, // Pacific/Wake - { 689, 7405, 225617, 6, }, // Pacific/Wallis + { 689, 4331, 225163, 6, }, // Europe/Samara + { 689, 6470, 225169, 10, }, // Europe/San_Marino + { 689, 6245, 225179, 8, }, // Europe/Sarajevo + { 689, 4451, 225187, 7, }, // Europe/Saratov + { 689, 8849, 225194, 10, }, // Europe/Simferopol + { 689, 6383, 225204, 5, }, // Europe/Skopje + { 689, 6599, 225209, 6, }, // Europe/Sofia + { 689, 6523, 225215, 7, }, // Europe/Stockholm + { 689, 8867, 225222, 5, }, // Europe/Tallinn + { 689, 6202, 225227, 6, }, // Europe/Tirane + { 689, 8882, 225233, 9, }, // Europe/Ulyanovsk + { 689, 6352, 225242, 5, }, // Europe/Vaduz + { 689, 6567, 225247, 7, }, // Europe/Vatican + { 689, 6231, 225254, 6, }, // Europe/Vienna + { 689, 8899, 225260, 7, }, // Europe/Vilnius + { 689, 4727, 225267, 9, }, // Europe/Volgograd + { 689, 3190, 225276, 5, }, // Europe/Warsaw + { 689, 6261, 225281, 11, }, // Europe/Zagreb + { 689, 6540, 225292, 5, }, // Europe/Zurich + { 689, 5078, 225297, 9, }, // Indian/Antananarivo + { 689, 6947, 225306, 6, }, // Indian/Chagos + { 689, 6046, 225312, 8, }, // Indian/Christmas + { 689, 6063, 225320, 5, }, // Indian/Cocos + { 689, 5029, 225325, 6, }, // Indian/Comoro + { 689, 6661, 225331, 9, }, // Indian/Kerguelen + { 689, 7260, 225340, 4, }, // Indian/Mahe + { 689, 7050, 225344, 8, }, // Indian/Maldives + { 689, 4069, 225352, 9, }, // Indian/Mauritius + { 689, 5098, 225361, 5, }, // Indian/Mayotte + { 689, 7211, 225366, 7, }, // Indian/Reunion + { 689, 4422, 225373, 4, }, // Pacific/Apia + { 689, 932, 225377, 6, }, // Pacific/Auckland + { 689, 3706, 225383, 10, }, // Pacific/Bougainville + { 689, 3015, 225393, 5, }, // Pacific/Chatham + { 689, 3157, 225398, 3, }, // Pacific/Chuuk + { 689, 2237, 225401, 5, }, // Pacific/Easter + { 689, 7360, 225406, 5, }, // Pacific/Efate + { 689, 7327, 225411, 7, }, // Pacific/Fakaofo + { 689, 3902, 225418, 4, }, // Pacific/Fiji + { 689, 7343, 225422, 8, }, // Pacific/Funafuti + { 689, 6678, 225430, 9, }, // Pacific/Galapagos + { 689, 6696, 225439, 7, }, // Pacific/Gambier + { 689, 3822, 225446, 11, }, // Pacific/Guadalcanal + { 689, 6018, 223582, 4, }, // Pacific/Guam + { 689, 3049, 225457, 6, }, // Pacific/Kanton + { 689, 3998, 225463, 10, }, // Pacific/Kiritimati + { 689, 7019, 225473, 6, }, // Pacific/Kosrae + { 689, 2842, 225479, 9, }, // Pacific/Kwajalein + { 689, 4877, 225488, 6, }, // Pacific/Majuro + { 689, 4051, 225494, 8, }, // Pacific/Marquesas + { 689, 8914, 225502, 6, }, // Pacific/Midway + { 689, 7084, 225508, 5, }, // Pacific/Nauru + { 689, 7132, 225513, 4, }, // Pacific/Niue + { 689, 4168, 225517, 6, }, // Pacific/Norfolk + { 689, 7098, 225523, 5, }, // Pacific/Noumea + { 689, 3126, 225528, 11, }, // Pacific/Pago_Pago + { 689, 7155, 225539, 5, }, // Pacific/Palau + { 689, 7194, 225544, 7, }, // Pacific/Pitcairn + { 689, 3096, 225551, 6, }, // Pacific/Pohnpei + { 689, 4807, 225557, 12, }, // Pacific/Port_Moresby + { 689, 6076, 225569, 9, }, // Pacific/Rarotonga + { 689, 6031, 225578, 6, }, // Pacific/Saipan + { 689, 7312, 225584, 6, }, // Pacific/Tahiti + { 689, 6712, 225590, 6, }, // Pacific/Tarawa + { 689, 4583, 225596, 9, }, // Pacific/Tongatapu + { 689, 7392, 225605, 3, }, // Pacific/Wake + { 689, 7405, 225608, 6, }, // Pacific/Wallis { 690, 6788, 29964, 7, }, // Africa/Abidjan Kuvi/Devanagari/India { 690, 6760, 88252, 5, }, // Africa/Accra { 690, 5059, 88257, 10, }, // Africa/Addis_Ababa @@ -50854,7 +50854,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 14, 88276, 7, }, // Africa/Asmara { 690, 44, 88283, 6, }, // Africa/Bamako { 690, 5257, 88289, 6, }, // Africa/Bangui - { 690, 6746, 225623, 9, }, // Africa/Banjul + { 690, 6746, 225614, 9, }, // Africa/Banjul { 690, 7435, 88301, 5, }, // Africa/Bissau { 690, 4957, 88306, 9, }, // Africa/Blantyre { 690, 5287, 88315, 11, }, // Africa/Brazzaville @@ -50868,31 +50868,31 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 5043, 88368, 6, }, // Africa/Djibouti { 690, 5243, 88374, 5, }, // Africa/Douala { 690, 5166, 88379, 8, }, // Africa/El_Aaiun - { 690, 6853, 225632, 9, }, // Africa/Freetown + { 690, 6853, 225623, 9, }, // Africa/Freetown { 690, 4906, 88396, 7, }, // Africa/Gaborone { 690, 5015, 88403, 5, }, // Africa/Harare { 690, 4479, 88408, 10, }, // Africa/Johannesburg { 690, 4499, 30154, 4, }, // Africa/Juba { 690, 5151, 88418, 6, }, // Africa/Kampala - { 690, 4524, 225641, 7, }, // Africa/Khartoum + { 690, 4524, 225632, 7, }, // Africa/Khartoum { 690, 4973, 88424, 6, }, // Africa/Kigali - { 690, 5306, 225648, 7, }, // Africa/Kinshasa + { 690, 5306, 225639, 7, }, // Africa/Kinshasa { 690, 4744, 88437, 5, }, // Africa/Lagos { 690, 5336, 88442, 10, }, // Africa/Libreville { 690, 6869, 88452, 3, }, // Africa/Lome { 690, 5211, 88455, 6, }, // Africa/Luanda - { 690, 4939, 225655, 9, }, // Africa/Lubumbashi + { 690, 4939, 225646, 9, }, // Africa/Lubumbashi { 690, 5001, 30221, 6, }, // Africa/Lusaka { 690, 5322, 88470, 5, }, // Africa/Malabo { 690, 4987, 88475, 6, }, // Africa/Maputo { 690, 5197, 30239, 6, }, // Africa/Maseru - { 690, 5182, 225664, 9, }, // Africa/Mbabane - { 690, 5113, 225673, 8, }, // Africa/Mogadishu + { 690, 5182, 225655, 9, }, // Africa/Mbabane + { 690, 5113, 225664, 8, }, // Africa/Mogadishu { 690, 7034, 88496, 9, }, // Africa/Monrovia - { 690, 3853, 225681, 7, }, // Africa/Nairobi + { 690, 3853, 225672, 7, }, // Africa/Nairobi { 690, 5271, 88513, 8, }, // Africa/Ndjamena { 690, 5354, 88521, 6, }, // Africa/Niamey - { 690, 6803, 225688, 7, }, // Africa/Nouakchott + { 690, 6803, 225679, 7, }, // Africa/Nouakchott { 690, 6727, 88534, 7, }, // Africa/Ouagadougou { 690, 5225, 88541, 11, }, // Africa/Porto-Novo { 690, 4435, 88552, 7, }, // Africa/Sao_Tome @@ -50912,45 +50912,45 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 565, 88633, 8, }, // America/Argentina/Mendoza { 690, 7489, 88641, 12, }, // America/Argentina/Rio_Gallegos { 690, 7520, 30437, 6, }, // America/Argentina/Salta - { 690, 7544, 225695, 11, }, // America/Argentina/San_Juan - { 690, 5580, 225706, 10, }, // America/Argentina/San_Luis + { 690, 7544, 225686, 11, }, // America/Argentina/San_Juan + { 690, 5580, 225697, 10, }, // America/Argentina/San_Luis { 690, 7571, 88669, 6, }, // America/Argentina/Tucuman - { 690, 7597, 225716, 7, }, // America/Argentina/Ushuaia + { 690, 7597, 225707, 7, }, // America/Argentina/Ushuaia { 690, 5640, 88682, 5, }, // America/Aruba - { 690, 4252, 225723, 8, }, // America/Asuncion + { 690, 4252, 225714, 8, }, // America/Asuncion { 690, 237, 88695, 8, }, // America/Atikokan { 690, 3679, 88703, 5, }, // America/Bahia { 690, 7623, 88708, 15, }, // America/Bahia_Banderas { 690, 5654, 88723, 8, }, // America/Barbados { 690, 7646, 30526, 5, }, // America/Belem { 690, 5407, 88731, 6, }, // America/Belize - { 690, 7660, 225731, 12, }, // America/Blanc-Sablon + { 690, 7660, 225722, 12, }, // America/Blanc-Sablon { 690, 7681, 88750, 10, }, // America/Boa_Vista { 690, 4361, 88760, 6, }, // America/Bogota { 690, 7699, 88766, 5, }, // America/Boise - { 690, 7713, 225743, 12, }, // America/Cambridge_Bay - { 690, 7735, 225755, 16, }, // America/Campo_Grande - { 690, 3868, 225771, 8, }, // America/Cancun + { 690, 7713, 225734, 12, }, // America/Cambridge_Bay + { 690, 7735, 225746, 16, }, // America/Campo_Grande + { 690, 3868, 225762, 8, }, // America/Cancun { 690, 4694, 88805, 6, }, // America/Caracas { 690, 4345, 30609, 5, }, // America/Cayenne { 690, 5496, 138409, 7, }, // America/Cayman - { 690, 2260, 225779, 6, }, // America/Chicago + { 690, 2260, 225770, 6, }, // America/Chicago { 690, 7756, 88817, 8, }, // America/Chihuahua { 690, 5422, 88841, 11, }, // America/Costa_Rica { 690, 7796, 30642, 8, }, // America/Creston { 690, 3791, 88852, 7, }, // America/Cuiaba { 690, 5723, 88859, 7, }, // America/Curacao - { 690, 7812, 225785, 11, }, // America/Danmarkshavn + { 690, 7812, 225776, 11, }, // America/Danmarkshavn { 690, 7833, 88877, 4, }, // America/Dawson { 690, 7848, 88881, 10, }, // America/Dawson_Creek { 690, 805, 88891, 5, }, // America/Denver { 690, 3465, 88896, 8, }, // America/Detroit { 690, 5739, 88904, 8, }, // America/Dominica { 690, 893, 88912, 6, }, // America/Edmonton - { 690, 7869, 225796, 8, }, // America/Eirunepe + { 690, 7869, 225787, 8, }, // America/Eirunepe { 690, 5441, 88918, 11, }, // America/El_Salvador - { 690, 7886, 225804, 13, }, // America/Fort_Nelson - { 690, 7906, 225817, 12, }, // America/Fortaleza + { 690, 7886, 225795, 13, }, // America/Fort_Nelson + { 690, 7906, 225808, 12, }, // America/Fortaleza { 690, 7924, 30760, 8, }, // America/Glace_Bay { 690, 6881, 113910, 6, }, // America/Goose_Bay { 690, 4612, 88974, 11, }, // America/Grand_Turk @@ -50959,7 +50959,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 3760, 30806, 10, }, // America/Guatemala { 690, 4841, 88994, 9, }, // America/Guayaquil { 690, 6932, 89003, 5, }, // America/Guyana - { 690, 1939, 225829, 9, }, // America/Halifax + { 690, 1939, 225820, 9, }, // America/Halifax { 690, 2281, 89018, 5, }, // America/Havana { 690, 7942, 89023, 11, }, // America/Hermosillo { 690, 348, 89034, 13, }, // America/Indiana/Indianapolis @@ -50971,20 +50971,20 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 8060, 89131, 18, }, // America/Indiana/Vincennes { 690, 8086, 89149, 17, }, // America/Indiana/Winamac { 690, 8110, 30999, 6, }, // America/Inuvik - { 690, 660, 225838, 8, }, // America/Iqaluit + { 690, 660, 225829, 8, }, // America/Iqaluit { 690, 2799, 138734, 6, }, // America/Jamaica { 690, 5380, 89178, 7, }, // America/Juneau { 690, 521, 89185, 8, }, // America/Kentucky/Louisville { 690, 8125, 89193, 17, }, // America/Kentucky/Monticello - { 690, 5704, 225846, 13, }, // America/Kralendijk + { 690, 5704, 225837, 13, }, // America/Kralendijk { 690, 4376, 89222, 7, }, // America/La_Paz { 690, 7169, 31064, 4, }, // America/Lima { 690, 3239, 89229, 11, }, // America/Los_Angeles { 690, 5932, 89240, 22, }, // America/Lower_Princes { 690, 8153, 89262, 5, }, // America/Maceio { 690, 8168, 89267, 7, }, // America/Managua - { 690, 1908, 225859, 4, }, // America/Manaus - { 690, 5897, 225863, 7, }, // America/Marigot + { 690, 1908, 225850, 4, }, // America/Manaus + { 690, 5897, 225854, 7, }, // America/Marigot { 690, 5805, 89285, 9, }, // America/Martinique { 690, 8184, 89294, 9, }, // America/Matamoros { 690, 2917, 89303, 9, }, // America/Mazatlan @@ -51001,43 +51001,43 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 2379, 89392, 9, }, // America/New_York { 690, 8288, 89314, 3, }, // America/Nome { 690, 1850, 89401, 8, }, // America/Noronha - { 690, 8301, 225870, 19, }, // America/North_Dakota/Beulah - { 690, 8329, 225889, 18, }, // America/North_Dakota/Center - { 690, 8357, 225907, 23, }, // America/North_Dakota/New_Salem + { 690, 8301, 225861, 19, }, // America/North_Dakota/Beulah + { 690, 8329, 225880, 18, }, // America/North_Dakota/Center + { 690, 8357, 225898, 23, }, // America/North_Dakota/New_Salem { 690, 393, 89472, 3, }, // America/Nuuk - { 690, 8388, 225930, 9, }, // America/Ojinaga + { 690, 8388, 225921, 9, }, // America/Ojinaga { 690, 2356, 89484, 5, }, // America/Panama { 690, 6173, 89489, 10, }, // America/Paramaribo - { 690, 2973, 225939, 8, }, // America/Phoenix + { 690, 2973, 225930, 8, }, // America/Phoenix { 690, 3945, 89507, 14, }, // America/Port-au-Prince - { 690, 5954, 225947, 15, }, // America/Port_of_Spain + { 690, 5954, 225938, 15, }, // America/Port_of_Spain { 690, 8404, 89536, 13, }, // America/Porto_Velho { 690, 5843, 89549, 11, }, // America/Puerto_Rico { 690, 4030, 89560, 12, }, // America/Punta_Arenas { 690, 8424, 89572, 12, }, // America/Rankin_Inlet - { 690, 8445, 225962, 7, }, // America/Recife + { 690, 8445, 225953, 7, }, // America/Recife { 690, 1995, 31431, 6, }, // America/Regina { 690, 8460, 89591, 9, }, // America/Resolute { 690, 695, 89600, 12, }, // America/Rio_Branco - { 690, 8477, 225969, 9, }, // America/Santarem - { 690, 2201, 225978, 8, }, // America/Santiago + { 690, 8477, 225960, 9, }, // America/Santarem + { 690, 2201, 225969, 8, }, // America/Santiago { 690, 6111, 89629, 13, }, // America/Santo_Domingo { 690, 1878, 89642, 9, }, // America/Sao_Paulo { 690, 6899, 89651, 13, }, // America/Scoresbysund { 690, 8494, 89664, 6, }, // America/Sitka - { 690, 8508, 225986, 15, }, // America/St_Barthelemy + { 690, 8508, 225977, 15, }, // America/St_Barthelemy { 690, 2061, 114496, 10, }, // America/St_Johns { 690, 5863, 89694, 10, }, // America/St_Kitts { 690, 5880, 89704, 11, }, // America/St_Lucia - { 690, 855, 226001, 9, }, // America/St_Thomas + { 690, 855, 225992, 9, }, // America/St_Thomas { 690, 5913, 89724, 12, }, // America/St_Vincent - { 690, 8530, 226010, 13, }, // America/Swift_Current + { 690, 8530, 226001, 13, }, // America/Swift_Current { 690, 5461, 89749, 11, }, // America/Tegucigalpa { 690, 5756, 129890, 4, }, // America/Thule { 690, 313, 89766, 7, }, // America/Tijuana { 690, 608, 89773, 6, }, // America/Toronto { 690, 5688, 89779, 8, }, // America/Tortola - { 690, 2093, 226023, 10, }, // America/Vancouver + { 690, 2093, 226014, 10, }, // America/Vancouver { 690, 2144, 89794, 11, }, // America/Whitehorse { 690, 734, 89805, 7, }, // America/Winnipeg { 690, 8552, 89812, 7, }, // America/Yakutat @@ -51046,37 +51046,37 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 6133, 89824, 19, }, // Antarctica/DumontDUrville { 690, 8568, 89843, 7, }, // Antarctica/Macquarie { 690, 7066, 89850, 4, }, // Antarctica/Mawson - { 690, 7113, 226033, 11, }, // Antarctica/McMurdo + { 690, 7113, 226024, 11, }, // Antarctica/McMurdo { 690, 8589, 89863, 4, }, // Antarctica/Palmer { 690, 7226, 89867, 6, }, // Antarctica/Rothera { 690, 7295, 89873, 6, }, // Antarctica/Syowa { 690, 8607, 89879, 5, }, // Antarctica/Troll { 690, 7374, 89884, 7, }, // Antarctica/Vostok - { 690, 1429, 226044, 12, }, // Arctic/Longyearbyen + { 690, 1429, 226035, 12, }, // Arctic/Longyearbyen { 690, 5570, 89904, 4, }, // Asia/Aden { 690, 5395, 89908, 7, }, // Asia/Almaty { 690, 3968, 89915, 6, }, // Asia/Amman { 690, 5511, 89921, 6, }, // Asia/Anadyr { 690, 5523, 31778, 6, }, // Asia/Aqtau { 690, 5368, 114670, 7, }, // Asia/Aqtobe - { 690, 964, 226056, 8, }, // Asia/Ashgabat + { 690, 964, 226047, 8, }, // Asia/Ashgabat { 690, 8624, 89933, 5, }, // Asia/Atyrau { 690, 3607, 89938, 5, }, // Asia/Baghdad { 690, 5534, 89943, 5, }, // Asia/Bahrain { 690, 3653, 88857, 4, }, // Asia/Baku - { 690, 4466, 226064, 9, }, // Asia/Bangkok + { 690, 4466, 226055, 9, }, // Asia/Bangkok { 690, 3571, 89954, 6, }, // Asia/Barnaul { 690, 4086, 89960, 5, }, // Asia/Beirut - { 690, 3778, 226073, 7, }, // Asia/Bishkek - { 690, 5989, 226080, 8, }, // Asia/Brunei - { 690, 4601, 226088, 6, }, // Asia/Chita + { 690, 3778, 226064, 7, }, // Asia/Bishkek + { 690, 5989, 226071, 8, }, // Asia/Brunei + { 690, 4601, 226079, 6, }, // Asia/Chita { 690, 4511, 89978, 6, }, // Asia/Colombo { 690, 4540, 89984, 7, }, // Asia/Damascus { 690, 1093, 89991, 4, }, // Asia/Dhaka { 690, 6192, 89995, 4, }, // Asia/Dili - { 690, 3596, 226094, 5, }, // Asia/Dubai - { 690, 6159, 226099, 7, }, // Asia/Dushanbe - { 690, 8636, 226106, 11, }, // Asia/Famagusta + { 690, 3596, 226085, 5, }, // Asia/Dubai + { 690, 6159, 226090, 7, }, // Asia/Dushanbe + { 690, 8636, 226097, 11, }, // Asia/Famagusta { 690, 8651, 90021, 5, }, // Asia/Gaza { 690, 4795, 90026, 7, }, // Asia/Hebron { 690, 1259, 90033, 16, }, // Asia/Ho_Chi_Minh @@ -51085,12 +51085,12 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 4184, 90063, 10, }, // Asia/Irkutsk { 690, 7006, 90073, 7, }, // Asia/Jakarta { 690, 6992, 31943, 7, }, // Asia/Jayapura - { 690, 1290, 226117, 8, }, // Asia/Jerusalem + { 690, 1290, 226108, 8, }, // Asia/Jerusalem { 690, 3560, 90086, 5, }, // Asia/Kabul { 690, 4316, 90091, 7, }, // Asia/Kamchatka { 690, 4239, 31972, 5, }, // Asia/Karachi { 690, 1185, 90098, 8, }, // Asia/Kathmandu - { 690, 8661, 226125, 7, }, // Asia/Khandyga + { 690, 8661, 226116, 7, }, // Asia/Khandyga { 690, 992, 90113, 7, }, // Asia/Kolkata { 690, 4197, 90120, 15, }, // Asia/Krasnoyarsk { 690, 4859, 90135, 10, }, // Asia/Kuala_Lumpur @@ -51106,22 +51106,22 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 4135, 90184, 13, }, // Asia/Novosibirsk { 690, 4229, 90197, 6, }, // Asia/Omsk { 690, 7145, 90203, 3, }, // Asia/Oral - { 690, 6961, 226132, 10, }, // Asia/Phnom_Penh + { 690, 6961, 226123, 10, }, // Asia/Phnom_Penh { 690, 8693, 90215, 9, }, // Asia/Pontianak { 690, 4214, 90224, 10, }, // Asia/Pyongyang { 690, 5559, 90234, 3, }, // Asia/Qatar { 690, 8708, 90237, 8, }, // Asia/Qostanay - { 690, 4269, 226142, 10, }, // Asia/Qyzylorda + { 690, 4269, 226133, 10, }, // Asia/Qyzylorda { 690, 3584, 90256, 5, }, // Asia/Riyadh - { 690, 4408, 226152, 7, }, // Asia/Sakhalin + { 690, 4408, 226143, 7, }, // Asia/Sakhalin { 690, 7245, 90267, 6, }, // Asia/Samarkand { 690, 3279, 90273, 4, }, // Asia/Seoul - { 690, 1053, 226159, 6, }, // Asia/Shanghai + { 690, 1053, 226150, 6, }, // Asia/Shanghai { 690, 3300, 32190, 8, }, // Asia/Singapore { 690, 4297, 90282, 16, }, // Asia/Srednekolymsk - { 690, 3263, 226165, 8, }, // Asia/Taipei - { 690, 4781, 226173, 6, }, // Asia/Tashkent - { 690, 3915, 226179, 9, }, // Asia/Tbilisi + { 690, 3263, 226156, 8, }, // Asia/Taipei + { 690, 4781, 226164, 6, }, // Asia/Tashkent + { 690, 3915, 226170, 9, }, // Asia/Tbilisi { 690, 2772, 32236, 6, }, // Asia/Tehran { 690, 1317, 90317, 5, }, // Asia/Thimphu { 690, 2821, 90322, 6, }, // Asia/Tokyo @@ -51132,19 +51132,19 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 6977, 90360, 9, }, // Asia/Vientiane { 690, 4710, 90369, 13, }, // Asia/Vladivostok { 690, 4828, 32305, 9, }, // Asia/Yakutsk - { 690, 1235, 226188, 6, }, // Asia/Yangon + { 690, 1235, 226179, 6, }, // Asia/Yangon { 690, 3883, 90382, 13, }, // Asia/Yekaterinburg { 690, 3747, 90395, 7, }, // Asia/Yerevan { 690, 3663, 90402, 7, }, // Atlantic/Azores { 690, 5671, 90409, 6, }, // Atlantic/Bermuda - { 690, 6628, 226194, 8, }, // Atlantic/Canary + { 690, 6628, 226185, 8, }, // Atlantic/Canary { 690, 3727, 90421, 8, }, // Atlantic/Cape_Verde - { 690, 1395, 226202, 6, }, // Atlantic/Faroe + { 690, 1395, 226193, 6, }, // Atlantic/Faroe { 690, 8736, 90434, 5, }, // Atlantic/Madeira { 690, 2748, 90439, 9, }, // Atlantic/Reykjavik - { 690, 7272, 226208, 18, }, // Atlantic/South_Georgia + { 690, 7272, 226199, 18, }, // Atlantic/South_Georgia { 690, 6821, 90463, 11, }, // Atlantic/St_Helena - { 690, 6644, 226226, 9, }, // Atlantic/Stanley + { 690, 6644, 226217, 9, }, // Atlantic/Stanley { 690, 1670, 90481, 6, }, // Australia/Adelaide { 690, 1635, 90487, 8, }, // Australia/Brisbane { 690, 1799, 90495, 10, }, // Australia/Broken_Hill @@ -51158,8 +51158,8 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 1463, 32494, 5, }, // Australia/Sydney { 690, 6441, 90549, 10, }, // Europe/Amsterdam { 690, 6216, 90559, 6, }, // Europe/Andorra - { 690, 3620, 226235, 10, }, // Europe/Astrakhan - { 690, 2300, 226245, 6, }, // Europe/Athens + { 690, 3620, 226226, 10, }, // Europe/Astrakhan + { 690, 2300, 226236, 6, }, // Europe/Athens { 690, 6336, 32532, 8, }, // Europe/Belgrade { 690, 4757, 90580, 6, }, // Europe/Berlin { 690, 6488, 90586, 12, }, // Europe/Bratislava @@ -51173,7 +51173,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 6307, 90657, 10, }, // Europe/Gibraltar { 690, 8788, 90667, 6, }, // Europe/Guernsey { 690, 6612, 90673, 8, }, // Europe/Helsinki - { 690, 8804, 226251, 13, }, // Europe/Isle_of_Man + { 690, 8804, 226242, 13, }, // Europe/Isle_of_Man { 690, 1130, 90692, 9, }, // Europe/Istanbul { 690, 8823, 90701, 5, }, // Europe/Jersey { 690, 3979, 90706, 12, }, // Europe/Kaliningrad @@ -51199,9 +51199,9 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 6470, 90814, 10, }, // Europe/San_Marino { 690, 6245, 90824, 8, }, // Europe/Sarajevo { 690, 4451, 90832, 7, }, // Europe/Saratov - { 690, 8849, 226264, 12, }, // Europe/Simferopol - { 690, 6383, 226276, 8, }, // Europe/Skopje - { 690, 6599, 226284, 7, }, // Europe/Sofia + { 690, 8849, 226255, 12, }, // Europe/Simferopol + { 690, 6383, 226267, 8, }, // Europe/Skopje + { 690, 6599, 226275, 7, }, // Europe/Sofia { 690, 6523, 90866, 8, }, // Europe/Stockholm { 690, 8867, 90874, 5, }, // Europe/Tallinn { 690, 6202, 90879, 6, }, // Europe/Tirane @@ -51213,7 +51213,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 4727, 90922, 11, }, // Europe/Volgograd { 690, 3190, 90933, 5, }, // Europe/Warsaw { 690, 6261, 90938, 8, }, // Europe/Zagreb - { 690, 6540, 226291, 9, }, // Europe/Zurich + { 690, 6540, 226282, 9, }, // Europe/Zurich { 690, 5078, 90955, 11, }, // Indian/Antananarivo { 690, 6947, 115401, 5, }, // Indian/Chagos { 690, 6046, 90971, 7, }, // Indian/Christmas @@ -51222,38 +51222,38 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 6661, 90989, 7, }, // Indian/Kerguelen { 690, 7260, 32983, 4, }, // Indian/Mahe { 690, 7050, 90996, 6, }, // Indian/Maldives - { 690, 4069, 226300, 6, }, // Indian/Mauritius + { 690, 4069, 226291, 6, }, // Indian/Mauritius { 690, 5098, 91008, 8, }, // Indian/Mayotte { 690, 7211, 91016, 8, }, // Indian/Reunion { 690, 4422, 91024, 5, }, // Pacific/Apia - { 690, 932, 226306, 6, }, // Pacific/Auckland + { 690, 932, 226297, 6, }, // Pacific/Auckland { 690, 3706, 91035, 8, }, // Pacific/Bougainville - { 690, 3015, 226312, 6, }, // Pacific/Chatham + { 690, 3015, 226303, 6, }, // Pacific/Chatham { 690, 3157, 91047, 2, }, // Pacific/Chuuk - { 690, 2237, 226318, 6, }, // Pacific/Easter - { 690, 7360, 226324, 5, }, // Pacific/Efate - { 690, 7327, 226329, 9, }, // Pacific/Fakaofo - { 690, 3902, 226338, 5, }, // Pacific/Fiji - { 690, 7343, 226343, 12, }, // Pacific/Funafuti + { 690, 2237, 226309, 6, }, // Pacific/Easter + { 690, 7360, 226315, 5, }, // Pacific/Efate + { 690, 7327, 226320, 9, }, // Pacific/Fakaofo + { 690, 3902, 226329, 5, }, // Pacific/Fiji + { 690, 7343, 226334, 12, }, // Pacific/Funafuti { 690, 6678, 91085, 9, }, // Pacific/Galapagos - { 690, 6696, 226355, 9, }, // Pacific/Gambier + { 690, 6696, 226346, 9, }, // Pacific/Gambier { 690, 3822, 91101, 10, }, // Pacific/Guadalcanal { 690, 6018, 31112, 4, }, // Pacific/Guam - { 690, 3049, 226364, 5, }, // Pacific/Kanton + { 690, 3049, 226355, 5, }, // Pacific/Kanton { 690, 3998, 33132, 10, }, // Pacific/Kiritimati { 690, 7019, 91126, 6, }, // Pacific/Kosrae { 690, 2842, 91132, 10, }, // Pacific/Kwajalein { 690, 4877, 91142, 6, }, // Pacific/Majuro { 690, 4051, 91148, 8, }, // Pacific/Marquesas { 690, 8914, 91156, 5, }, // Pacific/Midway - { 690, 7084, 226369, 6, }, // Pacific/Nauru + { 690, 7084, 226360, 6, }, // Pacific/Nauru { 690, 7132, 91165, 4, }, // Pacific/Niue - { 690, 4168, 226375, 7, }, // Pacific/Norfolk - { 690, 7098, 226382, 6, }, // Pacific/Noumea + { 690, 4168, 226366, 7, }, // Pacific/Norfolk + { 690, 7098, 226373, 6, }, // Pacific/Noumea { 690, 3126, 91182, 9, }, // Pacific/Pago_Pago { 690, 7155, 91191, 4, }, // Pacific/Palau { 690, 7194, 137202, 8, }, // Pacific/Pitcairn - { 690, 3096, 226388, 7, }, // Pacific/Pohnpei + { 690, 3096, 226379, 7, }, // Pacific/Pohnpei { 690, 4807, 91201, 14, }, // Pacific/Port_Moresby { 690, 6076, 91215, 9, }, // Pacific/Rarotonga { 690, 6031, 91224, 6, }, // Pacific/Saipan @@ -51263,7 +51263,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 690, 7392, 33268, 3, }, // Pacific/Wake { 690, 7405, 33271, 5, }, // Pacific/Wallis { 691, 6788, 148234, 7, }, // Africa/Abidjan Kuvi/Odia/India - { 691, 6760, 226395, 5, }, // Africa/Accra + { 691, 6760, 226386, 5, }, // Africa/Accra { 691, 5059, 148246, 12, }, // Africa/Addis_Ababa { 691, 7420, 148258, 8, }, // Africa/Algiers { 691, 14, 148266, 5, }, // Africa/Asmara @@ -51272,217 +51272,217 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 691, 6746, 148284, 7, }, // Africa/Banjul { 691, 7435, 148291, 5, }, // Africa/Bissau { 691, 4957, 148296, 13, }, // Africa/Blantyre - { 691, 5287, 226400, 12, }, // Africa/Brazzaville - { 691, 4922, 226412, 10, }, // Africa/Bujumbura + { 691, 5287, 226391, 12, }, // Africa/Brazzaville + { 691, 4922, 226403, 10, }, // Africa/Bujumbura { 691, 2320, 148331, 4, }, // Africa/Cairo { 691, 4117, 148336, 12, }, // Africa/Casablanca { 691, 7449, 148348, 5, }, // Africa/Ceuta - { 691, 6773, 226422, 7, }, // Africa/Conakry + { 691, 6773, 226413, 7, }, // Africa/Conakry { 691, 6840, 148361, 4, }, // Africa/Dakar { 691, 5130, 148365, 15, }, // Africa/Dar_es_Salaam - { 691, 5043, 226429, 5, }, // Africa/Djibouti + { 691, 5043, 226420, 5, }, // Africa/Djibouti { 691, 5243, 148386, 4, }, // Africa/Douala { 691, 5166, 148390, 9, }, // Africa/El_Aaiun - { 691, 6853, 226434, 10, }, // Africa/Freetown - { 691, 4906, 226444, 8, }, // Africa/Gaborone + { 691, 6853, 226425, 10, }, // Africa/Freetown + { 691, 4906, 226435, 8, }, // Africa/Gaborone { 691, 5015, 148418, 5, }, // Africa/Harare - { 691, 4479, 226452, 10, }, // Africa/Johannesburg + { 691, 4479, 226443, 10, }, // Africa/Johannesburg { 691, 4499, 148434, 4, }, // Africa/Juba { 691, 5151, 148438, 8, }, // Africa/Kampala - { 691, 4524, 226462, 7, }, // Africa/Khartoum + { 691, 4524, 226453, 7, }, // Africa/Khartoum { 691, 4973, 148453, 6, }, // Africa/Kigali { 691, 5306, 148459, 8, }, // Africa/Kinshasa - { 691, 4744, 226469, 6, }, // Africa/Lagos - { 691, 5336, 226475, 12, }, // Africa/Libreville - { 691, 6869, 226487, 4, }, // Africa/Lome + { 691, 4744, 226460, 6, }, // Africa/Lagos + { 691, 5336, 226466, 12, }, // Africa/Libreville + { 691, 6869, 226478, 4, }, // Africa/Lome { 691, 5211, 148491, 7, }, // Africa/Luanda { 691, 4939, 148498, 10, }, // Africa/Lubumbashi { 691, 5001, 148508, 6, }, // Africa/Lusaka { 691, 5322, 148514, 5, }, // Africa/Malabo { 691, 4987, 148520, 6, }, // Africa/Maputo { 691, 5197, 148526, 6, }, // Africa/Maseru - { 691, 5182, 226491, 9, }, // Africa/Mbabane - { 691, 5113, 226500, 8, }, // Africa/Mogadishu - { 691, 7034, 226508, 7, }, // Africa/Monrovia - { 691, 3853, 226515, 6, }, // Africa/Nairobi + { 691, 5182, 226482, 9, }, // Africa/Mbabane + { 691, 5113, 226491, 8, }, // Africa/Mogadishu + { 691, 7034, 226499, 7, }, // Africa/Monrovia + { 691, 3853, 226506, 6, }, // Africa/Nairobi { 691, 5271, 148561, 6, }, // Africa/Ndjamena { 691, 5354, 148567, 5, }, // Africa/Niamey - { 691, 6803, 226521, 6, }, // Africa/Nouakchott - { 691, 6727, 226527, 6, }, // Africa/Ouagadougou - { 691, 5225, 226533, 7, }, // Africa/Porto-Novo - { 691, 4435, 226540, 7, }, // Africa/Sao_Tome - { 691, 2866, 226547, 7, }, // Africa/Tripoli + { 691, 6803, 226512, 6, }, // Africa/Nouakchott + { 691, 6727, 226518, 6, }, // Africa/Ouagadougou + { 691, 5225, 226524, 7, }, // Africa/Porto-Novo + { 691, 4435, 226531, 7, }, // Africa/Sao_Tome + { 691, 2866, 226538, 7, }, // Africa/Tripoli { 691, 6554, 148614, 7, }, // Africa/Tunis - { 691, 4152, 226554, 8, }, // Africa/Windhoek + { 691, 4152, 226545, 8, }, // Africa/Windhoek { 691, 132, 148631, 5, }, // America/Adak { 691, 3346, 148636, 8, }, // America/Anchorage { 691, 5607, 148644, 8, }, // America/Anguilla { 691, 5624, 148652, 8, }, // America/Antigua { 691, 4554, 148660, 8, }, // America/Araguaina - { 691, 166, 226562, 13, }, // America/Argentina/Buenos_Aires - { 691, 91, 226575, 10, }, // America/Argentina/Catamarca - { 691, 270, 226585, 6, }, // America/Argentina/Cordoba - { 691, 441, 226591, 5, }, // America/Argentina/Jujuy - { 691, 7462, 226596, 9, }, // America/Argentina/La_Rioja - { 691, 565, 226605, 7, }, // America/Argentina/Mendoza - { 691, 7489, 226612, 12, }, // America/Argentina/Rio_Gallegos - { 691, 7520, 226624, 6, }, // America/Argentina/Salta - { 691, 7544, 226630, 11, }, // America/Argentina/San_Juan - { 691, 5580, 226641, 9, }, // America/Argentina/San_Luis - { 691, 7571, 226650, 6, }, // America/Argentina/Tucuman - { 691, 7597, 226656, 7, }, // America/Argentina/Ushuaia - { 691, 5640, 226663, 5, }, // America/Aruba + { 691, 166, 226553, 13, }, // America/Argentina/Buenos_Aires + { 691, 91, 226566, 10, }, // America/Argentina/Catamarca + { 691, 270, 226576, 6, }, // America/Argentina/Cordoba + { 691, 441, 226582, 5, }, // America/Argentina/Jujuy + { 691, 7462, 226587, 9, }, // America/Argentina/La_Rioja + { 691, 565, 226596, 7, }, // America/Argentina/Mendoza + { 691, 7489, 226603, 12, }, // America/Argentina/Rio_Gallegos + { 691, 7520, 226615, 6, }, // America/Argentina/Salta + { 691, 7544, 226621, 11, }, // America/Argentina/San_Juan + { 691, 5580, 226632, 9, }, // America/Argentina/San_Luis + { 691, 7571, 226641, 6, }, // America/Argentina/Tucuman + { 691, 7597, 226647, 7, }, // America/Argentina/Ushuaia + { 691, 5640, 226654, 5, }, // America/Aruba { 691, 4252, 148781, 9, }, // America/Asuncion { 691, 237, 148790, 9, }, // America/Atikokan { 691, 3679, 148799, 5, }, // America/Bahia { 691, 7623, 148804, 18, }, // America/Bahia_Banderas - { 691, 5654, 226668, 7, }, // America/Barbados + { 691, 5654, 226659, 7, }, // America/Barbados { 691, 7646, 148832, 5, }, // America/Belem { 691, 5407, 148837, 6, }, // America/Belize - { 691, 7660, 226675, 14, }, // America/Blanc-Sablon - { 691, 7681, 226689, 10, }, // America/Boa_Vista - { 691, 4361, 226699, 4, }, // America/Bogota - { 691, 7699, 226703, 4, }, // America/Boise + { 691, 7660, 226666, 14, }, // America/Blanc-Sablon + { 691, 7681, 226680, 10, }, // America/Boa_Vista + { 691, 4361, 226690, 4, }, // America/Bogota + { 691, 7699, 226694, 4, }, // America/Boise { 691, 7713, 148879, 13, }, // America/Cambridge_Bay - { 691, 7735, 226707, 14, }, // America/Campo_Grande + { 691, 7735, 226698, 14, }, // America/Campo_Grande { 691, 3868, 148907, 7, }, // America/Cancun { 691, 4694, 148914, 8, }, // America/Caracas { 691, 4345, 148922, 8, }, // America/Cayenne { 691, 5496, 148930, 9, }, // America/Cayman - { 691, 2260, 226721, 5, }, // America/Chicago + { 691, 2260, 226712, 5, }, // America/Chicago { 691, 7756, 148945, 8, }, // America/Chihuahua - { 691, 5422, 226726, 10, }, // America/Costa_Rica - { 691, 7796, 226736, 9, }, // America/Creston + { 691, 5422, 226717, 10, }, // America/Costa_Rica + { 691, 7796, 226727, 9, }, // America/Creston { 691, 3791, 148989, 5, }, // America/Cuiaba { 691, 5723, 148994, 5, }, // America/Curacao { 691, 7812, 149000, 13, }, // America/Danmarkshavn { 691, 7833, 149013, 5, }, // America/Dawson { 691, 7848, 149018, 12, }, // America/Dawson_Creek - { 691, 805, 226745, 7, }, // America/Denver - { 691, 3465, 226752, 8, }, // America/Detroit - { 691, 5739, 226760, 7, }, // America/Dominica - { 691, 893, 226767, 9, }, // America/Edmonton + { 691, 805, 226736, 7, }, // America/Denver + { 691, 3465, 226743, 8, }, // America/Detroit + { 691, 5739, 226751, 7, }, // America/Dominica + { 691, 893, 226758, 9, }, // America/Edmonton { 691, 7869, 149063, 7, }, // America/Eirunepe - { 691, 5441, 226776, 13, }, // America/El_Salvador - { 691, 7886, 226789, 11, }, // America/Fort_Nelson - { 691, 7906, 226800, 8, }, // America/Fortaleza + { 691, 5441, 226767, 13, }, // America/El_Salvador + { 691, 7886, 226780, 11, }, // America/Fort_Nelson + { 691, 7906, 226791, 8, }, // America/Fortaleza { 691, 7924, 149106, 9, }, // America/Glace_Bay { 691, 6881, 149115, 7, }, // America/Goose_Bay { 691, 4612, 149122, 14, }, // America/Grand_Turk { 691, 5770, 149136, 8, }, // America/Grenada - { 691, 5786, 226808, 9, }, // America/Guadeloupe - { 691, 3760, 226817, 9, }, // America/Guatemala + { 691, 5786, 226799, 9, }, // America/Guadeloupe + { 691, 3760, 226808, 9, }, // America/Guatemala { 691, 4841, 149163, 9, }, // America/Guayaquil { 691, 6932, 149172, 5, }, // America/Guyana { 691, 1939, 149177, 12, }, // America/Halifax - { 691, 2281, 226826, 5, }, // America/Havana - { 691, 7942, 226831, 8, }, // America/Hermosillo - { 691, 348, 226839, 13, }, // America/Indiana/Indianapolis + { 691, 2281, 226817, 5, }, // America/Havana + { 691, 7942, 226822, 8, }, // America/Hermosillo + { 691, 348, 226830, 13, }, // America/Indiana/Indianapolis { 691, 481, 149218, 17, }, // America/Indiana/Knox - { 691, 7961, 226852, 16, }, // America/Indiana/Marengo + { 691, 7961, 226843, 16, }, // America/Indiana/Marengo { 691, 7985, 149252, 22, }, // America/Indiana/Petersburg { 691, 8012, 149274, 19, }, // America/Indiana/Tell_City - { 691, 8038, 226868, 15, }, // America/Indiana/Vevay + { 691, 8038, 226859, 15, }, // America/Indiana/Vevay { 691, 8060, 149308, 21, }, // America/Indiana/Vincennes { 691, 8086, 149329, 18, }, // America/Indiana/Winamac - { 691, 8110, 226883, 7, }, // America/Inuvik + { 691, 8110, 226874, 7, }, // America/Inuvik { 691, 660, 149354, 10, }, // America/Iqaluit { 691, 2799, 149364, 7, }, // America/Jamaica { 691, 5380, 149371, 6, }, // America/Juneau - { 691, 521, 226890, 10, }, // America/Kentucky/Louisville - { 691, 8125, 226900, 20, }, // America/Kentucky/Monticello - { 691, 5704, 226920, 13, }, // America/Kralendijk + { 691, 521, 226881, 10, }, // America/Kentucky/Louisville + { 691, 8125, 226891, 20, }, // America/Kentucky/Monticello + { 691, 5704, 226911, 13, }, // America/Kralendijk { 691, 4376, 149420, 6, }, // America/La_Paz { 691, 7169, 149428, 4, }, // America/Lima { 691, 3239, 149432, 13, }, // America/Los_Angeles { 691, 5932, 149445, 23, }, // America/Lower_Princes - { 691, 8153, 226933, 5, }, // America/Maceio + { 691, 8153, 226924, 5, }, // America/Maceio { 691, 8168, 149473, 7, }, // America/Managua { 691, 1908, 149480, 8, }, // America/Manaus - { 691, 5897, 226938, 7, }, // America/Marigot + { 691, 5897, 226929, 7, }, // America/Marigot { 691, 5805, 149496, 12, }, // America/Martinique - { 691, 8184, 226945, 8, }, // America/Matamoros - { 691, 2917, 226953, 9, }, // America/Mazatlan + { 691, 8184, 226936, 8, }, // America/Matamoros + { 691, 2917, 226944, 9, }, // America/Mazatlan { 691, 8202, 149527, 8, }, // America/Menominee { 691, 8220, 149535, 6, }, // America/Merida { 691, 8235, 149541, 10, }, // America/Metlakatla { 691, 2949, 149551, 13, }, // America/Mexico_City - { 691, 4391, 226962, 9, }, // America/Miquelon - { 691, 8254, 226971, 7, }, // America/Moncton - { 691, 8270, 226978, 7, }, // America/Monterrey - { 691, 4098, 226985, 10, }, // America/Montevideo - { 691, 5824, 226995, 10, }, // America/Montserrat + { 691, 4391, 226953, 9, }, // America/Miquelon + { 691, 8254, 226962, 7, }, // America/Moncton + { 691, 8270, 226969, 7, }, // America/Monterrey + { 691, 4098, 226976, 10, }, // America/Montevideo + { 691, 5824, 226986, 10, }, // America/Montserrat { 691, 5481, 149611, 5, }, // America/Nassau - { 691, 2379, 227005, 10, }, // America/New_York + { 691, 2379, 226996, 10, }, // America/New_York { 691, 8288, 149627, 4, }, // America/Nome - { 691, 1850, 227015, 5, }, // America/Noronha - { 691, 8301, 227020, 19, }, // America/North_Dakota/Beulah - { 691, 8329, 227039, 20, }, // America/North_Dakota/Center - { 691, 8357, 227059, 24, }, // America/North_Dakota/New_Salem + { 691, 1850, 227006, 5, }, // America/Noronha + { 691, 8301, 227011, 19, }, // America/North_Dakota/Beulah + { 691, 8329, 227030, 20, }, // America/North_Dakota/Center + { 691, 8357, 227050, 24, }, // America/North_Dakota/New_Salem { 691, 393, 149705, 5, }, // America/Nuuk - { 691, 8388, 227083, 7, }, // America/Ojinaga + { 691, 8388, 227074, 7, }, // America/Ojinaga { 691, 2356, 149717, 6, }, // America/Panama { 691, 6173, 149723, 9, }, // America/Paramaribo - { 691, 2973, 227090, 7, }, // America/Phoenix - { 691, 3945, 227097, 17, }, // America/Port-au-Prince - { 691, 5954, 227114, 16, }, // America/Port_of_Spain + { 691, 2973, 227081, 7, }, // America/Phoenix + { 691, 3945, 227088, 17, }, // America/Port-au-Prince + { 691, 5954, 227105, 16, }, // America/Port_of_Spain { 691, 8404, 149776, 11, }, // America/Porto_Velho - { 691, 5843, 227130, 10, }, // America/Puerto_Rico + { 691, 5843, 227121, 10, }, // America/Puerto_Rico { 691, 4030, 149799, 15, }, // America/Punta_Arenas { 691, 8424, 149814, 14, }, // America/Rankin_Inlet - { 691, 8445, 227140, 6, }, // America/Recife + { 691, 8445, 227131, 6, }, // America/Recife { 691, 1995, 149834, 6, }, // America/Regina { 691, 8460, 149840, 8, }, // America/Resolute - { 691, 695, 227146, 11, }, // America/Rio_Branco - { 691, 8477, 227157, 9, }, // America/Santarem + { 691, 695, 227137, 11, }, // America/Rio_Branco + { 691, 8477, 227148, 9, }, // America/Santarem { 691, 2201, 149871, 8, }, // America/Santiago - { 691, 6111, 227166, 12, }, // America/Santo_Domingo + { 691, 6111, 227157, 12, }, // America/Santo_Domingo { 691, 1878, 149895, 9, }, // America/Sao_Paulo - { 691, 6899, 227178, 14, }, // America/Scoresbysund + { 691, 6899, 227169, 14, }, // America/Scoresbysund { 691, 8494, 149921, 5, }, // America/Sitka - { 691, 8508, 227192, 16, }, // America/St_Barthelemy + { 691, 8508, 227183, 16, }, // America/St_Barthelemy { 691, 2061, 149944, 12, }, // America/St_Johns - { 691, 5863, 227208, 13, }, // America/St_Kitts + { 691, 5863, 227199, 13, }, // America/St_Kitts { 691, 5880, 149969, 13, }, // America/St_Lucia - { 691, 855, 227221, 13, }, // America/St_Thomas - { 691, 5913, 227234, 17, }, // America/St_Vincent + { 691, 855, 227212, 13, }, // America/St_Thomas + { 691, 5913, 227225, 17, }, // America/St_Vincent { 691, 8530, 150013, 15, }, // America/Swift_Current { 691, 5461, 150028, 11, }, // America/Tegucigalpa - { 691, 5756, 227251, 4, }, // America/Thule + { 691, 5756, 227242, 4, }, // America/Thule { 691, 313, 150043, 7, }, // America/Tijuana - { 691, 608, 227255, 5, }, // America/Toronto - { 691, 5688, 227260, 5, }, // America/Tortola - { 691, 2093, 227265, 9, }, // America/Vancouver + { 691, 608, 227246, 5, }, // America/Toronto + { 691, 5688, 227251, 5, }, // America/Tortola + { 691, 2093, 227256, 9, }, // America/Vancouver { 691, 2144, 150074, 11, }, // America/Whitehorse { 691, 734, 150085, 8, }, // America/Winnipeg { 691, 8552, 150093, 8, }, // America/Yakutat - { 691, 6001, 227274, 4, }, // Antarctica/Casey - { 691, 6094, 227278, 6, }, // Antarctica/Davis - { 691, 6133, 227284, 19, }, // Antarctica/DumontDUrville - { 691, 8568, 227303, 7, }, // Antarctica/Macquarie - { 691, 7066, 227310, 5, }, // Antarctica/Mawson - { 691, 7113, 227315, 10, }, // Antarctica/McMurdo - { 691, 8589, 227325, 5, }, // Antarctica/Palmer - { 691, 7226, 227330, 6, }, // Antarctica/Rothera + { 691, 6001, 227265, 4, }, // Antarctica/Casey + { 691, 6094, 227269, 6, }, // Antarctica/Davis + { 691, 6133, 227275, 19, }, // Antarctica/DumontDUrville + { 691, 8568, 227294, 7, }, // Antarctica/Macquarie + { 691, 7066, 227301, 5, }, // Antarctica/Mawson + { 691, 7113, 227306, 10, }, // Antarctica/McMurdo + { 691, 8589, 227316, 5, }, // Antarctica/Palmer + { 691, 7226, 227321, 6, }, // Antarctica/Rothera { 691, 7295, 150167, 4, }, // Antarctica/Syowa - { 691, 8607, 227336, 4, }, // Antarctica/Troll - { 691, 7374, 227340, 7, }, // Antarctica/Vostok - { 691, 1429, 227347, 10, }, // Arctic/Longyearbyen + { 691, 8607, 227327, 4, }, // Antarctica/Troll + { 691, 7374, 227331, 7, }, // Antarctica/Vostok + { 691, 1429, 227338, 10, }, // Arctic/Longyearbyen { 691, 5570, 150199, 6, }, // Asia/Aden { 691, 5395, 150205, 6, }, // Asia/Almaty { 691, 3968, 150211, 6, }, // Asia/Amman { 691, 5511, 150217, 8, }, // Asia/Anadyr { 691, 5523, 150225, 5, }, // Asia/Aqtau - { 691, 5368, 227357, 6, }, // Asia/Aqtobe - { 691, 964, 227363, 9, }, // Asia/Ashgabat + { 691, 5368, 227348, 6, }, // Asia/Aqtobe + { 691, 964, 227354, 9, }, // Asia/Ashgabat { 691, 8624, 150248, 6, }, // Asia/Atyrau { 691, 3607, 150254, 8, }, // Asia/Baghdad - { 691, 5534, 227372, 6, }, // Asia/Bahrain + { 691, 5534, 227363, 6, }, // Asia/Bahrain { 691, 3653, 148992, 4, }, // Asia/Baku { 691, 4466, 150270, 11, }, // Asia/Bangkok { 691, 3571, 150281, 8, }, // Asia/Barnaul { 691, 4086, 150289, 7, }, // Asia/Beirut - { 691, 3778, 227378, 8, }, // Asia/Bishkek + { 691, 3778, 227369, 8, }, // Asia/Bishkek { 691, 5989, 150304, 7, }, // Asia/Brunei { 691, 4601, 150311, 4, }, // Asia/Chita { 691, 4511, 150315, 6, }, // Asia/Colombo @@ -51490,24 +51490,24 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 691, 1093, 150849, 4, }, // Asia/Dhaka { 691, 6192, 150334, 6, }, // Asia/Dili { 691, 3596, 150340, 5, }, // Asia/Dubai - { 691, 6159, 227386, 7, }, // Asia/Dushanbe - { 691, 8636, 227393, 10, }, // Asia/Famagusta + { 691, 6159, 227377, 7, }, // Asia/Dushanbe + { 691, 8636, 227384, 10, }, // Asia/Famagusta { 691, 8651, 150362, 4, }, // Asia/Gaza { 691, 4795, 150366, 8, }, // Asia/Hebron - { 691, 1259, 227403, 15, }, // Asia/Ho_Chi_Minh + { 691, 1259, 227394, 15, }, // Asia/Ho_Chi_Minh { 691, 2704, 150390, 5, }, // Asia/Hong_Kong - { 691, 4771, 227418, 6, }, // Asia/Hovd + { 691, 4771, 227409, 6, }, // Asia/Hovd { 691, 4184, 150401, 8, }, // Asia/Irkutsk - { 691, 7006, 227424, 7, }, // Asia/Jakarta + { 691, 7006, 227415, 7, }, // Asia/Jakarta { 691, 6992, 150418, 6, }, // Asia/Jayapura { 691, 1290, 150424, 8, }, // Asia/Jerusalem - { 691, 3560, 227431, 5, }, // Asia/Kabul + { 691, 3560, 227422, 5, }, // Asia/Kabul { 691, 4316, 150437, 8, }, // Asia/Kamchatka { 691, 4239, 150445, 5, }, // Asia/Karachi - { 691, 1185, 227436, 9, }, // Asia/Kathmandu - { 691, 8661, 227445, 9, }, // Asia/Khandyga + { 691, 1185, 227427, 9, }, // Asia/Kathmandu + { 691, 8661, 227436, 9, }, // Asia/Khandyga { 691, 992, 150468, 7, }, // Asia/Kolkata - { 691, 4197, 227454, 12, }, // Asia/Krasnoyarsk + { 691, 4197, 227445, 12, }, // Asia/Krasnoyarsk { 691, 4859, 150488, 12, }, // Asia/Kuala_Lumpur { 691, 5976, 150500, 5, }, // Asia/Kuching { 691, 5547, 150505, 4, }, // Asia/Kuwait @@ -51516,83 +51516,83 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 691, 1349, 150522, 9, }, // Asia/Makassar { 691, 7182, 150531, 6, }, // Asia/Manila { 691, 6920, 150537, 8, }, // Asia/Muscat - { 691, 2554, 227466, 6, }, // Asia/Nicosia - { 691, 8675, 227472, 11, }, // Asia/Novokuznetsk - { 691, 4135, 227483, 10, }, // Asia/Novosibirsk + { 691, 2554, 227457, 6, }, // Asia/Nicosia + { 691, 8675, 227463, 11, }, // Asia/Novokuznetsk + { 691, 4135, 227474, 10, }, // Asia/Novosibirsk { 691, 4229, 150577, 5, }, // Asia/Omsk - { 691, 7145, 227493, 6, }, // Asia/Oral - { 691, 6961, 227499, 10, }, // Asia/Phnom_Penh - { 691, 8693, 227509, 11, }, // Asia/Pontianak + { 691, 7145, 227484, 6, }, // Asia/Oral + { 691, 6961, 227490, 10, }, // Asia/Phnom_Penh + { 691, 8693, 227500, 11, }, // Asia/Pontianak { 691, 4214, 150611, 11, }, // Asia/Pyongyang { 691, 5559, 150622, 5, }, // Asia/Qatar - { 691, 8708, 227520, 6, }, // Asia/Qostanay - { 691, 4269, 227526, 9, }, // Asia/Qyzylorda + { 691, 8708, 227511, 6, }, // Asia/Qostanay + { 691, 4269, 227517, 9, }, // Asia/Qyzylorda { 691, 3584, 150644, 4, }, // Asia/Riyadh - { 691, 4408, 227535, 7, }, // Asia/Sakhalin + { 691, 4408, 227526, 7, }, // Asia/Sakhalin { 691, 7245, 150655, 7, }, // Asia/Samarkand - { 691, 3279, 227542, 4, }, // Asia/Seoul - { 691, 1053, 227546, 5, }, // Asia/Shanghai + { 691, 3279, 227533, 4, }, // Asia/Seoul + { 691, 1053, 227537, 5, }, // Asia/Shanghai { 691, 3300, 150672, 11, }, // Asia/Singapore - { 691, 4297, 227551, 14, }, // Asia/Srednekolymsk + { 691, 4297, 227542, 14, }, // Asia/Srednekolymsk { 691, 3263, 150698, 6, }, // Asia/Taipei - { 691, 4781, 227565, 8, }, // Asia/Tashkent + { 691, 4781, 227556, 8, }, // Asia/Tashkent { 691, 3915, 150712, 8, }, // Asia/Tbilisi { 691, 2772, 150720, 8, }, // Asia/Tehran - { 691, 1317, 227573, 6, }, // Asia/Thimphu - { 691, 2821, 227579, 4, }, // Asia/Tokyo - { 691, 4572, 227583, 5, }, // Asia/Tomsk + { 691, 1317, 227564, 6, }, // Asia/Thimphu + { 691, 2821, 227570, 4, }, // Asia/Tokyo + { 691, 4572, 227574, 5, }, // Asia/Tomsk { 691, 1021, 150745, 12, }, // Asia/Ulaanbaatar { 691, 1159, 150757, 6, }, // Asia/Urumqi - { 691, 8722, 227588, 11, }, // Asia/Ust-Nera - { 691, 6977, 227599, 11, }, // Asia/Vientiane - { 691, 4710, 227610, 13, }, // Asia/Vladivostok + { 691, 8722, 227579, 11, }, // Asia/Ust-Nera + { 691, 6977, 227590, 11, }, // Asia/Vientiane + { 691, 4710, 227601, 13, }, // Asia/Vladivostok { 691, 4828, 150798, 8, }, // Asia/Yakutsk { 691, 1235, 150806, 9, }, // Asia/Yangon { 691, 3883, 150815, 14, }, // Asia/Yekaterinburg - { 691, 3747, 227623, 8, }, // Asia/Yerevan - { 691, 3663, 227631, 6, }, // Atlantic/Azores - { 691, 5671, 227637, 6, }, // Atlantic/Bermuda + { 691, 3747, 227614, 8, }, // Asia/Yerevan + { 691, 3663, 227622, 6, }, // Atlantic/Azores + { 691, 5671, 227628, 6, }, // Atlantic/Bermuda { 691, 6628, 150851, 6, }, // Atlantic/Canary - { 691, 3727, 227643, 11, }, // Atlantic/Cape_Verde - { 691, 1395, 227654, 3, }, // Atlantic/Faroe + { 691, 3727, 227634, 11, }, // Atlantic/Cape_Verde + { 691, 1395, 227645, 3, }, // Atlantic/Faroe { 691, 8736, 150873, 7, }, // Atlantic/Madeira - { 691, 2748, 227657, 9, }, // Atlantic/Reykjavik + { 691, 2748, 227648, 9, }, // Atlantic/Reykjavik { 691, 7272, 150890, 13, }, // Atlantic/South_Georgia { 691, 6821, 150903, 14, }, // Atlantic/St_Helena - { 691, 6644, 227666, 8, }, // Atlantic/Stanley - { 691, 1670, 227674, 7, }, // Australia/Adelaide - { 691, 1635, 227681, 8, }, // Australia/Brisbane - { 691, 1799, 227689, 10, }, // Australia/Broken_Hill - { 691, 1583, 227699, 8, }, // Australia/Darwin + { 691, 6644, 227657, 8, }, // Atlantic/Stanley + { 691, 1670, 227665, 7, }, // Australia/Adelaide + { 691, 1635, 227672, 8, }, // Australia/Brisbane + { 691, 1799, 227680, 10, }, // Australia/Broken_Hill + { 691, 1583, 227690, 8, }, // Australia/Darwin { 691, 3637, 150965, 5, }, // Australia/Eucla { 691, 1516, 150970, 7, }, // Australia/Hobart - { 691, 8753, 227707, 9, }, // Australia/Lindeman - { 691, 1547, 227716, 10, }, // Australia/Lord_Howe - { 691, 1727, 227726, 7, }, // Australia/Melbourne - { 691, 1762, 227733, 4, }, // Australia/Perth + { 691, 8753, 227698, 9, }, // Australia/Lindeman + { 691, 1547, 227707, 10, }, // Australia/Lord_Howe + { 691, 1727, 227717, 7, }, // Australia/Melbourne + { 691, 1762, 227724, 4, }, // Australia/Perth { 691, 1463, 151017, 5, }, // Australia/Sydney - { 691, 6441, 227737, 12, }, // Europe/Amsterdam - { 691, 6216, 227749, 6, }, // Europe/Andorra - { 691, 3620, 227755, 10, }, // Europe/Astrakhan - { 691, 2300, 227765, 6, }, // Europe/Athens - { 691, 6336, 227771, 9, }, // Europe/Belgrade + { 691, 6441, 227728, 12, }, // Europe/Amsterdam + { 691, 6216, 227740, 6, }, // Europe/Andorra + { 691, 3620, 227746, 10, }, // Europe/Astrakhan + { 691, 2300, 227756, 6, }, // Europe/Athens + { 691, 6336, 227762, 9, }, // Europe/Belgrade { 691, 4757, 151065, 7, }, // Europe/Berlin - { 691, 6488, 227780, 11, }, // Europe/Bratislava - { 691, 2167, 227791, 10, }, // Europe/Brussels - { 691, 3928, 227801, 9, }, // Europe/Bucharest - { 691, 3806, 227810, 9, }, // Europe/Budapest + { 691, 6488, 227771, 11, }, // Europe/Bratislava + { 691, 2167, 227782, 10, }, // Europe/Brussels + { 691, 3928, 227792, 9, }, // Europe/Bucharest + { 691, 3806, 227801, 9, }, // Europe/Budapest { 691, 8772, 151111, 9, }, // Europe/Busingen - { 691, 2583, 227819, 7, }, // Europe/Chisinau - { 691, 6289, 227826, 10, }, // Europe/Copenhagen + { 691, 2583, 227810, 7, }, // Europe/Chisinau + { 691, 6289, 227817, 10, }, // Europe/Copenhagen { 691, 2338, 151137, 6, }, // Europe/Dublin { 691, 6307, 151143, 11, }, // Europe/Gibraltar { 691, 8788, 151154, 7, }, // Europe/Guernsey { 691, 6612, 151161, 8, }, // Europe/Helsinki - { 691, 8804, 227836, 15, }, // Europe/Isle_of_Man + { 691, 8804, 227827, 15, }, // Europe/Isle_of_Man { 691, 1130, 151182, 9, }, // Europe/Istanbul { 691, 8823, 151191, 5, }, // Europe/Jersey { 691, 3979, 151196, 13, }, // Europe/Kaliningrad - { 691, 8929, 227851, 4, }, // Europe/Kirov + { 691, 8929, 227842, 4, }, // Europe/Kirov { 691, 2527, 151214, 5, }, // Europe/Kyiv { 691, 3213, 151219, 7, }, // Europe/Lisbon { 691, 6506, 151226, 10, }, // Europe/Ljubljana @@ -51600,61 +51600,61 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 691, 6365, 151242, 9, }, // Europe/Luxembourg { 691, 4892, 151251, 8, }, // Europe/Madrid { 691, 6397, 151259, 5, }, // Europe/Malta - { 691, 6582, 227855, 9, }, // Europe/Mariehamn + { 691, 6582, 227846, 9, }, // Europe/Mariehamn { 691, 3693, 151274, 6, }, // Europe/Minsk - { 691, 6410, 227864, 4, }, // Europe/Monaco + { 691, 6410, 227855, 4, }, // Europe/Monaco { 691, 3537, 150537, 4, }, // Europe/Moscow - { 691, 6458, 227868, 4, }, // Europe/Oslo + { 691, 6458, 227859, 4, }, // Europe/Oslo { 691, 4284, 151295, 6, }, // Europe/Paris - { 691, 6424, 227872, 7, }, // Europe/Podgorica + { 691, 6424, 227863, 7, }, // Europe/Podgorica { 691, 6275, 151310, 6, }, // Europe/Prague { 691, 8837, 151316, 4, }, // Europe/Riga - { 691, 6324, 227879, 3, }, // Europe/Rome + { 691, 6324, 227870, 3, }, // Europe/Rome { 691, 4331, 151324, 6, }, // Europe/Samara { 691, 6470, 151330, 11, }, // Europe/San_Marino - { 691, 6245, 227882, 7, }, // Europe/Sarajevo - { 691, 4451, 227889, 7, }, // Europe/Saratov - { 691, 8849, 227896, 9, }, // Europe/Simferopol - { 691, 6383, 227905, 6, }, // Europe/Skopje - { 691, 6599, 227911, 5, }, // Europe/Sofia - { 691, 6523, 227916, 10, }, // Europe/Stockholm + { 691, 6245, 227873, 7, }, // Europe/Sarajevo + { 691, 4451, 227880, 7, }, // Europe/Saratov + { 691, 8849, 227887, 9, }, // Europe/Simferopol + { 691, 6383, 227896, 6, }, // Europe/Skopje + { 691, 6599, 227902, 5, }, // Europe/Sofia + { 691, 6523, 227907, 10, }, // Europe/Stockholm { 691, 8867, 151389, 7, }, // Europe/Tallinn - { 691, 6202, 227926, 7, }, // Europe/Tirane - { 691, 8882, 227933, 10, }, // Europe/Ulyanovsk - { 691, 6352, 227943, 5, }, // Europe/Vaduz - { 691, 6567, 227948, 8, }, // Europe/Vatican - { 691, 6231, 227956, 5, }, // Europe/Vienna - { 691, 8899, 227961, 8, }, // Europe/Vilnius - { 691, 4727, 227969, 9, }, // Europe/Volgograd + { 691, 6202, 227917, 7, }, // Europe/Tirane + { 691, 8882, 227924, 10, }, // Europe/Ulyanovsk + { 691, 6352, 227934, 5, }, // Europe/Vaduz + { 691, 6567, 227939, 8, }, // Europe/Vatican + { 691, 6231, 227947, 5, }, // Europe/Vienna + { 691, 8899, 227952, 8, }, // Europe/Vilnius + { 691, 4727, 227960, 9, }, // Europe/Volgograd { 691, 3190, 151450, 6, }, // Europe/Warsaw { 691, 6261, 151456, 8, }, // Europe/Zagreb { 691, 6540, 151464, 6, }, // Europe/Zurich { 691, 5078, 151470, 12, }, // Indian/Antananarivo { 691, 6947, 151483, 7, }, // Indian/Chagos - { 691, 6046, 227978, 12, }, // Indian/Christmas - { 691, 6063, 227990, 5, }, // Indian/Cocos - { 691, 5029, 227995, 3, }, // Indian/Comoro - { 691, 6661, 227998, 8, }, // Indian/Kerguelen + { 691, 6046, 227969, 12, }, // Indian/Christmas + { 691, 6063, 227981, 5, }, // Indian/Cocos + { 691, 5029, 227986, 3, }, // Indian/Comoro + { 691, 6661, 227989, 8, }, // Indian/Kerguelen { 691, 7260, 151522, 4, }, // Indian/Mahe { 691, 7050, 151526, 8, }, // Indian/Maldives - { 691, 4069, 228006, 6, }, // Indian/Mauritius - { 691, 5098, 228012, 5, }, // Indian/Mayotte + { 691, 4069, 227997, 6, }, // Indian/Mauritius + { 691, 5098, 228003, 5, }, // Indian/Mayotte { 691, 7211, 151547, 10, }, // Indian/Reunion { 691, 4422, 151557, 4, }, // Pacific/Apia { 691, 932, 151561, 7, }, // Pacific/Auckland - { 691, 3706, 228017, 12, }, // Pacific/Bougainville - { 691, 3015, 228029, 7, }, // Pacific/Chatham + { 691, 3706, 228008, 12, }, // Pacific/Bougainville + { 691, 3015, 228020, 7, }, // Pacific/Chatham { 691, 3157, 151588, 5, }, // Pacific/Chuuk { 691, 2237, 151593, 7, }, // Pacific/Easter { 691, 7360, 151600, 6, }, // Pacific/Efate - { 691, 7327, 228036, 5, }, // Pacific/Fakaofo - { 691, 3902, 228041, 4, }, // Pacific/Fiji + { 691, 7327, 228027, 5, }, // Pacific/Fakaofo + { 691, 3902, 228032, 4, }, // Pacific/Fiji { 691, 7343, 151617, 8, }, // Pacific/Funafuti - { 691, 6678, 228045, 8, }, // Pacific/Galapagos + { 691, 6678, 228036, 8, }, // Pacific/Galapagos { 691, 6696, 151634, 10, }, // Pacific/Gambier { 691, 3822, 151644, 11, }, // Pacific/Guadalcanal { 691, 6018, 149477, 4, }, // Pacific/Guam - { 691, 3049, 228053, 6, }, // Pacific/Kanton + { 691, 3049, 228044, 6, }, // Pacific/Kanton { 691, 3998, 151673, 10, }, // Pacific/Kiritimati { 691, 7019, 151683, 6, }, // Pacific/Kosrae { 691, 2842, 151689, 11, }, // Pacific/Kwajalein @@ -51663,18 +51663,18 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 691, 8914, 151719, 7, }, // Pacific/Midway { 691, 7084, 151726, 5, }, // Pacific/Nauru { 691, 7132, 151731, 4, }, // Pacific/Niue - { 691, 4168, 228059, 6, }, // Pacific/Norfolk - { 691, 7098, 228065, 5, }, // Pacific/Noumea + { 691, 4168, 228050, 6, }, // Pacific/Norfolk + { 691, 7098, 228056, 5, }, // Pacific/Noumea { 691, 3126, 151747, 9, }, // Pacific/Pago_Pago { 691, 7155, 151756, 5, }, // Pacific/Palau { 691, 7194, 151761, 10, }, // Pacific/Pitcairn - { 691, 3096, 228070, 6, }, // Pacific/Pohnpei - { 691, 4807, 228076, 13, }, // Pacific/Port_Moresby - { 691, 6076, 228089, 8, }, // Pacific/Rarotonga + { 691, 3096, 228061, 6, }, // Pacific/Pohnpei + { 691, 4807, 228067, 13, }, // Pacific/Port_Moresby + { 691, 6076, 228080, 8, }, // Pacific/Rarotonga { 691, 6031, 151803, 7, }, // Pacific/Saipan { 691, 7312, 151810, 6, }, // Pacific/Tahiti { 691, 6712, 151816, 5, }, // Pacific/Tarawa - { 691, 4583, 228097, 9, }, // Pacific/Tongatapu + { 691, 4583, 228088, 9, }, // Pacific/Tongatapu { 691, 7392, 151831, 4, }, // Pacific/Wake { 691, 7405, 151835, 7, }, // Pacific/Wallis { 692, 6788, 186476, 9, }, // Africa/Abidjan Kuvi/Telugu/India @@ -51731,7 +51731,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 692, 4152, 186868, 9, }, // Africa/Windhoek { 692, 132, 186877, 5, }, // America/Adak { 692, 3346, 186882, 8, }, // America/Anchorage - { 692, 5607, 228106, 10, }, // America/Anguilla + { 692, 5607, 228097, 10, }, // America/Anguilla { 692, 5624, 186900, 8, }, // America/Antigua { 692, 4554, 186908, 11, }, // America/Araguaina { 692, 166, 186919, 16, }, // America/Argentina/Buenos_Aires @@ -51975,7 +51975,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 692, 7272, 189115, 15, }, // Atlantic/South_Georgia { 692, 6821, 189130, 14, }, // Atlantic/St_Helena { 692, 6644, 189144, 8, }, // Atlantic/Stanley - { 692, 1670, 228116, 36, }, // Australia/Adelaide + { 692, 1670, 228107, 36, }, // Australia/Adelaide { 692, 1635, 189159, 13, }, // Australia/Brisbane { 692, 1799, 189172, 13, }, // Australia/Broken_Hill { 692, 1583, 189185, 8, }, // Australia/Darwin @@ -52069,7 +52069,7 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 692, 6696, 189891, 9, }, // Pacific/Gambier { 692, 3822, 189900, 13, }, // Pacific/Guadalcanal { 692, 6018, 189913, 6, }, // Pacific/Guam - { 692, 3049, 228152, 6, }, // Pacific/Kanton + { 692, 3049, 228143, 6, }, // Pacific/Kanton { 692, 3998, 189936, 10, }, // Pacific/Kiritimati { 692, 7019, 189946, 6, }, // Pacific/Kosrae { 692, 2842, 189952, 10, }, // Pacific/Kwajalein @@ -52137,12 +52137,12 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 695, 14, 0, 6, }, // Africa/Asmara Swampy Cree/Canadian Aboriginal/Canada { 695, 4435, 6, 8, }, // Africa/Sao_Tome { 695, 4252, 14, 8, }, // America/Asuncion - { 695, 237, 228158, 6, }, // America/Atikokan + { 695, 237, 228149, 6, }, // America/Atikokan { 695, 7623, 30, 17, }, // America/Bahia_Banderas { 695, 3868, 47, 6, }, // America/Cancun { 695, 7774, 53, 13, }, // America/Ciudad_Juarez { 695, 5723, 66, 7, }, // America/Curacao - { 695, 893, 228164, 6, }, // America/Edmonton + { 695, 893, 228155, 6, }, // America/Edmonton { 695, 481, 73, 13, }, // America/Indiana/Knox { 695, 7961, 86, 16, }, // America/Indiana/Marengo { 695, 7985, 102, 19, }, // America/Indiana/Petersburg @@ -52150,8 +52150,8 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 695, 8038, 139, 14, }, // America/Indiana/Vevay { 695, 8060, 153, 18, }, // America/Indiana/Vincennes { 695, 8086, 171, 16, }, // America/Indiana/Winamac - { 695, 8110, 228170, 4, }, // America/Inuvik - { 695, 660, 228174, 6, }, // America/Iqaluit + { 695, 8110, 228161, 4, }, // America/Inuvik + { 695, 660, 228165, 6, }, // America/Iqaluit { 695, 8125, 187, 20, }, // America/Kentucky/Monticello { 695, 5932, 207, 22, }, // America/Lower_Princes { 695, 8220, 229, 6, }, // America/Merida @@ -52167,8 +52167,8 @@ static inline constexpr LocaleZoneExemplar localeZoneExemplarTable[] = { { 695, 5880, 370, 9, }, // America/St_Lucia { 695, 855, 379, 10, }, // America/St_Thomas { 695, 5913, 389, 11, }, // America/St_Vincent - { 695, 8530, 228180, 7, }, // America/Swift_Current - { 695, 734, 228187, 4, }, // America/Winnipeg + { 695, 8530, 228171, 7, }, // America/Swift_Current + { 695, 734, 228178, 4, }, // America/Winnipeg { 695, 6133, 400, 16, }, // Antarctica/DumontDUrville { 695, 1259, 432, 11, }, // Asia/Ho_Chi_Minh { 695, 1185, 448, 9, }, // Asia/Kathmandu @@ -102034,603 +102034,603 @@ static inline constexpr char16_t exemplarCityTable[] = { 0x62, 0x69, 0x69, 0x52, 0x61, 0x72, 0x6f, 0x74, 0x254, 0x14b, 0x67, 0x61, 0x53, 0x61, 0x269, 0x70, 0x61, 0x6e, 0x54, 0x61, 0x72, 0x61, 0x77, 0x61, 0x61, 0x54, 0x254, 0x14b, 0x67, 0x61, 0x74, 0x61, 0x70, 0x75, 0x75, 0x57, -0x65, 0x65, 0x6b, 0x905, 0x932, 0x20, 0x906, 0x907, 0x92f, 0x942, 0x928, 0x3c, -0x92e, 0x91c, 0x93c, 0x93e, 0x91f, 0x932, 0x93e, 0x928, 0x921, 0x92c, 0x908, 0x915, -0x93e, 0x92c, 0x932, 0x926, 0x916, 0x923, 0x940, 0x20, 0x91c, 0x949, 0x930, 0x94d, -0x91c, 0x93f, 0x92f, 0x93e, 0x90f, 0x92e, 0x94d, 0x938, 0x94d, 0x91f, 0x930, 0x921, -0x92e, 0x92a, 0x948, 0x930, 0x938, 0x915, 0x94d, 0x930, 0x93f, 0x938, 0x92e, 0x93f, -0x938, 0x915, 0x948, 0x902, 0x91f, 0x928, 0x92a, 0x93e, 0x917, 0x94b, 0x20, 0x917, -0x902, 0x917, 0x94b, 0x41, 0x6c, 0x6a, 0x65, 0x72, 0x69, 0x41, 0x7a, 0x6d, -0x61, 0x72, 0x61, 0x42, 0x61, 0x6e, 0x67, 0x68, 0xec, 0x42, 0x69, 0x73, -0xe0, 0x6f, 0x42, 0x75, 0x6a, 0x75, 0x6e, 0x62, 0x75, 0x72, 0x61, 0x43, -0x61, 0x7a, 0x61, 0x62, 0x6c, 0x61, 0x6e, 0x63, 0x61, 0x4b, 0x61, 0x6e, -0x70, 0x61, 0x6c, 0x61, 0x4c, 0x75, 0x62, 0x75, 0x6e, 0x62, 0x61, 0x73, -0x68, 0x69, 0x4d, 0x61, 0x7a, 0x65, 0x72, 0x75, 0x4e, 0x62, 0x61, 0x62, -0x61, 0x6e, 0x65, 0x4d, 0x6f, 0x67, 0x61, 0x64, 0x69, 0x73, 0x6f, 0x55, -0x61, 0x67, 0x61, 0x64, 0x75, 0x67, 0xf9, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, -0x20, 0x53, 0x2e, 0x20, 0x54, 0x6f, 0x6d, 0x61, 0x7a, 0x6f, 0x54, 0xf9, -0x6e, 0x65, 0x7a, 0x69, 0x43, 0xf2, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x52, -0x69, 0x6f, 0x20, 0x47, 0xe0, 0x6c, 0x65, 0x67, 0x6f, 0x73, 0x42, 0x61, -0x69, 0x61, 0x20, 0x64, 0x65, 0x20, 0x42, 0x61, 0x6e, 0x64, 0x65, 0x72, -0x61, 0x73, 0x43, 0x61, 0x6e, 0x70, 0x6f, 0x20, 0x47, 0x72, 0x61, 0x6e, -0x64, 0x65, 0x43, 0x75, 0x69, 0x61, 0x62, 0xe0, 0x44, 0xe8, 0x6e, 0x76, -0x65, 0x72, 0x44, 0x6f, 0x6d, 0xe9, 0x6e, 0x65, 0x67, 0x61, 0x49, 0x6e, -0x64, 0x69, 0x61, 0x6e, 0xe0, 0x70, 0x6f, 0x6c, 0x69, 0x73, 0x4b, 0x6e, -0x6f, 0x78, 0x20, 0x28, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x29, -0x4d, 0x61, 0x72, 0x65, 0x6e, 0x67, 0x6f, 0x20, 0x28, 0x49, 0x6e, 0x64, -0x69, 0x61, 0x6e, 0x61, 0x29, 0x50, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62, -0x75, 0x72, 0x67, 0x20, 0x28, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, -0x29, 0x54, 0x65, 0x6c, 0x6c, 0x20, 0x43, 0x69, 0x74, 0x79, 0x20, 0x28, -0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x29, 0x56, 0x65, 0x76, 0x61, +0x65, 0x65, 0x6b, 0x92e, 0x91c, 0x93c, 0x93e, 0x91f, 0x932, 0x93e, 0x928, 0x921, +0x92c, 0x908, 0x915, 0x93e, 0x92c, 0x932, 0x926, 0x916, 0x923, 0x940, 0x20, 0x91c, +0x949, 0x930, 0x94d, 0x91c, 0x93f, 0x92f, 0x93e, 0x90f, 0x92e, 0x94d, 0x938, 0x94d, +0x91f, 0x930, 0x921, 0x92e, 0x92a, 0x948, 0x930, 0x938, 0x915, 0x94d, 0x930, 0x93f, +0x938, 0x92e, 0x93f, 0x938, 0x915, 0x948, 0x902, 0x91f, 0x928, 0x92a, 0x93e, 0x917, +0x94b, 0x20, 0x917, 0x902, 0x917, 0x94b, 0x41, 0x6c, 0x6a, 0x65, 0x72, 0x69, +0x41, 0x7a, 0x6d, 0x61, 0x72, 0x61, 0x42, 0x61, 0x6e, 0x67, 0x68, 0xec, +0x42, 0x69, 0x73, 0xe0, 0x6f, 0x42, 0x75, 0x6a, 0x75, 0x6e, 0x62, 0x75, +0x72, 0x61, 0x43, 0x61, 0x7a, 0x61, 0x62, 0x6c, 0x61, 0x6e, 0x63, 0x61, +0x4b, 0x61, 0x6e, 0x70, 0x61, 0x6c, 0x61, 0x4c, 0x75, 0x62, 0x75, 0x6e, +0x62, 0x61, 0x73, 0x68, 0x69, 0x4d, 0x61, 0x7a, 0x65, 0x72, 0x75, 0x4e, +0x62, 0x61, 0x62, 0x61, 0x6e, 0x65, 0x4d, 0x6f, 0x67, 0x61, 0x64, 0x69, +0x73, 0x6f, 0x55, 0x61, 0x67, 0x61, 0x64, 0x75, 0x67, 0xf9, 0xcc, 0x7a, +0x6f, 0x6c, 0x61, 0x20, 0x53, 0x2e, 0x20, 0x54, 0x6f, 0x6d, 0x61, 0x7a, +0x6f, 0x54, 0xf9, 0x6e, 0x65, 0x7a, 0x69, 0x43, 0xf2, 0x72, 0x64, 0x6f, +0x62, 0x61, 0x52, 0x69, 0x6f, 0x20, 0x47, 0xe0, 0x6c, 0x65, 0x67, 0x6f, +0x73, 0x42, 0x61, 0x69, 0x61, 0x20, 0x64, 0x65, 0x20, 0x42, 0x61, 0x6e, +0x64, 0x65, 0x72, 0x61, 0x73, 0x43, 0x61, 0x6e, 0x70, 0x6f, 0x20, 0x47, +0x72, 0x61, 0x6e, 0x64, 0x65, 0x43, 0x75, 0x69, 0x61, 0x62, 0xe0, 0x44, +0xe8, 0x6e, 0x76, 0x65, 0x72, 0x44, 0x6f, 0x6d, 0xe9, 0x6e, 0x65, 0x67, +0x61, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0xe0, 0x70, 0x6f, 0x6c, 0x69, +0x73, 0x4b, 0x6e, 0x6f, 0x78, 0x20, 0x28, 0x49, 0x6e, 0x64, 0x69, 0x61, +0x6e, 0x61, 0x29, 0x4d, 0x61, 0x72, 0x65, 0x6e, 0x67, 0x6f, 0x20, 0x28, +0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x29, 0x50, 0x65, 0x74, 0x65, +0x72, 0x73, 0x62, 0x75, 0x72, 0x67, 0x20, 0x28, 0x49, 0x6e, 0x64, 0x69, +0x61, 0x6e, 0x61, 0x29, 0x54, 0x65, 0x6c, 0x6c, 0x20, 0x43, 0x69, 0x74, 0x79, 0x20, 0x28, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x29, 0x56, -0x69, 0x6e, 0x63, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x20, 0x28, 0x49, 0x6e, -0x64, 0x69, 0x61, 0x6e, 0x61, 0x29, 0x57, 0x69, 0x6e, 0x61, 0x6d, 0x61, -0x63, 0x20, 0x28, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x29, 0x4a, -0x61, 0x6d, 0xe0, 0x65, 0x67, 0x61, 0x4d, 0x6f, 0x6e, 0x74, 0x69, 0x63, -0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x28, 0x4b, 0x65, 0x6e, 0x74, 0x75, 0x63, -0x6b, 0x79, 0x29, 0x4c, 0x6f, 0x73, 0x20, 0xc0, 0x6e, 0x67, 0x65, 0x6c, -0x65, 0x73, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x67, 0x61, 0x53, -0x69, 0x74, 0xe0, 0x20, 0x64, 0x65, 0x2019, 0x6c, 0x20, 0x4d, 0xe8, 0x73, -0x65, 0x67, 0x6f, 0x4d, 0x69, 0x63, 0x68, 0x65, 0x6c, 0x6f, 0x6e, 0x42, -0x65, 0x75, 0x6c, 0x61, 0x68, 0x20, 0x28, 0x4e, 0x6f, 0x72, 0x64, 0x20, -0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61, 0x29, 0x43, 0x65, 0x6e, 0x74, 0x65, -0x72, 0x20, 0x28, 0x4e, 0x6f, 0x72, 0x64, 0x20, 0x44, 0x61, 0x6b, 0x6f, -0x74, 0x61, 0x29, 0x4e, 0x65, 0x77, 0x20, 0x53, 0x61, 0x6c, 0x65, 0x6d, -0x20, 0x28, 0x4e, 0x6f, 0x72, 0x64, 0x20, 0x44, 0x61, 0x6b, 0x6f, 0x74, -0x61, 0x29, 0x50, 0x6f, 0x72, 0x74, 0x6f, 0x20, 0x50, 0x72, 0xec, 0x6e, -0x73, 0x69, 0x70, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x6f, 0x20, 0x64, 0x65, -0x20, 0x53, 0x70, 0x61, 0x67, 0x6e, 0x61, 0x53, 0x61, 0x6e, 0x20, 0x50, -0x6f, 0x6c, 0x6f, 0x53, 0x2e, 0x20, 0x42, 0x61, 0x72, 0x74, 0x6f, 0x6c, -0x6f, 0x6d, 0xe8, 0x6f, 0x53, 0x2e, 0x20, 0x4a, 0x6f, 0x61, 0x6e, 0x69, -0x53, 0x2e, 0x20, 0x43, 0x72, 0x69, 0x73, 0x74, 0x6f, 0x66, 0x65, 0x72, -0x53, 0x2e, 0x20, 0x4c, 0x75, 0x73, 0xec, 0x61, 0x53, 0x2e, 0x20, 0x56, -0x69, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x6f, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, -0x20, 0x4d, 0x61, 0x63, 0x71, 0x75, 0x61, 0x72, 0x69, 0x65, 0x41, 0x6e, -0xe0, 0x64, 0x79, 0x72, 0x41, 0x6b, 0x74, 0xe0, 0x75, 0x41, 0x7a, 0x67, -0x61, 0x62, 0x61, 0x64, 0x41, 0x74, 0x79, 0x72, 0xe0, 0x75, 0x43, 0x6f, -0x6c, 0x6f, 0x6e, 0x62, 0x6f, 0x44, 0x75, 0x62, 0xe0, 0x69, 0x44, 0x75, -0x73, 0x61, 0x6e, 0x62, 0xe9, 0x4b, 0x61, 0x74, 0x6d, 0x61, 0x6e, 0x64, -0xf9, 0x48, 0xe0, 0x6e, 0x64, 0x69, 0x67, 0x61, 0x4b, 0x72, 0x61, 0x7a, -0x6e, 0x61, 0x79, 0x61, 0x72, 0x73, 0x6b, 0x4b, 0x75, 0x61, 0x6c, 0x61, -0x20, 0x4c, 0x75, 0x6e, 0x70, 0x75, 0x72, 0x4d, 0x61, 0x63, 0xe0, 0x6f, -0x4e, 0x6f, 0x76, 0x6f, 0x6b, 0x75, 0x7a, 0x6e, 0x69, 0x65, 0x74, 0x73, -0x6b, 0x4b, 0x6f, 0x73, 0x74, 0x61, 0x6e, 0xe0, 0x69, 0x53, 0x68, 0x61, -0x6e, 0x67, 0x68, 0xe0, 0x69, 0x5a, 0x72, 0xe9, 0x64, 0x6e, 0x65, 0x6b, -0x6f, 0x6c, 0x69, 0x6d, 0x73, 0x6b, 0x54, 0x69, 0x6e, 0x70, 0x75, 0x55, -0x6c, 0x61, 0x6e, 0x20, 0x42, 0xe0, 0x74, 0x6f, 0x72, 0x55, 0x73, 0x74, -0x2d, 0x47, 0x6e, 0x65, 0x72, 0x61, 0x59, 0x65, 0x6b, 0x61, 0x74, 0x65, -0x72, 0x69, 0x6e, 0x62, 0x75, 0x72, 0x67, 0x6f, 0x4a, 0xe8, 0x72, 0x65, -0x76, 0x61, 0x6e, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x41, 0x7a, 0x6f, -0x72, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x43, 0x61, 0x6e, 0x61, -0x72, 0x69, 0x65, 0x43, 0x61, 0x6f, 0x20, 0x56, 0x65, 0x72, 0x64, 0x6f, -0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x46, 0xe0, 0x72, 0x6f, 0x65, 0xcc, -0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x4d, 0x61, 0x64, 0xe8, 0x69, 0x72, 0x61, -0x52, 0x65, 0x6b, 0x69, 0x61, 0x76, 0x69, 0x6b, 0x47, 0x65, 0x6f, 0x72, -0x67, 0x69, 0x61, 0x20, 0x64, 0x65, 0x2019, 0x6c, 0x20, 0x73, 0x75, 0x64, -0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x53, 0x2e, 0x20, 0x45, 0x6c, 0x65, -0x6e, 0x61, 0x41, 0x64, 0x65, 0x6c, 0xe0, 0x69, 0x64, 0x65, 0x42, 0x72, -0x69, 0x7a, 0x62, 0x61, 0x6e, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, -0x4c, 0x6f, 0x72, 0x64, 0x20, 0x48, 0x6f, 0x77, 0x65, 0xc0, 0x6d, 0x73, -0x74, 0x65, 0x72, 0x64, 0x61, 0x6d, 0x42, 0x72, 0x61, 0x74, 0x69, 0x7a, -0x6c, 0x61, 0x76, 0x61, 0x4a, 0x69, 0x62, 0x69, 0x6c, 0x74, 0x65, 0x72, -0x61, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, -0x6e, 0x4c, 0x75, 0x62, 0x6c, 0x69, 0x61, 0x6e, 0x61, 0x4c, 0x75, 0x73, -0x65, 0x6e, 0x62, 0x75, 0x72, 0x67, 0x6f, 0x4f, 0x7a, 0x6c, 0x6f, 0x50, -0x61, 0x72, 0x69, 0x6a, 0x69, 0x53, 0x69, 0x6e, 0x66, 0x65, 0x72, 0xf2, -0x70, 0x6f, 0x6c, 0x69, 0x53, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x6d, 0x61, -0x55, 0x6c, 0x69, 0xe0, 0x6e, 0x6f, 0x73, 0x6b, 0x56, 0x61, 0x74, 0x65, -0x67, 0x61, 0x6e, 0x43, 0x69, 0x61, 0x67, 0x6f, 0x73, 0xcc, 0x7a, 0x6f, -0x6c, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4e, 0x61, 0x64, 0x61, 0x6c, 0x65, -0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x63, 0x6f, 0x73, 0xcc, -0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x6d, 0x6f, 0x72, 0x65, 0xcc, -0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x6c, 0x64, 0x69, 0x76, 0x65, -0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x73, -0x69, 0x6f, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x69, 0x6f, -0x74, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x52, 0x65, 0x75, 0x6e, -0x69, 0x6f, 0x6e, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x42, 0x6f, 0x75, -0x67, 0x61, 0x69, 0x6e, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0xcc, 0x7a, 0x6f, -0x6c, 0x65, 0x20, 0x43, 0x69, 0x61, 0x74, 0x65, 0x6d, 0xcc, 0x7a, 0x6f, -0x6c, 0x65, 0x20, 0x43, 0x68, 0x75, 0x75, 0x6b, 0xcc, 0x7a, 0x6f, 0x6c, -0x61, 0x20, 0x64, 0x65, 0x20, 0x50, 0x61, 0x73, 0x63, 0x75, 0x61, 0xcc, -0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x45, 0x66, 0x61, 0x74, 0x65, 0x41, 0x74, -0x6f, 0x6c, 0x6f, 0x20, 0x46, 0x61, 0x6b, 0x61, 0x6f, 0x66, 0x6f, 0x41, -0x74, 0x6f, 0x6c, 0x6f, 0x20, 0x46, 0x75, 0x6e, 0x61, 0x66, 0x75, 0x74, -0x69, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x47, 0x61, 0x6d, 0x62, 0x69, -0x65, 0x72, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x47, 0x75, 0x61, 0x64, -0x61, 0x6c, 0x63, 0x61, 0x6e, 0x61, 0x6c, 0x41, 0x74, 0x6f, 0x6c, 0x6f, -0x20, 0x43, 0x61, 0x6e, 0x74, 0x6f, 0x6e, 0x41, 0x74, 0x6f, 0x6c, 0x6f, -0x20, 0x4b, 0x69, 0x72, 0x69, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x69, 0xcc, -0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x4b, 0x6f, 0x73, 0x72, 0x61, 0x65, 0x41, -0x74, 0x6f, 0x6c, 0x6f, 0x20, 0x4b, 0x77, 0x61, 0x6a, 0x61, 0x6c, 0x65, -0x69, 0x6e, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x72, 0x63, -0x68, 0x65, 0x7a, 0x69, 0x41, 0x74, 0x6f, 0x6c, 0x6f, 0x20, 0x4d, 0x69, -0x64, 0x77, 0x61, 0x79, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x4e, 0x61, -0x75, 0x72, 0x75, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x4e, 0x69, 0x75, -0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x4e, 0x6f, 0x72, 0x66, 0x6f, -0x6c, 0x6b, 0x50, 0x61, 0x6c, 0xe0, 0x75, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, -0x20, 0x50, 0x69, 0x74, 0x63, 0x61, 0x69, 0x72, 0x6e, 0xcc, 0x7a, 0x6f, -0x6c, 0x61, 0x20, 0x50, 0x6f, 0x6e, 0x70, 0xe8, 0x69, 0x50, 0x6f, 0x72, -0x74, 0x6f, 0x20, 0x4d, 0x6f, 0x72, 0x65, 0x73, 0x62, 0x79, 0xcc, 0x7a, -0x6f, 0x6c, 0x61, 0x20, 0x52, 0x61, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x67, -0x61, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x53, 0x61, 0x69, 0x70, 0xe0, -0x6e, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x54, 0x61, 0x69, 0x74, 0x69, -0x41, 0x74, 0x6f, 0x6c, 0x6c, 0x6f, 0x20, 0x54, 0x61, 0x72, 0x61, 0x77, -0x61, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x54, 0x6f, 0x6e, 0x67, 0x61, -0x74, 0x61, 0x70, 0x75, 0x41, 0x74, 0x6f, 0x6c, 0x6f, 0x20, 0x57, 0x61, -0x6b, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x57, 0x61, 0x6c, 0x6c, -0x69, 0x73, 0x61, 0x62, 0x69, 0x64, 0x6a, 0x61, 0x6e, 0x65, 0x63, 0x72, -0x61, 0x61, 0x1e0d, 0x69, 0x73, 0x20, 0x61, 0x62, 0x61, 0x62, 0x61, 0x61, -0x6c, 0x6a, 0x12b, 0x79, 0x72, 0x73, 0x61, 0x73, 0x6d, 0x61, 0x72, 0x61, -0x62, 0x61, 0x6d, 0x61, 0x6b, 0x6f, 0x62, 0x61, 0x6e, 0x67, 0x75, 0x69, -0x62, 0x61, 0x6e, 0x6a, 0x75, 0x6c, 0x62, 0x69, 0x73, 0x73, 0x61, 0x75, -0x62, 0x6c, 0x61, 0x6e, 0x1e6d, 0x61, 0x65, 0x72, 0x62, 0x72, 0x61, 0x6a, -0x61, 0x76, 0x69, 0x6c, 0x6c, 0x62, 0x75, 0x6a, 0x75, 0x6d, 0x62, 0x75, -0x72, 0x61, 0x6b, 0x61, 0x69, 0x72, 0x6f, 0x6b, 0x61, 0x73, 0x61, 0x62, -0x6c, 0x61, 0x6e, 0x6b, 0x61, 0x73, 0x65, 0x75, 0x1e6d, 0x61, 0x6b, 0x6f, -0x6e, 0x61, 0x6b, 0x72, 0x12b, 0x1e0d, 0x6b, 0x61, 0x72, 0x64, 0x61, 0x72, -0x20, 0x65, 0x73, 0x20, 0x73, 0x61, 0x6c, 0x61, 0x61, 0x6d, 0x64, 0x75, -0x61, 0x6c, 0x61, 0x65, 0x6c, 0x20, 0x61, 0x61, 0x69, 0x79, 0x75, 0x6e, -0x70, 0x72, 0x12b, 0x1e6d, 0x61, 0x75, 0x6e, 0x67, 0x61, 0x62, 0x6f, 0x72, -0x6f, 0x6e, 0x68, 0x72, 0x61, 0x72, 0x65, 0x6a, 0x6f, 0x68, 0x61, 0x6e, -0x6e, 0x65, 0x73, 0x62, 0x75, 0x72, 0x67, 0x6a, 0x75, 0x62, 0x61, 0x6b, -0x6d, 0x70, 0x61, 0x6c, 0x61, 0x6b, 0x61, 0x72, 0x1e6d, 0x6f, 0x75, 0x6d, -0x6b, 0x69, 0x67, 0x61, 0x6c, 0x69, 0x6b, 0x69, 0x6e, 0x73, 0x61, 0x73, -0x61, 0x6c, 0x61, 0x67, 0x6f, 0x73, 0x6c, 0x69, 0x62, 0x72, 0x65, 0x76, -0x69, 0x6c, 0x6c, 0x6c, 0x75, 0x61, 0x6e, 0x1e0d, 0x61, 0x6c, 0x75, 0x62, -0x75, 0x6d, 0x62, 0x61, 0x73, 0x69, 0x6c, 0x75, 0x73, 0x61, 0x6b, 0x61, -0x6d, 0x61, 0x6c, 0x61, 0x62, 0x6f, 0x6d, 0x61, 0x70, 0x75, 0x1e6d, 0x75, -0x6d, 0x61, 0x73, 0x65, 0x72, 0x75, 0x6d, 0x62, 0x61, 0x62, 0x61, 0x6e, -0x65, 0x6d, 0x6f, 0x67, 0x61, 0x1e0d, 0x69, 0x73, 0x75, 0x6d, 0x6f, 0x6e, -0x72, 0x6f, 0x76, 0x69, 0x61, 0x6e, 0x61, 0x69, 0x72, 0x6f, 0x62, 0x69, -0x6e, 0x6a, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x6d, -0x65, 0x6e, 0x75, 0x65, 0x6b, 0x73, 0x61, 0x76, 0x61, 0x67, 0x64, 0x75, -0x67, 0x75, 0x70, 0x6f, 0x72, 0x1e6d, 0x6f, 0x2d, 0x1e47, 0x6f, 0x76, 0x6f, -0x73, 0x61, 0x6f, 0x20, 0x1e6d, 0x6f, 0x6d, 0x74, 0x72, 0x69, 0x70, 0x6f, -0x6c, 0x69, 0x1e6d, 0x75, 0x6e, 0x69, 0x73, 0x76, 0x69, 0x6e, 0x64, 0x68, -0x75, 0x6b, 0x61, 0x1e0d, 0x61, 0x6b, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x61, -0x6a, 0x65, 0x6e, 0x67, 0x75, 0x69, 0x6c, 0x6c, 0x61, 0x65, 0x6e, 0x1e6d, -0x69, 0x67, 0x75, 0x61, 0x61, 0x72, 0x61, 0x67, 0x76, 0x61, 0x69, 0x6e, -0x61, 0x62, 0x75, 0x65, 0x6e, 0x6f, 0x75, 0x73, 0x20, 0x61, 0x69, 0x72, -0x65, 0x73, 0x6b, 0x61, 0x74, 0x61, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x6b, -0x6f, 0x72, 0x1e0d, 0x61, 0x62, 0x61, 0x68, 0x75, 0x68, 0x75, 0x65, 0x6c, -0x61, 0x20, 0x72, 0x69, 0x6f, 0x6a, 0x61, 0x6d, 0x65, 0x6e, 0x1e0d, 0x6f, -0x6a, 0x61, 0x72, 0x69, 0x79, 0x6f, 0x20, 0x67, 0x61, 0x6c, 0x6c, 0x65, -0x67, 0x6f, 0x73, 0x73, 0x61, 0x6c, 0x1e6d, 0x61, 0x73, 0x61, 0x6e, 0x20, -0x68, 0x75, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x20, 0x6c, 0x75, 0x69, 0x73, -0x1e6d, 0x75, 0x6b, 0x16b, 0x6d, 0x6e, 0x75, 0x73, 0x76, 0x61, 0x69, 0x79, -0x61, 0x61, 0x72, 0x75, 0x62, 0x61, 0x65, 0x73, 0x75, 0x6e, 0x73, 0x69, -0x6f, 0x6e, 0x65, 0x1e6d, 0x69, 0x6b, 0x6f, 0x6b, 0x65, 0x6e, 0x62, 0x61, -0x68, 0x69, 0x61, 0x62, 0x61, 0x69, 0x61, 0x20, 0x62, 0x61, 0x6e, 0x1e0d, -0x65, 0x72, 0x61, 0x73, 0x62, 0x61, 0x72, 0x62, 0x61, 0x1e0d, 0x6f, 0x73, -0x62, 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x65, 0x6c, 0x69, 0x6a, 0x62, 0x6c, -0x61, 0x6e, 0x6b, 0x2d, 0x73, 0x61, 0x62, 0x6c, 0x6f, 0x6e, 0x62, 0x6f, -0x61, 0x20, 0x76, 0x69, 0x73, 0x74, 0x61, 0x62, 0x6f, 0x67, 0x6f, 0x1e6d, -0x61, 0x62, 0x6f, 0x69, 0x73, 0x12b, 0x6b, 0x65, 0x6d, 0x62, 0x72, 0x69, -0x6a, 0x20, 0x62, 0x65, 0x6b, 0x61, 0x6d, 0x70, 0x6f, 0x20, 0x67, 0x72, -0x61, 0x6e, 0x1e0d, 0x65, 0x6b, 0x61, 0x6e, 0x6b, 0x75, 0x6e, 0x6b, 0x61, -0x72, 0x61, 0x6b, 0x61, 0x73, 0x6b, 0x65, 0x79, 0x65, 0x6e, 0x6b, 0x65, -0x69, 0x6d, 0x61, 0x6e, 0x63, 0x69, 0x6b, 0x61, 0x67, 0x6f, 0x63, 0x68, -0x69, 0x68, 0x75, 0x61, 0x68, 0x75, 0x61, 0x6b, 0x6f, 0x73, 0x1e6d, 0x61, -0x20, 0x72, 0x69, 0x6b, 0x61, 0x6b, 0x72, 0x65, 0x73, 0x1e6d, 0x6f, 0x6e, -0x6b, 0x75, 0x61, 0x61, 0x62, 0x61, 0x6b, 0x79, 0x75, 0x72, 0x61, 0x73, -0x6f, 0x1e0d, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x61, 0x76, 0x6e, -0x1e0d, 0x61, 0x6f, 0x73, 0x6e, 0x1e0d, 0x61, 0x6f, 0x73, 0x6f, 0x6e, 0x20, -0x6b, 0x72, 0x12b, 0x6b, 0x1e0d, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x1e0d, 0x65, -0x1e6d, 0x72, 0x6f, 0x69, 0x1e6d, 0x1e0d, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x6b, -0x61, 0x65, 0x1e0d, 0x6d, 0x6f, 0x6e, 0x1e6d, 0x6f, 0x6e, 0x65, 0x69, 0x72, -0x75, 0x6e, 0x65, 0x70, 0x65, 0x65, 0x6c, 0x20, 0x73, 0x61, 0x6c, 0x76, -0x61, 0x1e0d, 0x6f, 0x72, 0x70, 0x68, 0x6f, 0x72, 0x74, 0x20, 0x6e, 0x65, -0x6c, 0x73, 0x6e, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x65, 0x6a, 0x61, -0x67, 0x6c, 0x61, 0x73, 0x20, 0x62, 0x61, 0x79, 0x67, 0x6f, 0x6f, 0x73, -0x20, 0x62, 0x65, 0x67, 0x72, 0x61, 0x6e, 0x1e0d, 0x20, 0x1e6d, 0x75, 0x72, -0x6b, 0x67, 0x72, 0x65, 0x6e, 0x61, 0x1e0d, 0x61, 0x67, 0x75, 0x61, 0x1e0d, -0x65, 0x6c, 0x6f, 0x75, 0x70, 0x65, 0x67, 0x75, 0x61, 0x74, 0x65, 0x6d, -0x61, 0x6c, 0x61, 0x67, 0x75, 0x61, 0x6a, 0x61, 0x6b, 0x69, 0x6c, 0x67, -0x75, 0x79, 0x61, 0x6e, 0x61, 0x68, 0x65, 0x6c, 0x69, 0x70, 0x61, 0x6b, -0x73, 0x68, 0x61, 0x76, 0x61, 0x6e, 0x61, 0x69, 0x6e, 0x1e0d, 0x69, 0x61, -0x6e, 0x61, 0x70, 0x6f, 0x6c, 0x69, 0x73, 0x6e, 0x6f, 0x6b, 0x73, 0x2c, -0x20, 0x69, 0x6e, 0x1e0d, 0x69, 0x79, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x72, -0x65, 0x6e, 0x67, 0x6f, 0x2c, 0x20, 0x69, 0x6e, 0x1e0d, 0x69, 0x79, 0x61, -0x6e, 0x61, 0x70, 0x69, 0x1e6d, 0x74, 0x72, 0x73, 0x62, 0x65, 0x72, 0x67, -0x2c, 0x20, 0x69, 0x6e, 0x1e0d, 0x69, 0x79, 0x61, 0x6e, 0x61, 0x1e6d, 0x65, -0x6c, 0x6c, 0x20, 0x73, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x69, 0x6e, 0x1e0d, -0x69, 0x79, 0x61, 0x6e, 0x61, 0x76, 0x69, 0x76, 0x69, 0x2c, 0x20, 0x69, -0x6e, 0x1e0d, 0x69, 0x79, 0x61, 0x6e, 0x61, 0x76, 0x69, 0x6e, 0x63, 0x65, -0x6e, 0x73, 0x2c, 0x20, 0x69, 0x6e, 0x1e0d, 0x69, 0x79, 0x61, 0x6e, 0x61, -0x76, 0x69, 0x6e, 0x61, 0x6d, 0x61, 0x6b, 0x2c, 0x20, 0x69, 0x6e, 0x1e0d, -0x69, 0x79, 0x61, 0x6e, 0x61, 0x69, 0x6e, 0x16b, 0x76, 0x69, 0x6b, 0x69, -0x6b, 0x61, 0x6c, 0x75, 0x69, 0x1e6d, 0x6a, 0x61, 0x6d, 0x61, 0x69, 0x6b, -0x61, 0x6a, 0x75, 0x6e, 0x6f, 0x76, 0x6c, 0x6f, 0x75, 0x69, 0x76, 0x69, -0x6c, 0x6c, 0x65, 0x6d, 0x6f, 0x6e, 0x1e6d, 0x69, 0x73, 0x65, 0x6c, 0x6c, -0x6f, 0x2c, 0x20, 0x6b, 0x65, 0x6e, 0x1e6d, 0x75, 0x6b, 0x12b, 0x6b, 0x72, -0x65, 0x6c, 0x65, 0x6e, 0x1e0d, 0x65, 0x69, 0x6b, 0x6c, 0x61, 0x20, 0x70, -0x61, 0x6a, 0x6c, 0x6f, 0x73, 0x20, 0x61, 0x6e, 0x6a, 0x65, 0x6c, 0x65, -0x73, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63, -0x2019, 0x73, 0x20, 0x6b, 0x75, 0x76, 0x61, 0x1e6d, 0x61, 0x72, 0x6d, 0x61, -0x73, 0x12b, 0x6f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x75, 0x61, 0x6d, 0x61, -0x6e, 0x61, 0x75, 0x73, 0x6d, 0x61, 0x72, 0x69, 0x67, 0x6f, 0x1e6d, 0x6d, -0x61, 0x72, 0x1e6d, 0x69, 0x6e, 0x69, 0x6b, 0x6d, 0x61, 0x1e6d, 0x61, 0x6d, -0x6f, 0x72, 0x6f, 0x73, 0x6d, 0x61, 0x73, 0x61, 0x1e6d, 0x6c, 0x61, 0x6e, -0x6d, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x6e, 0x12b, 0x6d, 0x65, 0x72, 0x69, -0x1e0d, 0x61, 0x6d, 0x65, 0x1e6d, 0x6c, 0x61, 0x6b, 0x61, 0x1e6d, 0x6c, 0x61, -0x6d, 0x65, 0x6b, 0x73, 0x69, 0x63, 0x6f, 0x20, 0x73, 0x69, 0x1e6d, 0x79, -0x6d, 0x69, 0x6b, 0x76, 0x69, 0x6c, 0xf5, 0x6d, 0x6f, 0x6e, 0x6b, 0x1e6d, -0x6f, 0x6e, 0x6d, 0x6f, 0x6e, 0x1e6d, 0x65, 0x72, 0x72, 0x65, 0x6d, 0x6f, -0x6e, 0x1e6d, 0x65, 0x76, 0x69, 0x64, 0x69, 0x6f, 0x6d, 0x6f, 0x6e, 0x1e6d, -0x73, 0x65, 0x72, 0x72, 0x65, 0x1e6d, 0x6e, 0x61, 0x73, 0x61, 0x75, 0x6e, -0x69, 0x79, 0x75, 0x20, 0x79, 0x6f, 0x72, 0x6b, 0x6e, 0x6f, 0x72, 0x6f, -0x6e, 0x68, 0x61, 0x62, 0x69, 0x79, 0x75, 0x6c, 0x61, 0x2c, 0x20, 0x75, -0x74, 0x74, 0x61, 0x72, 0x20, 0x1e0d, 0x61, 0x6b, 0x6f, 0x1e6d, 0x61, 0x6d, -0x61, 0x1e0d, 0x69, 0x6e, 0x12b, 0x20, 0x75, 0x74, 0x74, 0x61, 0x72, 0x20, -0x1e0d, 0x61, 0x6b, 0x6f, 0x1e6d, 0x61, 0x6e, 0x65, 0x75, 0x20, 0x73, 0x61, -0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x75, 0x74, 0x74, 0x61, 0x72, 0x20, 0x1e0d, -0x61, 0x6b, 0x6f, 0x1e6d, 0x61, 0x6e, 0x16b, 0x6b, 0x6f, 0x6a, 0x69, 0x6e, -0x61, 0x67, 0x61, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x70, 0x61, 0x72, -0x61, 0x6d, 0x61, 0x72, 0x69, 0x62, 0x6f, 0x70, 0x69, 0x6e, 0x69, 0x6b, -0x73, 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x61, 0x75, 0x2d, 0x70, 0x72, 0x69, -0x6e, 0x73, 0x65, 0x70, 0x6f, 0x72, 0x1e6d, 0x20, 0x61, 0x70, 0x20, 0x73, -0x70, 0x61, 0x69, 0x6e, 0x70, 0x6f, 0x72, 0x1e6d, 0x70, 0x20, 0x76, 0x65, -0x6c, 0x68, 0x6f, 0x70, 0x75, 0x65, 0x72, 0x74, 0x6f, 0x20, 0x72, 0x69, -0x6b, 0x6f, 0x70, 0x75, 0x1e47, 0x1e6d, 0x61, 0x20, 0x65, 0x72, 0x65, 0x6e, -0x61, 0x73, 0x72, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x20, 0x69, 0x6e, 0x6c, -0x65, 0x64, 0x1e6d, 0x72, 0x65, 0x73, 0x69, 0x70, 0x69, 0x72, 0x65, 0x6a, -0x69, 0x6e, 0x61, 0x72, 0x65, 0x6a, 0x61, 0x6c, 0x79, 0x75, 0x1e6d, 0x72, -0x69, 0x6f, 0x20, 0x62, 0x72, 0x61, 0x6e, 0x6b, 0x6f, 0x73, 0x61, 0x74, -0x61, 0x72, 0x69, 0x73, 0x61, 0x6e, 0x1e6d, 0x69, 0x61, 0x67, 0x6f, 0x73, -0x65, 0x6e, 0x74, 0x6f, 0x20, 0x1e0d, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, -0x73, 0x61, 0x6f, 0x20, 0x70, 0x61, 0x75, 0x6c, 0x6f, 0x69, 0x1e6d, 0x6f, -0x6b, 0x6f, 0x1e6d, 0x6f, 0x72, 0x6d, 0x69, 0x1e6d, 0x73, 0x69, 0x74, 0x6b, -0x61, 0x73, 0x65, 0x6e, 0x1e6d, 0x20, 0x62, 0x61, 0x72, 0x74, 0x65, 0x6c, -0x65, 0x6d, 0x69, 0x73, 0x65, 0x6e, 0x1e6d, 0x20, 0x6a, 0x6f, 0x6e, 0x73, -0x73, 0x65, 0x6e, 0x74, 0x20, 0x6b, 0x69, 0x1e6d, 0x1e6d, 0x73, 0x73, 0x65, -0x6e, 0x74, 0x20, 0x6c, 0x75, 0x73, 0x69, 0x61, 0x73, 0x65, 0x6e, 0x1e6d, -0x20, 0x74, 0x6f, 0x6d, 0x61, 0x73, 0x73, 0x65, 0x6e, 0x1e6d, 0x20, 0x76, -0x69, 0x6e, 0x73, 0x65, 0x6e, 0x1e6d, 0x73, 0x76, 0x69, 0x70, 0x1e6d, 0x20, -0x6b, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x1e6d, 0x74, 0x65, 0x67, 0x75, 0x74, -0x75, 0x6c, 0x65, 0x74, 0x69, 0x68, 0x76, 0x61, 0x6e, 0x61, 0x1e6d, 0x6f, -0x72, 0x6f, 0x6e, 0x1e6d, 0x6f, 0x1e6d, 0x6f, 0x72, 0x1e6d, 0x6f, 0x6c, 0x61, -0x76, 0x61, 0x6e, 0x6b, 0x16b, 0x76, 0x65, 0x72, 0x76, 0x68, 0x61, 0x69, -0x1e6d, 0x68, 0x6f, 0x72, 0x73, 0x76, 0x69, 0x6e, 0x6e, 0x69, 0x70, 0x65, -0x67, 0x79, 0x61, 0x6b, 0x75, 0x1e6d, 0x61, 0x1e6d, 0x6b, 0x65, 0x73, 0x65, -0x65, 0x1e0d, 0x65, 0x76, 0x69, 0x73, 0x1e0d, 0x79, 0x75, 0x6d, 0x6f, 0x6e, -0x74, 0x20, 0x64, 0x65, 0x20, 0x75, 0x72, 0x76, 0x69, 0x6c, 0x6c, 0x6d, -0x65, 0x6b, 0x76, 0x61, 0x72, 0x69, 0x6d, 0x61, 0x76, 0x73, 0x6f, 0x6e, -0x6d, 0x65, 0x6b, 0x20, 0x6d, 0x75, 0x72, 0x1e0d, 0x6f, 0x70, 0x61, 0x6c, -0x6d, 0x65, 0x72, 0x72, 0x6f, 0x74, 0x65, 0x72, 0x61, 0x73, 0x79, 0x6f, -0x76, 0x61, 0x1e6d, 0x72, 0x6f, 0x6c, 0x6c, 0x76, 0x6f, 0x73, 0x1e6d, 0x6f, -0x6b, 0x6c, 0x6e, 0x67, 0x79, 0x61, 0x72, 0x62, 0x79, 0x65, 0x6e, 0x65, -0x1e0d, 0x65, 0x6e, 0x61, 0x6c, 0x6d, 0x61, 0x1e6d, 0x79, 0x61, 0x6d, 0x6d, -0x61, 0x6e, 0x61, 0x6e, 0x61, 0x1e0d, 0x69, 0x72, 0x61, 0x6b, 0x74, 0x61, -0x75, 0x61, 0x61, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x61, 0x73, 0x67, 0x61, -0x62, 0x61, 0x1e6d, 0x61, 0x74, 0x61, 0x72, 0x61, 0x75, 0x62, 0x61, 0x67, -0x64, 0x61, 0x64, 0x62, 0x61, 0x68, 0x72, 0x61, 0x69, 0x6e, 0x62, 0x61, -0x6b, 0x75, 0x62, 0x61, 0x6e, 0x67, 0x6b, 0x6f, 0x6b, 0x62, 0x61, 0x72, -0x6e, 0x61, 0x75, 0x6c, 0x62, 0x65, 0x69, 0x72, 0x75, 0x74, 0x62, 0x69, -0x73, 0x6b, 0x65, 0x6b, 0x62, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x63, 0x69, -0x74, 0x61, 0x6b, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x6f, 0x1e0d, 0x61, 0x6d, -0x61, 0x73, 0x6b, 0x75, 0x73, 0x1e0d, 0x69, 0x6c, 0x69, 0x64, 0x75, 0x62, -0x61, 0x69, 0x64, 0x75, 0x73, 0x61, 0x6d, 0x62, 0x65, 0x70, 0x61, 0x6d, -0x61, 0x67, 0x75, 0x73, 0x74, 0x61, 0x67, 0x61, 0x6a, 0x61, 0x68, 0x65, -0x62, 0x72, 0x6f, 0x6e, 0x68, 0x6f, 0x20, 0x63, 0x69, 0x20, 0x6d, 0x69, -0x6e, 0x68, 0x20, 0x73, 0x69, 0x74, 0x69, 0x68, 0x6f, 0x6e, 0x67, 0x20, -0x6b, 0x6f, 0x6e, 0x67, 0x69, 0x72, 0x6b, 0x75, 0x1e6d, 0x73, 0x6b, 0x6a, -0x61, 0x79, 0x61, 0x70, 0x75, 0x72, 0x61, 0x6a, 0x65, 0x72, 0x75, 0x73, -0x61, 0x6c, 0x65, 0x6d, 0x6b, 0x61, 0x62, 0x75, 0x6c, 0x6b, 0x61, 0x6d, -0x63, 0x61, 0x1e6d, 0x6b, 0x61, 0x6b, 0x61, 0x72, 0x61, 0x63, 0x12b, 0x6b, -0x61, 0x1e6d, 0x6d, 0x61, 0x6e, 0x1e0d, 0x75, 0x6b, 0x61, 0x6e, 0x64, 0x69, -0x67, 0x61, 0x6b, 0x6f, 0x6c, 0x6b, 0x61, 0x74, 0x61, 0x6b, 0x72, 0x61, -0x73, 0x6e, 0x65, 0x79, 0x61, 0x72, 0x73, 0x6b, 0x6b, 0x75, 0x61, 0x6c, -0x61, 0x20, 0x6c, 0x75, 0x6d, 0x70, 0x75, 0x72, 0x6b, 0x75, 0x63, 0x69, -0x6e, 0x67, 0x6b, 0x75, 0x76, 0x61, 0x69, 0x74, 0x6d, 0x6b, 0x61, 0x6f, -0x6d, 0x65, 0x67, 0x61, 0x1e0d, 0x61, 0x6e, 0x6d, 0x61, 0x6b, 0x61, 0x73, -0x61, 0x72, 0x6d, 0x61, 0x6e, 0x12b, 0x6c, 0x61, 0x6d, 0x61, 0x73, 0x6b, -0x61, 0x74, 0x6e, 0x69, 0x6b, 0x6f, 0x73, 0x69, 0x79, 0x61, 0x6e, 0x65, -0x76, 0x6f, 0x6b, 0x75, 0x6a, 0x6e, 0x65, 0x1e6d, 0x73, 0x6b, 0x6e, 0x6f, -0x76, 0x6f, 0x73, 0x69, 0x62, 0x69, 0x72, 0x73, 0x6b, 0x70, 0x6e, 0x6f, -0x6d, 0x20, 0x70, 0x65, 0x6e, 0x68, 0x70, 0x6f, 0x6e, 0x1e6d, 0x69, 0x61, -0x6e, 0x61, 0x6b, 0x70, 0x79, 0x6f, 0x6e, 0x67, 0x79, 0x61, 0x6e, 0x67, -0x6b, 0x6f, 0x73, 0x1e6d, 0x61, 0x6e, 0x65, 0x6b, 0x69, 0x6a, 0x75, 0x6f, -0x72, 0x64, 0x61, 0x72, 0x69, 0x79, 0x61, 0x64, 0x73, 0x61, 0x68, 0x61, -0x6c, 0x69, 0x6e, 0x73, 0x61, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x6e, 0x64, -0x73, 0x65, 0x6f, 0x6c, 0x73, 0x65, 0x6e, 0x67, 0x61, 0x69, 0x73, 0x69, -0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x73, 0x72, 0x65, 0x1e0d, 0x6e, 0x65, -0x6b, 0x6f, 0x6c, 0x79, 0x6d, 0x73, 0x6b, 0x74, 0x61, 0x69, 0x70, 0x65, -0x69, 0x74, 0x61, 0x73, 0x6b, 0x65, 0x6e, 0x1e6d, 0x74, 0x62, 0x69, 0x6c, -0x69, 0x73, 0x69, 0x74, 0x65, 0x68, 0x72, 0x61, 0x6e, 0x74, 0x69, 0x6d, -0x70, 0x68, 0x75, 0x1e6d, 0x6f, 0x6b, 0x79, 0x6f, 0x1e6d, 0x6f, 0x6d, 0x73, -0x6b, 0x75, 0x6c, 0x61, 0x6e, 0x62, 0x61, 0x1e6d, 0x61, 0x72, 0x75, 0x72, -0x75, 0x6d, 0x63, 0x69, 0x79, 0x75, 0x73, 0x74, 0x2d, 0x6e, 0x65, 0x72, -0x61, 0x76, 0x69, 0x65, 0x6e, 0x1e6d, 0x69, 0x61, 0x61, 0x6e, 0x76, 0x6c, -0x61, 0x1e0d, 0x69, 0x76, 0x6f, 0x73, 0x1e6d, 0x6f, 0x6b, 0x79, 0x61, 0x6b, -0x75, 0x1e6d, 0x73, 0x6b, 0x79, 0x61, 0x6e, 0x67, 0x6f, 0x6e, 0x79, 0x69, -0x6b, 0x61, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x62, 0x75, 0x72, 0x67, 0x79, -0x65, 0x72, 0x65, 0x76, 0x61, 0x6e, 0x61, 0x6a, 0x6f, 0x72, 0x65, 0x73, -0x62, 0x65, 0x72, 0x6d, 0x16b, 0x64, 0x61, 0x6b, 0x65, 0x6e, 0x65, 0x72, -0x69, 0x6b, 0x65, 0x70, 0x20, 0x76, 0x65, 0x72, 0x1e0d, 0x65, 0x70, 0x65, -0x72, 0x6f, 0x6d, 0x61, 0x1e0d, 0x69, 0x65, 0x72, 0x61, 0x72, 0x65, 0x79, -0x6b, 0x79, 0x61, 0x76, 0x69, 0x6b, 0x64, 0x6b, 0x69, 0x1e47, 0x20, 0x6a, -0x6f, 0x72, 0x6a, 0x69, 0x61, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x68, 0x65, -0x6c, 0x65, 0x6e, 0x61, 0x73, 0x1e6d, 0x61, 0x6e, 0x6c, 0x69, 0x61, 0x65, -0x64, 0x69, 0x6c, 0x65, 0x69, 0x64, 0x62, 0x72, 0x69, 0x73, 0x62, 0x61, -0x6e, 0x65, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x68, 0x69, 0x6c, -0x6c, 0x1e0d, 0x61, 0x72, 0x76, 0x69, 0x6e, 0x79, 0x75, 0x6b, 0x6c, 0x61, -0x68, 0x6f, 0x62, 0x61, 0x72, 0x1e6d, 0x6c, 0x69, 0x6e, 0x1e0d, 0x65, 0x72, -0x6d, 0x61, 0x6e, 0x6c, 0x6f, 0x72, 0x1e0d, 0x20, 0x68, 0x6f, 0x76, 0x65, -0x6d, 0x65, 0x6c, 0x62, 0x6f, 0x72, 0x6e, 0x65, 0x70, 0x65, 0x72, 0x74, -0x73, 0x79, 0x1e0d, 0x6e, 0x12b, 0x61, 0x6d, 0x73, 0x1e6d, 0x65, 0x72, 0x1e0d, -0x61, 0x6d, 0x61, 0x61, 0x1e47, 0x1e0d, 0x6f, 0x72, 0x61, 0x61, 0x61, 0x73, -0x1e6d, 0x72, 0x61, 0x68, 0x61, 0x6e, 0x65, 0x74, 0x65, 0x6e, 0x73, 0x62, -0x65, 0x6c, 0x67, 0x72, 0x61, 0x1e0d, 0x65, 0x62, 0x65, 0x72, 0x6c, 0x69, -0x6e, 0x62, 0x72, 0x61, 0x1e6d, 0x69, 0x73, 0x6c, 0x61, 0x76, 0x61, 0x62, -0x72, 0x75, 0x73, 0x73, 0x65, 0x6c, 0x73, 0x62, 0x75, 0x6b, 0x61, 0x72, -0x65, 0x73, 0x74, 0x62, 0x75, 0x1e0d, 0x61, 0x70, 0x65, 0x73, 0x74, 0x62, -0x75, 0x73, 0x69, 0x6e, 0x67, 0x65, 0x6e, 0x6b, 0x69, 0x73, 0x69, 0x6e, -0x61, 0x75, 0x6b, 0x6f, 0x70, 0x65, 0x6e, 0x68, 0x61, 0x67, 0x65, 0x6e, -0x1e0d, 0x62, 0x6c, 0x69, 0x6e, 0x6a, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x1e6d, -0x61, 0x72, 0x67, 0x65, 0x72, 0x6e, 0x73, 0x69, 0x68, 0x65, 0x6c, 0x73, -0x69, 0x6e, 0x6b, 0x69, 0x61, 0x61, 0x69, 0x6c, 0x20, 0x61, 0x70, 0x20, -0x6d, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x6c, 0x6a, -0x65, 0x72, 0x73, 0x69, 0x6b, 0x61, 0x6c, 0x69, 0x6e, 0x69, 0x6e, 0x67, -0x72, 0x61, 0x1e0d, 0x6b, 0x69, 0x72, 0x6f, 0x76, 0x6b, 0x69, 0x79, 0x76, -0x6c, 0x69, 0x73, 0x62, 0x6f, 0x6e, 0x6c, 0x79, 0x75, 0x62, 0x6c, 0x79, -0x61, 0x6e, 0x61, 0x6c, 0x6e, 0x1e0d, 0x6e, 0x6c, 0x6b, 0x73, 0x65, 0x6d, -0x62, 0x72, 0x67, 0x6d, 0x65, 0x1e0d, 0x72, 0x69, 0x1e0d, 0x6d, 0x61, 0x6c, -0x1e6d, 0x61, 0x6d, 0x61, 0x72, 0x69, 0x65, 0x68, 0x61, 0x6d, 0x6d, 0x69, -0x6e, 0x73, 0x6b, 0x6d, 0x6f, 0x6e, 0x61, 0x6b, 0x6f, 0x6d, 0x6f, 0x73, -0x6b, 0x6f, 0x6f, 0x73, 0x6c, 0x6f, 0x70, 0x61, 0x72, 0x69, 0x73, 0x70, -0x1e0d, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x73, 0x61, 0x70, 0x72, 0x61, 0x67, -0x72, 0x69, 0x67, 0x61, 0x73, 0x61, 0x6d, 0x61, 0x72, 0x61, 0x73, 0x61, -0x6e, 0x20, 0x6d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x73, 0x61, 0x72, 0x61, -0x6a, 0x65, 0x76, 0x6f, 0x73, 0x61, 0x72, 0x61, 0x1e6d, 0x6f, 0x76, 0x73, -0x69, 0x6d, 0x70, 0x65, 0x72, 0x6f, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x6f, -0x70, 0x69, 0x73, 0x6f, 0x70, 0x69, 0x79, 0x61, 0x73, 0x1e6d, 0x6f, 0x6b, -0x68, 0x6f, 0x6d, 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x1e6d, 0x69, 0x72, 0x61, -0x6e, 0x65, 0x75, 0x6c, 0x79, 0x61, 0x6e, 0x6f, 0x76, 0x73, 0x6b, 0x76, -0x61, 0x1e0d, 0x75, 0x6a, 0x76, 0x61, 0x1e6d, 0x69, 0x6b, 0x61, 0x6e, 0x76, -0x69, 0x65, 0x6e, 0x6e, 0x61, 0x76, 0x69, 0x6c, 0x6e, 0x69, 0x75, 0x73, -0x76, 0x6f, 0x6c, 0x67, 0x6f, 0x67, 0x72, 0x61, 0x1e0d, 0x76, 0x61, 0x72, -0x73, 0x61, 0x74, 0x65, 0x67, 0x75, 0x73, 0x69, 0x67, 0x61, 0x6c, 0x70, -0x61, 0x6a, 0x75, 0x72, 0x69, 0x63, 0x1e6d, 0x61, 0x6e, 0x61, 0x6e, 0x61, -0x72, 0x69, 0x76, 0x63, 0x68, 0x61, 0x67, 0x6f, 0x73, 0x6b, 0x72, 0x69, -0x73, 0x1e6d, 0x6d, 0x61, 0x73, 0x6b, 0x6f, 0x6b, 0x6f, 0x73, 0x6b, 0x6f, -0x6d, 0x6f, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x67, 0x75, 0x65, 0x6c, 0x65, -0x6e, 0x6d, 0x61, 0x68, 0x65, 0x6d, 0x61, 0x6c, 0x64, 0x69, 0x76, 0x65, -0x73, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x73, 0x69, 0x75, 0x73, 0x6d, 0x61, -0x79, 0x6f, 0x1e6d, 0x72, 0x65, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x61, 0x70, -0x69, 0x61, 0x101, 0x6b, 0x6c, 0x61, 0x6e, 0x1e0d, 0x62, 0x6f, 0x75, 0x67, -0x61, 0x6e, 0x76, 0x69, 0x6c, 0x6c, 0x63, 0x65, 0x1e6d, 0x61, 0x6d, 0x63, -0x16b, 0x6b, 0x12b, 0x73, 0x74, 0x65, 0x72, 0x69, 0x70, 0x65, 0x1e6d, 0x65, -0x70, 0x61, 0x6b, 0x61, 0x6f, 0x70, 0x6f, 0x70, 0x69, 0x6a, 0x69, 0x70, -0x75, 0x6e, 0x61, 0x70, 0x75, 0x74, 0x69, 0x67, 0x61, 0x6c, 0x61, 0x70, -0x61, 0x67, 0x6f, 0x73, 0x67, 0x61, 0x6d, 0x62, 0x69, 0x65, 0x72, 0x67, -0x75, 0x61, 0x1e0d, 0x61, 0x6c, 0x6b, 0x65, 0x6e, 0x61, 0x6c, 0x6b, 0x61, -0x6e, 0x1e6d, 0x6f, 0x6e, 0x6b, 0x69, 0x72, 0x69, 0x74, 0x69, 0x6d, 0x61, -0x74, 0x69, 0x6b, 0x69, 0x73, 0x72, 0x61, 0x65, 0x6b, 0x76, 0x61, 0x6a, -0x61, 0x6c, 0x65, 0x69, 0x6e, 0x6d, 0x61, 0x6a, 0x75, 0x72, 0x6f, 0x6d, -0x61, 0x72, 0x6b, 0x69, 0x73, 0x61, 0x73, 0x6d, 0x69, 0x1e0d, 0x76, 0x61, -0x79, 0x6e, 0x61, 0x75, 0x72, 0x75, 0x6e, 0x69, 0x75, 0x65, 0x6e, 0x6f, -0x72, 0x70, 0x6f, 0x6b, 0x6e, 0x75, 0x6d, 0x69, 0x65, 0x70, 0x61, 0x6e, -0x67, 0x6f, 0x20, 0x70, 0x61, 0x6e, 0x67, 0x6f, 0x70, 0x61, 0x6c, 0x61, -0x75, 0x70, 0x69, 0x1e6d, 0x6b, 0x65, 0x72, 0x6e, 0x70, 0x6f, 0x6e, 0x70, -0x65, 0x69, 0x70, 0x6f, 0x72, 0x1e6d, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x73, -0x62, 0x69, 0x72, 0x61, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x73, -0x61, 0x69, 0x70, 0x61, 0x6e, 0x1e6d, 0x61, 0x68, 0x69, 0x1e6d, 0x69, 0x74, -0x61, 0x72, 0x61, 0x76, 0x61, 0x1e6d, 0x6f, 0x6e, 0x67, 0x61, 0x1e6d, 0x61, -0x70, 0x75, 0x76, 0x65, 0x6b, 0x76, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x92c, -0x94d, 0x92f, 0x93e, 0x928, 0x94d, 0x91c, 0x941, 0x932, 0x92a, 0x93c, 0x94d, 0x930, -0x940, 0x91f, 0x93e, 0x909, 0x928, 0x915, 0x93e, 0x930, 0x94d, 0x924, 0x941, 0x92e, -0x915, 0x93f, 0x902, 0x938, 0x93e, 0x938, 0x93e, 0x932, 0x941, 0x92c, 0x941, 0x92e, -0x92c, 0x93e, 0x938, 0x940, 0x92e, 0x94d, 0x2d, 0x92c, 0x93e, 0x92c, 0x93e, 0x928, -0x947, 0x92e, 0x94b, 0x917, 0x93e, 0x926, 0x93f, 0x938, 0x941, 0x928, 0x93e, 0x907, -0x930, 0x94b, 0x92c, 0x93f, 0x928, 0x941, 0x906, 0x915, 0x91a, 0x949, 0x91f, 0x938, -0x94d, 0x92f, 0x93e, 0x928, 0x20, 0x939, 0x94d, 0x935, 0x93e, 0x928, 0x938, 0x94d, -0x92f, 0x93e, 0x928, 0x20, 0x932, 0x942, 0x924, 0x93f, 0x909, 0x938, 0x941, 0x906, -0x907, 0x92f, 0x93e, 0x90f, 0x938, 0x928, 0x938, 0x93f, 0x92f, 0x949, 0x928, 0x92c, -0x94d, 0x932, 0x93e, 0x902, 0x2d, 0x938, 0x947, 0x92c, 0x932, 0x94b, 0x928, 0x915, -0x947, 0x92e, 0x94d, 0x92c, 0x94d, 0x930, 0x93f, 0x91c, 0x20, 0x92c, 0x947, 0x915, -0x94d, 0x92f, 0x93e, 0x92e, 0x94d, 0x92a, 0x94b, 0x20, 0x917, 0x94d, 0x930, 0x93e, -0x902, 0x921, 0x947, 0x915, 0x94d, 0x92f, 0x93e, 0x928, 0x915, 0x941, 0x928, 0x938, -0x93f, 0x915, 0x93e, 0x917, 0x94b, 0x921, 0x947, 0x928, 0x92e, 0x93e, 0x930, 0x94d, -0x915, 0x938, 0x949, 0x928, 0x924, 0x93f, 0x930, 0x941, 0x928, 0x947, 0x92a, 0x947, -0x92a, 0x93c, 0x94b, 0x930, 0x94d, 0x91f, 0x20, 0x928, 0x947, 0x932, 0x94d, 0x938, -0x928, 0x92a, 0x93c, 0x94b, 0x930, 0x94d, 0x91f, 0x93e, 0x932, 0x947, 0x91c, 0x93c, -0x93e, 0x939, 0x947, 0x932, 0x93f, 0x92a, 0x947, 0x915, 0x94d, 0x938, 0x907, 0x915, -0x93e, 0x932, 0x941, 0x924, 0x93f, 0x91f, 0x915, 0x94d, 0x930, 0x93e, 0x932, 0x947, -0x928, 0x94d, 0x921, 0x93f, 0x91c, 0x93f, 0x915, 0x92e, 0x928, 0x94b, 0x938, 0x92e, -0x947, 0x930, 0x93f, 0x917, 0x94b, 0x91f, 0x92c, 0x94d, 0x92f, 0x942, 0x932, 0x93e, -0x2c, 0x20, 0x909, 0x924, 0x949, 0x930, 0x949, 0x20, 0x921, 0x915, 0x94b, 0x91f, -0x93e, 0x92e, 0x93e, 0x926, 0x93f, 0x928, 0x940, 0x20, 0x909, 0x924, 0x949, 0x930, -0x949, 0x20, 0x921, 0x915, 0x94b, 0x91f, 0x93e, 0x928, 0x94d, 0x92f, 0x942, 0x20, -0x938, 0x93e, 0x932, 0x947, 0x92e, 0x2c, 0x20, 0x909, 0x924, 0x949, 0x930, 0x949, -0x20, 0x921, 0x915, 0x94b, 0x91f, 0x93e, 0x913, 0x915, 0x93e, 0x91c, 0x940, 0x928, -0x93e, 0x917, 0x93e, 0x92a, 0x93c, 0x940, 0x928, 0x93f, 0x915, 0x94d, 0x938, 0x92a, -0x94b, 0x930, 0x94d, 0x91f, 0x20, 0x911, 0x92a, 0x93c, 0x20, 0x938, 0x94d, 0x92a, -0x947, 0x928, 0x930, 0x947, 0x938, 0x93e, 0x907, 0x92a, 0x93c, 0x938, 0x947, 0x928, -0x94d, 0x91f, 0x93e, 0x930, 0x947, 0x92e, 0x938, 0x947, 0x902, 0x924, 0x93f, 0x906, -0x917, 0x94b, 0x938, 0x947, 0x902, 0x91f, 0x20, 0x92c, 0x93e, 0x930, 0x94d, 0x924, -0x947, 0x932, 0x947, 0x92e, 0x93f, 0x938, 0x947, 0x902, 0x91f, 0x20, 0x924, 0x949, -0x92e, 0x938, 0x938, 0x94d, 0x935, 0x93f, 0x92a, 0x93c, 0x94d, 0x91f, 0x20, 0x915, -0x930, 0x902, 0x91f, 0x935, 0x94d, 0x92f, 0x93e, 0x928, 0x94d, 0x915, 0x942, 0x935, -0x930, 0x92e, 0x94d, 0x92f, 0x93e, 0x915, 0x92e, 0x941, 0x930, 0x94d, 0x921, 0x94b, -0x932, 0x949, 0x928, 0x94d, 0x917, 0x92f, 0x930, 0x92c, 0x94d, 0x92f, 0x947, 0x928, -0x905, 0x938, 0x94d, 0x917, 0x93e, 0x92c, 0x93e, 0x924, 0x92c, 0x94d, 0x92f, 0x93e, -0x902, 0x917, 0x915, 0x949, 0x915, 0x92c, 0x93f, 0x938, 0x94d, 0x915, 0x947, 0x915, -0x92c, 0x94d, 0x930, 0x942, 0x928, 0x947, 0x924, 0x93f, 0x924, 0x94d, 0x938, 0x93f, -0x924, 0x93e, 0x926, 0x941, 0x92c, 0x924, 0x93f, 0x926, 0x941, 0x938, 0x93e, 0x902, -0x92c, 0x947, 0x92a, 0x93c, 0x93e, 0x92e, 0x93e, 0x917, 0x941, 0x938, 0x94d, 0x924, -0x93e, 0x92f, 0x947, 0x930, 0x941, 0x938, 0x932, 0x947, 0x92e, 0x915, 0x93e, 0x921, -0x93f, 0x902, 0x917, 0x93e, 0x92a, 0x928, 0x949, 0x92e, 0x20, 0x92a, 0x947, 0x928, -0x94d, 0x939, 0x915, 0x93f, 0x91c, 0x93f, 0x932, 0x949, 0x930, 0x94d, 0x921, 0x93e, -0x938, 0x93e, 0x915, 0x93e, 0x932, 0x93f, 0x928, 0x938, 0x902, 0x918, 0x93e, 0x924, -0x93f, 0x924, 0x93e, 0x924, 0x93f, 0x92a, 0x947, 0x924, 0x93f, 0x924, 0x93e, 0x938, -0x915, 0x902, 0x924, 0x91f, 0x94d, 0x2d, 0x92c, 0x93f, 0x932, 0x93f, 0x938, 0x93f, -0x92f, 0x93e, 0x902, 0x917, 0x949, 0x928, 0x915, 0x94d, 0x92f, 0x93e, 0x928, 0x947, -0x930, 0x940, 0x92a, 0x94d, 0x92f, 0x93e, 0x930, 0x94b, 0x926, 0x93e, 0x945, 0x915, -0x93f, 0x923, 0x93e, 0x945, 0x20, 0x91c, 0x93e, 0x945, 0x930, 0x94d, 0x91c, 0x93f, -0x92f, 0x93e, 0x938, 0x94d, 0x91f, 0x94d, 0x92f, 0x93e, 0x928, 0x932, 0x940, 0x906, -0x938, 0x94d, 0x91f, 0x94d, 0x930, 0x93e, 0x915, 0x93e, 0x928, 0x90f, 0x924, 0x947, -0x928, 0x94d, 0x938, 0x906, 0x907, 0x932, 0x20, 0x911, 0x92a, 0x94d, 0x20, 0x92e, -0x94d, 0x92f, 0x93e, 0x928, 0x938, 0x93f, 0x92e, 0x94d, 0x92a, 0x93c, 0x947, 0x930, -0x94b, 0x92a, 0x94b, 0x932, 0x938, 0x94d, 0x915, 0x94b, 0x92a, 0x94d, 0x92f, 0x947, -0x938, 0x94b, 0x92a, 0x93c, 0x93f, 0x92f, 0x93e, 0x91c, 0x93c, 0x94d, 0x92f, 0x942, -0x930, 0x93f, 0x915, 0x93c, 0x92e, 0x949, 0x930, 0x940, 0x938, 0x938, 0x911, 0x915, -0x932, 0x947, 0x902, 0x921, 0x91a, 0x94d, 0x92f, 0x93e, 0x925, 0x92e, 0x924, 0x93f, -0x938, 0x94d, 0x91f, 0x930, 0x90f, 0x92a, 0x93c, 0x947, 0x91f, 0x92a, 0x93c, 0x93e, -0x915, 0x93e, 0x913, 0x92a, 0x93c, 0x94b, 0x92a, 0x93c, 0x93f, 0x91c, 0x940, 0x92a, -0x93c, 0x94d, 0x92f, 0x942, 0x928, 0x93e, 0x92a, 0x93c, 0x941, 0x91f, 0x940, 0x917, -0x94d, 0x92f, 0x93e, 0x92e, 0x92c, 0x93f, 0x92f, 0x930, 0x915, 0x947, 0x902, 0x91f, -0x928, 0x928, 0x93e, 0x945, 0x909, 0x930, 0x941, 0x928, 0x949, 0x930, 0x92a, 0x93c, -0x949, 0x915, 0x928, 0x949, 0x92e, 0x93f, 0x92f, 0x93e, 0x92a, 0x94b, 0x928, 0x92a, -0x947, 0x924, 0x93f, 0xb0f, 0xb15, 0xb4d, 0xb30, 0xb3e, 0xb2c, 0xb4d, 0xb30, 0xb3e, -0xb1c, 0xb3e, 0xb71, 0xb3f, 0xb32, 0xb4d, 0xb32, 0xb47, 0xb2c, 0xb41, 0xb1c, 0xb42, -0xb2e, 0xb4d, 0xb2c, 0xb41, 0xb30, 0xb3e, 0xb15, 0xb28, 0xb3e, 0xb15, 0xb4d, 0xb30, -0xb3f, 0xb1c, 0xb3f, 0xb2c, 0xb1f, 0xb3f, 0xb2a, 0xb4d, 0xb30, 0xb3f, 0xb1f, 0xb3e, -0xb09, 0xb28, 0xb4d, 0x200c, 0xb17, 0xb3e, 0xb2c, 0xb30, 0xb4d, 0xb23, 0xb4d, 0xb23, -0xb1c, 0xb39, 0xb3e, 0xb28, 0xb4d, 0xb38, 0xb2c, 0xb30, 0xb4d, 0xb17, 0xb15, 0xb30, -0xb1f, 0xb09, 0xb2e, 0xb4d, 0x200c, 0xb32, 0xb3e, 0xb17, 0xb38, 0xb4d, 0x200c, 0xb32, -0xb3f, 0xb2c, 0xb4d, 0xb30, 0xb47, 0xb71, 0xb3f, 0xb32, 0xb4d, 0xb32, 0xb47, 0xb32, -0xb2e, 0xb4d, 0x200c, 0xb2e, 0xb4d, 0x2d, 0xb2c, 0xb3e, 0xb2c, 0xb3e, 0xb28, 0xb47, -0xb2e, 0xb4b, 0xb17, 0xb3e, 0xb21, 0xb3f, 0xb38, 0xb41, 0xb2e, 0xb28, 0xb30, 0xb4b, -0xb2c, 0xb3f, 0xb06, 0xb28, 0xb3e, 0xb07, 0xb30, 0xb2c, 0xb3f, 0xb28, 0xb41, 0xb06, -0xb15, 0xb1a, 0xb1f, 0xb05, 0xb17, 0xb3e, 0xb21, 0xb17, 0xb41, 0xb2a, 0xb30, 0xb4d, -0xb1f, 0x2d, 0xb28, 0xb71, 0xb38, 0xb3e, 0xb05, 0x20, 0xb1f, 0xb2e, 0xb47, 0xb24, -0xb4d, 0xb30, 0xb3f, 0xb2a, 0xb32, 0xb3f, 0xb71, 0xb3f, 0xb23, 0xb4d, 0xb21, 0xb39, -0xb15, 0xb4d, 0xb2c, 0xb41, 0xb0f, 0xb28, 0xb38, 0xb4d, 0x20, 0xb06, 0xb07, 0xb30, -0xb47, 0xb38, 0xb4d, 0xb15, 0xb3e, 0xb3c, 0xb1f, 0xb3e, 0xb2e, 0xb3e, 0xb15, 0xb3e, -0xb01, 0xb15, 0xb4b, 0xb21, 0xb4b, 0xb2c, 0xb3e, 0xb1c, 0xb41, 0xb1c, 0xb4b, 0xb0f, -0xb32, 0xb3e, 0x20, 0xb30, 0xb3f, 0xb4d, 0xb05, 0xb1c, 0xb3e, 0xb2e, 0xb47, 0xb23, -0xb4d, 0xb21, 0xb1c, 0xb3e, 0xb30, 0xb3f, 0xb5f, 0xb4b, 0x20, 0xb17, 0xb3e, 0xb32, -0xb47, 0xb17, 0xb4b, 0xb38, 0xb38, 0xb3e, 0xb32, 0xb4d, 0xb1f, 0xb3e, 0xb38, 0xb3e, -0xb5f, 0xb3e, 0xb28, 0xb4d, 0x20, 0xb71, 0xb3e, 0xb28, 0xb4d, 0xb38, 0xb5f, 0xb3e, -0xb28, 0x20, 0xb32, 0xb41, 0xb07, 0xb38, 0xb1f, 0xb4b, 0xb15, 0xb41, 0xb2e, 0xb28, -0xb09, 0xb38, 0xb41, 0xb06, 0xb07, 0xb5f, 0xb3e, 0xb05, 0xb30, 0xb41, 0xb2c, 0xb3e, -0xb2c, 0xb3e, 0xb30, 0xb2c, 0xb3e, 0xb21, 0xb38, 0xb2c, 0xb4d, 0xb32, 0xb3e, 0xb19, -0xb4d, 0xb15, 0x2d, 0xb38, 0xb3e, 0xb2c, 0xb32, 0xb28, 0xb4d, 0xb2c, 0xb4b, 0xb06, -0x20, 0xb71, 0xb3f, 0xb38, 0xb4d, 0xb1f, 0xb3e, 0xb2c, 0xb17, 0xb1f, 0xb3e, 0xb2c, -0xb07, 0xb38, 0xb47, 0xb15, 0xb3e, 0xb2e, 0xb4d, 0xb2a, 0x20, 0xb17, 0xb4d, 0xb30, -0xb3e, 0xb23, 0xb4d, 0xb21, 0xb47, 0xb38, 0xb3f, 0xb15, 0xb3e, 0xb17, 0xb15, 0xb37, -0xb4d, 0xb1f, 0xb3e, 0x20, 0xb30, 0xb3f, 0xb15, 0xb3e, 0xb15, 0xb4d, 0xb30, 0xb47, -0xb38, 0xb4d, 0x200d, 0xb1f, 0xb28, 0xb21, 0xb47, 0xb28, 0xb71, 0xb3f, 0xb30, 0xb4d, -0xb21, 0xb47, 0xb1f, 0xb4d, 0xb30, 0xb07, 0xb1f, 0xb4d, 0xb21, 0xb2e, 0xb3f, 0xb28, -0xb3f, 0xb15, 0xb3e, 0xb0f, 0xb21, 0xb4d, 0x200d, 0xb2e, 0xb28, 0xb1f, 0xb28, 0xb4d, -0xb0f, 0xb32, 0xb4d, 0x20, 0xb38, 0xb3e, 0xb32, 0xb71, 0xb3e, 0xb21, 0xb4b, 0xb30, -0xb4d, 0xb2a, 0xb30, 0xb4d, 0xb1f, 0x20, 0xb28, 0xb47, 0xb32, 0xb38, 0xb28, 0xb4d, -0xb2a, 0xb30, 0xb4d, 0xb1f, 0xb32, 0xb47, 0xb1c, 0xb3e, 0xb17, 0xb41, 0xb06, 0xb21, -0xb47, 0xb32, 0xb09, 0xb2a, 0xb47, 0xb17, 0xb41, 0xb06, 0xb24, 0xb47, 0xb2e, 0xb3e, -0xb32, 0xb3e, 0xb39, 0xb3e, 0xb71, 0xb28, 0xb3e, 0xb39, 0xb47, 0xb30, 0xb2e, 0xb38, -0xb3f, 0xb32, 0xb4b, 0xb07, 0xb23, 0xb4d, 0xb21, 0xb3f, 0xb06, 0xb28, 0xb3e, 0xb2a, -0xb32, 0xb3f, 0xb38, 0xb4d, 0xb2e, 0xb3e, 0xb30, 0xb47, 0xb28, 0xb17, 0x2c, 0x20, -0xb07, 0xb23, 0xb4d, 0xb21, 0xb3f, 0xb06, 0xb28, 0xb3e, 0xb71, 0xb47, 0xb71, 0xb3e, -0xb5f, 0x2c, 0x20, 0xb07, 0xb23, 0xb4d, 0xb21, 0xb3f, 0xb06, 0xb28, 0xb3e, 0xb07, -0xb28, 0xb41, 0xb71, 0xb3f, 0xb15, 0xb4d, 0xb32, 0xb09, 0xb07, 0xb38, 0xb71, 0xb3f, -0xb32, 0xb4d, 0xb32, 0xb47, 0xb2e, 0xb23, 0xb4d, 0xb1f, 0xb3f, 0xb38, 0xb47, 0xb32, -0x2c, 0x20, 0xb15, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb09, 0xb15, 0xb3f, 0xb15, 0xb47, -0xb15, 0xb4d, 0xb30, 0xb3e, 0xb32, 0xb47, 0xb23, 0xb4d, 0xb21, 0xb3f, 0xb1c, 0xb3f, -0xb15, 0xb2e, 0xb3e, 0xb38, 0xb3f, 0xb05, 0xb2e, 0xb3e, 0xb30, 0xb3f, 0xb17, 0xb1f, -0xb4d, 0xb2e, 0xb3e, 0xb1f, 0xb3e, 0xb2e, 0xb30, 0xb38, 0xb4d, 0xb2e, 0xb3e, 0xb1c, -0xb3e, 0xb1f, 0xb32, 0xb3e, 0xb28, 0xb4d, 0xb2e, 0xb3f, 0xb15, 0xb4d, 0xb35, 0xb47, -0xb32, 0xb28, 0xb4d, 0xb2e, 0xb3e, 0xb28, 0xb15, 0xb1f, 0xb28, 0xb4d, 0xb2e, 0xb28, -0xb1f, 0xb47, 0xb30, 0xb3f, 0xb0f, 0xb2e, 0xb23, 0xb4d, 0xb1f, 0xb47, 0xb2d, 0xb3f, -0xb21, 0xb3f, 0xb05, 0xb2e, 0xb28, 0xb1f, 0xb38, 0xb47, 0xb30, 0xb30, 0xb3e, 0xb1f, -0xb4d, 0xb28, 0xb4d, 0xb5f, 0xb41, 0x20, 0xb5f, 0xb30, 0xb4d, 0xb15, 0xb4d, 0xb28, -0xb30, 0xb39, 0xb4d, 0xb28, 0xb2c, 0xb47, 0xb09, 0xb32, 0xb3e, 0xb39, 0x2c, 0x20, -0xb09, 0xb24, 0xb4d, 0xb24, 0xb30, 0x20, 0xb21, 0xb3e, 0xb15, 0xb1f, 0xb3e, 0xb15, -0xb47, 0xb28, 0xb4d, 0xb26, 0xb4d, 0xb30, 0x2c, 0x20, 0xb09, 0xb24, 0xb4d, 0xb24, -0xb30, 0x20, 0xb21, 0xb3e, 0xb15, 0xb1f, 0xb3e, 0xb28, 0xb4d, 0xb5f, 0xb41, 0x20, -0xb38, 0xb3e, 0xb32, 0xb47, 0xb2e, 0xb4d, 0x2c, 0x20, 0xb09, 0xb24, 0xb4d, 0xb24, -0xb30, 0x20, 0xb21, 0xb3e, 0xb15, 0xb1f, 0xb3e, 0xb05, 0xb1c, 0xb3f, 0xb28, 0xb3e, -0xb17, 0xb3e, 0xb2a, 0xb07, 0xb28, 0xb3f, 0xb15, 0xb4d, 0xb38, 0xb2a, 0xb30, 0xb4d, -0xb1f, 0x2d, 0xb0f, 0xb5f, 0xb41, 0x2d, 0xb2a, 0xb4d, 0xb30, 0xb3f, 0xb28, 0xb4d, -0x200d, 0xb38, 0xb2a, 0xb30, 0xb4d, 0xb1f, 0xb4d, 0x20, 0xb05, 0xb2b, 0xb4d, 0x20, -0xb38, 0xb4d, 0xb2a, 0xb47, 0xb28, 0xb4d, 0xb2a, 0xb41, 0xb0f, 0xb30, 0xb4d, 0xb24, -0x20, 0xb30, 0xb3f, 0xb15, 0xb30, 0xb47, 0xb38, 0xb3f, 0xb2a, 0xb3f, 0xb30, 0xb3f, -0xb5f, 0x20, 0xb2c, 0xb4d, 0xb30, 0xb3e, 0xb19, 0xb4d, 0xb15, 0xb38, 0xb3e, 0xb28, -0xb4d, 0xb24, 0xb30, 0xb47, 0xb2e, 0xb4d, 0xb38, 0xb3e, 0xb23, 0xb4d, 0xb1f, 0x20, -0xb21, 0xb2e, 0xb3f, 0xb19, 0xb4d, 0xb17, 0xb07, 0xb1f, 0xb4d, 0xb1f, 0xb15, 0xb4d, -0xb35, 0xb30, 0xb1f, 0xb30, 0xb2e, 0xb3f, 0xb1f, 0xb4d, 0xb38, 0xb47, 0xb23, 0xb4d, -0xb1f, 0x20, 0xb2c, 0xb3e, 0xb30, 0xb4d, 0xb24, 0xb47, 0xb32, 0xb47, 0xb2e, 0xb3f, -0xb38, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb4d, 0x20, 0xb15, 0xb3f, 0xb1f, 0xb4d, 0x200d, -0xb38, 0xb38, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb4d, 0x2e, 0x20, 0xb25, 0xb2e, 0xb3e, -0xb38, 0xb4d, 0xb38, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb4d, 0x2e, 0x20, 0xb71, 0xb3f, -0xb28, 0xb38, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb4d, 0xb24, 0xb41, 0xb32, 0xb47, 0xb1f, -0xb30, 0xb23, 0xb4d, 0xb1f, 0xb1f, 0xb30, 0xb1f, 0xb32, 0xb3e, 0xb71, 0xb3e, 0xb19, -0xb4d, 0xb15, 0xb41, 0xb71, 0xb30, 0xb4d, 0xb15, 0xb47, 0xb38, 0xb3f, 0xb21, 0xb47, -0xb71, 0xb3f, 0xb38, 0xb4d, 0xb21, 0xb4d, 0xb5f, 0xb41, 0xb2e, 0xb3e, 0xb23, 0xb4d, -0xb1f, 0x20, 0xb21, 0xb3f, 0x20, 0xb09, 0xb30, 0xb71, 0xb3f, 0xb32, 0xb47, 0xb2e, -0xb15, 0xb4d, 0xb71, 0xb3e, 0xb30, 0xb3f, 0xb2e, 0xb3e, 0xb01, 0xb38, 0xb28, 0xb2e, -0xb4d, 0xb5f, 0xb3e, 0xb15, 0xb2e, 0xb41, 0xb30, 0xb4d, 0xb21, 0xb2a, 0xb3e, 0xb01, -0xb2e, 0xb30, 0xb30, 0xb4b, 0xb24, 0xb47, 0xb30, 0xb3e, 0xb1f, 0xb4b, 0xb32, 0xb4d, -0xb71, 0xb4b, 0xb38, 0xb4d, 0xb24, 0xb15, 0xb4b, 0xb33, 0xb19, 0xb4d, 0xb16, 0xb5f, -0xb3e, 0xb30, 0xb2c, 0xb47, 0xb28, 0xb06, 0xb15, 0xb4d, 0xb1f, 0xb2c, 0xb47, 0xb06, -0xb38, 0xb4d, 0x200d, 0xb17, 0xb3e, 0xb2c, 0xb1f, 0xb4d, 0xb2c, 0xb39, 0xb3e, 0xb30, -0xb47, 0xb28, 0xb2c, 0xb3f, 0xb38, 0xb15, 0xb47, 0xb15, 0xb4d, 0x200c, 0xb26, 0xb41, -0xb38, 0xb3e, 0xb28, 0xb2c, 0xb47, 0xb2a, 0xb3e, 0xb2e, 0xb3e, 0xb17, 0xb41, 0xb38, -0xb4d, 0xb1f, 0xb3e, 0xb39, 0x20, 0xb1a, 0xb3f, 0x20, 0xb2e, 0xb3f, 0xb28, 0xb4d, -0x200c, 0x20, 0xb38, 0xb3f, 0xb1f, 0xb3f, 0xb39, 0xb4b, 0xb71, 0xb21, 0xb4d, 0x200c, -0xb1c, 0xb3e, 0xb15, 0xb30, 0xb4d, 0xb24, 0xb3e, 0xb15, 0xb2c, 0xb41, 0xb32, 0xb4d, -0xb15, 0xb3e, 0xb1f, 0xb2e, 0xb3e, 0xb23, 0xb4d, 0xb21, 0xb41, 0xb15, 0xb3e, 0xb28, -0xb21, 0xb4d, 0xb5f, 0xb3e, 0xb17, 0xb3e, 0xb15, 0xb4d, 0xb30, 0xb3e, 0xb38, 0xb28, -0xb5f, 0xb3e, 0xb30, 0xb38, 0xb4d, 0xb15, 0xb28, 0xb3f, 0xb15, 0xb38, 0xb3f, 0xb06, -0xb28, 0xb71, 0xb15, 0xb41, 0xb1c, 0xb28, 0xb47, 0xb1f, 0xb38, 0xb4d, 0xb15, 0xb28, -0xb71, 0xb38, 0xb3f, 0xb2c, 0xb3f, 0xb30, 0xb38, 0xb4d, 0xb15, 0xb05, 0xb30, 0xb3e, -0xb32, 0xb4d, 0x200c, 0xb2a, 0xb28, 0xb2e, 0xb4d, 0x200c, 0x20, 0xb2a, 0xb47, 0xb28, -0xb39, 0xb2a, 0xb23, 0xb4d, 0xb1f, 0xb3f, 0xb06, 0xb28, 0xb3e, 0xb15, 0xb4d, 0x200c, -0xb15, 0xb37, 0xb4d, 0xb1f, 0xb28, 0xb47, 0xb15, 0xb40, 0xb1c, 0xb3f, 0xb32, 0xb30, -0xb4d, 0xb21, 0xb3e, 0xb38, 0xb15, 0xb3e, 0xb32, 0xb3f, 0xb28, 0xb4d, 0xb38, 0xb3f, -0xb05, 0xb32, 0xb38, 0xb02, 0xb17, 0xb3e, 0xb07, 0xb38, 0xb4d, 0xb30, 0xb47, 0xb21, -0xb28, 0xb47, 0xb15, 0xb32, 0xb5f, 0xb2e, 0xb38, 0xb4d, 0xb15, 0xb24, 0xb3e, 0xb38, -0xb15, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb24, 0xb3f, 0xb2e, 0xb4d, 0xb2a, 0xb41, 0xb1f, -0xb15, 0xb3f, 0xb05, 0xb1f, 0xb2e, 0xb38, 0xb4d, 0xb15, 0xb5f, 0xb41, 0xb38, 0xb4d, -0x200d, 0xb1f, 0x2d, 0xb28, 0xb47, 0xb30, 0xb3e, 0xb71, 0xb3f, 0xb0f, 0xb23, 0xb4d, -0xb1f, 0xb3f, 0xb0f, 0xb28, 0xb4d, 0x200c, 0xb71, 0xb4d, 0xb32, 0xb3e, 0xb21, 0xb3f, -0xb71, 0xb37, 0xb4d, 0xb1f, 0xb4b, 0xb15, 0xb4d, 0xb5f, 0xb47, 0xb30, 0xb47, 0xb2c, -0xb3e, 0xb28, 0xb4d, 0xb06, 0xb1c, 0xb30, 0xb47, 0xb38, 0xb4d, 0xb2c, 0xb30, 0xb2e, -0xb41, 0xb21, 0xb3e, 0xb15, 0xb47, 0xb2a, 0xb4d, 0x200c, 0x20, 0xb71, 0xb30, 0xb4d, -0xb26, 0xb47, 0xb2a, 0xb30, 0xb0f, 0xb30, 0xb47, 0xb15, 0xb4d, 0xb5f, 0xb3e, 0xb2c, -0xb3f, 0xb15, 0xb38, 0xb4d, 0x200d, 0xb1f, 0xb3e, 0xb32, 0xb3f, 0xb28, 0xb0f, 0xb21, -0xb3f, 0xb32, 0xb47, 0xb21, 0xb4d, 0xb2c, 0xb4d, 0xb30, 0xb3f, 0xb38, 0xb2c, 0xb28, -0xb4d, 0xb2c, 0xb4d, 0xb30, 0xb4b, 0xb15, 0xb28, 0x20, 0xb39, 0xb3f, 0xb32, 0xb21, -0xb3e, 0xb30, 0xb4d, 0xb71, 0xb3f, 0xb28, 0xb4d, 0xb32, 0xb3f, 0xb23, 0xb4d, 0xb21, -0xb47, 0xb2e, 0xb3e, 0xb28, 0xb32, 0xb30, 0xb4d, 0x200d, 0xb21, 0x20, 0xb39, 0xb3e, -0xb71, 0xb47, 0xb2e, 0xb47, 0xb32, 0xb2c, 0xb4b, 0xb28, 0xb01, 0xb2a, 0xb30, 0xb4d, -0xb24, 0xb06, 0xb2e, 0xb37, 0xb4d, 0xb1f, 0xb4d, 0xb30, 0xb47, 0xb21, 0xb3e, 0xb2e, -0xb4d, 0xb06, 0xb23, 0xb4d, 0xb21, 0xb30, 0xb3e, 0xb06, 0xb38, 0xb4d, 0x200d, 0xb1f, -0xb30, 0xb3e, 0xb15, 0xb3e, 0xb28, 0xb0f, 0xb24, 0xb47, 0xb28, 0xb4d, 0xb38, 0xb2c, -0xb47, 0xb32, 0xb17, 0xb4d, 0xb30, 0xb47, 0xb21, 0xb47, 0xb2c, 0xb4d, 0xb30, 0xb3e, -0xb1f, 0xb3f, 0xb38, 0xb32, 0xb3e, 0xb71, 0xb3e, 0xb2c, 0xb4d, 0xb30, 0xb41, 0xb38, -0xb3f, 0xb32, 0xb4d, 0x200d, 0xb38, 0xb2c, 0xb41, 0xb1a, 0xb3e, 0xb30, 0xb47, 0xb38, -0xb4d, 0xb1f, 0xb2c, 0xb41, 0xb21, 0xb3e, 0xb2a, 0xb47, 0xb38, 0xb4d, 0xb1f, 0xb1a, -0xb3f, 0xb38, 0xb3f, 0xb28, 0xb3e, 0xb09, 0xb15, 0xb2a, 0xb47, 0xb28, 0xb39, 0xb3e, -0xb17, 0xb47, 0xb28, 0xb4d, 0xb06, 0xb07, 0xb32, 0xb4d, 0x20, 0xb05, 0xb2a, 0xb4d, -0x20, 0xb2e, 0xb4d, 0xb5f, 0xb3e, 0xb28, 0xb4d, 0xb15, 0xb3f, 0xb30, 0xb71, 0xb2e, -0xb3e, 0xb30, 0xb3f, 0xb5f, 0xb3e, 0xb39, 0xb47, 0xb2e, 0xb2e, 0xb28, 0xb3e, 0xb15, -0xb05, 0xb38, 0xb32, 0xb4b, 0xb2a, 0xb21, 0xb17, 0xb30, 0xb3f, 0xb15, 0xb3e, 0xb30, -0xb2e, 0xb4d, 0xb38, 0xb3e, 0xb30, 0xb3e, 0xb1c, 0xb47, 0xb2c, 0xb38, 0xb3e, 0xb30, -0xb3e, 0xb1f, 0xb71, 0xb4d, 0xb38, 0xb3f, 0xb2e, 0xb2b, 0xb47, 0xb30, 0xb2a, 0xb32, -0xb4d, 0xb38, 0xb4d, 0xb15, 0xb2a, 0xb5f, 0xb47, 0xb38, 0xb2a, 0xb3f, 0xb5f, 0xb3e, -0xb38, 0xb4d, 0xb1f, 0xb15, 0xb4d, 0x20, 0xb39, 0xb2e, 0xb4d, 0x200c, 0xb1f, 0xb3e, -0xb07, 0xb30, 0xb47, 0xb28, 0xb4d, 0xb5f, 0xb41, 0xb32, 0xb5f, 0xb3e, 0xb28, 0xb71, -0xb38, 0xb4d, 0xb15, 0xb2c, 0xb3e, 0xb21, 0xb41, 0xb1c, 0xb71, 0xb3e, 0xb1f, 0xb3f, -0xb15, 0xb3e, 0xb28, 0xb4d, 0xb71, 0xb3f, 0xb0f, 0xb28, 0xb3e, 0xb71, 0xb3f, 0xb32, -0xb28, 0xb3f, 0xb09, 0xb38, 0xb4d, 0xb71, 0xb32, 0xb17, 0xb17, 0xb4d, 0xb30, 0xb3e, -0xb21, 0xb4d, 0xb16, 0xb4d, 0xb30, 0xb40, 0xb38, 0xb4d, 0x200d, 0xb1f, 0x20, 0xb2e, -0xb3e, 0xb38, 0xb15, 0xb15, 0xb38, 0xb4d, 0x200c, 0xb15, 0xb2e, 0xb30, 0xb15, 0xb47, -0xb30, 0xb17, 0xb41, 0xb32, 0xb47, 0xb28, 0xb2e, 0xb30, 0xb3f, 0xb38, 0xb38, 0xb4d, -0xb2e, 0xb3e, 0xb5f, 0xb1f, 0xb47, 0xb2c, 0xb17, 0xb47, 0xb28, 0xb4d, 0x200c, 0xb71, -0xb3f, 0xb32, 0xb4d, 0xb32, 0xb47, 0xb1a, 0xb3e, 0xb24, 0xb3e, 0xb2e, 0xb4d, 0x200c, -0xb2a, 0xb15, 0xb3e, 0xb05, 0xb2a, 0xb2a, 0xb3f, 0xb1c, 0xb3f, 0xb17, 0xb3e, 0xb32, -0xb3e, 0xb2a, 0xb3e, 0xb17, 0xb38, 0xb15, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb28, 0xb28, -0xb30, 0xb2a, 0xb15, 0xb4d, 0x200c, 0xb28, 0xb09, 0xb2e, 0xb3f, 0xb5f, 0xb2a, 0xb39, -0xb28, 0xb2a, 0xb47, 0xb07, 0xb2a, 0xb30, 0xb4d, 0xb1f, 0xb4d, 0x200c, 0x20, 0xb2e, -0xb30, 0xb47, 0xb38, 0xb2c, 0xb3f, 0xb30, 0xb3e, 0xb30, 0xb1f, 0xb19, 0xb4d, 0xb17, -0xb3e, 0xb1f, 0xb19, 0xb4d, 0xb17, 0xb3e, 0xb1f, 0xb3e, 0xb2a, 0xb41, 0xc0e, 0xc02, -0xc17, 0xc4d, 0xc35, 0xc3f, 0xc32, 0xc4d, 0xc32, 0xc3e, 0x3c, 0x65, 0x78, 0x65, -0x6d, 0x70, 0x6c, 0x61, 0x72, 0x43, 0x69, 0x74, 0x79, 0x3e, 0xc05, 0xc21, -0xc46, 0xc32, 0xc48, 0xc21, 0xc4d, 0x3c, 0x2f, 0x65, 0x78, 0x65, 0x6d, 0x70, -0x6c, 0x61, 0x72, 0x43, 0x69, 0x74, 0x79, 0x3e, 0xc15, 0xc3e, 0xc02, 0xc1f, -0xc28, 0xc4d, 0x140a, 0x144e, 0x1426, 0x146f, 0x1472, 0x1423, 0x1401, 0x141f, 0x14aa, 0x1423, -0x1450, 0x1423, 0x1403, 0x14c4, 0x1431, 0x1420, 0x1403, 0x1473, 0x14eb, 0x1405, 0x1403, 0x141f, -0x14f4, 0x1422, 0x1473, 0x141f, 0x1489, 0x1418, 0x1423, 0x1411, 0x14c2, 0x142f, 0x1420 +0x65, 0x76, 0x61, 0x79, 0x20, 0x28, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, +0x61, 0x29, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x20, +0x28, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x29, 0x57, 0x69, 0x6e, +0x61, 0x6d, 0x61, 0x63, 0x20, 0x28, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, +0x61, 0x29, 0x4a, 0x61, 0x6d, 0xe0, 0x65, 0x67, 0x61, 0x4d, 0x6f, 0x6e, +0x74, 0x69, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x28, 0x4b, 0x65, 0x6e, +0x74, 0x75, 0x63, 0x6b, 0x79, 0x29, 0x4c, 0x6f, 0x73, 0x20, 0xc0, 0x6e, +0x67, 0x65, 0x6c, 0x65, 0x73, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, +0x67, 0x61, 0x53, 0x69, 0x74, 0xe0, 0x20, 0x64, 0x65, 0x2019, 0x6c, 0x20, +0x4d, 0xe8, 0x73, 0x65, 0x67, 0x6f, 0x4d, 0x69, 0x63, 0x68, 0x65, 0x6c, +0x6f, 0x6e, 0x42, 0x65, 0x75, 0x6c, 0x61, 0x68, 0x20, 0x28, 0x4e, 0x6f, +0x72, 0x64, 0x20, 0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61, 0x29, 0x43, 0x65, +0x6e, 0x74, 0x65, 0x72, 0x20, 0x28, 0x4e, 0x6f, 0x72, 0x64, 0x20, 0x44, +0x61, 0x6b, 0x6f, 0x74, 0x61, 0x29, 0x4e, 0x65, 0x77, 0x20, 0x53, 0x61, +0x6c, 0x65, 0x6d, 0x20, 0x28, 0x4e, 0x6f, 0x72, 0x64, 0x20, 0x44, 0x61, +0x6b, 0x6f, 0x74, 0x61, 0x29, 0x50, 0x6f, 0x72, 0x74, 0x6f, 0x20, 0x50, +0x72, 0xec, 0x6e, 0x73, 0x69, 0x70, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x6f, +0x20, 0x64, 0x65, 0x20, 0x53, 0x70, 0x61, 0x67, 0x6e, 0x61, 0x53, 0x61, +0x6e, 0x20, 0x50, 0x6f, 0x6c, 0x6f, 0x53, 0x2e, 0x20, 0x42, 0x61, 0x72, +0x74, 0x6f, 0x6c, 0x6f, 0x6d, 0xe8, 0x6f, 0x53, 0x2e, 0x20, 0x4a, 0x6f, +0x61, 0x6e, 0x69, 0x53, 0x2e, 0x20, 0x43, 0x72, 0x69, 0x73, 0x74, 0x6f, +0x66, 0x65, 0x72, 0x53, 0x2e, 0x20, 0x4c, 0x75, 0x73, 0xec, 0x61, 0x53, +0x2e, 0x20, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x73, 0x6f, 0xcc, 0x7a, +0x6f, 0x6c, 0x61, 0x20, 0x4d, 0x61, 0x63, 0x71, 0x75, 0x61, 0x72, 0x69, +0x65, 0x41, 0x6e, 0xe0, 0x64, 0x79, 0x72, 0x41, 0x6b, 0x74, 0xe0, 0x75, +0x41, 0x7a, 0x67, 0x61, 0x62, 0x61, 0x64, 0x41, 0x74, 0x79, 0x72, 0xe0, +0x75, 0x43, 0x6f, 0x6c, 0x6f, 0x6e, 0x62, 0x6f, 0x44, 0x75, 0x62, 0xe0, +0x69, 0x44, 0x75, 0x73, 0x61, 0x6e, 0x62, 0xe9, 0x4b, 0x61, 0x74, 0x6d, +0x61, 0x6e, 0x64, 0xf9, 0x48, 0xe0, 0x6e, 0x64, 0x69, 0x67, 0x61, 0x4b, +0x72, 0x61, 0x7a, 0x6e, 0x61, 0x79, 0x61, 0x72, 0x73, 0x6b, 0x4b, 0x75, +0x61, 0x6c, 0x61, 0x20, 0x4c, 0x75, 0x6e, 0x70, 0x75, 0x72, 0x4d, 0x61, +0x63, 0xe0, 0x6f, 0x4e, 0x6f, 0x76, 0x6f, 0x6b, 0x75, 0x7a, 0x6e, 0x69, +0x65, 0x74, 0x73, 0x6b, 0x4b, 0x6f, 0x73, 0x74, 0x61, 0x6e, 0xe0, 0x69, +0x53, 0x68, 0x61, 0x6e, 0x67, 0x68, 0xe0, 0x69, 0x5a, 0x72, 0xe9, 0x64, +0x6e, 0x65, 0x6b, 0x6f, 0x6c, 0x69, 0x6d, 0x73, 0x6b, 0x54, 0x69, 0x6e, +0x70, 0x75, 0x55, 0x6c, 0x61, 0x6e, 0x20, 0x42, 0xe0, 0x74, 0x6f, 0x72, +0x55, 0x73, 0x74, 0x2d, 0x47, 0x6e, 0x65, 0x72, 0x61, 0x59, 0x65, 0x6b, +0x61, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x62, 0x75, 0x72, 0x67, 0x6f, 0x4a, +0xe8, 0x72, 0x65, 0x76, 0x61, 0x6e, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, +0x41, 0x7a, 0x6f, 0x72, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x43, +0x61, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x43, 0x61, 0x6f, 0x20, 0x56, 0x65, +0x72, 0x64, 0x6f, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x46, 0xe0, 0x72, +0x6f, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x4d, 0x61, 0x64, 0xe8, +0x69, 0x72, 0x61, 0x52, 0x65, 0x6b, 0x69, 0x61, 0x76, 0x69, 0x6b, 0x47, +0x65, 0x6f, 0x72, 0x67, 0x69, 0x61, 0x20, 0x64, 0x65, 0x2019, 0x6c, 0x20, +0x73, 0x75, 0x64, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x53, 0x2e, 0x20, +0x45, 0x6c, 0x65, 0x6e, 0x61, 0x41, 0x64, 0x65, 0x6c, 0xe0, 0x69, 0x64, +0x65, 0x42, 0x72, 0x69, 0x7a, 0x62, 0x61, 0x6e, 0x65, 0xcc, 0x7a, 0x6f, +0x6c, 0x61, 0x20, 0x4c, 0x6f, 0x72, 0x64, 0x20, 0x48, 0x6f, 0x77, 0x65, +0xc0, 0x6d, 0x73, 0x74, 0x65, 0x72, 0x64, 0x61, 0x6d, 0x42, 0x72, 0x61, +0x74, 0x69, 0x7a, 0x6c, 0x61, 0x76, 0x61, 0x4a, 0x69, 0x62, 0x69, 0x6c, +0x74, 0x65, 0x72, 0x61, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x64, 0x65, +0x20, 0x4d, 0x61, 0x6e, 0x4c, 0x75, 0x62, 0x6c, 0x69, 0x61, 0x6e, 0x61, +0x4c, 0x75, 0x73, 0x65, 0x6e, 0x62, 0x75, 0x72, 0x67, 0x6f, 0x4f, 0x7a, +0x6c, 0x6f, 0x50, 0x61, 0x72, 0x69, 0x6a, 0x69, 0x53, 0x69, 0x6e, 0x66, +0x65, 0x72, 0xf2, 0x70, 0x6f, 0x6c, 0x69, 0x53, 0x74, 0x6f, 0x63, 0x6f, +0x6c, 0x6d, 0x61, 0x55, 0x6c, 0x69, 0xe0, 0x6e, 0x6f, 0x73, 0x6b, 0x56, +0x61, 0x74, 0x65, 0x67, 0x61, 0x6e, 0x43, 0x69, 0x61, 0x67, 0x6f, 0x73, +0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4e, 0x61, 0x64, +0x61, 0x6c, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x63, +0x6f, 0x73, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x6d, 0x6f, +0x72, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x6c, 0x64, +0x69, 0x76, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x75, +0x72, 0x69, 0x73, 0x69, 0x6f, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x4d, +0x61, 0x69, 0x6f, 0x74, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x52, +0x65, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, +0x42, 0x6f, 0x75, 0x67, 0x61, 0x69, 0x6e, 0x76, 0x69, 0x6c, 0x6c, 0x65, +0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x43, 0x69, 0x61, 0x74, 0x65, 0x6d, +0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x43, 0x68, 0x75, 0x75, 0x6b, 0xcc, +0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x64, 0x65, 0x20, 0x50, 0x61, 0x73, 0x63, +0x75, 0x61, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x45, 0x66, 0x61, 0x74, +0x65, 0x41, 0x74, 0x6f, 0x6c, 0x6f, 0x20, 0x46, 0x61, 0x6b, 0x61, 0x6f, +0x66, 0x6f, 0x41, 0x74, 0x6f, 0x6c, 0x6f, 0x20, 0x46, 0x75, 0x6e, 0x61, +0x66, 0x75, 0x74, 0x69, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x47, 0x61, +0x6d, 0x62, 0x69, 0x65, 0x72, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x47, +0x75, 0x61, 0x64, 0x61, 0x6c, 0x63, 0x61, 0x6e, 0x61, 0x6c, 0x41, 0x74, +0x6f, 0x6c, 0x6f, 0x20, 0x43, 0x61, 0x6e, 0x74, 0x6f, 0x6e, 0x41, 0x74, +0x6f, 0x6c, 0x6f, 0x20, 0x4b, 0x69, 0x72, 0x69, 0x74, 0x69, 0x6d, 0x61, +0x74, 0x69, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x4b, 0x6f, 0x73, 0x72, +0x61, 0x65, 0x41, 0x74, 0x6f, 0x6c, 0x6f, 0x20, 0x4b, 0x77, 0x61, 0x6a, +0x61, 0x6c, 0x65, 0x69, 0x6e, 0xcc, 0x7a, 0x6f, 0x6c, 0x65, 0x20, 0x4d, +0x61, 0x72, 0x63, 0x68, 0x65, 0x7a, 0x69, 0x41, 0x74, 0x6f, 0x6c, 0x6f, +0x20, 0x4d, 0x69, 0x64, 0x77, 0x61, 0x79, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, +0x20, 0x4e, 0x61, 0x75, 0x72, 0x75, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, +0x4e, 0x69, 0x75, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x4e, 0x6f, +0x72, 0x66, 0x6f, 0x6c, 0x6b, 0x50, 0x61, 0x6c, 0xe0, 0x75, 0xcc, 0x7a, +0x6f, 0x6c, 0x61, 0x20, 0x50, 0x69, 0x74, 0x63, 0x61, 0x69, 0x72, 0x6e, +0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x50, 0x6f, 0x6e, 0x70, 0xe8, 0x69, +0x50, 0x6f, 0x72, 0x74, 0x6f, 0x20, 0x4d, 0x6f, 0x72, 0x65, 0x73, 0x62, +0x79, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x52, 0x61, 0x72, 0x6f, 0x74, +0x6f, 0x6e, 0x67, 0x61, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x53, 0x61, +0x69, 0x70, 0xe0, 0x6e, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x54, 0x61, +0x69, 0x74, 0x69, 0x41, 0x74, 0x6f, 0x6c, 0x6c, 0x6f, 0x20, 0x54, 0x61, +0x72, 0x61, 0x77, 0x61, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x54, 0x6f, +0x6e, 0x67, 0x61, 0x74, 0x61, 0x70, 0x75, 0x41, 0x74, 0x6f, 0x6c, 0x6f, +0x20, 0x57, 0x61, 0x6b, 0x65, 0xcc, 0x7a, 0x6f, 0x6c, 0x61, 0x20, 0x57, +0x61, 0x6c, 0x6c, 0x69, 0x73, 0x61, 0x62, 0x69, 0x64, 0x6a, 0x61, 0x6e, +0x65, 0x63, 0x72, 0x61, 0x61, 0x1e0d, 0x69, 0x73, 0x20, 0x61, 0x62, 0x61, +0x62, 0x61, 0x61, 0x6c, 0x6a, 0x12b, 0x79, 0x72, 0x73, 0x61, 0x73, 0x6d, +0x61, 0x72, 0x61, 0x62, 0x61, 0x6d, 0x61, 0x6b, 0x6f, 0x62, 0x61, 0x6e, +0x67, 0x75, 0x69, 0x62, 0x61, 0x6e, 0x6a, 0x75, 0x6c, 0x62, 0x69, 0x73, +0x73, 0x61, 0x75, 0x62, 0x6c, 0x61, 0x6e, 0x1e6d, 0x61, 0x65, 0x72, 0x62, +0x72, 0x61, 0x6a, 0x61, 0x76, 0x69, 0x6c, 0x6c, 0x62, 0x75, 0x6a, 0x75, +0x6d, 0x62, 0x75, 0x72, 0x61, 0x6b, 0x61, 0x69, 0x72, 0x6f, 0x6b, 0x61, +0x73, 0x61, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x61, 0x73, 0x65, 0x75, 0x1e6d, +0x61, 0x6b, 0x6f, 0x6e, 0x61, 0x6b, 0x72, 0x12b, 0x1e0d, 0x6b, 0x61, 0x72, +0x64, 0x61, 0x72, 0x20, 0x65, 0x73, 0x20, 0x73, 0x61, 0x6c, 0x61, 0x61, +0x6d, 0x64, 0x75, 0x61, 0x6c, 0x61, 0x65, 0x6c, 0x20, 0x61, 0x61, 0x69, +0x79, 0x75, 0x6e, 0x70, 0x72, 0x12b, 0x1e6d, 0x61, 0x75, 0x6e, 0x67, 0x61, +0x62, 0x6f, 0x72, 0x6f, 0x6e, 0x68, 0x72, 0x61, 0x72, 0x65, 0x6a, 0x6f, +0x68, 0x61, 0x6e, 0x6e, 0x65, 0x73, 0x62, 0x75, 0x72, 0x67, 0x6a, 0x75, +0x62, 0x61, 0x6b, 0x6d, 0x70, 0x61, 0x6c, 0x61, 0x6b, 0x61, 0x72, 0x1e6d, +0x6f, 0x75, 0x6d, 0x6b, 0x69, 0x67, 0x61, 0x6c, 0x69, 0x6b, 0x69, 0x6e, +0x73, 0x61, 0x73, 0x61, 0x6c, 0x61, 0x67, 0x6f, 0x73, 0x6c, 0x69, 0x62, +0x72, 0x65, 0x76, 0x69, 0x6c, 0x6c, 0x6c, 0x75, 0x61, 0x6e, 0x1e0d, 0x61, +0x6c, 0x75, 0x62, 0x75, 0x6d, 0x62, 0x61, 0x73, 0x69, 0x6c, 0x75, 0x73, +0x61, 0x6b, 0x61, 0x6d, 0x61, 0x6c, 0x61, 0x62, 0x6f, 0x6d, 0x61, 0x70, +0x75, 0x1e6d, 0x75, 0x6d, 0x61, 0x73, 0x65, 0x72, 0x75, 0x6d, 0x62, 0x61, +0x62, 0x61, 0x6e, 0x65, 0x6d, 0x6f, 0x67, 0x61, 0x1e0d, 0x69, 0x73, 0x75, +0x6d, 0x6f, 0x6e, 0x72, 0x6f, 0x76, 0x69, 0x61, 0x6e, 0x61, 0x69, 0x72, +0x6f, 0x62, 0x69, 0x6e, 0x6a, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x6e, 0x69, +0x79, 0x61, 0x6d, 0x65, 0x6e, 0x75, 0x65, 0x6b, 0x73, 0x61, 0x76, 0x61, +0x67, 0x64, 0x75, 0x67, 0x75, 0x70, 0x6f, 0x72, 0x1e6d, 0x6f, 0x2d, 0x1e47, +0x6f, 0x76, 0x6f, 0x73, 0x61, 0x6f, 0x20, 0x1e6d, 0x6f, 0x6d, 0x74, 0x72, +0x69, 0x70, 0x6f, 0x6c, 0x69, 0x1e6d, 0x75, 0x6e, 0x69, 0x73, 0x76, 0x69, +0x6e, 0x64, 0x68, 0x75, 0x6b, 0x61, 0x1e0d, 0x61, 0x6b, 0x61, 0x6e, 0x6b, +0x6f, 0x72, 0x61, 0x6a, 0x65, 0x6e, 0x67, 0x75, 0x69, 0x6c, 0x6c, 0x61, +0x65, 0x6e, 0x1e6d, 0x69, 0x67, 0x75, 0x61, 0x61, 0x72, 0x61, 0x67, 0x76, +0x61, 0x69, 0x6e, 0x61, 0x62, 0x75, 0x65, 0x6e, 0x6f, 0x75, 0x73, 0x20, +0x61, 0x69, 0x72, 0x65, 0x73, 0x6b, 0x61, 0x74, 0x61, 0x6d, 0x61, 0x72, +0x6b, 0x61, 0x6b, 0x6f, 0x72, 0x1e0d, 0x61, 0x62, 0x61, 0x68, 0x75, 0x68, +0x75, 0x65, 0x6c, 0x61, 0x20, 0x72, 0x69, 0x6f, 0x6a, 0x61, 0x6d, 0x65, +0x6e, 0x1e0d, 0x6f, 0x6a, 0x61, 0x72, 0x69, 0x79, 0x6f, 0x20, 0x67, 0x61, +0x6c, 0x6c, 0x65, 0x67, 0x6f, 0x73, 0x73, 0x61, 0x6c, 0x1e6d, 0x61, 0x73, +0x61, 0x6e, 0x20, 0x68, 0x75, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x20, 0x6c, +0x75, 0x69, 0x73, 0x1e6d, 0x75, 0x6b, 0x16b, 0x6d, 0x6e, 0x75, 0x73, 0x76, +0x61, 0x69, 0x79, 0x61, 0x61, 0x72, 0x75, 0x62, 0x61, 0x65, 0x73, 0x75, +0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x1e6d, 0x69, 0x6b, 0x6f, 0x6b, 0x65, +0x6e, 0x62, 0x61, 0x68, 0x69, 0x61, 0x62, 0x61, 0x69, 0x61, 0x20, 0x62, +0x61, 0x6e, 0x1e0d, 0x65, 0x72, 0x61, 0x73, 0x62, 0x61, 0x72, 0x62, 0x61, +0x1e0d, 0x6f, 0x73, 0x62, 0x65, 0x6c, 0x65, 0x6d, 0x62, 0x65, 0x6c, 0x69, +0x6a, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x2d, 0x73, 0x61, 0x62, 0x6c, 0x6f, +0x6e, 0x62, 0x6f, 0x61, 0x20, 0x76, 0x69, 0x73, 0x74, 0x61, 0x62, 0x6f, +0x67, 0x6f, 0x1e6d, 0x61, 0x62, 0x6f, 0x69, 0x73, 0x12b, 0x6b, 0x65, 0x6d, +0x62, 0x72, 0x69, 0x6a, 0x20, 0x62, 0x65, 0x6b, 0x61, 0x6d, 0x70, 0x6f, +0x20, 0x67, 0x72, 0x61, 0x6e, 0x1e0d, 0x65, 0x6b, 0x61, 0x6e, 0x6b, 0x75, +0x6e, 0x6b, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x73, 0x6b, 0x65, 0x79, 0x65, +0x6e, 0x6b, 0x65, 0x69, 0x6d, 0x61, 0x6e, 0x63, 0x69, 0x6b, 0x61, 0x67, +0x6f, 0x63, 0x68, 0x69, 0x68, 0x75, 0x61, 0x68, 0x75, 0x61, 0x6b, 0x6f, +0x73, 0x1e6d, 0x61, 0x20, 0x72, 0x69, 0x6b, 0x61, 0x6b, 0x72, 0x65, 0x73, +0x1e6d, 0x6f, 0x6e, 0x6b, 0x75, 0x61, 0x61, 0x62, 0x61, 0x6b, 0x79, 0x75, +0x72, 0x61, 0x73, 0x6f, 0x1e0d, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x73, +0x61, 0x76, 0x6e, 0x1e0d, 0x61, 0x6f, 0x73, 0x6e, 0x1e0d, 0x61, 0x6f, 0x73, +0x6f, 0x6e, 0x20, 0x6b, 0x72, 0x12b, 0x6b, 0x1e0d, 0x65, 0x6e, 0x76, 0x65, +0x72, 0x1e0d, 0x65, 0x1e6d, 0x72, 0x6f, 0x69, 0x1e6d, 0x1e0d, 0x6f, 0x6d, 0x69, +0x6e, 0x69, 0x6b, 0x61, 0x65, 0x1e0d, 0x6d, 0x6f, 0x6e, 0x1e6d, 0x6f, 0x6e, +0x65, 0x69, 0x72, 0x75, 0x6e, 0x65, 0x70, 0x65, 0x65, 0x6c, 0x20, 0x73, +0x61, 0x6c, 0x76, 0x61, 0x1e0d, 0x6f, 0x72, 0x70, 0x68, 0x6f, 0x72, 0x74, +0x20, 0x6e, 0x65, 0x6c, 0x73, 0x6e, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6c, +0x65, 0x6a, 0x61, 0x67, 0x6c, 0x61, 0x73, 0x20, 0x62, 0x61, 0x79, 0x67, +0x6f, 0x6f, 0x73, 0x20, 0x62, 0x65, 0x67, 0x72, 0x61, 0x6e, 0x1e0d, 0x20, +0x1e6d, 0x75, 0x72, 0x6b, 0x67, 0x72, 0x65, 0x6e, 0x61, 0x1e0d, 0x61, 0x67, +0x75, 0x61, 0x1e0d, 0x65, 0x6c, 0x6f, 0x75, 0x70, 0x65, 0x67, 0x75, 0x61, +0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x67, 0x75, 0x61, 0x6a, 0x61, 0x6b, +0x69, 0x6c, 0x67, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x68, 0x65, 0x6c, 0x69, +0x70, 0x61, 0x6b, 0x73, 0x68, 0x61, 0x76, 0x61, 0x6e, 0x61, 0x69, 0x6e, +0x1e0d, 0x69, 0x61, 0x6e, 0x61, 0x70, 0x6f, 0x6c, 0x69, 0x73, 0x6e, 0x6f, +0x6b, 0x73, 0x2c, 0x20, 0x69, 0x6e, 0x1e0d, 0x69, 0x79, 0x61, 0x6e, 0x61, +0x6d, 0x61, 0x72, 0x65, 0x6e, 0x67, 0x6f, 0x2c, 0x20, 0x69, 0x6e, 0x1e0d, +0x69, 0x79, 0x61, 0x6e, 0x61, 0x70, 0x69, 0x1e6d, 0x74, 0x72, 0x73, 0x62, +0x65, 0x72, 0x67, 0x2c, 0x20, 0x69, 0x6e, 0x1e0d, 0x69, 0x79, 0x61, 0x6e, +0x61, 0x1e6d, 0x65, 0x6c, 0x6c, 0x20, 0x73, 0x69, 0x74, 0x79, 0x2c, 0x20, +0x69, 0x6e, 0x1e0d, 0x69, 0x79, 0x61, 0x6e, 0x61, 0x76, 0x69, 0x76, 0x69, +0x2c, 0x20, 0x69, 0x6e, 0x1e0d, 0x69, 0x79, 0x61, 0x6e, 0x61, 0x76, 0x69, +0x6e, 0x63, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x69, 0x6e, 0x1e0d, 0x69, 0x79, +0x61, 0x6e, 0x61, 0x76, 0x69, 0x6e, 0x61, 0x6d, 0x61, 0x6b, 0x2c, 0x20, +0x69, 0x6e, 0x1e0d, 0x69, 0x79, 0x61, 0x6e, 0x61, 0x69, 0x6e, 0x16b, 0x76, +0x69, 0x6b, 0x69, 0x6b, 0x61, 0x6c, 0x75, 0x69, 0x1e6d, 0x6a, 0x61, 0x6d, +0x61, 0x69, 0x6b, 0x61, 0x6a, 0x75, 0x6e, 0x6f, 0x76, 0x6c, 0x6f, 0x75, +0x69, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x6d, 0x6f, 0x6e, 0x1e6d, 0x69, 0x73, +0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x6b, 0x65, 0x6e, 0x1e6d, 0x75, 0x6b, +0x12b, 0x6b, 0x72, 0x65, 0x6c, 0x65, 0x6e, 0x1e0d, 0x65, 0x69, 0x6b, 0x6c, +0x61, 0x20, 0x70, 0x61, 0x6a, 0x6c, 0x6f, 0x73, 0x20, 0x61, 0x6e, 0x6a, +0x65, 0x6c, 0x65, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x70, 0x72, +0x69, 0x6e, 0x63, 0x2019, 0x73, 0x20, 0x6b, 0x75, 0x76, 0x61, 0x1e6d, 0x61, +0x72, 0x6d, 0x61, 0x73, 0x12b, 0x6f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x75, +0x61, 0x6d, 0x61, 0x6e, 0x61, 0x75, 0x73, 0x6d, 0x61, 0x72, 0x69, 0x67, +0x6f, 0x1e6d, 0x6d, 0x61, 0x72, 0x1e6d, 0x69, 0x6e, 0x69, 0x6b, 0x6d, 0x61, +0x1e6d, 0x61, 0x6d, 0x6f, 0x72, 0x6f, 0x73, 0x6d, 0x61, 0x73, 0x61, 0x1e6d, +0x6c, 0x61, 0x6e, 0x6d, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x6e, 0x12b, 0x6d, +0x65, 0x72, 0x69, 0x1e0d, 0x61, 0x6d, 0x65, 0x1e6d, 0x6c, 0x61, 0x6b, 0x61, +0x1e6d, 0x6c, 0x61, 0x6d, 0x65, 0x6b, 0x73, 0x69, 0x63, 0x6f, 0x20, 0x73, +0x69, 0x1e6d, 0x79, 0x6d, 0x69, 0x6b, 0x76, 0x69, 0x6c, 0xf5, 0x6d, 0x6f, +0x6e, 0x6b, 0x1e6d, 0x6f, 0x6e, 0x6d, 0x6f, 0x6e, 0x1e6d, 0x65, 0x72, 0x72, +0x65, 0x6d, 0x6f, 0x6e, 0x1e6d, 0x65, 0x76, 0x69, 0x64, 0x69, 0x6f, 0x6d, +0x6f, 0x6e, 0x1e6d, 0x73, 0x65, 0x72, 0x72, 0x65, 0x1e6d, 0x6e, 0x61, 0x73, +0x61, 0x75, 0x6e, 0x69, 0x79, 0x75, 0x20, 0x79, 0x6f, 0x72, 0x6b, 0x6e, +0x6f, 0x72, 0x6f, 0x6e, 0x68, 0x61, 0x62, 0x69, 0x79, 0x75, 0x6c, 0x61, +0x2c, 0x20, 0x75, 0x74, 0x74, 0x61, 0x72, 0x20, 0x1e0d, 0x61, 0x6b, 0x6f, +0x1e6d, 0x61, 0x6d, 0x61, 0x1e0d, 0x69, 0x6e, 0x12b, 0x20, 0x75, 0x74, 0x74, +0x61, 0x72, 0x20, 0x1e0d, 0x61, 0x6b, 0x6f, 0x1e6d, 0x61, 0x6e, 0x65, 0x75, +0x20, 0x73, 0x61, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x75, 0x74, 0x74, 0x61, +0x72, 0x20, 0x1e0d, 0x61, 0x6b, 0x6f, 0x1e6d, 0x61, 0x6e, 0x16b, 0x6b, 0x6f, +0x6a, 0x69, 0x6e, 0x61, 0x67, 0x61, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x61, +0x70, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x72, 0x69, 0x62, 0x6f, 0x70, 0x69, +0x6e, 0x69, 0x6b, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x61, 0x75, 0x2d, +0x70, 0x72, 0x69, 0x6e, 0x73, 0x65, 0x70, 0x6f, 0x72, 0x1e6d, 0x20, 0x61, +0x70, 0x20, 0x73, 0x70, 0x61, 0x69, 0x6e, 0x70, 0x6f, 0x72, 0x1e6d, 0x70, +0x20, 0x76, 0x65, 0x6c, 0x68, 0x6f, 0x70, 0x75, 0x65, 0x72, 0x74, 0x6f, +0x20, 0x72, 0x69, 0x6b, 0x6f, 0x70, 0x75, 0x1e47, 0x1e6d, 0x61, 0x20, 0x65, +0x72, 0x65, 0x6e, 0x61, 0x73, 0x72, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x20, +0x69, 0x6e, 0x6c, 0x65, 0x64, 0x1e6d, 0x72, 0x65, 0x73, 0x69, 0x70, 0x69, +0x72, 0x65, 0x6a, 0x69, 0x6e, 0x61, 0x72, 0x65, 0x6a, 0x61, 0x6c, 0x79, +0x75, 0x1e6d, 0x72, 0x69, 0x6f, 0x20, 0x62, 0x72, 0x61, 0x6e, 0x6b, 0x6f, +0x73, 0x61, 0x74, 0x61, 0x72, 0x69, 0x73, 0x61, 0x6e, 0x1e6d, 0x69, 0x61, +0x67, 0x6f, 0x73, 0x65, 0x6e, 0x74, 0x6f, 0x20, 0x1e0d, 0x6f, 0x6d, 0x69, +0x6e, 0x67, 0x6f, 0x73, 0x61, 0x6f, 0x20, 0x70, 0x61, 0x75, 0x6c, 0x6f, +0x69, 0x1e6d, 0x6f, 0x6b, 0x6f, 0x1e6d, 0x6f, 0x72, 0x6d, 0x69, 0x1e6d, 0x73, +0x69, 0x74, 0x6b, 0x61, 0x73, 0x65, 0x6e, 0x1e6d, 0x20, 0x62, 0x61, 0x72, +0x74, 0x65, 0x6c, 0x65, 0x6d, 0x69, 0x73, 0x65, 0x6e, 0x1e6d, 0x20, 0x6a, +0x6f, 0x6e, 0x73, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x6b, 0x69, 0x1e6d, 0x1e6d, +0x73, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x75, 0x73, 0x69, 0x61, 0x73, +0x65, 0x6e, 0x1e6d, 0x20, 0x74, 0x6f, 0x6d, 0x61, 0x73, 0x73, 0x65, 0x6e, +0x1e6d, 0x20, 0x76, 0x69, 0x6e, 0x73, 0x65, 0x6e, 0x1e6d, 0x73, 0x76, 0x69, +0x70, 0x1e6d, 0x20, 0x6b, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x1e6d, 0x74, 0x65, +0x67, 0x75, 0x74, 0x75, 0x6c, 0x65, 0x74, 0x69, 0x68, 0x76, 0x61, 0x6e, +0x61, 0x1e6d, 0x6f, 0x72, 0x6f, 0x6e, 0x1e6d, 0x6f, 0x1e6d, 0x6f, 0x72, 0x1e6d, +0x6f, 0x6c, 0x61, 0x76, 0x61, 0x6e, 0x6b, 0x16b, 0x76, 0x65, 0x72, 0x76, +0x68, 0x61, 0x69, 0x1e6d, 0x68, 0x6f, 0x72, 0x73, 0x76, 0x69, 0x6e, 0x6e, +0x69, 0x70, 0x65, 0x67, 0x79, 0x61, 0x6b, 0x75, 0x1e6d, 0x61, 0x1e6d, 0x6b, +0x65, 0x73, 0x65, 0x65, 0x1e0d, 0x65, 0x76, 0x69, 0x73, 0x1e0d, 0x79, 0x75, +0x6d, 0x6f, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x20, 0x75, 0x72, 0x76, 0x69, +0x6c, 0x6c, 0x6d, 0x65, 0x6b, 0x76, 0x61, 0x72, 0x69, 0x6d, 0x61, 0x76, +0x73, 0x6f, 0x6e, 0x6d, 0x65, 0x6b, 0x20, 0x6d, 0x75, 0x72, 0x1e0d, 0x6f, +0x70, 0x61, 0x6c, 0x6d, 0x65, 0x72, 0x72, 0x6f, 0x74, 0x65, 0x72, 0x61, +0x73, 0x79, 0x6f, 0x76, 0x61, 0x1e6d, 0x72, 0x6f, 0x6c, 0x6c, 0x76, 0x6f, +0x73, 0x1e6d, 0x6f, 0x6b, 0x6c, 0x6e, 0x67, 0x79, 0x61, 0x72, 0x62, 0x79, +0x65, 0x6e, 0x65, 0x1e0d, 0x65, 0x6e, 0x61, 0x6c, 0x6d, 0x61, 0x1e6d, 0x79, +0x61, 0x6d, 0x6d, 0x61, 0x6e, 0x61, 0x6e, 0x61, 0x1e0d, 0x69, 0x72, 0x61, +0x6b, 0x74, 0x61, 0x75, 0x61, 0x61, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x61, +0x73, 0x67, 0x61, 0x62, 0x61, 0x1e6d, 0x61, 0x74, 0x61, 0x72, 0x61, 0x75, +0x62, 0x61, 0x67, 0x64, 0x61, 0x64, 0x62, 0x61, 0x68, 0x72, 0x61, 0x69, +0x6e, 0x62, 0x61, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x67, 0x6b, 0x6f, 0x6b, +0x62, 0x61, 0x72, 0x6e, 0x61, 0x75, 0x6c, 0x62, 0x65, 0x69, 0x72, 0x75, +0x74, 0x62, 0x69, 0x73, 0x6b, 0x65, 0x6b, 0x62, 0x72, 0x75, 0x6e, 0x65, +0x69, 0x63, 0x69, 0x74, 0x61, 0x6b, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x6f, +0x1e0d, 0x61, 0x6d, 0x61, 0x73, 0x6b, 0x75, 0x73, 0x1e0d, 0x69, 0x6c, 0x69, +0x64, 0x75, 0x62, 0x61, 0x69, 0x64, 0x75, 0x73, 0x61, 0x6d, 0x62, 0x65, +0x70, 0x61, 0x6d, 0x61, 0x67, 0x75, 0x73, 0x74, 0x61, 0x67, 0x61, 0x6a, +0x61, 0x68, 0x65, 0x62, 0x72, 0x6f, 0x6e, 0x68, 0x6f, 0x20, 0x63, 0x69, +0x20, 0x6d, 0x69, 0x6e, 0x68, 0x20, 0x73, 0x69, 0x74, 0x69, 0x68, 0x6f, +0x6e, 0x67, 0x20, 0x6b, 0x6f, 0x6e, 0x67, 0x69, 0x72, 0x6b, 0x75, 0x1e6d, +0x73, 0x6b, 0x6a, 0x61, 0x79, 0x61, 0x70, 0x75, 0x72, 0x61, 0x6a, 0x65, +0x72, 0x75, 0x73, 0x61, 0x6c, 0x65, 0x6d, 0x6b, 0x61, 0x62, 0x75, 0x6c, +0x6b, 0x61, 0x6d, 0x63, 0x61, 0x1e6d, 0x6b, 0x61, 0x6b, 0x61, 0x72, 0x61, +0x63, 0x12b, 0x6b, 0x61, 0x1e6d, 0x6d, 0x61, 0x6e, 0x1e0d, 0x75, 0x6b, 0x61, +0x6e, 0x64, 0x69, 0x67, 0x61, 0x6b, 0x6f, 0x6c, 0x6b, 0x61, 0x74, 0x61, +0x6b, 0x72, 0x61, 0x73, 0x6e, 0x65, 0x79, 0x61, 0x72, 0x73, 0x6b, 0x6b, +0x75, 0x61, 0x6c, 0x61, 0x20, 0x6c, 0x75, 0x6d, 0x70, 0x75, 0x72, 0x6b, +0x75, 0x63, 0x69, 0x6e, 0x67, 0x6b, 0x75, 0x76, 0x61, 0x69, 0x74, 0x6d, +0x6b, 0x61, 0x6f, 0x6d, 0x65, 0x67, 0x61, 0x1e0d, 0x61, 0x6e, 0x6d, 0x61, +0x6b, 0x61, 0x73, 0x61, 0x72, 0x6d, 0x61, 0x6e, 0x12b, 0x6c, 0x61, 0x6d, +0x61, 0x73, 0x6b, 0x61, 0x74, 0x6e, 0x69, 0x6b, 0x6f, 0x73, 0x69, 0x79, +0x61, 0x6e, 0x65, 0x76, 0x6f, 0x6b, 0x75, 0x6a, 0x6e, 0x65, 0x1e6d, 0x73, +0x6b, 0x6e, 0x6f, 0x76, 0x6f, 0x73, 0x69, 0x62, 0x69, 0x72, 0x73, 0x6b, +0x70, 0x6e, 0x6f, 0x6d, 0x20, 0x70, 0x65, 0x6e, 0x68, 0x70, 0x6f, 0x6e, +0x1e6d, 0x69, 0x61, 0x6e, 0x61, 0x6b, 0x70, 0x79, 0x6f, 0x6e, 0x67, 0x79, +0x61, 0x6e, 0x67, 0x6b, 0x6f, 0x73, 0x1e6d, 0x61, 0x6e, 0x65, 0x6b, 0x69, +0x6a, 0x75, 0x6f, 0x72, 0x64, 0x61, 0x72, 0x69, 0x79, 0x61, 0x64, 0x73, +0x61, 0x68, 0x61, 0x6c, 0x69, 0x6e, 0x73, 0x61, 0x6d, 0x61, 0x72, 0x6b, +0x61, 0x6e, 0x64, 0x73, 0x65, 0x6f, 0x6c, 0x73, 0x65, 0x6e, 0x67, 0x61, +0x69, 0x73, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x73, 0x72, 0x65, +0x1e0d, 0x6e, 0x65, 0x6b, 0x6f, 0x6c, 0x79, 0x6d, 0x73, 0x6b, 0x74, 0x61, +0x69, 0x70, 0x65, 0x69, 0x74, 0x61, 0x73, 0x6b, 0x65, 0x6e, 0x1e6d, 0x74, +0x62, 0x69, 0x6c, 0x69, 0x73, 0x69, 0x74, 0x65, 0x68, 0x72, 0x61, 0x6e, +0x74, 0x69, 0x6d, 0x70, 0x68, 0x75, 0x1e6d, 0x6f, 0x6b, 0x79, 0x6f, 0x1e6d, +0x6f, 0x6d, 0x73, 0x6b, 0x75, 0x6c, 0x61, 0x6e, 0x62, 0x61, 0x1e6d, 0x61, +0x72, 0x75, 0x72, 0x75, 0x6d, 0x63, 0x69, 0x79, 0x75, 0x73, 0x74, 0x2d, +0x6e, 0x65, 0x72, 0x61, 0x76, 0x69, 0x65, 0x6e, 0x1e6d, 0x69, 0x61, 0x61, +0x6e, 0x76, 0x6c, 0x61, 0x1e0d, 0x69, 0x76, 0x6f, 0x73, 0x1e6d, 0x6f, 0x6b, +0x79, 0x61, 0x6b, 0x75, 0x1e6d, 0x73, 0x6b, 0x79, 0x61, 0x6e, 0x67, 0x6f, +0x6e, 0x79, 0x69, 0x6b, 0x61, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x62, 0x75, +0x72, 0x67, 0x79, 0x65, 0x72, 0x65, 0x76, 0x61, 0x6e, 0x61, 0x6a, 0x6f, +0x72, 0x65, 0x73, 0x62, 0x65, 0x72, 0x6d, 0x16b, 0x64, 0x61, 0x6b, 0x65, +0x6e, 0x65, 0x72, 0x69, 0x6b, 0x65, 0x70, 0x20, 0x76, 0x65, 0x72, 0x1e0d, +0x65, 0x70, 0x65, 0x72, 0x6f, 0x6d, 0x61, 0x1e0d, 0x69, 0x65, 0x72, 0x61, +0x72, 0x65, 0x79, 0x6b, 0x79, 0x61, 0x76, 0x69, 0x6b, 0x64, 0x6b, 0x69, +0x1e47, 0x20, 0x6a, 0x6f, 0x72, 0x6a, 0x69, 0x61, 0x73, 0x65, 0x6e, 0x74, +0x20, 0x68, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x73, 0x1e6d, 0x61, 0x6e, 0x6c, +0x69, 0x61, 0x65, 0x64, 0x69, 0x6c, 0x65, 0x69, 0x64, 0x62, 0x72, 0x69, +0x73, 0x62, 0x61, 0x6e, 0x65, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x6e, 0x20, +0x68, 0x69, 0x6c, 0x6c, 0x1e0d, 0x61, 0x72, 0x76, 0x69, 0x6e, 0x79, 0x75, +0x6b, 0x6c, 0x61, 0x68, 0x6f, 0x62, 0x61, 0x72, 0x1e6d, 0x6c, 0x69, 0x6e, +0x1e0d, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x6c, 0x6f, 0x72, 0x1e0d, 0x20, 0x68, +0x6f, 0x76, 0x65, 0x6d, 0x65, 0x6c, 0x62, 0x6f, 0x72, 0x6e, 0x65, 0x70, +0x65, 0x72, 0x74, 0x73, 0x79, 0x1e0d, 0x6e, 0x12b, 0x61, 0x6d, 0x73, 0x1e6d, +0x65, 0x72, 0x1e0d, 0x61, 0x6d, 0x61, 0x61, 0x1e47, 0x1e0d, 0x6f, 0x72, 0x61, +0x61, 0x61, 0x73, 0x1e6d, 0x72, 0x61, 0x68, 0x61, 0x6e, 0x65, 0x74, 0x65, +0x6e, 0x73, 0x62, 0x65, 0x6c, 0x67, 0x72, 0x61, 0x1e0d, 0x65, 0x62, 0x65, +0x72, 0x6c, 0x69, 0x6e, 0x62, 0x72, 0x61, 0x1e6d, 0x69, 0x73, 0x6c, 0x61, +0x76, 0x61, 0x62, 0x72, 0x75, 0x73, 0x73, 0x65, 0x6c, 0x73, 0x62, 0x75, +0x6b, 0x61, 0x72, 0x65, 0x73, 0x74, 0x62, 0x75, 0x1e0d, 0x61, 0x70, 0x65, +0x73, 0x74, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x65, 0x6e, 0x6b, 0x69, +0x73, 0x69, 0x6e, 0x61, 0x75, 0x6b, 0x6f, 0x70, 0x65, 0x6e, 0x68, 0x61, +0x67, 0x65, 0x6e, 0x1e0d, 0x62, 0x6c, 0x69, 0x6e, 0x6a, 0x69, 0x62, 0x72, +0x61, 0x6c, 0x1e6d, 0x61, 0x72, 0x67, 0x65, 0x72, 0x6e, 0x73, 0x69, 0x68, +0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x61, 0x61, 0x69, 0x6c, 0x20, +0x61, 0x70, 0x20, 0x6d, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x62, +0x75, 0x6c, 0x6a, 0x65, 0x72, 0x73, 0x69, 0x6b, 0x61, 0x6c, 0x69, 0x6e, +0x69, 0x6e, 0x67, 0x72, 0x61, 0x1e0d, 0x6b, 0x69, 0x72, 0x6f, 0x76, 0x6b, +0x69, 0x79, 0x76, 0x6c, 0x69, 0x73, 0x62, 0x6f, 0x6e, 0x6c, 0x79, 0x75, +0x62, 0x6c, 0x79, 0x61, 0x6e, 0x61, 0x6c, 0x6e, 0x1e0d, 0x6e, 0x6c, 0x6b, +0x73, 0x65, 0x6d, 0x62, 0x72, 0x67, 0x6d, 0x65, 0x1e0d, 0x72, 0x69, 0x1e0d, +0x6d, 0x61, 0x6c, 0x1e6d, 0x61, 0x6d, 0x61, 0x72, 0x69, 0x65, 0x68, 0x61, +0x6d, 0x6d, 0x69, 0x6e, 0x73, 0x6b, 0x6d, 0x6f, 0x6e, 0x61, 0x6b, 0x6f, +0x6d, 0x6f, 0x73, 0x6b, 0x6f, 0x6f, 0x73, 0x6c, 0x6f, 0x70, 0x61, 0x72, +0x69, 0x73, 0x70, 0x1e0d, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x73, 0x61, 0x70, +0x72, 0x61, 0x67, 0x72, 0x69, 0x67, 0x61, 0x73, 0x61, 0x6d, 0x61, 0x72, +0x61, 0x73, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x73, +0x61, 0x72, 0x61, 0x6a, 0x65, 0x76, 0x6f, 0x73, 0x61, 0x72, 0x61, 0x1e6d, +0x6f, 0x76, 0x73, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x6f, 0x70, 0x6f, 0x6c, +0x73, 0x6b, 0x6f, 0x70, 0x69, 0x73, 0x6f, 0x70, 0x69, 0x79, 0x61, 0x73, +0x1e6d, 0x6f, 0x6b, 0x68, 0x6f, 0x6d, 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x1e6d, +0x69, 0x72, 0x61, 0x6e, 0x65, 0x75, 0x6c, 0x79, 0x61, 0x6e, 0x6f, 0x76, +0x73, 0x6b, 0x76, 0x61, 0x1e0d, 0x75, 0x6a, 0x76, 0x61, 0x1e6d, 0x69, 0x6b, +0x61, 0x6e, 0x76, 0x69, 0x65, 0x6e, 0x6e, 0x61, 0x76, 0x69, 0x6c, 0x6e, +0x69, 0x75, 0x73, 0x76, 0x6f, 0x6c, 0x67, 0x6f, 0x67, 0x72, 0x61, 0x1e0d, +0x76, 0x61, 0x72, 0x73, 0x61, 0x74, 0x65, 0x67, 0x75, 0x73, 0x69, 0x67, +0x61, 0x6c, 0x70, 0x61, 0x6a, 0x75, 0x72, 0x69, 0x63, 0x1e6d, 0x61, 0x6e, +0x61, 0x6e, 0x61, 0x72, 0x69, 0x76, 0x63, 0x68, 0x61, 0x67, 0x6f, 0x73, +0x6b, 0x72, 0x69, 0x73, 0x1e6d, 0x6d, 0x61, 0x73, 0x6b, 0x6f, 0x6b, 0x6f, +0x73, 0x6b, 0x6f, 0x6d, 0x6f, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x67, 0x75, +0x65, 0x6c, 0x65, 0x6e, 0x6d, 0x61, 0x68, 0x65, 0x6d, 0x61, 0x6c, 0x64, +0x69, 0x76, 0x65, 0x73, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x73, 0x69, 0x75, +0x73, 0x6d, 0x61, 0x79, 0x6f, 0x1e6d, 0x72, 0x65, 0x75, 0x6e, 0x69, 0x6f, +0x6e, 0x61, 0x70, 0x69, 0x61, 0x101, 0x6b, 0x6c, 0x61, 0x6e, 0x1e0d, 0x62, +0x6f, 0x75, 0x67, 0x61, 0x6e, 0x76, 0x69, 0x6c, 0x6c, 0x63, 0x65, 0x1e6d, +0x61, 0x6d, 0x63, 0x16b, 0x6b, 0x12b, 0x73, 0x74, 0x65, 0x72, 0x69, 0x70, +0x65, 0x1e6d, 0x65, 0x70, 0x61, 0x6b, 0x61, 0x6f, 0x70, 0x6f, 0x70, 0x69, +0x6a, 0x69, 0x70, 0x75, 0x6e, 0x61, 0x70, 0x75, 0x74, 0x69, 0x67, 0x61, +0x6c, 0x61, 0x70, 0x61, 0x67, 0x6f, 0x73, 0x67, 0x61, 0x6d, 0x62, 0x69, +0x65, 0x72, 0x67, 0x75, 0x61, 0x1e0d, 0x61, 0x6c, 0x6b, 0x65, 0x6e, 0x61, +0x6c, 0x6b, 0x61, 0x6e, 0x1e6d, 0x6f, 0x6e, 0x6b, 0x69, 0x72, 0x69, 0x74, +0x69, 0x6d, 0x61, 0x74, 0x69, 0x6b, 0x69, 0x73, 0x72, 0x61, 0x65, 0x6b, +0x76, 0x61, 0x6a, 0x61, 0x6c, 0x65, 0x69, 0x6e, 0x6d, 0x61, 0x6a, 0x75, +0x72, 0x6f, 0x6d, 0x61, 0x72, 0x6b, 0x69, 0x73, 0x61, 0x73, 0x6d, 0x69, +0x1e0d, 0x76, 0x61, 0x79, 0x6e, 0x61, 0x75, 0x72, 0x75, 0x6e, 0x69, 0x75, +0x65, 0x6e, 0x6f, 0x72, 0x70, 0x6f, 0x6b, 0x6e, 0x75, 0x6d, 0x69, 0x65, +0x70, 0x61, 0x6e, 0x67, 0x6f, 0x20, 0x70, 0x61, 0x6e, 0x67, 0x6f, 0x70, +0x61, 0x6c, 0x61, 0x75, 0x70, 0x69, 0x1e6d, 0x6b, 0x65, 0x72, 0x6e, 0x70, +0x6f, 0x6e, 0x70, 0x65, 0x69, 0x70, 0x6f, 0x72, 0x1e6d, 0x20, 0x6d, 0x6f, +0x72, 0x65, 0x73, 0x62, 0x69, 0x72, 0x61, 0x72, 0x6f, 0x74, 0x6f, 0x6e, +0x67, 0x61, 0x73, 0x61, 0x69, 0x70, 0x61, 0x6e, 0x1e6d, 0x61, 0x68, 0x69, +0x1e6d, 0x69, 0x74, 0x61, 0x72, 0x61, 0x76, 0x61, 0x1e6d, 0x6f, 0x6e, 0x67, +0x61, 0x1e6d, 0x61, 0x70, 0x75, 0x76, 0x65, 0x6b, 0x76, 0x61, 0x6c, 0x6c, +0x69, 0x73, 0x92c, 0x94d, 0x92f, 0x93e, 0x928, 0x94d, 0x91c, 0x941, 0x932, 0x92a, +0x93c, 0x94d, 0x930, 0x940, 0x91f, 0x93e, 0x909, 0x928, 0x915, 0x93e, 0x930, 0x94d, +0x924, 0x941, 0x92e, 0x915, 0x93f, 0x902, 0x938, 0x93e, 0x938, 0x93e, 0x932, 0x941, +0x92c, 0x941, 0x92e, 0x92c, 0x93e, 0x938, 0x940, 0x92e, 0x94d, 0x2d, 0x92c, 0x93e, +0x92c, 0x93e, 0x928, 0x947, 0x92e, 0x94b, 0x917, 0x93e, 0x926, 0x93f, 0x938, 0x941, +0x928, 0x93e, 0x907, 0x930, 0x94b, 0x92c, 0x93f, 0x928, 0x941, 0x906, 0x915, 0x91a, +0x949, 0x91f, 0x938, 0x94d, 0x92f, 0x93e, 0x928, 0x20, 0x939, 0x94d, 0x935, 0x93e, +0x928, 0x938, 0x94d, 0x92f, 0x93e, 0x928, 0x20, 0x932, 0x942, 0x924, 0x93f, 0x909, +0x938, 0x941, 0x906, 0x907, 0x92f, 0x93e, 0x90f, 0x938, 0x928, 0x938, 0x93f, 0x92f, +0x949, 0x928, 0x92c, 0x94d, 0x932, 0x93e, 0x902, 0x2d, 0x938, 0x947, 0x92c, 0x932, +0x94b, 0x928, 0x915, 0x947, 0x92e, 0x94d, 0x92c, 0x94d, 0x930, 0x93f, 0x91c, 0x20, +0x92c, 0x947, 0x915, 0x94d, 0x92f, 0x93e, 0x92e, 0x94d, 0x92a, 0x94b, 0x20, 0x917, +0x94d, 0x930, 0x93e, 0x902, 0x921, 0x947, 0x915, 0x94d, 0x92f, 0x93e, 0x928, 0x915, +0x941, 0x928, 0x938, 0x93f, 0x915, 0x93e, 0x917, 0x94b, 0x921, 0x947, 0x928, 0x92e, +0x93e, 0x930, 0x94d, 0x915, 0x938, 0x949, 0x928, 0x924, 0x93f, 0x930, 0x941, 0x928, +0x947, 0x92a, 0x947, 0x92a, 0x93c, 0x94b, 0x930, 0x94d, 0x91f, 0x20, 0x928, 0x947, +0x932, 0x94d, 0x938, 0x928, 0x92a, 0x93c, 0x94b, 0x930, 0x94d, 0x91f, 0x93e, 0x932, +0x947, 0x91c, 0x93c, 0x93e, 0x939, 0x947, 0x932, 0x93f, 0x92a, 0x947, 0x915, 0x94d, +0x938, 0x907, 0x915, 0x93e, 0x932, 0x941, 0x924, 0x93f, 0x91f, 0x915, 0x94d, 0x930, +0x93e, 0x932, 0x947, 0x928, 0x94d, 0x921, 0x93f, 0x91c, 0x93f, 0x915, 0x92e, 0x928, +0x94b, 0x938, 0x92e, 0x947, 0x930, 0x93f, 0x917, 0x94b, 0x91f, 0x92c, 0x94d, 0x92f, +0x942, 0x932, 0x93e, 0x2c, 0x20, 0x909, 0x924, 0x949, 0x930, 0x949, 0x20, 0x921, +0x915, 0x94b, 0x91f, 0x93e, 0x92e, 0x93e, 0x926, 0x93f, 0x928, 0x940, 0x20, 0x909, +0x924, 0x949, 0x930, 0x949, 0x20, 0x921, 0x915, 0x94b, 0x91f, 0x93e, 0x928, 0x94d, +0x92f, 0x942, 0x20, 0x938, 0x93e, 0x932, 0x947, 0x92e, 0x2c, 0x20, 0x909, 0x924, +0x949, 0x930, 0x949, 0x20, 0x921, 0x915, 0x94b, 0x91f, 0x93e, 0x913, 0x915, 0x93e, +0x91c, 0x940, 0x928, 0x93e, 0x917, 0x93e, 0x92a, 0x93c, 0x940, 0x928, 0x93f, 0x915, +0x94d, 0x938, 0x92a, 0x94b, 0x930, 0x94d, 0x91f, 0x20, 0x911, 0x92a, 0x93c, 0x20, +0x938, 0x94d, 0x92a, 0x947, 0x928, 0x930, 0x947, 0x938, 0x93e, 0x907, 0x92a, 0x93c, +0x938, 0x947, 0x928, 0x94d, 0x91f, 0x93e, 0x930, 0x947, 0x92e, 0x938, 0x947, 0x902, +0x924, 0x93f, 0x906, 0x917, 0x94b, 0x938, 0x947, 0x902, 0x91f, 0x20, 0x92c, 0x93e, +0x930, 0x94d, 0x924, 0x947, 0x932, 0x947, 0x92e, 0x93f, 0x938, 0x947, 0x902, 0x91f, +0x20, 0x924, 0x949, 0x92e, 0x938, 0x938, 0x94d, 0x935, 0x93f, 0x92a, 0x93c, 0x94d, +0x91f, 0x20, 0x915, 0x930, 0x902, 0x91f, 0x935, 0x94d, 0x92f, 0x93e, 0x928, 0x94d, +0x915, 0x942, 0x935, 0x930, 0x92e, 0x94d, 0x92f, 0x93e, 0x915, 0x92e, 0x941, 0x930, +0x94d, 0x921, 0x94b, 0x932, 0x949, 0x928, 0x94d, 0x917, 0x92f, 0x930, 0x92c, 0x94d, +0x92f, 0x947, 0x928, 0x905, 0x938, 0x94d, 0x917, 0x93e, 0x92c, 0x93e, 0x924, 0x92c, +0x94d, 0x92f, 0x93e, 0x902, 0x917, 0x915, 0x949, 0x915, 0x92c, 0x93f, 0x938, 0x94d, +0x915, 0x947, 0x915, 0x92c, 0x94d, 0x930, 0x942, 0x928, 0x947, 0x924, 0x93f, 0x924, +0x94d, 0x938, 0x93f, 0x924, 0x93e, 0x926, 0x941, 0x92c, 0x924, 0x93f, 0x926, 0x941, +0x938, 0x93e, 0x902, 0x92c, 0x947, 0x92a, 0x93c, 0x93e, 0x92e, 0x93e, 0x917, 0x941, +0x938, 0x94d, 0x924, 0x93e, 0x92f, 0x947, 0x930, 0x941, 0x938, 0x932, 0x947, 0x92e, +0x915, 0x93e, 0x921, 0x93f, 0x902, 0x917, 0x93e, 0x92a, 0x928, 0x949, 0x92e, 0x20, +0x92a, 0x947, 0x928, 0x94d, 0x939, 0x915, 0x93f, 0x91c, 0x93f, 0x932, 0x949, 0x930, +0x94d, 0x921, 0x93e, 0x938, 0x93e, 0x915, 0x93e, 0x932, 0x93f, 0x928, 0x938, 0x902, +0x918, 0x93e, 0x924, 0x93f, 0x924, 0x93e, 0x924, 0x93f, 0x92a, 0x947, 0x924, 0x93f, +0x924, 0x93e, 0x938, 0x915, 0x902, 0x924, 0x91f, 0x94d, 0x2d, 0x92c, 0x93f, 0x932, +0x93f, 0x938, 0x93f, 0x92f, 0x93e, 0x902, 0x917, 0x949, 0x928, 0x915, 0x94d, 0x92f, +0x93e, 0x928, 0x947, 0x930, 0x940, 0x92a, 0x94d, 0x92f, 0x93e, 0x930, 0x94b, 0x926, +0x93e, 0x945, 0x915, 0x93f, 0x923, 0x93e, 0x945, 0x20, 0x91c, 0x93e, 0x945, 0x930, +0x94d, 0x91c, 0x93f, 0x92f, 0x93e, 0x938, 0x94d, 0x91f, 0x94d, 0x92f, 0x93e, 0x928, +0x932, 0x940, 0x906, 0x938, 0x94d, 0x91f, 0x94d, 0x930, 0x93e, 0x915, 0x93e, 0x928, +0x90f, 0x924, 0x947, 0x928, 0x94d, 0x938, 0x906, 0x907, 0x932, 0x20, 0x911, 0x92a, +0x94d, 0x20, 0x92e, 0x94d, 0x92f, 0x93e, 0x928, 0x938, 0x93f, 0x92e, 0x94d, 0x92a, +0x93c, 0x947, 0x930, 0x94b, 0x92a, 0x94b, 0x932, 0x938, 0x94d, 0x915, 0x94b, 0x92a, +0x94d, 0x92f, 0x947, 0x938, 0x94b, 0x92a, 0x93c, 0x93f, 0x92f, 0x93e, 0x91c, 0x93c, +0x94d, 0x92f, 0x942, 0x930, 0x93f, 0x915, 0x93c, 0x92e, 0x949, 0x930, 0x940, 0x938, +0x938, 0x911, 0x915, 0x932, 0x947, 0x902, 0x921, 0x91a, 0x94d, 0x92f, 0x93e, 0x925, +0x92e, 0x924, 0x93f, 0x938, 0x94d, 0x91f, 0x930, 0x90f, 0x92a, 0x93c, 0x947, 0x91f, +0x92a, 0x93c, 0x93e, 0x915, 0x93e, 0x913, 0x92a, 0x93c, 0x94b, 0x92a, 0x93c, 0x93f, +0x91c, 0x940, 0x92a, 0x93c, 0x94d, 0x92f, 0x942, 0x928, 0x93e, 0x92a, 0x93c, 0x941, +0x91f, 0x940, 0x917, 0x94d, 0x92f, 0x93e, 0x92e, 0x92c, 0x93f, 0x92f, 0x930, 0x915, +0x947, 0x902, 0x91f, 0x928, 0x928, 0x93e, 0x945, 0x909, 0x930, 0x941, 0x928, 0x949, +0x930, 0x92a, 0x93c, 0x949, 0x915, 0x928, 0x949, 0x92e, 0x93f, 0x92f, 0x93e, 0x92a, +0x94b, 0x928, 0x92a, 0x947, 0x924, 0x93f, 0xb0f, 0xb15, 0xb4d, 0xb30, 0xb3e, 0xb2c, +0xb4d, 0xb30, 0xb3e, 0xb1c, 0xb3e, 0xb71, 0xb3f, 0xb32, 0xb4d, 0xb32, 0xb47, 0xb2c, +0xb41, 0xb1c, 0xb42, 0xb2e, 0xb4d, 0xb2c, 0xb41, 0xb30, 0xb3e, 0xb15, 0xb28, 0xb3e, +0xb15, 0xb4d, 0xb30, 0xb3f, 0xb1c, 0xb3f, 0xb2c, 0xb1f, 0xb3f, 0xb2a, 0xb4d, 0xb30, +0xb3f, 0xb1f, 0xb3e, 0xb09, 0xb28, 0xb4d, 0x200c, 0xb17, 0xb3e, 0xb2c, 0xb30, 0xb4d, +0xb23, 0xb4d, 0xb23, 0xb1c, 0xb39, 0xb3e, 0xb28, 0xb4d, 0xb38, 0xb2c, 0xb30, 0xb4d, +0xb17, 0xb15, 0xb30, 0xb1f, 0xb09, 0xb2e, 0xb4d, 0x200c, 0xb32, 0xb3e, 0xb17, 0xb38, +0xb4d, 0x200c, 0xb32, 0xb3f, 0xb2c, 0xb4d, 0xb30, 0xb47, 0xb71, 0xb3f, 0xb32, 0xb4d, +0xb32, 0xb47, 0xb32, 0xb2e, 0xb4d, 0x200c, 0xb2e, 0xb4d, 0x2d, 0xb2c, 0xb3e, 0xb2c, +0xb3e, 0xb28, 0xb47, 0xb2e, 0xb4b, 0xb17, 0xb3e, 0xb21, 0xb3f, 0xb38, 0xb41, 0xb2e, +0xb28, 0xb30, 0xb4b, 0xb2c, 0xb3f, 0xb06, 0xb28, 0xb3e, 0xb07, 0xb30, 0xb2c, 0xb3f, +0xb28, 0xb41, 0xb06, 0xb15, 0xb1a, 0xb1f, 0xb05, 0xb17, 0xb3e, 0xb21, 0xb17, 0xb41, +0xb2a, 0xb30, 0xb4d, 0xb1f, 0x2d, 0xb28, 0xb71, 0xb38, 0xb3e, 0xb05, 0x20, 0xb1f, +0xb2e, 0xb47, 0xb24, 0xb4d, 0xb30, 0xb3f, 0xb2a, 0xb32, 0xb3f, 0xb71, 0xb3f, 0xb23, +0xb4d, 0xb21, 0xb39, 0xb15, 0xb4d, 0xb2c, 0xb41, 0xb0f, 0xb28, 0xb38, 0xb4d, 0x20, +0xb06, 0xb07, 0xb30, 0xb47, 0xb38, 0xb4d, 0xb15, 0xb3e, 0xb3c, 0xb1f, 0xb3e, 0xb2e, +0xb3e, 0xb15, 0xb3e, 0xb01, 0xb15, 0xb4b, 0xb21, 0xb4b, 0xb2c, 0xb3e, 0xb1c, 0xb41, +0xb1c, 0xb4b, 0xb0f, 0xb32, 0xb3e, 0x20, 0xb30, 0xb3f, 0xb4d, 0xb05, 0xb1c, 0xb3e, +0xb2e, 0xb47, 0xb23, 0xb4d, 0xb21, 0xb1c, 0xb3e, 0xb30, 0xb3f, 0xb5f, 0xb4b, 0x20, +0xb17, 0xb3e, 0xb32, 0xb47, 0xb17, 0xb4b, 0xb38, 0xb38, 0xb3e, 0xb32, 0xb4d, 0xb1f, +0xb3e, 0xb38, 0xb3e, 0xb5f, 0xb3e, 0xb28, 0xb4d, 0x20, 0xb71, 0xb3e, 0xb28, 0xb4d, +0xb38, 0xb5f, 0xb3e, 0xb28, 0x20, 0xb32, 0xb41, 0xb07, 0xb38, 0xb1f, 0xb4b, 0xb15, +0xb41, 0xb2e, 0xb28, 0xb09, 0xb38, 0xb41, 0xb06, 0xb07, 0xb5f, 0xb3e, 0xb05, 0xb30, +0xb41, 0xb2c, 0xb3e, 0xb2c, 0xb3e, 0xb30, 0xb2c, 0xb3e, 0xb21, 0xb38, 0xb2c, 0xb4d, +0xb32, 0xb3e, 0xb19, 0xb4d, 0xb15, 0x2d, 0xb38, 0xb3e, 0xb2c, 0xb32, 0xb28, 0xb4d, +0xb2c, 0xb4b, 0xb06, 0x20, 0xb71, 0xb3f, 0xb38, 0xb4d, 0xb1f, 0xb3e, 0xb2c, 0xb17, +0xb1f, 0xb3e, 0xb2c, 0xb07, 0xb38, 0xb47, 0xb15, 0xb3e, 0xb2e, 0xb4d, 0xb2a, 0x20, +0xb17, 0xb4d, 0xb30, 0xb3e, 0xb23, 0xb4d, 0xb21, 0xb47, 0xb38, 0xb3f, 0xb15, 0xb3e, +0xb17, 0xb15, 0xb37, 0xb4d, 0xb1f, 0xb3e, 0x20, 0xb30, 0xb3f, 0xb15, 0xb3e, 0xb15, +0xb4d, 0xb30, 0xb47, 0xb38, 0xb4d, 0x200d, 0xb1f, 0xb28, 0xb21, 0xb47, 0xb28, 0xb71, +0xb3f, 0xb30, 0xb4d, 0xb21, 0xb47, 0xb1f, 0xb4d, 0xb30, 0xb07, 0xb1f, 0xb4d, 0xb21, +0xb2e, 0xb3f, 0xb28, 0xb3f, 0xb15, 0xb3e, 0xb0f, 0xb21, 0xb4d, 0x200d, 0xb2e, 0xb28, +0xb1f, 0xb28, 0xb4d, 0xb0f, 0xb32, 0xb4d, 0x20, 0xb38, 0xb3e, 0xb32, 0xb71, 0xb3e, +0xb21, 0xb4b, 0xb30, 0xb4d, 0xb2a, 0xb30, 0xb4d, 0xb1f, 0x20, 0xb28, 0xb47, 0xb32, +0xb38, 0xb28, 0xb4d, 0xb2a, 0xb30, 0xb4d, 0xb1f, 0xb32, 0xb47, 0xb1c, 0xb3e, 0xb17, +0xb41, 0xb06, 0xb21, 0xb47, 0xb32, 0xb09, 0xb2a, 0xb47, 0xb17, 0xb41, 0xb06, 0xb24, +0xb47, 0xb2e, 0xb3e, 0xb32, 0xb3e, 0xb39, 0xb3e, 0xb71, 0xb28, 0xb3e, 0xb39, 0xb47, +0xb30, 0xb2e, 0xb38, 0xb3f, 0xb32, 0xb4b, 0xb07, 0xb23, 0xb4d, 0xb21, 0xb3f, 0xb06, +0xb28, 0xb3e, 0xb2a, 0xb32, 0xb3f, 0xb38, 0xb4d, 0xb2e, 0xb3e, 0xb30, 0xb47, 0xb28, +0xb17, 0x2c, 0x20, 0xb07, 0xb23, 0xb4d, 0xb21, 0xb3f, 0xb06, 0xb28, 0xb3e, 0xb71, +0xb47, 0xb71, 0xb3e, 0xb5f, 0x2c, 0x20, 0xb07, 0xb23, 0xb4d, 0xb21, 0xb3f, 0xb06, +0xb28, 0xb3e, 0xb07, 0xb28, 0xb41, 0xb71, 0xb3f, 0xb15, 0xb4d, 0xb32, 0xb09, 0xb07, +0xb38, 0xb71, 0xb3f, 0xb32, 0xb4d, 0xb32, 0xb47, 0xb2e, 0xb23, 0xb4d, 0xb1f, 0xb3f, +0xb38, 0xb47, 0xb32, 0x2c, 0x20, 0xb15, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb09, 0xb15, +0xb3f, 0xb15, 0xb47, 0xb15, 0xb4d, 0xb30, 0xb3e, 0xb32, 0xb47, 0xb23, 0xb4d, 0xb21, +0xb3f, 0xb1c, 0xb3f, 0xb15, 0xb2e, 0xb3e, 0xb38, 0xb3f, 0xb05, 0xb2e, 0xb3e, 0xb30, +0xb3f, 0xb17, 0xb1f, 0xb4d, 0xb2e, 0xb3e, 0xb1f, 0xb3e, 0xb2e, 0xb30, 0xb38, 0xb4d, +0xb2e, 0xb3e, 0xb1c, 0xb3e, 0xb1f, 0xb32, 0xb3e, 0xb28, 0xb4d, 0xb2e, 0xb3f, 0xb15, +0xb4d, 0xb35, 0xb47, 0xb32, 0xb28, 0xb4d, 0xb2e, 0xb3e, 0xb28, 0xb15, 0xb1f, 0xb28, +0xb4d, 0xb2e, 0xb28, 0xb1f, 0xb47, 0xb30, 0xb3f, 0xb0f, 0xb2e, 0xb23, 0xb4d, 0xb1f, +0xb47, 0xb2d, 0xb3f, 0xb21, 0xb3f, 0xb05, 0xb2e, 0xb28, 0xb1f, 0xb38, 0xb47, 0xb30, +0xb30, 0xb3e, 0xb1f, 0xb4d, 0xb28, 0xb4d, 0xb5f, 0xb41, 0x20, 0xb5f, 0xb30, 0xb4d, +0xb15, 0xb4d, 0xb28, 0xb30, 0xb39, 0xb4d, 0xb28, 0xb2c, 0xb47, 0xb09, 0xb32, 0xb3e, +0xb39, 0x2c, 0x20, 0xb09, 0xb24, 0xb4d, 0xb24, 0xb30, 0x20, 0xb21, 0xb3e, 0xb15, +0xb1f, 0xb3e, 0xb15, 0xb47, 0xb28, 0xb4d, 0xb26, 0xb4d, 0xb30, 0x2c, 0x20, 0xb09, +0xb24, 0xb4d, 0xb24, 0xb30, 0x20, 0xb21, 0xb3e, 0xb15, 0xb1f, 0xb3e, 0xb28, 0xb4d, +0xb5f, 0xb41, 0x20, 0xb38, 0xb3e, 0xb32, 0xb47, 0xb2e, 0xb4d, 0x2c, 0x20, 0xb09, +0xb24, 0xb4d, 0xb24, 0xb30, 0x20, 0xb21, 0xb3e, 0xb15, 0xb1f, 0xb3e, 0xb05, 0xb1c, +0xb3f, 0xb28, 0xb3e, 0xb17, 0xb3e, 0xb2a, 0xb07, 0xb28, 0xb3f, 0xb15, 0xb4d, 0xb38, +0xb2a, 0xb30, 0xb4d, 0xb1f, 0x2d, 0xb0f, 0xb5f, 0xb41, 0x2d, 0xb2a, 0xb4d, 0xb30, +0xb3f, 0xb28, 0xb4d, 0x200d, 0xb38, 0xb2a, 0xb30, 0xb4d, 0xb1f, 0xb4d, 0x20, 0xb05, +0xb2b, 0xb4d, 0x20, 0xb38, 0xb4d, 0xb2a, 0xb47, 0xb28, 0xb4d, 0xb2a, 0xb41, 0xb0f, +0xb30, 0xb4d, 0xb24, 0x20, 0xb30, 0xb3f, 0xb15, 0xb30, 0xb47, 0xb38, 0xb3f, 0xb2a, +0xb3f, 0xb30, 0xb3f, 0xb5f, 0x20, 0xb2c, 0xb4d, 0xb30, 0xb3e, 0xb19, 0xb4d, 0xb15, +0xb38, 0xb3e, 0xb28, 0xb4d, 0xb24, 0xb30, 0xb47, 0xb2e, 0xb4d, 0xb38, 0xb3e, 0xb23, +0xb4d, 0xb1f, 0x20, 0xb21, 0xb2e, 0xb3f, 0xb19, 0xb4d, 0xb17, 0xb07, 0xb1f, 0xb4d, +0xb1f, 0xb15, 0xb4d, 0xb35, 0xb30, 0xb1f, 0xb30, 0xb2e, 0xb3f, 0xb1f, 0xb4d, 0xb38, +0xb47, 0xb23, 0xb4d, 0xb1f, 0x20, 0xb2c, 0xb3e, 0xb30, 0xb4d, 0xb24, 0xb47, 0xb32, +0xb47, 0xb2e, 0xb3f, 0xb38, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb4d, 0x20, 0xb15, 0xb3f, +0xb1f, 0xb4d, 0x200d, 0xb38, 0xb38, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb4d, 0x2e, 0x20, +0xb25, 0xb2e, 0xb3e, 0xb38, 0xb4d, 0xb38, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb4d, 0x2e, +0x20, 0xb71, 0xb3f, 0xb28, 0xb38, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb4d, 0xb24, 0xb41, +0xb32, 0xb47, 0xb1f, 0xb30, 0xb23, 0xb4d, 0xb1f, 0xb1f, 0xb30, 0xb1f, 0xb32, 0xb3e, +0xb71, 0xb3e, 0xb19, 0xb4d, 0xb15, 0xb41, 0xb71, 0xb30, 0xb4d, 0xb15, 0xb47, 0xb38, +0xb3f, 0xb21, 0xb47, 0xb71, 0xb3f, 0xb38, 0xb4d, 0xb21, 0xb4d, 0xb5f, 0xb41, 0xb2e, +0xb3e, 0xb23, 0xb4d, 0xb1f, 0x20, 0xb21, 0xb3f, 0x20, 0xb09, 0xb30, 0xb71, 0xb3f, +0xb32, 0xb47, 0xb2e, 0xb15, 0xb4d, 0xb71, 0xb3e, 0xb30, 0xb3f, 0xb2e, 0xb3e, 0xb01, +0xb38, 0xb28, 0xb2e, 0xb4d, 0xb5f, 0xb3e, 0xb15, 0xb2e, 0xb41, 0xb30, 0xb4d, 0xb21, +0xb2a, 0xb3e, 0xb01, 0xb2e, 0xb30, 0xb30, 0xb4b, 0xb24, 0xb47, 0xb30, 0xb3e, 0xb1f, +0xb4b, 0xb32, 0xb4d, 0xb71, 0xb4b, 0xb38, 0xb4d, 0xb24, 0xb15, 0xb4b, 0xb33, 0xb19, +0xb4d, 0xb16, 0xb5f, 0xb3e, 0xb30, 0xb2c, 0xb47, 0xb28, 0xb06, 0xb15, 0xb4d, 0xb1f, +0xb2c, 0xb47, 0xb06, 0xb38, 0xb4d, 0x200d, 0xb17, 0xb3e, 0xb2c, 0xb1f, 0xb4d, 0xb2c, +0xb39, 0xb3e, 0xb30, 0xb47, 0xb28, 0xb2c, 0xb3f, 0xb38, 0xb15, 0xb47, 0xb15, 0xb4d, +0x200c, 0xb26, 0xb41, 0xb38, 0xb3e, 0xb28, 0xb2c, 0xb47, 0xb2a, 0xb3e, 0xb2e, 0xb3e, +0xb17, 0xb41, 0xb38, 0xb4d, 0xb1f, 0xb3e, 0xb39, 0x20, 0xb1a, 0xb3f, 0x20, 0xb2e, +0xb3f, 0xb28, 0xb4d, 0x200c, 0x20, 0xb38, 0xb3f, 0xb1f, 0xb3f, 0xb39, 0xb4b, 0xb71, +0xb21, 0xb4d, 0x200c, 0xb1c, 0xb3e, 0xb15, 0xb30, 0xb4d, 0xb24, 0xb3e, 0xb15, 0xb2c, +0xb41, 0xb32, 0xb4d, 0xb15, 0xb3e, 0xb1f, 0xb2e, 0xb3e, 0xb23, 0xb4d, 0xb21, 0xb41, +0xb15, 0xb3e, 0xb28, 0xb21, 0xb4d, 0xb5f, 0xb3e, 0xb17, 0xb3e, 0xb15, 0xb4d, 0xb30, +0xb3e, 0xb38, 0xb28, 0xb5f, 0xb3e, 0xb30, 0xb38, 0xb4d, 0xb15, 0xb28, 0xb3f, 0xb15, +0xb38, 0xb3f, 0xb06, 0xb28, 0xb71, 0xb15, 0xb41, 0xb1c, 0xb28, 0xb47, 0xb1f, 0xb38, +0xb4d, 0xb15, 0xb28, 0xb71, 0xb38, 0xb3f, 0xb2c, 0xb3f, 0xb30, 0xb38, 0xb4d, 0xb15, +0xb05, 0xb30, 0xb3e, 0xb32, 0xb4d, 0x200c, 0xb2a, 0xb28, 0xb2e, 0xb4d, 0x200c, 0x20, +0xb2a, 0xb47, 0xb28, 0xb39, 0xb2a, 0xb23, 0xb4d, 0xb1f, 0xb3f, 0xb06, 0xb28, 0xb3e, +0xb15, 0xb4d, 0x200c, 0xb15, 0xb37, 0xb4d, 0xb1f, 0xb28, 0xb47, 0xb15, 0xb40, 0xb1c, +0xb3f, 0xb32, 0xb30, 0xb4d, 0xb21, 0xb3e, 0xb38, 0xb15, 0xb3e, 0xb32, 0xb3f, 0xb28, +0xb4d, 0xb38, 0xb3f, 0xb05, 0xb32, 0xb38, 0xb02, 0xb17, 0xb3e, 0xb07, 0xb38, 0xb4d, +0xb30, 0xb47, 0xb21, 0xb28, 0xb47, 0xb15, 0xb32, 0xb5f, 0xb2e, 0xb38, 0xb4d, 0xb15, +0xb24, 0xb3e, 0xb38, 0xb15, 0xb47, 0xb23, 0xb4d, 0xb1f, 0xb24, 0xb3f, 0xb2e, 0xb4d, +0xb2a, 0xb41, 0xb1f, 0xb15, 0xb3f, 0xb05, 0xb1f, 0xb2e, 0xb38, 0xb4d, 0xb15, 0xb5f, +0xb41, 0xb38, 0xb4d, 0x200d, 0xb1f, 0x2d, 0xb28, 0xb47, 0xb30, 0xb3e, 0xb71, 0xb3f, +0xb0f, 0xb23, 0xb4d, 0xb1f, 0xb3f, 0xb0f, 0xb28, 0xb4d, 0x200c, 0xb71, 0xb4d, 0xb32, +0xb3e, 0xb21, 0xb3f, 0xb71, 0xb37, 0xb4d, 0xb1f, 0xb4b, 0xb15, 0xb4d, 0xb5f, 0xb47, +0xb30, 0xb47, 0xb2c, 0xb3e, 0xb28, 0xb4d, 0xb06, 0xb1c, 0xb30, 0xb47, 0xb38, 0xb4d, +0xb2c, 0xb30, 0xb2e, 0xb41, 0xb21, 0xb3e, 0xb15, 0xb47, 0xb2a, 0xb4d, 0x200c, 0x20, +0xb71, 0xb30, 0xb4d, 0xb26, 0xb47, 0xb2a, 0xb30, 0xb0f, 0xb30, 0xb47, 0xb15, 0xb4d, +0xb5f, 0xb3e, 0xb2c, 0xb3f, 0xb15, 0xb38, 0xb4d, 0x200d, 0xb1f, 0xb3e, 0xb32, 0xb3f, +0xb28, 0xb0f, 0xb21, 0xb3f, 0xb32, 0xb47, 0xb21, 0xb4d, 0xb2c, 0xb4d, 0xb30, 0xb3f, +0xb38, 0xb2c, 0xb28, 0xb4d, 0xb2c, 0xb4d, 0xb30, 0xb4b, 0xb15, 0xb28, 0x20, 0xb39, +0xb3f, 0xb32, 0xb21, 0xb3e, 0xb30, 0xb4d, 0xb71, 0xb3f, 0xb28, 0xb4d, 0xb32, 0xb3f, +0xb23, 0xb4d, 0xb21, 0xb47, 0xb2e, 0xb3e, 0xb28, 0xb32, 0xb30, 0xb4d, 0x200d, 0xb21, +0x20, 0xb39, 0xb3e, 0xb71, 0xb47, 0xb2e, 0xb47, 0xb32, 0xb2c, 0xb4b, 0xb28, 0xb01, +0xb2a, 0xb30, 0xb4d, 0xb24, 0xb06, 0xb2e, 0xb37, 0xb4d, 0xb1f, 0xb4d, 0xb30, 0xb47, +0xb21, 0xb3e, 0xb2e, 0xb4d, 0xb06, 0xb23, 0xb4d, 0xb21, 0xb30, 0xb3e, 0xb06, 0xb38, +0xb4d, 0x200d, 0xb1f, 0xb30, 0xb3e, 0xb15, 0xb3e, 0xb28, 0xb0f, 0xb24, 0xb47, 0xb28, +0xb4d, 0xb38, 0xb2c, 0xb47, 0xb32, 0xb17, 0xb4d, 0xb30, 0xb47, 0xb21, 0xb47, 0xb2c, +0xb4d, 0xb30, 0xb3e, 0xb1f, 0xb3f, 0xb38, 0xb32, 0xb3e, 0xb71, 0xb3e, 0xb2c, 0xb4d, +0xb30, 0xb41, 0xb38, 0xb3f, 0xb32, 0xb4d, 0x200d, 0xb38, 0xb2c, 0xb41, 0xb1a, 0xb3e, +0xb30, 0xb47, 0xb38, 0xb4d, 0xb1f, 0xb2c, 0xb41, 0xb21, 0xb3e, 0xb2a, 0xb47, 0xb38, +0xb4d, 0xb1f, 0xb1a, 0xb3f, 0xb38, 0xb3f, 0xb28, 0xb3e, 0xb09, 0xb15, 0xb2a, 0xb47, +0xb28, 0xb39, 0xb3e, 0xb17, 0xb47, 0xb28, 0xb4d, 0xb06, 0xb07, 0xb32, 0xb4d, 0x20, +0xb05, 0xb2a, 0xb4d, 0x20, 0xb2e, 0xb4d, 0xb5f, 0xb3e, 0xb28, 0xb4d, 0xb15, 0xb3f, +0xb30, 0xb71, 0xb2e, 0xb3e, 0xb30, 0xb3f, 0xb5f, 0xb3e, 0xb39, 0xb47, 0xb2e, 0xb2e, +0xb28, 0xb3e, 0xb15, 0xb05, 0xb38, 0xb32, 0xb4b, 0xb2a, 0xb21, 0xb17, 0xb30, 0xb3f, +0xb15, 0xb3e, 0xb30, 0xb2e, 0xb4d, 0xb38, 0xb3e, 0xb30, 0xb3e, 0xb1c, 0xb47, 0xb2c, +0xb38, 0xb3e, 0xb30, 0xb3e, 0xb1f, 0xb71, 0xb4d, 0xb38, 0xb3f, 0xb2e, 0xb2b, 0xb47, +0xb30, 0xb2a, 0xb32, 0xb4d, 0xb38, 0xb4d, 0xb15, 0xb2a, 0xb5f, 0xb47, 0xb38, 0xb2a, +0xb3f, 0xb5f, 0xb3e, 0xb38, 0xb4d, 0xb1f, 0xb15, 0xb4d, 0x20, 0xb39, 0xb2e, 0xb4d, +0x200c, 0xb1f, 0xb3e, 0xb07, 0xb30, 0xb47, 0xb28, 0xb4d, 0xb5f, 0xb41, 0xb32, 0xb5f, +0xb3e, 0xb28, 0xb71, 0xb38, 0xb4d, 0xb15, 0xb2c, 0xb3e, 0xb21, 0xb41, 0xb1c, 0xb71, +0xb3e, 0xb1f, 0xb3f, 0xb15, 0xb3e, 0xb28, 0xb4d, 0xb71, 0xb3f, 0xb0f, 0xb28, 0xb3e, +0xb71, 0xb3f, 0xb32, 0xb28, 0xb3f, 0xb09, 0xb38, 0xb4d, 0xb71, 0xb32, 0xb17, 0xb17, +0xb4d, 0xb30, 0xb3e, 0xb21, 0xb4d, 0xb16, 0xb4d, 0xb30, 0xb40, 0xb38, 0xb4d, 0x200d, +0xb1f, 0x20, 0xb2e, 0xb3e, 0xb38, 0xb15, 0xb15, 0xb38, 0xb4d, 0x200c, 0xb15, 0xb2e, +0xb30, 0xb15, 0xb47, 0xb30, 0xb17, 0xb41, 0xb32, 0xb47, 0xb28, 0xb2e, 0xb30, 0xb3f, +0xb38, 0xb38, 0xb4d, 0xb2e, 0xb3e, 0xb5f, 0xb1f, 0xb47, 0xb2c, 0xb17, 0xb47, 0xb28, +0xb4d, 0x200c, 0xb71, 0xb3f, 0xb32, 0xb4d, 0xb32, 0xb47, 0xb1a, 0xb3e, 0xb24, 0xb3e, +0xb2e, 0xb4d, 0x200c, 0xb2a, 0xb15, 0xb3e, 0xb05, 0xb2a, 0xb2a, 0xb3f, 0xb1c, 0xb3f, +0xb17, 0xb3e, 0xb32, 0xb3e, 0xb2a, 0xb3e, 0xb17, 0xb38, 0xb15, 0xb47, 0xb23, 0xb4d, +0xb1f, 0xb28, 0xb28, 0xb30, 0xb2a, 0xb15, 0xb4d, 0x200c, 0xb28, 0xb09, 0xb2e, 0xb3f, +0xb5f, 0xb2a, 0xb39, 0xb28, 0xb2a, 0xb47, 0xb07, 0xb2a, 0xb30, 0xb4d, 0xb1f, 0xb4d, +0x200c, 0x20, 0xb2e, 0xb30, 0xb47, 0xb38, 0xb2c, 0xb3f, 0xb30, 0xb3e, 0xb30, 0xb1f, +0xb19, 0xb4d, 0xb17, 0xb3e, 0xb1f, 0xb19, 0xb4d, 0xb17, 0xb3e, 0xb1f, 0xb3e, 0xb2a, +0xb41, 0xc0e, 0xc02, 0xc17, 0xc4d, 0xc35, 0xc3f, 0xc32, 0xc4d, 0xc32, 0xc3e, 0x3c, +0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x43, 0x69, 0x74, 0x79, +0x3e, 0xc05, 0xc21, 0xc46, 0xc32, 0xc48, 0xc21, 0xc4d, 0x3c, 0x2f, 0x65, 0x78, +0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x43, 0x69, 0x74, 0x79, 0x3e, 0xc15, +0xc3e, 0xc02, 0xc1f, 0xc28, 0xc4d, 0x140a, 0x144e, 0x1426, 0x146f, 0x1472, 0x1423, 0x1401, +0x141f, 0x14aa, 0x1423, 0x1450, 0x1423, 0x1403, 0x14c4, 0x1431, 0x1420, 0x1403, 0x1473, 0x14eb, +0x1405, 0x1403, 0x141f, 0x14f4, 0x1422, 0x1473, 0x141f, 0x1489, 0x1418, 0x1423, 0x1411, 0x14c2, +0x142f, 0x1420 }; static inline constexpr char16_t shortZoneNameTable[] = { diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index 37d6dea35f9..54bd971cb36 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -181,13 +181,12 @@ allocateHelper(qsizetype objectSize, qsizetype alignment, qsizetype capacity, return {}; void *data = nullptr; - QArrayData *header = static_cast<QArrayData *>(::malloc(size_t(allocSize))); - if (Q_LIKELY(header)) { - header->ref_.storeRelaxed(1); - header->flags = {}; + void *mem = ::malloc(size_t(allocSize)); + QArrayData *header = nullptr; + if (Q_LIKELY(mem)) { + header = new (mem) QArrayData{1, {}, capacity}; // find where offset should point to so that data() is aligned to alignment bytes data = QTypedArrayData<void>::dataStart(header, alignment); - header->alloc = capacity; } return { data, header }; @@ -245,8 +244,12 @@ QArrayData::reallocateUnaligned(QArrayData *data, void *dataPointer, Q_ASSERT(offset > 0); Q_ASSERT(offset <= allocSize); // equals when all free space is at the beginning - QArrayData *header = static_cast<QArrayData *>(::realloc(data, size_t(allocSize))); - if (header) { + const bool hadData = data; + void *mem = ::realloc(data, size_t(allocSize)); + QArrayData *header = static_cast<QArrayData *>(mem); + if (mem) { + if (!hadData) + header = new (mem) QArrayData{0, {}, {}}; header->alloc = capacity; dataPointer = reinterpret_cast<char *>(header) + offset; } else { diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index 38d1091ac1f..71e183e646e 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -39,7 +39,7 @@ struct QArrayData }; Q_DECLARE_FLAGS(ArrayOptions, ArrayOption) - QBasicAtomicInt ref_; + QBasicAtomicInt m_ref; ArrayOptions flags; qsizetype alloc; @@ -56,19 +56,19 @@ struct QArrayData /// Returns true if sharing took place bool ref() noexcept { - ref_.ref(); + m_ref.ref(); return true; } /// Returns false if deallocation is necessary bool deref() noexcept { - return ref_.deref(); + return m_ref.deref(); } bool isShared() const noexcept { - return ref_.loadRelaxed() != 1; + return m_ref.loadRelaxed() != 1; } // Returns true if a detach is necessary before modifying the data @@ -76,7 +76,7 @@ struct QArrayData // detaching is necessary, you should be in a non-const function already bool needsDetach() noexcept { - return ref_.loadRelaxed() > 1; + return m_ref.loadRelaxed() > 1; } qsizetype detachCapacity(qsizetype newSize) const noexcept diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index c20abd12c23..419585b0260 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -82,7 +82,7 @@ public: void destroyAll() noexcept // Call from destructors, ONLY! { Q_ASSERT(this->d); - Q_ASSERT(this->d->ref_.loadRelaxed() == 0); + Q_ASSERT(this->d->m_ref.loadRelaxed() == 0); // As this is to be called only from destructor, it doesn't need to be // exception safe; size not updated. @@ -345,7 +345,7 @@ public: // As this is to be called only from destructor, it doesn't need to be // exception safe; size not updated. - Q_ASSERT(this->d->ref_.loadRelaxed() == 0); + Q_ASSERT(this->d->m_ref.loadRelaxed() == 0); std::destroy(this->begin(), this->end()); } diff --git a/src/corelib/tools/qatomicscopedvaluerollback.h b/src/corelib/tools/qatomicscopedvaluerollback.h index 8f653acba5e..929a2e2d466 100644 --- a/src/corelib/tools/qatomicscopedvaluerollback.h +++ b/src/corelib/tools/qatomicscopedvaluerollback.h @@ -11,6 +11,7 @@ #include <QtCore/qtconfigmacros.h> #include <atomic> +#include <type_traits> QT_BEGIN_NAMESPACE @@ -122,6 +123,33 @@ template <typename T> QAtomicScopedValueRollback(QBasicAtomicPointer<T> &, std::memory_order) -> QAtomicScopedValueRollback<T*>; +template <typename T, typename V, + std::enable_if_t<std::is_convertible_v<V, T>, bool> = true> +QAtomicScopedValueRollback(std::atomic<T>&, V) + -> QAtomicScopedValueRollback<T>; +template <typename T, typename V, + std::enable_if_t<std::is_convertible_v<V, T>, bool> = true> +QAtomicScopedValueRollback(std::atomic<T>&, V, std::memory_order) + -> QAtomicScopedValueRollback<T>; + +template <typename T, typename V, + std::enable_if_t<std::is_convertible_v<V, T>, bool> = true> +QAtomicScopedValueRollback(QBasicAtomicInteger<T>&, V) + -> QAtomicScopedValueRollback<T>; +template <typename T, typename V, + std::enable_if_t<std::is_convertible_v<V, T>, bool> = true> +QAtomicScopedValueRollback(QBasicAtomicInteger<T>&, V, std::memory_order) + -> QAtomicScopedValueRollback<T>; + +template <typename T, typename V, + std::enable_if_t<std::is_convertible_v<V, T*>, bool> = true> +QAtomicScopedValueRollback(QBasicAtomicPointer<T>&, V) + -> QAtomicScopedValueRollback<T*>; +template <typename T, typename V, + std::enable_if_t<std::is_convertible_v<V, T*>, bool> = true> +QAtomicScopedValueRollback(QBasicAtomicPointer<T>&, V, std::memory_order) + -> QAtomicScopedValueRollback<T*>; + QT_END_NAMESPACE #endif // QATOMICASCOPEDVALUEROLLBACK_H diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h index 5c12332aa4a..ecefd1f55df 100644 --- a/src/corelib/tools/qfreelist_p.h +++ b/src/corelib/tools/qfreelist_p.h @@ -199,27 +199,27 @@ inline typename QFreeList<T, ConstantsType>::ReferenceType QFreeList<T, Constant template <typename T, typename ConstantsType> inline int QFreeList<T, ConstantsType>::next() { - int id, newid, at; - ElementType *v; + int newid; + int id = _next.loadAcquire(); do { - id = _next.loadAcquire(); - - at = id & ConstantsType::IndexMask; + int at = id & ConstantsType::IndexMask; const int block = blockfor(at); - v = _v[block].loadAcquire(); + ElementType *v = _v[block].loadAcquire(); if (!v) { - v = allocate((id & ConstantsType::IndexMask) - at, ConstantsType::Sizes[block]); - if (!_v[block].testAndSetRelease(nullptr, v)) { + ElementType* const alloced = allocate((id & ConstantsType::IndexMask) - at, + ConstantsType::Sizes[block]); + if (_v[block].testAndSetRelease(nullptr, alloced, v)) { + v = alloced; + } else { // race with another thread lost - delete[] v; - v = _v[block].loadAcquire(); + delete[] alloced; Q_ASSERT(v != nullptr); } } newid = v[at].next.loadRelaxed() | (id & ~ConstantsType::IndexMask); - } while (!_next.testAndSetRelease(id, newid)); + } while (!_next.testAndSetOrdered(id, newid, id)); // qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)", // id & ConstantsType::IndexMask, // newid & ConstantsType::IndexMask, @@ -232,7 +232,7 @@ inline void QFreeList<T, ConstantsType>::release(int id) { int at = id & ConstantsType::IndexMask; const int block = blockfor(at); - ElementType *v = _v[block].loadRelaxed(); + ElementType *v = _v[block].loadAcquire(); int x, newid; do { diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h index cbe217db11e..3e44f5f3442 100644 --- a/src/corelib/tools/qhashfunctions.h +++ b/src/corelib/tools/qhashfunctions.h @@ -298,19 +298,32 @@ bool qHashEquals(const T1 &a, const T2 &b) } namespace QtPrivate { -template <typename Mixer> struct QHashCombiner : private Mixer +template <typename Mixer> struct QHashCombinerWithSeed : private Mixer { - using result_type = typename Mixer::result_type ; + using result_type = typename Mixer::result_type; + size_t seed; + constexpr QHashCombinerWithSeed(result_type s) noexcept : seed(s) {} + + template <typename T> + constexpr result_type operator()(result_type result, const T &t) const + noexcept(noexcept(qHash(t, seed))) + { + return Mixer::operator()(result, qHash(t, seed)); + } +}; #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED) - // Qt 6.x didn't use to pass the seed; bootstrap has no seed +// Earlier Qt 6.x versions of qHashMulti() failed to pass the seed as the seed +// argument of qHash(), so this class exists for compatibility with user and +// inline code that relies on the old behavior. For Qt 7, we'll replace with +// the above version, except for the bootstrapped tools (which have no seed). +template <typename Mixer> struct QHashCombiner : private Mixer +{ + using result_type = typename Mixer::result_type; + static constexpr size_t seed = 0; constexpr QHashCombiner(result_type) noexcept {} Q_DECL_DEPRECATED_X("pass the seed argument") constexpr QHashCombiner() noexcept {} -#else - size_t seed; - constexpr QHashCombiner(result_type s) : seed(s) noexcept {} -#endif template <typename T> constexpr result_type operator()(result_type result, const T &t) const @@ -319,6 +332,9 @@ template <typename Mixer> struct QHashCombiner : private Mixer return Mixer::operator()(result, qHash(t, seed)); } }; +#else +template <typename Mixer> using QHashCombiner = QHashCombinerWithSeed<Mixer>; +#endif struct QHashCombineMixer { @@ -330,6 +346,7 @@ struct QHashCombineMixer } }; using QHashCombine = QHashCombiner<QHashCombineMixer>; +using QHashCombineWithSeed = QHashCombinerWithSeed<QHashCombineMixer>; struct QHashCombineCommutativeMixer : std::plus<size_t> { @@ -341,6 +358,7 @@ struct QHashCombineCommutativeMixer : std::plus<size_t> typedef size_t result_type; }; using QHashCombineCommutative = QHashCombiner<QHashCombineCommutativeMixer>; +using QHashCombineCommutativeWithSeed = QHashCombinerWithSeed<QHashCombineCommutativeMixer>; template <typename... T> using QHashMultiReturnType = decltype( diff --git a/src/corelib/tools/qmultimap.qdoc b/src/corelib/tools/qmultimap.qdoc index 8a008d27960..8760bf93bf7 100644 --- a/src/corelib/tools/qmultimap.qdoc +++ b/src/corelib/tools/qmultimap.qdoc @@ -38,7 +38,7 @@ \snippet code/src_corelib_tools_qmultimap.cpp 2 - This inserts the following three (key, value) pairs into the + This inserts the following four (key, value) pairs into the QMultiMap: ("a", 1), ("b", 3), ("c", 7), and ("c", -5); note that duplicate keys are allowed. diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index ed17dddbcf5..4c9736dea6d 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -6,6 +6,7 @@ #include <qcoreapplication.h> #include <qelapsedtimer.h> +#include <private/qlatch_p.h> #include <qloggingcategory.h> #include <qmetaobject.h> #include <qobject.h> @@ -1530,8 +1531,8 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg) ObjectTreeNode result; int usedLength; QThread *objThread = nullptr; - QSemaphore sem; - bool semWait; + QLatch latch(1); + bool latchWait; { QDBusReadLocker locker(HandleObjectCallAction, this); @@ -1569,16 +1570,16 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg) // synchronize with it postEventToThread(HandleObjectCallPostEventAction, result.obj, new QDBusActivateObjectEvent(QDBusConnection(this), this, result, - usedLength, msg, &sem)); - semWait = true; + usedLength, msg, &latch)); + latchWait = true; } else { // looped-back message, targeting current thread - semWait = false; + latchWait = false; } } // release the lock - if (semWait) - SEM_ACQUIRE(HandleObjectCallSemaphoreAction, sem); + if (latchWait) + latch.wait(); else activateObject(result, msg, usedLength); } diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h index 9c5fa1b061f..ac9adf02100 100644 --- a/src/dbus/qdbusintegrator_p.h +++ b/src/dbus/qdbusintegrator_p.h @@ -107,8 +107,8 @@ class QDBusActivateObjectEvent: public QAbstractMetaCallEvent public: QDBusActivateObjectEvent(const QDBusConnection &c, QObject *sender, const QDBusConnectionPrivate::ObjectTreeNode &n, - int p, const QDBusMessage &m, QSemaphore *s = nullptr) - : QAbstractMetaCallEvent(sender, -1, s), connection(c), node(n), + int p, const QDBusMessage &m, QLatch *l = nullptr) + : QAbstractMetaCallEvent(sender, -1, l), connection(c), node(n), pathStartPos(p), message(m), handled(false) { } ~QDBusActivateObjectEvent() override; diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h index a1d3a420ec6..bcbd1efb494 100644 --- a/src/dbus/qdbusthreaddebug_p.h +++ b/src/dbus/qdbusthreaddebug_p.h @@ -129,25 +129,5 @@ struct QDBusWriteLocker: QDBusLockerBase } }; -#if QDBUS_THREAD_DEBUG -# define SEM_ACQUIRE(action, sem) \ - do { \ - QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforeAcquire, this); \ - sem.acquire(); \ - QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterAcquire, this); \ - } while (false) - -# define SEM_RELEASE(action, sem) \ - do { \ - QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::BeforeRelease, that); \ - sem.release(); \ - QDBusLockerBase::reportThreadAction(action, QDBusLockerBase::AfterRelease, that); \ - } while (false) - -#else -# define SEM_ACQUIRE(action, sem) sem.acquire() -# define SEM_RELEASE(action, sem) sem.release() -#endif - #endif // QT_NO_DBUS #endif diff --git a/src/gui/accessible/linux/atspiadaptor.cpp b/src/gui/accessible/linux/atspiadaptor.cpp index 6154af00950..e0cd5aee25c 100644 --- a/src/gui/accessible/linux/atspiadaptor.cpp +++ b/src/gui/accessible/linux/atspiadaptor.cpp @@ -1462,9 +1462,12 @@ bool AtSpiAdaptor::handleMessage(const QDBusMessage &message, const QDBusConnect // handle properties like regular functions if (interface == "org.freedesktop.DBus.Properties"_L1) { - interface = message.arguments().at(0).toString(); - // Get/Set + Name - function = message.member() + message.arguments().at(1).toString(); + const auto arguments = message.arguments(); + if (arguments.size() > 0) { + interface = arguments.at(0).toString(); + if (arguments.size() > 1) // e.g. Get/Set + Name + function = function + arguments.at(1).toString(); + } } // switch interface to call diff --git a/src/gui/compat/removed_api.cpp b/src/gui/compat/removed_api.cpp index 34e64cd03e6..33549a06504 100644 --- a/src/gui/compat/removed_api.cpp +++ b/src/gui/compat/removed_api.cpp @@ -37,6 +37,10 @@ bool Qt::mightBeRichText(const QString& text) return Qt::mightBeRichText(qToStringViewIgnoringNull(text)); } +// #include "qotherheader.h" +// // implement removed functions from qotherheader.h +// order sections alphabetically + #endif // QT_GUI_REMOVED_SINCE(6, 7) #if QT_GUI_REMOVED_SINCE(6, 8) @@ -84,3 +88,16 @@ void QWindowSystemInterface::handleContextMenuEvent(QWindow *window, bool mouseT // order sections alphabetically #endif // QT_GUI_REMOVED_SINCE(6, 8) + +#if QT_GUI_REMOVED_SINCE(6, 11) + +#include "qpainter.h" // inlined API + +#include "qquaternion.h" // inlined API + + +// #include "qotherheader.h" +// // implement removed functions from qotherheader.h +// order sections alphabetically + +#endif // QT_GUI_REMOVED_SINCE(6, 11) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 1c4b2f205b7..8fa996c8689 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -144,7 +144,7 @@ void QIconPrivate::clearIconCache() /*! \internal Computes the displayDevicePixelRatio for a pixmap. - If displayDevicePixelRatio is 1.0 the reurned value is 1.0, always. + If displayDevicePixelRatio is 1.0 the returned value is 1.0, always. For a displayDevicePixelRatio of 2.0 the returned value will be between 1.0 and 2.0, depending on requestedSize and actualsize: @@ -161,8 +161,9 @@ qreal QIconPrivate::pixmapDevicePixelRatio(qreal displayDevicePixelRatio, const return displayDevicePixelRatio; } qreal scale = 0.5 * (qreal(actualSize.width()) / qreal(targetSize.width()) + - qreal(actualSize.height() / qreal(targetSize.height()))); - return qMax(qreal(1.0), displayDevicePixelRatio *scale); + qreal(actualSize.height()) / qreal(targetSize.height())); + qreal dpr = qMax(qreal(1.0), displayDevicePixelRatio * scale); + return qRound(dpr * 100) / 100.0; } QPixmapIconEngine::QPixmapIconEngine() diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 840bff26e53..1413e611270 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -38,7 +38,7 @@ #include <private/qfont_p.h> #if QT_CONFIG(qtgui_threadpool) -#include <qsemaphore.h> +#include <private/qlatch_p.h> #include <qthreadpool.h> #include <private/qthreadpool_p.h> #endif @@ -5342,17 +5342,17 @@ void QImage::applyColorTransform(const QColorTransform &transform) segments = std::min(segments, height()); QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) { - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (height() - y) / (segments - i); threadPool->start([&, y, yn]() { transformSegment(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); } else #endif transformSegment(0, height()); @@ -5832,17 +5832,17 @@ QImage QImage::colorTransformed(const QColorTransform &transform, QImage::Format segments = std::min(segments, height()); QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) { - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (height() - y) / (segments - i); threadPool->start([&, y, yn]() { transformSegment(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); } else #endif transformSegment(0, height()); diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 43f3cca09e0..521d71796ea 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -14,7 +14,7 @@ #include <qendian.h> #include <qrgbafloat.h> #if QT_CONFIG(thread) -#include <qsemaphore.h> +#include <private/qlatch_p.h> #include <qthreadpool.h> #include <private/qthreadpool_p.h> #endif @@ -215,17 +215,17 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio if (segments <= 1 || !threadPool || threadPool->contains(QThread::currentThread())) return convertSegment(0, src->height); - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (src->height - y) / (segments - i); threadPool->start([&, y, yn]() { convertSegment(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); #else convertSegment(0, src->height); #endif @@ -270,17 +270,17 @@ void convert_generic_over_rgb64(QImageData *dest, const QImageData *src, Qt::Ima if (segments <= 1 || !threadPool || threadPool->contains(QThread::currentThread())) return convertSegment(0, src->height); - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (src->height - y) / (segments - i); threadPool->start([&, y, yn]() { convertSegment(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); #else convertSegment(0, src->height); #endif @@ -324,17 +324,17 @@ void convert_generic_over_rgba32f(QImageData *dest, const QImageData *src, Qt::I if (segments <= 1 || !threadPool || threadPool->contains(QThread::currentThread())) return convertSegment(0, src->height); - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (src->height - y) / (segments - i); threadPool->start([&, y, yn]() { convertSegment(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); #else convertSegment(0, src->height); #endif @@ -435,17 +435,17 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im segments = std::min(segments, data->height); QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) { - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (data->height - y) / (segments - i); threadPool->start([&, y, yn]() { convertSegment(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); if (data->bytes_per_line != params.bytesPerLine) { // Compress segments to a continuous block y = 0; @@ -529,17 +529,17 @@ bool convert_generic_inplace_over_rgb64(QImageData *data, QImage::Format dst_for segments = std::min(segments, data->height); QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) { - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (data->height - y) / (segments - i); threadPool->start([&, y, yn]() { convertSegment(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); if (data->bytes_per_line != params.bytesPerLine) { // Compress segments to a continuous block y = 0; @@ -624,17 +624,17 @@ bool convert_generic_inplace_over_rgba32f(QImageData *data, QImage::Format dst_f segments = std::min(segments, data->height); QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) { - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (data->height - y) / (segments - i); threadPool->start([&, y, yn]() { convertSegment(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); if (data->bytes_per_line != params.bytesPerLine) { // Compress segments to a continuous block y = 0; diff --git a/src/gui/itemmodels/qfileinfogatherer.cpp b/src/gui/itemmodels/qfileinfogatherer.cpp index a0192c99828..df43f53050a 100644 --- a/src/gui/itemmodels/qfileinfogatherer.cpp +++ b/src/gui/itemmodels/qfileinfogatherer.cpp @@ -149,6 +149,8 @@ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStr while ((loc = this->path.lastIndexOf(path, loc - 1)) != -1) { if (this->files.at(loc) == files) return; + if (loc == 0) + break; } #if QT_CONFIG(thread) diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp index 1768cd8aa1a..f965a5a30e9 100644 --- a/src/gui/kernel/qaction.cpp +++ b/src/gui/kernel/qaction.cpp @@ -1325,4 +1325,6 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAction *action) QT_END_NAMESPACE +#undef QAPP_CHECK + #include "moc_qaction.cpp" diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 7e448aa6ae1..99b416d4fd5 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1396,9 +1396,9 @@ static void init_platform(const QString &pluginNamesWithArguments, const QString const qsizetype equalsPos = argument.indexOf(u'='); const QByteArray name = equalsPos != -1 ? argument.left(equalsPos).toUtf8() : argument.toUtf8(); - const QVariant value = + QVariant value = equalsPos != -1 ? QVariant(argument.mid(equalsPos + 1)) : QVariant(true); - nativeInterface->setProperty(name.constData(), value); + nativeInterface->setProperty(name.constData(), std::move(value)); } } } @@ -2106,7 +2106,9 @@ bool QGuiApplication::event(QEvent *e) */ bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents) { + QT_IGNORE_DEPRECATIONS( return QCoreApplication::compressEvent(event, receiver, postedEvents); + ) } #endif diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 0af6489428e..717b2e6e8cc 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -164,6 +164,7 @@ Q_SIGNALS: protected: bool event(QEvent *) override; # if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + QT_DEPRECATED_VERSION_X_6_10("This feature will be removed in Qt 7") bool compressEvent(QEvent *, QObject *receiver, QPostEventList *) override; # endif diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp index c6462dfed7b..6da0c4d387b 100644 --- a/src/gui/kernel/qguivariant.cpp +++ b/src/gui/kernel/qguivariant.cpp @@ -52,14 +52,13 @@ QT_BEGIN_NAMESPACE namespace { - -// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor): this is not a base class struct QVariantGuiHelper : QMetaTypeModuleHelper { #define QT_IMPL_METATYPEINTERFACE_GUI_TYPES(MetaTypeName, MetaTypeId, RealName) \ QT_METATYPE_INTERFACE_INIT(RealName), - const QtPrivate::QMetaTypeInterface *interfaceForType(int type) const override { + static const QtPrivate::QMetaTypeInterface *interfaceForType(int type) + { switch (type) { QT_FOR_EACH_STATIC_GUI_CLASS(QT_METATYPE_CONVERT_ID_TO_TYPE) default: return nullptr; @@ -67,7 +66,7 @@ struct QVariantGuiHelper : QMetaTypeModuleHelper } #undef QT_IMPL_METATYPEINTERFACE_GUI_TYPES - bool convert(const void *from, int fromTypeId, void *to, int toTypeId) const override + static bool convert(const void *from, int fromTypeId, void *to, int toTypeId) { Q_ASSERT(fromTypeId != toTypeId); @@ -133,14 +132,14 @@ struct QVariantGuiHelper : QMetaTypeModuleHelper return false; } }; - -static constexpr QVariantGuiHelper qVariantGuiHelper; - } // namespace used to hide QVariant handler void qRegisterGuiVariant() { - qMetaTypeGuiHelper = &qVariantGuiHelper; + qMetaTypeGuiHelper = QMetaTypeModuleHelper{ + &QVariantGuiHelper::interfaceForType, + &QVariantGuiHelper::convert, + }; } Q_CONSTRUCTOR_FUNCTION(qRegisterGuiVariant) diff --git a/src/gui/kernel/qplatformwindow_p.h b/src/gui/kernel/qplatformwindow_p.h index 5ee14c90e8a..c446ac760c0 100644 --- a/src/gui/kernel/qplatformwindow_p.h +++ b/src/gui/kernel/qplatformwindow_p.h @@ -135,6 +135,7 @@ public: auto role = std::any_cast<T *>(&anyRole); return role ? *role : nullptr; } + virtual void setSessionRestoreId(const QString &role) = 0; Q_SIGNALS: void surfaceCreated(); void surfaceDestroyed(); diff --git a/src/gui/kernel/qshortcut.cpp b/src/gui/kernel/qshortcut.cpp index 3f6822cb031..e730b5f9e8b 100644 --- a/src/gui/kernel/qshortcut.cpp +++ b/src/gui/kernel/qshortcut.cpp @@ -577,4 +577,6 @@ bool QShortcut::event(QEvent *e) QT_END_NAMESPACE +#undef QAPP_CHECK + #include "moc_qshortcut.cpp" diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index e7c59452085..99061fb7163 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -336,6 +336,9 @@ QVector3D QQuaternion::rotatedVector(const QVector3D &vector) const Extracts a 3D axis \a axis and a rotating angle \a angle (in degrees) that corresponds to this quaternion. + Both \a axis and \a angle must be valid, non-\nullptr pointers, + otherwise the behavior is undefined. + \sa fromAxisAndAngle() */ @@ -366,6 +369,9 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D &axis, float angle) Extracts a 3D axis (\a x, \a y, \a z) and a rotating angle \a angle (in degrees) that corresponds to this quaternion. + All of \a x, \a y, \a z, and \a angle must be valid, non-\nullptr pointers, + otherwise the behavior is undefined. + \sa fromAxisAndAngle() */ void QQuaternion::getAxisAndAngle(float *x, float *y, float *z, float *angle) const @@ -419,22 +425,22 @@ QQuaternion QQuaternion::fromAxisAndAngle /*! \fn QVector3D QQuaternion::toEulerAngles() const \since 5.5 - \overload Calculates roll, pitch, and yaw Euler angles (in degrees) - that corresponds to this quaternion. + that correspond to this quaternion. \sa fromEulerAngles() */ /*! - \fn QQuaternion QQuaternion::fromEulerAngles(const QVector3D &eulerAngles) + \fn QQuaternion QQuaternion::fromEulerAngles(const QVector3D &angles) \since 5.5 \overload - Creates a quaternion that corresponds to a rotation of \a eulerAngles: - eulerAngles.z() degrees around the z axis, eulerAngles.x() degrees around the x axis, - and eulerAngles.y() degrees around the y axis (in that order). + Creates a quaternion that corresponds to a rotation of \a angles: + angles.\l{QVector3D::}{z()} degrees around the z axis, + angles.\l{QVector3D::}{x()} degrees around the x axis, and + angles.\l{QVector3D::}{y()} degrees around the y axis (in that order). \sa toEulerAngles() */ @@ -447,6 +453,9 @@ QQuaternion QQuaternion::fromAxisAndAngle Calculates \a roll, \a pitch, and \a yaw Euler angles (in degrees) that corresponds to this quaternion. + All of \a pitch, \a yaw, and \a roll must be valid, non-\nullptr pointers, + otherwise the behavior is undefined. + \sa fromEulerAngles() */ void QQuaternion::getEulerAngles(float *pitch, float *yaw, float *roll) const @@ -548,7 +557,7 @@ QQuaternion QQuaternion::fromEulerAngles(float pitch, float yaw, float roll) \note If this quaternion is not normalized, the resulting rotation matrix will contain scaling information. - \sa fromRotationMatrix(), getAxes() + \sa fromRotationMatrix(), toAxes() */ QMatrix3x3 QQuaternion::toRotationMatrix() const { @@ -586,9 +595,9 @@ QMatrix3x3 QQuaternion::toRotationMatrix() const /*! \since 5.5 - Creates a quaternion that corresponds to a rotation matrix \a rot3x3. + Creates a quaternion that corresponds to the rotation matrix \a rot3x3. - \note If a given rotation matrix is not normalized, + \note If the given rotation matrix is not normalized, the resulting quaternion will contain scaling information. \sa toRotationMatrix(), fromAxes() @@ -609,7 +618,7 @@ QQuaternion QQuaternion::fromRotationMatrix(const QMatrix3x3 &rot3x3) axis[1] = (rot3x3(0, 2) - rot3x3(2, 0)) / s; axis[2] = (rot3x3(1, 0) - rot3x3(0, 1)) / s; } else { - static int s_next[3] = { 1, 2, 0 }; + constexpr int s_next[3] = { 1, 2, 0 }; int i = 0; if (rot3x3(1, 1) > rot3x3(0, 0)) i = 1; @@ -631,23 +640,71 @@ QQuaternion QQuaternion::fromRotationMatrix(const QMatrix3x3 &rot3x3) #ifndef QT_NO_VECTOR3D /*! - \since 5.5 + \since 6.11 + \class QQuaternion::Axes + \ingroup painting-3D + \inmodule QtGui - Returns the 3 orthonormal axes (\a xAxis, \a yAxis, \a zAxis) defining the quaternion. + A struct containing the three orthonormal axes that define a + \l{QQuaternion}{quaternion}. - \sa fromAxes(), toRotationMatrix() + + \sa QQuaternion::toAxes(), QQuaternion::fromAxes(Axes) +*/ + +/*! + \variable QQuaternion::Axes::x + + The x orthonormal axis that, together with \l{y} and \l{z}, defines a + quaternion. +*/ + +/*! + \variable QQuaternion::Axes::y + + The y orthonormal axis that, together with \l{x} and \l{z}, defines a + quaternion. +*/ + +/*! + \variable QQuaternion::Axes::z + + The z orthonormal axis that, together with \l{x} and \l{y}, defines a + quaternion. */ -void QQuaternion::getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const -{ - Q_ASSERT(xAxis && yAxis && zAxis); +/*! + \since 6.11 + + Returns the three orthonormal axes that define this quaternion. + + \sa QQuaternion::Axes, fromAxes(QQuaternion::Axes), toRotationMatrix() +*/ +auto QQuaternion::toAxes() const -> Axes +{ const QMatrix3x3 rot3x3(toRotationMatrix()); - *xAxis = QVector3D(rot3x3(0, 0), rot3x3(1, 0), rot3x3(2, 0)); - *yAxis = QVector3D(rot3x3(0, 1), rot3x3(1, 1), rot3x3(2, 1)); - *zAxis = QVector3D(rot3x3(0, 2), rot3x3(1, 2), rot3x3(2, 2)); + return { {rot3x3(0, 0), rot3x3(1, 0), rot3x3(2, 0)}, + {rot3x3(0, 1), rot3x3(1, 1), rot3x3(2, 1)}, + {rot3x3(0, 2), rot3x3(1, 2), rot3x3(2, 2)} }; } + +/*! + \fn void QQuaternion::getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const + \since 5.5 + + \obsolete + Use toAxes() instead. + + Returns the 3 orthonormal axes (\a xAxis, \a yAxis, \a zAxis) defining the quaternion. + + All of \a xAxis, \a yAxis, and \a zAxis must be valid, non-\nullptr pointers, + otherwise the behavior is undefined. + + \sa fromAxes(), toRotationMatrix() +*/ + /*! \since 5.5 @@ -655,7 +712,7 @@ void QQuaternion::getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) \note The axes are assumed to be orthonormal. - \sa getAxes(), fromRotationMatrix() + \sa toAxes(), fromRotationMatrix() */ QQuaternion QQuaternion::fromAxes(const QVector3D &xAxis, const QVector3D &yAxis, const QVector3D &zAxis) { @@ -674,6 +731,17 @@ QQuaternion QQuaternion::fromAxes(const QVector3D &xAxis, const QVector3D &yAxis } /*! + \since 6.11 + \overload + + \sa toAxes(), fromRotationMatrix() +*/ +QQuaternion QQuaternion::fromAxes(Axes axes) // clazy:exclude=function-args-by-ref +{ + return fromAxes(axes.x, axes.y, axes.z); +} + +/*! \since 5.5 Constructs the quaternion using specified forward direction \a direction diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index 7cfbd9b818d..ffc95a852ce 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -109,7 +109,7 @@ QT_WARNING_POP #ifndef QT_NO_VECTOR3D inline QVector3D toEulerAngles() const; - QT7_ONLY(Q_GUI_EXPORT) static inline QQuaternion fromEulerAngles(const QVector3D &eulerAngles); + static inline QQuaternion fromEulerAngles(const QVector3D &angles); #endif QT7_ONLY(Q_GUI_EXPORT) void getEulerAngles(float *pitch, float *yaw, float *roll) const; QT7_ONLY(Q_GUI_EXPORT) static QQuaternion fromEulerAngles(float pitch, float yaw, float roll); @@ -118,7 +118,14 @@ QT_WARNING_POP QT7_ONLY(Q_GUI_EXPORT) static QQuaternion fromRotationMatrix(const QMatrix3x3 &rot3x3); #ifndef QT_NO_VECTOR3D - QT7_ONLY(Q_GUI_EXPORT) void getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const; + struct Axes + { + QVector3D x, y, z; + }; + QT7_ONLY(Q_GUI_EXPORT) Axes toAxes() const; + QT7_ONLY(Q_GUI_EXPORT) static QQuaternion fromAxes(Axes axes); // clazy:exclude=function-args-by-ref + QT_GUI_INLINE_SINCE(6, 11) + void getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const; QT7_ONLY(Q_GUI_EXPORT) static QQuaternion fromAxes(const QVector3D &xAxis, const QVector3D &yAxis, const QVector3D &zAxis); @@ -128,7 +135,7 @@ QT_WARNING_POP QT7_ONLY(Q_GUI_EXPORT) static QQuaternion rotationTo(const QVector3D &from, const QVector3D &to); -#endif +#endif // QT_NO_VECTOR3D QT7_ONLY(Q_GUI_EXPORT) static QQuaternion slerp(const QQuaternion &q1, const QQuaternion &q2, float t); @@ -311,26 +318,39 @@ inline QVector3D operator*(const QQuaternion &quaternion, const QVector3D &vec) return quaternion.rotatedVector(vec); } -inline void QQuaternion::getAxisAndAngle(QVector3D *axis, float *angle) const +void QQuaternion::getAxisAndAngle(QVector3D *axis, float *angle) const { float aX, aY, aZ; getAxisAndAngle(&aX, &aY, &aZ, angle); *axis = QVector3D(aX, aY, aZ); } -inline QVector3D QQuaternion::toEulerAngles() const +QVector3D QQuaternion::toEulerAngles() const { float pitch, yaw, roll; getEulerAngles(&pitch, &yaw, &roll); return QVector3D(pitch, yaw, roll); } -inline QQuaternion QQuaternion::fromEulerAngles(const QVector3D &eulerAngles) +QQuaternion QQuaternion::fromEulerAngles(const QVector3D &angles) { - return QQuaternion::fromEulerAngles(eulerAngles.x(), eulerAngles.y(), eulerAngles.z()); + return QQuaternion::fromEulerAngles(angles.x(), angles.y(), angles.z()); } -#endif +#if QT_GUI_INLINE_IMPL_SINCE(6, 11) +void QQuaternion::getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const +{ + Q_PRE(xAxis); + Q_PRE(yAxis); + Q_PRE(zAxis); + const Axes axes = toAxes(); + *xAxis = axes.x; + *yAxis = axes.y; + *zAxis = axes.z; +} +#endif // QT_GUI_INLINE_IMPL_SINCE(6, 11) + +#endif // QT_NO_VECTOR3D constexpr void QQuaternion::setVector(float aX, float aY, float aZ) noexcept { @@ -349,7 +369,7 @@ constexpr QVector4D QQuaternion::toVector4D() const noexcept return QVector4D(xp, yp, zp, wp); } -#endif +#endif // QT_NO_VECTOR4D #ifndef QT_NO_DEBUG_STREAM Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QQuaternion &q); @@ -360,8 +380,8 @@ Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QQuaternion &); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QQuaternion &); #endif -#endif +#endif // QT_NO_QUATERNION QT_END_NAMESPACE -#endif +#endif // QQUATERNION_H diff --git a/src/gui/painting/qcolortransfergeneric_p.h b/src/gui/painting/qcolortransfergeneric_p.h index 6caebceb1a4..c2ebd937a44 100644 --- a/src/gui/painting/qcolortransfergeneric_p.h +++ b/src/gui/painting/qcolortransfergeneric_p.h @@ -65,6 +65,7 @@ private: // HLG from linear [0-12] -> [0-1] static float hlgFromLinear(float x) { + x = std::clamp(x, 0.f, 12.f); if (x > 1.f) return m_hlg_a * std::log(x - m_hlg_b) + m_hlg_c; return std::sqrt(x * 0.25f); @@ -73,6 +74,7 @@ private: // HLG to linear [0-1] -> [0-12] static float hlgToLinear(float x) { + x = std::clamp(x, 0.f, 1.f); if (x < 0.5f) return (x * x) * 4.f; return std::exp((x - m_hlg_c) / m_hlg_a) + m_hlg_b; @@ -86,6 +88,7 @@ private: // PQ to linear [0-1] -> [0-64] static float pqToLinear(float e) { + e = std::clamp(e, 0.f, 1.f); // m2-th root of E' const float eRoot = std::pow(e, 1.f / m_pq_m2); // rational transform @@ -99,6 +102,7 @@ private: // PQ from linear [0-64] -> [0-1] static float pqFromLinear(float fd) { + fd = std::clamp(fd, 0.f, 64.f); // scale Fd to Y const float y = fd * (1.f / m_pq_f); // yRoot = Y^m1 -- "root" because m1 is <1 diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h index c7474dc57a3..4872853514b 100644 --- a/src/gui/painting/qdatabuffer_p.h +++ b/src/gui/painting/qdatabuffer_p.h @@ -87,8 +87,9 @@ public: capacity = 1; while (capacity < size) capacity *= 2; - buffer = (Type*) QtPrivate::fittedRealloc(static_cast<void*>(buffer), 0, &capacity, sizeof(Type)); - Q_CHECK_PTR(buffer); + auto ptr = QtPrivate::fittedRealloc(static_cast<void*>(buffer), 0, &capacity, sizeof(Type)); + Q_CHECK_PTR(ptr); + buffer = static_cast<Type*>(ptr); } } @@ -96,8 +97,9 @@ public: Q_ASSERT(capacity >= size); if (size) { capacity = size; - buffer = (Type*) QtPrivate::fittedRealloc(static_cast<void*>(buffer), 0, &capacity, sizeof(Type)); - Q_CHECK_PTR(buffer); + const auto ptr = QtPrivate::fittedRealloc(static_cast<void*>(buffer), 0, &capacity, sizeof(Type)); + Q_CHECK_PTR(ptr); + buffer = static_cast<Type*>(ptr); siz = std::min(siz, size); } else { QtPrivate::sizedFree(buffer, capacity, sizeof(Type)); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 8aefba86ee7..b109e9a5a20 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -28,7 +28,7 @@ #include <qmath.h> #if QT_CONFIG(qtgui_threadpool) -#include <qsemaphore.h> +#include <private/qlatch_p.h> #include <qthreadpool.h> #include <private/qthreadpool_p.h> #endif @@ -3970,17 +3970,17 @@ static void spanfill_from_first(QRasterBuffer *rasterBuffer, QPixelLayout::BPP b QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); \ if (segments > 1 && qPixelLayouts[data->rasterBuffer->format].bpp >= QPixelLayout::BPP8 \ && threadPool && !threadPool->contains(QThread::currentThread())) { \ - QSemaphore semaphore; \ + QLatch latch(segments); \ int c = 0; \ for (int i = 0; i < segments; ++i) { \ int cn = (count - c) / (segments - i); \ threadPool->start([&, c, cn]() { \ function(c, c + cn); \ - semaphore.release(1); \ + latch.countDown(); \ }, 1); \ c += cn; \ } \ - semaphore.acquire(segments); \ + latch.wait(); \ } else \ function(0, count) #else diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 1bbfcf07a0a..15ef5f57dc7 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -11,7 +11,7 @@ #include "qrgbafloat.h" #if QT_CONFIG(qtgui_threadpool) -#include <qsemaphore.h> +#include <private/qlatch_p.h> #include <qthreadpool.h> #include <private/qguiapplication_p.h> #include <private/qthreadpool_p.h> @@ -290,17 +290,17 @@ static inline void multithread_pixels_function(QImageScaleInfo *isi, int dh, con segments = std::min(segments, dh); QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) { - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (dh - y) / (segments - i); threadPool->start([&, y, yn]() { scaleSection(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); return; } #else diff --git a/src/gui/painting/qimagescale_neon.cpp b/src/gui/painting/qimagescale_neon.cpp index 1fc1070dc0d..81e04e8f082 100644 --- a/src/gui/painting/qimagescale_neon.cpp +++ b/src/gui/painting/qimagescale_neon.cpp @@ -7,7 +7,7 @@ #include <private/qsimd_p.h> #if QT_CONFIG(qtgui_threadpool) -#include <qsemaphore.h> +#include <private/qlatch_p.h> #include <qthreadpool.h> #include <private/qguiapplication_p.h> #include <private/qthreadpool_p.h> @@ -27,17 +27,17 @@ static inline void multithread_pixels_function(QImageScaleInfo *isi, int dh, con segments = std::min(segments, dh); QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) { - QSemaphore semaphore; + QLatch semaphore(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (dh - y) / (segments - i); threadPool->start([&, y, yn]() { scaleSection(y, y + yn); - semaphore.release(1); + semaphore.countDown(); }); y += yn; } - semaphore.acquire(segments); + semaphore.wait(); return; } #endif diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp index 5d4c3a4e7c2..740f1570345 100644 --- a/src/gui/painting/qimagescale_sse4.cpp +++ b/src/gui/painting/qimagescale_sse4.cpp @@ -7,7 +7,7 @@ #include <private/qsimd_p.h> #if QT_CONFIG(qtgui_threadpool) -#include <qsemaphore.h> +#include <private/qlatch_p.h> #include <qthreadpool.h> #include <private/qguiapplication_p.h> #include <private/qthreadpool_p.h> @@ -27,17 +27,17 @@ static inline void multithread_pixels_function(QImageScaleInfo *isi, int dh, con segments = std::min(segments, dh); QThreadPool *threadPool = QGuiApplicationPrivate::qtGuiThreadPool(); if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) { - QSemaphore semaphore; + QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (dh - y) / (segments - i); threadPool->start([&, y, yn]() { scaleSection(y, y + yn); - semaphore.release(1); + latch.countDown(); }); y += yn; } - semaphore.acquire(segments); + latch.wait(); return; } #endif diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index d436afc5c77..1a60afbdd8e 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -361,7 +361,7 @@ inline void QClipData::appendSpan(int x, int length, int y, int coverage) if (count == allocated) { allocated *= 2; - m_spans = (QT_FT_Span *)realloc(m_spans, allocated*sizeof(QT_FT_Span)); + m_spans = static_cast<QT_FT_Span*>(q_check_ptr(realloc(m_spans, allocated * sizeof(QT_FT_Span)))); } m_spans[count].x = x; m_spans[count].len = length; @@ -378,7 +378,7 @@ inline void QClipData::appendSpans(const QT_FT_Span *s, int num) do { allocated *= 2; } while (count + num > allocated); - m_spans = (QT_FT_Span *)realloc(m_spans, allocated*sizeof(QT_FT_Span)); + m_spans = static_cast<QT_FT_Span*>(q_check_ptr(realloc(m_spans, allocated * sizeof(QT_FT_Span)))); } memcpy(m_spans+count, s, num*sizeof(QT_FT_Span)); count += num; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index b800952ae39..344bb8f1bef 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -41,6 +41,8 @@ #include <private/qrawfont_p.h> #include <private/qfont_p.h> +#include <QtCore/private/qtclasshelper_p.h> + QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; @@ -53,7 +55,7 @@ static_assert(sizeof(QScopedPointer<QPainterPrivate>) == sizeof(std::unique_ptr< // #define QT_DEBUG_DRAW #ifdef QT_DEBUG_DRAW -bool qt_show_painter_debug_output = true; +constexpr bool qt_show_painter_debug_output = true; #endif extern QPixmap qt_pixmapForBrush(int style, bool invert); @@ -316,7 +318,7 @@ void QPainterPrivate::detachPainterPrivate(QPainter *q) void QPainterPrivate::draw_helper(const QPainterPath &originalPath, DrawOperation op) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) { + if constexpr (qt_show_painter_debug_output) { printf("QPainter::drawHelper\n"); } #endif @@ -1546,7 +1548,7 @@ void QPainterPrivate::initFrom(const QPaintDevice *device) void QPainter::save() { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::save()\n"); #endif Q_D(QPainter); @@ -1580,7 +1582,7 @@ void QPainter::save() void QPainter::restore() { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::restore()\n"); #endif Q_D(QPainter); @@ -1702,7 +1704,7 @@ bool QPainter::begin(QPaintDevice *pd) pd = rpd; #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::begin(), device=%p, type=%d\n", pd, pd->devType()); #endif @@ -1848,7 +1850,7 @@ bool QPainter::begin(QPaintDevice *pd) bool QPainter::end() { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::end()\n"); #endif Q_D(QPainter); @@ -2057,7 +2059,8 @@ void QPainter::setOpacity(qreal opacity) /*! - Returns the currently set brush origin. + Returns the current brush origin. + Prefer using QPainter::brushOriginF() to get the precise origin. \sa setBrushOrigin(), {QPainter#Settings}{Settings} */ @@ -2073,6 +2076,23 @@ QPoint QPainter::brushOrigin() const } /*! + Returns the current brush origin. + + \sa setBrushOrigin(), {QPainter#Settings}{Settings} + \since 6.11 +*/ + +QPointF QPainter::brushOriginF() const +{ + Q_D(const QPainter); + if (!d->engine) { + qWarning("QPainter::brushOrigin: Painter not active"); + return QPointF(); + } + return d->state->brushOrigin; +} + +/*! \fn void QPainter::setBrushOrigin(const QPointF &position) Sets the brush origin to \a position. @@ -2094,7 +2114,7 @@ void QPainter::setBrushOrigin(const QPointF &p) { Q_D(QPainter); #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setBrushOrigin(), (%.2f,%.2f)\n", p.x(), p.y()); #endif @@ -2422,7 +2442,7 @@ void QPainter::setClipping(bool enable) { Q_D(QPainter); #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setClipping(), enable=%s, was=%s\n", enable ? "on" : "off", hasClipping() ? "on" : "off"); @@ -2801,7 +2821,7 @@ void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op) Q_D(QPainter); #ifdef QT_DEBUG_DRAW QRect rect = r.boundingRect(); - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setClipRegion(), size=%d, [%d,%d,%d,%d]\n", r.rectCount(), rect.x(), rect.y(), rect.width(), rect.height()); #endif @@ -2852,7 +2872,7 @@ void QPainter::setWorldMatrixEnabled(bool enable) { Q_D(QPainter); #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setMatrixEnabled(), enable=%d\n", enable); #endif @@ -2895,7 +2915,7 @@ bool QPainter::worldMatrixEnabled() const void QPainter::scale(qreal sx, qreal sy) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::scale(), sx=%f, sy=%f\n", sx, sy); #endif Q_D(QPainter); @@ -2918,7 +2938,7 @@ void QPainter::scale(qreal sx, qreal sy) void QPainter::shear(qreal sh, qreal sv) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::shear(), sh=%f, sv=%f\n", sh, sv); #endif Q_D(QPainter); @@ -2943,7 +2963,7 @@ void QPainter::shear(qreal sh, qreal sv) void QPainter::rotate(qreal a) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::rotate(), angle=%f\n", a); #endif Q_D(QPainter); @@ -2968,7 +2988,7 @@ void QPainter::translate(const QPointF &offset) qreal dx = offset.x(); qreal dy = offset.y(); #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::translate(), dx=%f, dy=%f\n", dx, dy); #endif Q_D(QPainter); @@ -3011,7 +3031,7 @@ void QPainter::translate(const QPointF &offset) void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) { + if constexpr (qt_show_painter_debug_output) { QRectF b = path.boundingRect(); printf("QPainter::setClipPath(), size=%d, op=%d, bounds=[%.2f,%.2f,%.2f,%.2f]\n", path.elementCount(), op, b.x(), b.y(), b.width(), b.height()); @@ -3145,7 +3165,7 @@ void QPainter::drawPath(const QPainterPath &path) { #ifdef QT_DEBUG_DRAW QRectF pathBounds = path.boundingRect(); - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPath(), size=%d, [%.2f,%.2f,%.2f,%.2f]\n", path.elementCount(), pathBounds.x(), pathBounds.y(), pathBounds.width(), pathBounds.height()); @@ -3260,7 +3280,7 @@ void QPainter::drawPath(const QPainterPath &path) void QPainter::drawRects(const QRectF *rects, int rectCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawRects(), count=%d\n", rectCount); #endif Q_D(QPainter); @@ -3320,7 +3340,7 @@ void QPainter::drawRects(const QRectF *rects, int rectCount) void QPainter::drawRects(const QRect *rects, int rectCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawRects(), count=%d\n", rectCount); #endif Q_D(QPainter); @@ -3420,7 +3440,7 @@ void QPainter::drawRects(const QRect *rects, int rectCount) void QPainter::drawPoints(const QPointF *points, int pointCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPoints(), count=%d\n", pointCount); #endif Q_D(QPainter); @@ -3482,7 +3502,7 @@ void QPainter::drawPoints(const QPointF *points, int pointCount) void QPainter::drawPoints(const QPoint *points, int pointCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPoints(), count=%d\n", pointCount); #endif Q_D(QPainter); @@ -3567,7 +3587,7 @@ void QPainter::drawPoints(const QPoint *points, int pointCount) void QPainter::setBackgroundMode(Qt::BGMode mode) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setBackgroundMode(), mode=%d\n", mode); #endif @@ -3613,7 +3633,7 @@ Qt::BGMode QPainter::backgroundMode() const void QPainter::setPen(const QColor &color) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setPen(), color=%04x\n", color.rgb()); #endif Q_D(QPainter); @@ -3634,6 +3654,8 @@ void QPainter::setPen(const QColor &color) } /*! + \fn void QPainter::setPen(const QPen &pen) + Sets the painter's pen to be the given \a pen. The \a pen defines how to draw lines and outlines, and it also @@ -3642,11 +3664,17 @@ void QPainter::setPen(const QColor &color) \sa pen(), {QPainter#Settings}{Settings} */ -void QPainter::setPen(const QPen &pen) +/*! + \fn void QPainter::setPen(QPen &&pen) + \since 6.11 + \overload +*/ + +void QPainter::doSetPen(const QPen &pen, QPen *rvalue) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setPen(), color=%04x, (brushStyle=%d) style=%d, cap=%d, join=%d\n", pen.color().rgb(), pen.brush().style(), pen.style(), pen.capStyle(), pen.joinStyle()); #endif @@ -3659,7 +3687,7 @@ void QPainter::setPen(const QPen &pen) if (d->state->pen == pen) return; - d->state->pen = pen; + q_choose_assign(d->state->pen, pen, rvalue); if (d->extended) { d->checkEmulation(); @@ -3715,6 +3743,8 @@ const QPen &QPainter::pen() const /*! + \fn void QPainter::setBrush(const QBrush &brush) + Sets the painter's brush to the given \a brush. The painter's brush defines how shapes are filled. @@ -3722,10 +3752,16 @@ const QPen &QPainter::pen() const \sa brush(), {QPainter#Settings}{Settings} */ -void QPainter::setBrush(const QBrush &brush) +/*! + \fn void QPainter::setBrush(QBrush &&brush) + \since 6.11 + \overload +*/ + +void QPainter::doSetBrush(const QBrush &brush, QBrush *rvalue) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setBrush(), color=%04x, style=%d\n", brush.color().rgb(), brush.style()); #endif Q_D(QPainter); @@ -3738,13 +3774,13 @@ void QPainter::setBrush(const QBrush &brush) return; if (d->extended) { - d->state->brush = brush; + q_choose_assign(d->state->brush, brush, rvalue); d->checkEmulation(); d->extended->brushChanged(); return; } - d->state->brush = brush; + q_choose_assign(d->state->brush, brush, rvalue); d->state->dirtyFlags |= QPaintEngine::DirtyBrush; } @@ -3840,7 +3876,7 @@ const QBrush &QPainter::brush() const void QPainter::setBackground(const QBrush &bg) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setBackground(), color=%04x, style=%d\n", bg.color().rgb(), bg.style()); #endif @@ -3872,7 +3908,7 @@ void QPainter::setFont(const QFont &font) Q_D(QPainter); #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setFont(), family=%s, pointSize=%d\n", font.families().first().toLatin1().constData(), font.pointSize()); #endif @@ -3928,7 +3964,7 @@ const QFont &QPainter::font() const void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawRoundedRect(), [%.2f,%.2f,%.2f,%.2f]\n", rect.x(), rect.y(), rect.width(), rect.height()); #endif Q_D(QPainter); @@ -3992,7 +4028,7 @@ void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, void QPainter::drawEllipse(const QRectF &r) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawEllipse(), [%.2f,%.2f,%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height()); #endif Q_D(QPainter); @@ -4035,7 +4071,7 @@ void QPainter::drawEllipse(const QRectF &r) void QPainter::drawEllipse(const QRect &r) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawEllipse(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height()); #endif Q_D(QPainter); @@ -4123,7 +4159,7 @@ void QPainter::drawEllipse(const QRect &r) void QPainter::drawArc(const QRectF &r, int a, int alen) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawArc(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n", r.x(), r.y(), r.width(), r.height(), a/16, alen/16); #endif @@ -4187,7 +4223,7 @@ void QPainter::drawArc(const QRectF &r, int a, int alen) void QPainter::drawPie(const QRectF &r, int a, int alen) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPie(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n", r.x(), r.y(), r.width(), r.height(), a/16, alen/16); #endif @@ -4258,7 +4294,7 @@ void QPainter::drawPie(const QRectF &r, int a, int alen) void QPainter::drawChord(const QRectF &r, int a, int alen) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawChord(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n", r.x(), r.y(), r.width(), r.height(), a/16, alen/16); #endif @@ -4307,7 +4343,7 @@ void QPainter::drawChord(const QRectF &r, int a, int alen) void QPainter::drawLines(const QLineF *lines, int lineCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawLines(), line count=%d\n", lineCount); #endif @@ -4356,7 +4392,7 @@ void QPainter::drawLines(const QLineF *lines, int lineCount) void QPainter::drawLines(const QLine *lines, int lineCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawLine(), line count=%d\n", lineCount); #endif @@ -4475,7 +4511,7 @@ void QPainter::drawLines(const QPoint *pointPairs, int lineCount) void QPainter::drawPolyline(const QPointF *points, int pointCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPolyline(), count=%d\n", pointCount); #endif Q_D(QPainter); @@ -4516,7 +4552,7 @@ void QPainter::drawPolyline(const QPointF *points, int pointCount) void QPainter::drawPolyline(const QPoint *points, int pointCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPolyline(), count=%d\n", pointCount); #endif Q_D(QPainter); @@ -4591,7 +4627,7 @@ void QPainter::drawPolyline(const QPoint *points, int pointCount) void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPolygon(), count=%d\n", pointCount); #endif @@ -4630,7 +4666,7 @@ void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule f void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPolygon(), count=%d\n", pointCount); #endif @@ -4729,7 +4765,7 @@ void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fi void QPainter::drawConvexPolygon(const QPoint *points, int pointCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount); #endif @@ -4763,7 +4799,7 @@ void QPainter::drawConvexPolygon(const QPoint *points, int pointCount) void QPainter::drawConvexPolygon(const QPointF *points, int pointCount) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount); #endif @@ -4827,7 +4863,7 @@ static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransfor void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm) { #if defined QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPixmap(), p=[%.2f,%.2f], pix=[%d,%d]\n", p.x(), p.y(), pm.width(), pm.height()); @@ -4899,7 +4935,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm) void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) { #if defined QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], source=[%.2f,%.2f,%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height(), pm.width(), pm.height(), @@ -5619,7 +5655,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justificationPadding) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawText(), pos=[%.2f,%.2f], str='%s'\n", p.x(), p.y(), str.toLatin1().constData()); #endif @@ -5684,7 +5720,7 @@ void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justif void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawText(), r=[%d,%d,%d,%d], flags=%d, str='%s'\n", r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData()); #endif @@ -5771,7 +5807,7 @@ void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *br) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], flags=%d, str='%s'\n", r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData()); #endif @@ -5890,7 +5926,7 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], str='%s'\n", r.x(), r.y(), r.width(), r.height(), text.toLatin1().constData()); #endif @@ -6149,7 +6185,7 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti) void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QTextEngine *textEngine) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawTextItem(), pos=[%.f,%.f], str='%s'\n", p.x(), p.y(), qPrintable(_ti.text())); #endif @@ -6430,7 +6466,7 @@ QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextO void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sp) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::drawTiledPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], offset=[%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height(), pixmap.width(), pixmap.height(), @@ -6881,7 +6917,7 @@ void QPainter::fillRect(const QRectF &r, const QColor &color) void QPainter::setRenderHint(RenderHint hint, bool on) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setRenderHint: hint=%x, %s\n", hint, on ? "on" : "off"); #endif @@ -6994,7 +7030,7 @@ bool QPainter::viewTransformEnabled() const void QPainter::setWindow(const QRect &r) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setWindow(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height()); #endif @@ -7058,7 +7094,7 @@ QRect QPainter::window() const void QPainter::setViewport(const QRect &r) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setViewport(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height()); #endif @@ -7105,7 +7141,7 @@ QRect QPainter::viewport() const void QPainter::setViewTransformEnabled(bool enable) { #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::setViewTransformEnabled(), enable=%d\n", enable); #endif @@ -7957,7 +7993,7 @@ void QPainter::resetTransform() { Q_D(QPainter); #ifdef QT_DEBUG_DRAW - if (qt_show_painter_debug_output) + if constexpr (qt_show_painter_debug_output) printf("QPainter::resetMatrix()\n"); #endif if (!d->engine) { diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 7d4179fd43c..83bde3b8cad 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -150,11 +150,15 @@ public: QFontInfo fontInfo() const; void setPen(const QColor &color); + QT_GUI_INLINE_SINCE(6, 11) void setPen(const QPen &pen); + void setPen(QPen &&pen) { doSetPen(pen, &pen); } void setPen(Qt::PenStyle style); const QPen &pen() const; + QT_GUI_INLINE_SINCE(6, 11) void setBrush(const QBrush &brush); + void setBrush(QBrush &&brush) { doSetBrush(brush, &brush); } void setBrush(Qt::BrushStyle style); void setBrush(QColor color); void setBrush(Qt::GlobalColor color) { setBrush(QColor(color)); } @@ -165,6 +169,7 @@ public: Qt::BGMode backgroundMode() const; QPoint brushOrigin() const; + QPointF brushOriginF() const; inline void setBrushOrigin(int x, int y); inline void setBrushOrigin(const QPoint &); void setBrushOrigin(const QPointF &); @@ -418,6 +423,9 @@ public: private: Q_DISABLE_COPY(QPainter) + void doSetPen(const QPen &lvalue, QPen *rvalue); + void doSetBrush(const QBrush &lvalue, QBrush *rvalue); + std::unique_ptr<QPainterPrivate> d_ptr; friend class QWidget; @@ -699,6 +707,21 @@ inline void QPainter::fillRect(const QRectF &r, QGradient::Preset p) fillRect(r, QGradient(p)); } +#if QT_GUI_INLINE_IMPL_SINCE(6, 11) + +void QPainter::setPen(const QPen &p) +{ + doSetPen(p, nullptr); +} + +void QPainter::setBrush(const QBrush &b) +{ + doSetBrush(b, nullptr); +} + +#endif // QT_GUI_INLINE_IMPL_SINCE(6, 11) + + inline void QPainter::setBrushOrigin(int x, int y) { setBrushOrigin(QPoint(x, y)); diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 66f1cf2a985..148d40b8361 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -784,7 +784,7 @@ bool QTransform::operator==(const QTransform &o) const */ size_t qHash(const QTransform &key, size_t seed) noexcept { - QtPrivate::QHashCombine hash(seed); + QtPrivate::QHashCombineWithSeed hash(seed); seed = hash(seed, key.m11()); seed = hash(seed, key.m12()); seed = hash(seed, key.m21()); diff --git a/src/gui/platform/darwin/qapplefileiconengine.mm b/src/gui/platform/darwin/qapplefileiconengine.mm index f1ba6319d0a..594fdf23b60 100644 --- a/src/gui/platform/darwin/qapplefileiconengine.mm +++ b/src/gui/platform/darwin/qapplefileiconengine.mm @@ -10,6 +10,7 @@ # include <UIKit/UIKit.h> #endif +#include <QtCore/qurl.h> #include <QtGui/private/qcoregraphics_p.h> QT_BEGIN_NAMESPACE diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index b9312f6b304..7a3d4974e53 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -6543,7 +6543,7 @@ bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind size_t qHash(const QRhiShaderResourceBinding &b, size_t seed) noexcept { const QRhiShaderResourceBinding::Data *d = QRhiImplementation::shaderResourceBindingData(b); - QtPrivate::QHashCombine hash(seed); + QtPrivate::QHashCombineWithSeed hash(seed); seed = hash(seed, d->binding); seed = hash(seed, d->stage); seed = hash(seed, d->type); diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index e5ac6097a3d..f8ca24c1a08 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -2405,6 +2405,10 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain) } image.lastUse = QVkSwapChain::ImageResources::ScImageUseNone; + + VkSemaphoreCreateInfo semInfo = {}; + semInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + df->vkCreateSemaphore(dev, &semInfo, nullptr, &image.drawSem); } if (stereo) { for (int i = 0; i < swapChainD->bufferCount; ++i) { @@ -2433,6 +2437,10 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain) return false; } + VkSemaphoreCreateInfo semInfo = {}; + semInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + df->vkCreateSemaphore(dev, &semInfo, nullptr, &image.drawSem); + image.lastUse = QVkSwapChain::ImageResources::ScImageUseNone; } } @@ -2473,7 +2481,6 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain) frame.imageSemWaitable = false; df->vkCreateSemaphore(dev, &semInfo, nullptr, &frame.imageSem); - df->vkCreateSemaphore(dev, &semInfo, nullptr, &frame.drawSem); err = df->vkCreateFence(dev, &fenceInfo, nullptr, &frame.cmdFence); if (err != VK_SUCCESS) { @@ -2511,10 +2518,6 @@ void QRhiVulkan::releaseSwapChainResources(QRhiSwapChain *swapChain) df->vkDestroySemaphore(dev, frame.imageSem, nullptr); frame.imageSem = VK_NULL_HANDLE; } - if (frame.drawSem) { - df->vkDestroySemaphore(dev, frame.drawSem, nullptr); - frame.drawSem = VK_NULL_HANDLE; - } } for (int i = 0; i < swapChainD->bufferCount * (swapChainD->stereo ? 2 : 1); ++i) { @@ -2535,6 +2538,10 @@ void QRhiVulkan::releaseSwapChainResources(QRhiSwapChain *swapChain) df->vkDestroyImage(dev, image.msaaImage, nullptr); image.msaaImage = VK_NULL_HANDLE; } + if (image.drawSem) { + df->vkDestroySemaphore(dev, image.drawSem, nullptr); + image.drawSem = VK_NULL_HANDLE; + } } if (swapChainD->msaaImageMem) { @@ -2750,7 +2757,7 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram QRhi::FrameOpResult submitres = endAndSubmitPrimaryCommandBuffer(frame.cmdBuf, frame.cmdFence, frame.imageSemWaitable ? &frame.imageSem : nullptr, - needsPresent ? &frame.drawSem : nullptr); + needsPresent ? &image.drawSem : nullptr); if (submitres != QRhi::FrameOpSuccess) return submitres; @@ -2764,7 +2771,7 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram presInfo.swapchainCount = 1; presInfo.pSwapchains = &swapChainD->sc; presInfo.pImageIndices = &swapChainD->currentImageIndex; - waitSemaphoresForPresent.append(frame.drawSem); + waitSemaphoresForPresent.append(image.drawSem); presInfo.waitSemaphoreCount = uint32_t(waitSemaphoresForPresent.count());; presInfo.pWaitSemaphores = waitSemaphoresForPresent.constData(); diff --git a/src/gui/rhi/qrhivulkan_p.h b/src/gui/rhi/qrhivulkan_p.h index 2d812a9d5f0..59d98c309aa 100644 --- a/src/gui/rhi/qrhivulkan_p.h +++ b/src/gui/rhi/qrhivulkan_p.h @@ -642,6 +642,7 @@ struct QVkSwapChain : public QRhiSwapChain VkFramebuffer fb = VK_NULL_HANDLE; VkImage msaaImage = VK_NULL_HANDLE; VkImageView msaaImageView = VK_NULL_HANDLE; + VkSemaphore drawSem = VK_NULL_HANDLE; enum LastUse { ScImageUseNone, ScImageUseRender, @@ -653,7 +654,6 @@ struct QVkSwapChain : public QRhiSwapChain struct FrameResources { VkSemaphore imageSem = VK_NULL_HANDLE; - VkSemaphore drawSem = VK_NULL_HANDLE; bool imageAcquired = false; bool imageSemWaitable = false; VkFence cmdFence = VK_NULL_HANDLE; diff --git a/src/gui/rhi/qshader.cpp b/src/gui/rhi/qshader.cpp index 5e967c62e40..1234d01b6ec 100644 --- a/src/gui/rhi/qshader.cpp +++ b/src/gui/rhi/qshader.cpp @@ -812,7 +812,7 @@ bool operator==(const QShader &lhs, const QShader &rhs) noexcept size_t qHash(const QShader &s, size_t seed) noexcept { if (s.d) { - QtPrivate::QHashCombine hash(seed); + QtPrivate::QHashCombineWithSeed hash(seed); seed = hash(seed, s.stage()); if (!s.d->shaders.isEmpty()) { seed = hash(seed, s.d->shaders.firstKey()); diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 5d455219359..8380a8b7f68 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1570,7 +1570,6 @@ bool QFontDatabase::isFixedPitch(const QString &family, bool QFontDatabase::isBitmapScalable(const QString &family, const QString &style) { - bool bitmapScalable = false; QString familyName, foundryName; parseFontName(family, foundryName, familyName); @@ -1578,7 +1577,8 @@ bool QFontDatabase::isBitmapScalable(const QString &family, QFontDatabasePrivate *d = QFontDatabasePrivate::ensureFontDatabase(); QtFontFamily *f = d->family(familyName); - if (!f) return bitmapScalable; + if (!f) + return false; QtFontStyle::Key styleKey(style); for (int j = 0; j < f->count; j++) { @@ -1589,13 +1589,11 @@ bool QFontDatabase::isBitmapScalable(const QString &family, foundry->styles[k]->styleName == style || foundry->styles[k]->key == styleKey) && foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) { - bitmapScalable = true; - goto end; + return true; } } } - end: - return bitmapScalable; + return false; } @@ -1609,7 +1607,6 @@ bool QFontDatabase::isBitmapScalable(const QString &family, */ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &style) { - bool smoothScalable = false; QString familyName, foundryName; parseFontName(family, foundryName, familyName); @@ -1626,7 +1623,8 @@ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &sty } } } - if (!f) return smoothScalable; + if (!f) + return false; const QtFontStyle::Key styleKey(style); for (int j = 0; j < f->count; j++) { @@ -1634,7 +1632,7 @@ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &sty if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { for (int k = 0; k < foundry->count; k++) { const QtFontStyle *fontStyle = foundry->styles[k]; - smoothScalable = + const bool smoothScalable = fontStyle->smoothScalable && ((style.isEmpty() || fontStyle->styleName == style @@ -1643,12 +1641,11 @@ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &sty && style == styleStringHelper(fontStyle->key.weight, QFont::Style(fontStyle->key.style)))); if (smoothScalable) - goto end; + return true; } } } - end: - return smoothScalable; + return false; } /*! @@ -1679,7 +1676,6 @@ QList<int> QFontDatabase::pointSizes(const QString &family, if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable()) return standardSizes(); - bool smoothScalable = false; QString familyName, foundryName; parseFontName(family, foundryName, familyName); @@ -1701,10 +1697,9 @@ QList<int> QFontDatabase::pointSizes(const QString &family, QtFontStyle *style = foundry->style(styleKey, styleName); if (!style) continue; - if (style->smoothScalable) { - smoothScalable = true; - goto end; - } + if (style->smoothScalable) + return standardSizes(); + for (int l = 0; l < style->count; l++) { const QtFontSize *size = style->pixelSizes + l; @@ -1716,9 +1711,6 @@ QList<int> QFontDatabase::pointSizes(const QString &family, } } } - end: - if (smoothScalable) - return standardSizes(); std::sort(sizes.begin(), sizes.end()); return sizes; @@ -1781,7 +1773,6 @@ QList<int> QFontDatabase::smoothSizes(const QString &family, if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable()) return standardSizes(); - bool smoothScalable = false; QString familyName, foundryName; parseFontName(family, foundryName, familyName); @@ -1803,10 +1794,9 @@ QList<int> QFontDatabase::smoothSizes(const QString &family, QtFontStyle *style = foundry->style(styleKey, styleName); if (!style) continue; - if (style->smoothScalable) { - smoothScalable = true; - goto end; - } + if (style->smoothScalable) + return QFontDatabase::standardSizes(); + for (int l = 0; l < style->count; l++) { const QtFontSize *size = style->pixelSizes + l; @@ -1818,9 +1808,6 @@ QList<int> QFontDatabase::smoothSizes(const QString &family, } } } - end: - if (smoothScalable) - return QFontDatabase::standardSizes(); std::sort(sizes.begin(), sizes.end()); return sizes; diff --git a/src/gui/text/qfontdatabase_p.h b/src/gui/text/qfontdatabase_p.h index 4cd6996aab8..27fb34aecdd 100644 --- a/src/gui/text/qfontdatabase_p.h +++ b/src/gui/text/qfontdatabase_p.h @@ -51,7 +51,7 @@ inline bool operator!=(const QtFontFallbacksCacheKey &lhs, const QtFontFallbacks inline size_t qHash(const QtFontFallbacksCacheKey &key, size_t seed = 0) noexcept { - QtPrivate::QHashCombine hash(seed); + QtPrivate::QHashCombineWithSeed hash(seed); seed = hash(seed, key.family); seed = hash(seed, int(key.style)); seed = hash(seed, int(key.styleHint)); diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index dc05ef0bac3..8ff8d1278b8 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -1862,7 +1862,7 @@ void QTextDocumentLayoutPrivate::drawTableCell(const QRectF &cellRect, QPainter } const QBrush bg = cell.format().background(); - const QPointF brushOrigin = painter->brushOrigin(); + const QPointF brushOrigin = painter->brushOriginF(); if (bg.style() != Qt::NoBrush) { const qreal pageHeight = document->pageSize().height(); const int topPage = pageHeight > 0 ? static_cast<int>(cellRect.top() / pageHeight) : 0; diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 06ae00123f0..379fb70a81a 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -2245,6 +2245,17 @@ void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavi /*! Returns the font for this character format. + + This function takes into account the format's font attributes (such as fontWeight() + and fontPointSize()) and resolves them on top of the default font, defined as follows. + If the format is part of a document, that is the document's default font. + Otherwise the properties are resolved on top of a default constructed QFont. + + For example, if this format's font size hasn't been changed from the default font, + fontPointSize() returns 0, while \c {font().pointSize()} returns the actual + size used for drawing. + + \sa QTextDocument::defaultFont() */ QFont QTextCharFormat::font() const { diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 50153f27692..e7f0ae200d1 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -738,7 +738,7 @@ bool QNetworkAccessManager::isStrictTransportSecurityStoreEnabled() const policies, but this information can be overridden by "Strict-Transport-Security" response headers. - \sa addStrictTransportSecurityHosts(), enableStrictTransportSecurityStore(), QHstsPolicy + \sa strictTransportSecurityHosts(), enableStrictTransportSecurityStore(), QHstsPolicy */ void QNetworkAccessManager::addStrictTransportSecurityHosts(const QList<QHstsPolicy> &knownHosts) diff --git a/src/network/access/qnetworkrequestfactory.cpp b/src/network/access/qnetworkrequestfactory.cpp index 6b8d35f9065..3f53fc4f5b8 100644 --- a/src/network/access/qnetworkrequestfactory.cpp +++ b/src/network/access/qnetworkrequestfactory.cpp @@ -361,7 +361,7 @@ void QNetworkRequestFactory::clearUserName() /*! Returns the password set to this factory. - \sa password(), clearPassword(), userName() + \sa setPassword(), clearPassword(), userName() */ QString QNetworkRequestFactory::password() const { diff --git a/src/network/android/jar/build.gradle b/src/network/android/jar/build.gradle index 99e835c6d43..f1f470b6635 100644 --- a/src/network/android/jar/build.gradle +++ b/src/network/android/jar/build.gradle @@ -7,7 +7,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.8.0' + classpath 'com.android.tools.build:gradle:8.10.1' } } diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index ae2f7876f37..2d29f7a0152 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -1195,7 +1195,7 @@ bool QHostAddress::isSiteLocal() const 4193 says that, in practice, "applications may treat these addresses like global scoped addresses." Only routers need care about the distinction. - \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isUniqueLocalUnicast(), isPrivateUse() + \sa isLoopback(), isGlobal(), isMulticast(), isLinkLocal(), isPrivateUse() */ bool QHostAddress::isUniqueLocalUnicast() const { diff --git a/src/network/kernel/qnetworkdatagram.cpp b/src/network/kernel/qnetworkdatagram.cpp index dad8128aa81..36b8ee99f25 100644 --- a/src/network/kernel/qnetworkdatagram.cpp +++ b/src/network/kernel/qnetworkdatagram.cpp @@ -370,7 +370,7 @@ uint QNetworkDatagram::interfaceIndex() const index are different and neither is zero, it is undefined which interface the operating system will send the datagram on. - \sa setInterfaceIndex() + \sa interfaceIndex() */ void QNetworkDatagram::setInterfaceIndex(uint index) { diff --git a/src/network/kernel/qnetworkproxy_libproxy.cpp b/src/network/kernel/qnetworkproxy_libproxy.cpp index da1e8fdbd4a..b17d46ea96a 100644 --- a/src/network/kernel/qnetworkproxy_libproxy.cpp +++ b/src/network/kernel/qnetworkproxy_libproxy.cpp @@ -10,6 +10,7 @@ #include <QtCore/QMutex> #include <QtCore/QSemaphore> #include <QtCore/QUrl> +#include <QtCore/private/qlatch_p.h> #include <QtCore/private/qeventdispatcher_unix_p.h> #include <QtCore/private/qthread_p.h> #include <QtCore/qapplicationstatic.h> @@ -61,7 +62,7 @@ private: // we leave the conversion to/from QUrl to the calling thread const char *url; char **proxies; - QSemaphore replyReady; + QLatch replyReady{1}; }; void run() override; @@ -119,7 +120,7 @@ QList<QUrl> QLibProxyWrapper::getProxies(const QUrl &url) requestReady.release(); // wait for the reply - data.replyReady.acquire(); + data.replyReady.wait(); } else { // non-threaded mode data.proxies = px_proxy_factory_get_proxies(factory, data.url); @@ -147,7 +148,7 @@ void QLibProxyWrapper::run() if (isInterruptionRequested()) break; request->proxies = px_proxy_factory_get_proxies(factory, request->url); - request->replyReady.release(); + request->replyReady.countDown(); } px_proxy_factory_free(factory); diff --git a/src/network/ssl/qdtls.cpp b/src/network/ssl/qdtls.cpp index f9f7fd6fcab..13a651faf0d 100644 --- a/src/network/ssl/qdtls.cpp +++ b/src/network/ssl/qdtls.cpp @@ -718,7 +718,7 @@ bool QDtls::setCookieGeneratorParameters(const GeneratorParameters ¶ms) secret is obtained from the backend-specific cryptographically strong pseudorandom number generator. - \sa QDtlsClientVerifier, cookieGeneratorParameters() + \sa QDtlsClientVerifier, setCookieGeneratorParameters() */ QDtls::GeneratorParameters QDtls::cookieGeneratorParameters() const { diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h index 59ce3cd8896..61b0c705898 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h +++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h @@ -58,6 +58,7 @@ public: signals: void deviceDetected(const QString &deviceNode); void deviceRemoved(const QString &deviceNode); + void deviceChanged(const QString &deviceNode); protected: QDeviceDiscovery(QDeviceTypes types, QObject *parent) : QObject(parent), m_types(types) { } diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp index edb3fc58a22..e4d69101f75 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp +++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp @@ -175,6 +175,9 @@ void QDeviceDiscoveryUDev::handleUDevNotification() if (qstrcmp(action, "remove") == 0) emit deviceRemoved(devNode); + if (qstrcmp(action, "change") == 0) + emit deviceChanged(devNode); + cleanup: udev_device_unref(dev); } diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp index cdd2ac2d572..7b2637bfffe 100644 --- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp +++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp @@ -151,17 +151,45 @@ static inline void assignPlane(QKmsOutput *output, QKmsPlane *plane) output->eglfs_plane = plane; } -QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources, - drmModeConnectorPtr connector, - ScreenInfo *vinfo) +static bool orderedScreenLessThan(const QKmsDevice::OrderedScreen &a, + const QKmsDevice::OrderedScreen &b) +{ + return a.vinfo.virtualIndex < b.vinfo.virtualIndex; +} + +QKmsDevice::OrderedScreen::OrderedScreen() : screen(nullptr) { } + +QKmsDevice::OrderedScreen::OrderedScreen(QPlatformScreen *screen, + const QKmsDevice::ScreenInfo &vinfo) + : screen(screen), vinfo(vinfo) +{ +} + +QDebug operator<<(QDebug dbg, const QPlatformScreen *screen) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QPlatformScreen=" << (const void *)screen << " (" + << (screen ? screen->name() : QString()) << ")"; + return dbg; +} + +QDebug operator<<(QDebug dbg, const QKmsDevice::OrderedScreen &s) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "OrderedScreen(" << s.screen << ") : " << s.vinfo.virtualIndex << " / " + << s.vinfo.virtualPos << " / primary: " << s.vinfo.isPrimary << ")"; + return dbg; +} + +bool QKmsDevice::createScreenInfoForConnector(drmModeResPtr resources, + drmModeConnectorPtr connector, ScreenInfo &vinfo) { - Q_ASSERT(vinfo); const QByteArray connectorName = nameForConnector(connector); const int crtc = crtcForConnector(resources, connector); if (crtc < 0) { qWarning() << "No usable crtc/encoder pair for connector" << connectorName; - return nullptr; + return false; } OutputConfiguration configuration; @@ -195,45 +223,54 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources, configuration = OutputConfigPreferred; } - *vinfo = ScreenInfo(); - vinfo->virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt(); + vinfo.virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt(); if (userConnectorConfig.contains(QStringLiteral("virtualPos"))) { const QByteArray vpos = userConnectorConfig.value(QStringLiteral("virtualPos")).toByteArray(); const QByteArrayList vposComp = vpos.split(','); - if (vposComp.size() == 2) - vinfo->virtualPos = QPoint(vposComp[0].trimmed().toInt(), vposComp[1].trimmed().toInt()); + if (vposComp.count() == 2) { + vinfo.virtualPos = QPoint(vposComp[0].trimmed().toInt(), vposComp[1].trimmed().toInt()); + qCDebug(qLcKmsDebug) << "Parsing virtualPos to: " << vinfo.virtualPos; + } else { + vinfo.virtualPos = QPoint(-1, -1); + qCDebug(qLcKmsDebug) << "Could not parse virtualPos," + << "will be calculated based on virtualIndex"; + } + } else { + vinfo.virtualPos = QPoint(-1, -1); } + if (userConnectorConfig.value(QStringLiteral("primary")).toBool()) - vinfo->isPrimary = true; + vinfo.isPrimary = true; const uint32_t crtc_id = resources->crtcs[crtc]; if (configuration == OutputConfigOff) { qCDebug(qLcKmsDebug) << "Turning off output" << connectorName; drmModeSetCrtc(m_dri_fd, crtc_id, 0, 0, 0, 0, 0, nullptr); - return nullptr; + return false; } // Skip disconnected output if (configuration == OutputConfigPreferred && connector->connection == DRM_MODE_DISCONNECTED) { qCDebug(qLcKmsDebug) << "Skipping disconnected output" << connectorName; - return nullptr; + return false; } if (configuration == OutputConfigSkip) { qCDebug(qLcKmsDebug) << "Skipping output" << connectorName; - return nullptr; + return false; } // Get the current mode on the current crtc drmModeModeInfo crtc_mode; memset(&crtc_mode, 0, sizeof crtc_mode); if (drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->encoder_id)) { + drmModeCrtcPtr crtc = drmModeGetCrtc(m_dri_fd, encoder->crtc_id); drmModeFreeEncoder(encoder); if (!crtc) - return nullptr; + return false; if (crtc->mode_valid) crtc_mode = crtc->mode; @@ -303,7 +340,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources, if (selected_mode < 0) { qWarning() << "No modes available for output" << connectorName; - return nullptr; + return false; } else { int width = modes[selected_mode].hdisplay; int height = modes[selected_mode].vdisplay; @@ -504,9 +541,8 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources, m_crtc_allocator |= (1 << output.crtc_index); - vinfo->output = output; - - return createScreen(output); + vinfo.output = output; + return true; } drmModePropertyPtr QKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name) @@ -566,29 +602,233 @@ QKmsDevice::~QKmsDevice() #endif } -struct OrderedScreen +void QKmsDevice::checkConnectedScreens() { - OrderedScreen() : screen(nullptr) { } - OrderedScreen(QPlatformScreen *screen, const QKmsDevice::ScreenInfo &vinfo) - : screen(screen), vinfo(vinfo) { } - QPlatformScreen *screen; - QKmsDevice::ScreenInfo vinfo; -}; + if (m_screenConfig->headless()) + return; -QDebug operator<<(QDebug dbg, const OrderedScreen &s) -{ - QDebugStateSaver saver(dbg); - dbg.nospace() << "OrderedScreen(QPlatformScreen=" << s.screen << " (" << s.screen->name() << ") : " - << s.vinfo.virtualIndex - << " / " << s.vinfo.virtualPos - << " / primary: " << s.vinfo.isPrimary - << ")"; - return dbg; + drmModeResPtr resources = drmModeGetResources(m_dri_fd); + if (!resources) { + qErrnoWarning(errno, "drmModeGetResources failed"); + return; + } + + QList<uint32_t> newConnects; + QList<uint32_t> newDisconnects; + const QMap<QString, QVariantMap> userConfig = m_screenConfig->outputSettings(); + + for (int i = 0; i < resources->count_connectors; i++) { + drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); + if (!connector) { + qErrnoWarning(errno, "drmModeGetConnector failed"); + continue; + } + + const uint32_t id = connector->connector_id; + + const QByteArray connectorName = nameForConnector(connector); + const QVariantMap userCConfig = userConfig.value(QString::fromUtf8(connectorName)); + const QByteArray mode = userCConfig.value(QStringLiteral("mode")).toByteArray().toLower(); + if (mode == "off" || mode == "skip") + continue; + + if (connector->connection == DRM_MODE_CONNECTED) { + if (!m_registeredScreens.contains(id)) + newConnects.append(id); + else + qCDebug(qLcKmsDebug) << "Connected screen already registered: connector id=" << id; + } + + if (connector->connection == DRM_MODE_DISCONNECTED) { + if (m_registeredScreens.contains(id)) + newDisconnects.append(id); + else + qCDebug(qLcKmsDebug) << "Disconnected screen not registered: connector id=" << id; + } + + drmModeFreeConnector(connector); + } + + if (newConnects.isEmpty() && newDisconnects.isEmpty()) { + qCDebug(qLcKmsDebug) << "EGLFS/KMS: KMS-device-change but no new connects or disconnects " + << "to process - exiting"; + return; + } else { + qCDebug(qLcKmsDebug) << "EGLFS/KMS: KMS-device-change, new connects:" << newConnects + << ", and disconnected: " << newDisconnects; + } + + const int remainingScreenCount = m_registeredScreens.count() - newDisconnects.count(); + if (remainingScreenCount == 0 && m_headlessScreen == nullptr) { + qCDebug(qLcKmsDebug) << "EGLFS/KMS: creating headless screen before" + << "unregistering screens to avoid having no screens"; + m_headlessScreen = createHeadlessScreen(); + registerScreen(m_headlessScreen, true, QPoint(), + QList<QPlatformScreen *>() << m_headlessScreen); + } + + for (uint32_t connectorId : newDisconnects) { + OrderedScreen orderedScreen = m_registeredScreens.take(connectorId); + QPlatformScreen *screen = orderedScreen.screen; + + // Clear active crtc of the plane associated with the screen output + // and, if applicable, disassociate it from the eglfs plane. + uint32_t crtcId = (orderedScreen.vinfo.output.eglfs_plane != nullptr) // if we have an assigned plan + ? orderedScreen.vinfo.output.eglfs_plane->activeCrtcId // we use the active crtc_id to disable everything + : orderedScreen.vinfo.output.crtc_id; // if not, we use the default crtc_id + + if (orderedScreen.vinfo.output.eglfs_plane != nullptr) + orderedScreen.vinfo.output.eglfs_plane->activeCrtcId = 0; + + // Clear crtc allocator bit for screen + const int crtcIdx = orderedScreen.vinfo.output.crtc_index; + m_crtc_allocator &= ~(1 << crtcIdx); + + const int ret = drmModeSetCrtc(m_dri_fd, crtcId, 0, 0, 0, nullptr, 0, nullptr); + + if (ret != 0) { + qCWarning(qLcKmsDebug) << "Could not disable CRTC" << crtcId + << "on connector" << connectorId << "removal:" << ret; + } else { + qCDebug(qLcKmsDebug) << "Disabled CRTC" << crtcId + << "for connector " << connectorId << "disconnected"; + } + + // As we've already turned the crtc off, we don't want to restore the saved_crtc + if (orderedScreen.vinfo.output.saved_crtc) { + drmModeFreeCrtc(orderedScreen.vinfo.output.saved_crtc); + orderedScreen.vinfo.output.saved_crtc = nullptr; + updateScreenOutput(orderedScreen.screen, orderedScreen.vinfo.output); + } + + unregisterScreen(screen); + } + + for (uint32_t connectorId : newConnects) { + drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, connectorId); + if (!connector) { + qErrnoWarning(errno, "drmModeGetConnector failed"); + continue; + } + + ScreenInfo vinfo; + bool succ = createScreenInfoForConnector(resources, connector, vinfo); + drmModeFreeConnector(connector); + if (!succ) + continue; + + QPlatformScreen *screen = createScreen(vinfo.output); + if (!screen) + continue; + + OrderedScreen orderedScreen(screen, vinfo); + m_registeredScreens[connectorId] = orderedScreen; + } + + drmModeFreeResources(resources); + + registerScreens(newConnects); } -static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b) +void QKmsDevice::updateScreens() { - return a.vinfo.virtualIndex < b.vinfo.virtualIndex; + if (m_screenConfig->headless()) + return; + + drmModeResPtr resources = drmModeGetResources(m_dri_fd); + if (!resources) { + qErrnoWarning(errno, "drmModeGetResources failed"); + return; + } + + QList<uint32_t> newConnects; + QList<OrderedScreen> newDisconnects; + + for (int i = 0; i < resources->count_connectors; i++) { + drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); + if (!connector) + continue; + + if (m_registeredScreens.contains(connector->connector_id)) { + OrderedScreen &os = m_registeredScreens[connector->connector_id]; + + // As we're currently *re*creating the information of an used connector, + // we have to "fake" it being not in use at two places: + // (note: the only thing we'll restore is, in case of failure, the eglfs_plane + // probably not necessary but good practice) + + // 1) crtc_allocator for the crtc + const int crtcIdx = os.vinfo.output.crtc_index; + m_crtc_allocator &= ~(1 << crtcIdx); + + // 2) the plane itself + if (os.vinfo.output.eglfs_plane) + os.vinfo.output.eglfs_plane->activeCrtcId = 0; + + // We also save the saved crtc to restore it in case of success + // (otherwise QKmsOutput::restoreMode would restore to a second-latest crtc, + // rather then the original one) + drmModeCrtcPtr saved_saved_crtc = nullptr; + if (os.vinfo.output.saved_crtc) + saved_saved_crtc = os.vinfo.output.saved_crtc; + + ScreenInfo vinfo; + bool succ = createScreenInfoForConnector(resources, connector, vinfo); + if (!succ) { + // Here we either failed the recreate, or the config turns the screen off. + // In either case, we'll treat it as a disconnect + + // Either this connector is disconnected, broken or turned off + // In all those cases we don't need or want to restore the previous mode + if (os.vinfo.output.saved_crtc) { + drmModeFreeCrtc(os.vinfo.output.saved_crtc); + os.vinfo.output.saved_crtc = nullptr; + updateScreenOutput(os.screen, os.vinfo.output); + } + + // move from one container to another - we don't want registerScreens + // to deal with this, but need to call registerScreens before the disconnects + newDisconnects.append(m_registeredScreens.take(connector->connector_id)); + drmModeFreeConnector(connector); + continue; + } + drmModeFreeConnector(connector); + + drmModeFreeCrtc(vinfo.output.saved_crtc); + vinfo.output.saved_crtc = saved_saved_crtc; // This is vital as config changes should + // never override the original saved_crtc + os.vinfo = vinfo; + updateScreenOutput(os.screen, os.vinfo.output); + + } else { + ScreenInfo vinfo; + bool succ = createScreenInfoForConnector(resources, connector, vinfo); + if (!succ) // If we fail here we do nothing, as there is nothing to restore or cleanup + continue; + + QPlatformScreen *screen = createScreen(vinfo.output); + OrderedScreen orderedScreen(screen, vinfo); + m_registeredScreens[connector->connector_id] = orderedScreen; + newConnects.append(connector->connector_id); + } + } + + // In case we end up with zero screen, we do the fallback first + if (m_registeredScreens.count() == 0 && m_headlessScreen == nullptr) { + // Create headless screen before unregistering screens to avoid having no screens + m_headlessScreen = createHeadlessScreen(); + registerScreen(m_headlessScreen, true, QPoint(), + QList<QPlatformScreen *>() << m_headlessScreen); + } + + // Register new and updates existing screens + registerScreens(newConnects); + + // Last we unregister the disconncted ones + for (const OrderedScreen &os : newDisconnects) + unregisterScreen(os.screen); + + drmModeFreeResources(resources); } void QKmsDevice::createScreens() @@ -599,7 +839,8 @@ void QKmsDevice::createScreens() QPlatformScreen *screen = createHeadlessScreen(); if (screen) { qCDebug(qLcKmsDebug, "Headless mode enabled"); - registerScreen(screen, true, QPoint(0, 0), QList<QPlatformScreen *>()); + registerScreen(screen, true, QPoint(0, 0), + QList<QPlatformScreen *>() << screen); return; } else { qWarning("QKmsDevice: Requested headless mode without support in the backend. Request is ignored."); @@ -630,8 +871,7 @@ void QKmsDevice::createScreens() discoverPlanes(); - QList<OrderedScreen> screens; - + QList<uint32_t> newConnects; int wantedConnectorIndex = -1; bool ok; int idx = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_CONNECTOR_INDEX", &ok); @@ -647,19 +887,47 @@ void QKmsDevice::createScreens() continue; drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); - if (!connector) + if (!connector) { + qErrnoWarning(errno, "drmModeGetConnector failed"); continue; + } ScreenInfo vinfo; - QPlatformScreen *screen = createScreenForConnector(resources, connector, &vinfo); - if (screen) - screens.append(OrderedScreen(screen, vinfo)); - + bool succ = createScreenInfoForConnector(resources, connector, vinfo); + uint32_t connectorId = connector->connector_id; drmModeFreeConnector(connector); + if (!succ) + continue; + + QPlatformScreen *screen = createScreen(vinfo.output); + if (!screen) + continue; + + OrderedScreen orderedScreen(screen, vinfo); + m_registeredScreens[connectorId] = orderedScreen; + newConnects.append(connectorId); } drmModeFreeResources(resources); + if (!qEnvironmentVariable("QT_QPA_EGLFS_HOTPLUG_ENABLED").isEmpty() + && newConnects.empty() && m_headlessScreen == nullptr) { + qCDebug(qLcKmsDebug) << "'QT_QPA_EGLFS_HOTPLUG_ENABLED' was set and no screen was connected/found during start-up." + << "In order for Qt to operate properly a qt_headless screen will be created." + << "It will be automatically removed as soon as the first screen is connected"; + // Create headless screen before unregistering screens to avoid having no screens + m_headlessScreen = createHeadlessScreen(); + registerScreen(m_headlessScreen, true, QPoint(), + QList<QPlatformScreen *>() << m_headlessScreen); + } + + registerScreens(newConnects); +} + +void QKmsDevice::registerScreens(QList<uint32_t> newConnects) +{ + QList<OrderedScreen> screens = m_registeredScreens.values(); + // Use stable sort to preserve the original (DRM connector) order // for outputs with unspecified indices. std::stable_sort(screens.begin(), screens.end(), orderedScreenLessThan); @@ -692,44 +960,129 @@ void QKmsDevice::createScreens() // Figure out the virtual desktop and register the screens to QPA/QGuiApplication. QPoint pos(0, 0); - QList<QPlatformScreen *> siblings; + QList<OrderedScreen> siblings; QList<QPoint> virtualPositions; int primarySiblingIdx = -1; + QRegion deskRegion; for (const OrderedScreen &orderedScreen : screens) { QPlatformScreen *s = orderedScreen.screen; QPoint virtualPos(0, 0); // set up a horizontal or vertical virtual desktop - if (orderedScreen.vinfo.virtualPos.isNull()) { - virtualPos = pos; - if (m_screenConfig->virtualDesktopLayout() == QKmsScreenConfig::VirtualDesktopLayoutVertical) - pos.ry() += s->geometry().height(); - else - pos.rx() += s->geometry().width(); + if (orderedScreen.vinfo.virtualPos.x() == -1 || orderedScreen.vinfo.virtualPos.y() == -1) { + if (orderedScreen.vinfo.output.clone_source.isEmpty()) { + virtualPos = pos; + if (m_screenConfig->virtualDesktopLayout() == QKmsScreenConfig::VirtualDesktopLayoutVertical) + pos.ry() += s->geometry().height(); + else + pos.rx() += s->geometry().width(); + } else { + for (int i = 0; i < screens.count(); i++) { + const OrderedScreen &os = screens[i]; + if (os.vinfo.output.name == orderedScreen.vinfo.output.clone_source) { + if (i >= virtualPositions.count()) { + qCWarning(qLcKmsDebug) + << "WARNING: When using clone on kms config," + << "you have to either order your screens (virtualIndex)," + << "so clones come after their source," + << "or specify 'virtualPos' for each clone." + << "Otherwise desktop-geomerty might not work properly!"; + virtualPos = pos; + } else { + virtualPos = virtualPositions[i]; + } + break; + } + } + } } else { virtualPos = orderedScreen.vinfo.virtualPos; } - qCDebug(qLcKmsDebug) << "Adding QPlatformScreen" << s << "(" << s->name() << ")" - << "to QPA with geometry" << s->geometry() - << "and isPrimary=" << orderedScreen.vinfo.isPrimary; + // The order in qguiapp's screens list will match the order set by // virtualIndex. This is not only handy but also required since for instance // evdevtouch relies on it when performing touch device - screen mapping. if (!m_screenConfig->separateScreens()) { - qCDebug(qLcKmsDebug) << " virtual position is" << virtualPos; - siblings.append(s); + siblings.append(orderedScreen); virtualPositions.append(virtualPos); if (orderedScreen.vinfo.isPrimary) primarySiblingIdx = siblings.size() - 1; } else { - registerScreen(s, orderedScreen.vinfo.isPrimary, virtualPos, QList<QPlatformScreen *>() << s); + const bool isNewScreen = newConnects.contains(orderedScreen.vinfo.output.connector_id); + if (isNewScreen) { + qCDebug(qLcKmsDebug) << "Adding QPlatformScreen" << s << "(" << s->name() << ")" + << "to QPA with geometry" << s->geometry() + << ", virtual position" << virtualPos + << "and isPrimary=" << orderedScreen.vinfo.isPrimary; + registerScreen(s, orderedScreen.vinfo.isPrimary, virtualPos, + QList<QPlatformScreen *>() << s); + deskRegion += s->geometry(); + } else { + qCDebug(qLcKmsDebug) << "Updating QPlatformScreen" << s << "(" << s->name() << ")" + << "to QPA with geometry" << s->geometry() + << ", virtual position" << virtualPos + << "and isPrimary=" << orderedScreen.vinfo.isPrimary; + updateScreen(s, virtualPos, QList<QPlatformScreen *>() << s); + deskRegion += s->geometry(); + } } } if (!m_screenConfig->separateScreens()) { + QList<QPlatformScreen *> platformScreenSiblings; + for (int i = 0; i < siblings.count(); ++i) { + platformScreenSiblings.append(siblings[i].screen); + } + // enable the virtual desktop - for (int i = 0; i < siblings.size(); ++i) - registerScreen(siblings[i], i == primarySiblingIdx, virtualPositions[i], siblings); + for (int i = 0; i < siblings.count(); ++i) { + QPlatformScreen *screen = platformScreenSiblings[i]; + const OrderedScreen &orderedScreen = siblings[i]; + const bool isNewScreen = newConnects.contains(orderedScreen.vinfo.output.connector_id); + if (isNewScreen) { + qCDebug(qLcKmsDebug) << "Adding QPlatformScreen" << screen + << "(" << screen->name() << ")" + << "to QPA with geometry" << screen->geometry() + << ", virtual position" << virtualPositions[i] + << "and isPrimary=" << orderedScreen.vinfo.isPrimary; + registerScreen(screen, i == primarySiblingIdx, virtualPositions[i], + platformScreenSiblings); + deskRegion += screen->geometry(); + } else { + qCDebug(qLcKmsDebug) << "Updating QPlatformScreen" << screen + << "(" << screen->name() << ")" + << "to QPA with geometry" << screen->geometry() + << ", virtual position" << virtualPositions[i] + << "and isPrimary=" << orderedScreen.vinfo.isPrimary; + updateScreen(screen, virtualPositions[i], platformScreenSiblings); + deskRegion += screen->geometry(); + } + } + } + + // Remove headless screen if other screens have become available + if (!m_registeredScreens.empty() && m_headlessScreen) { + unregisterScreen(m_headlessScreen); + m_headlessScreen = nullptr; + } + + // Due to layout changes it's possible that we have to reset/bound + // the cursor into the available space (otherwise the cursor might vanish) + QPoint currCPos = QCursor::pos(); + if (!deskRegion.contains(currCPos)) { + + // We try boudingRect first + QRect deskRect = deskRegion.boundingRect(); + currCPos.setX(qMin(currCPos.x(), deskRect.width()) - 1); + currCPos.setY(qMin(currCPos.y(), deskRect.height()) - 1); + + // If boudingRect isn't good enough, we go to 0 + if (!deskRegion.contains(currCPos)) + currCPos = QPoint(0,0); + + qCDebug(qLcKmsDebug) << "Due to desktop layout change, overriding cursor pos." + << "Is: " << QCursor::pos() << ", will be: " << currCPos; + QCursor::setPos(currCPos); } } @@ -749,6 +1102,25 @@ void QKmsDevice::registerScreenCloning(QPlatformScreen *screen, Q_UNUSED(screensCloningThisScreen); } +void QKmsDevice::unregisterScreen(QPlatformScreen *screen) +{ + Q_UNUSED(screen); +} + +void QKmsDevice::updateScreen(QPlatformScreen *screen, const QPoint &virtualPos, + const QList<QPlatformScreen *> &virtualSiblings) +{ + Q_UNUSED(screen); + Q_UNUSED(virtualPos); + Q_UNUSED(virtualSiblings); +} + +void QKmsDevice::updateScreenOutput(QPlatformScreen *screen, const QKmsOutput &output) +{ + Q_UNUSED(screen); + Q_UNUSED(output); +} + // drm_property_type_is is not available in old headers static inline bool propTypeIs(drmModePropertyPtr prop, uint32_t type) { @@ -1002,6 +1374,12 @@ QKmsScreenConfig::QKmsScreenConfig() { } +void QKmsScreenConfig::refreshConfig() +{ + m_outputSettings.clear(); + loadConfig(); +} + void QKmsScreenConfig::loadConfig() { QByteArray json = qgetenv("QT_QPA_EGLFS_KMS_CONFIG"); @@ -1039,6 +1417,11 @@ void QKmsScreenConfig::loadConfig() m_headless = false; } + const QString headlessSizeStr = object.value(QLatin1String("headlessSize")).toString(); + if (sscanf(headlessSizeStr.toUtf8().constData(), "%dx%d", &headlessSize.rwidth(), + &headlessSize.rheight()) == 2) + m_headlessSize = headlessSize; + m_hwCursor = object.value("hwcursor"_L1).toBool(m_hwCursor); m_pbuffers = object.value("pbuffers"_L1).toBool(m_pbuffers); m_devicePath = object.value("device"_L1).toString(); diff --git a/src/platformsupport/kmsconvenience/qkmsdevice_p.h b/src/platformsupport/kmsconvenience/qkmsdevice_p.h index 050d836cb18..3e6ec108175 100644 --- a/src/platformsupport/kmsconvenience/qkmsdevice_p.h +++ b/src/platformsupport/kmsconvenience/qkmsdevice_p.h @@ -88,11 +88,12 @@ public: QMap<QString, QVariantMap> outputSettings() const { return m_outputSettings; } virtual void loadConfig(); + void refreshConfig(); protected: QString m_devicePath; bool m_headless; - QSize m_headlessSize; + QSize m_headlessSize{ 1024, 768 }; bool m_hwCursor; bool m_separateScreens; bool m_pbuffers; @@ -196,6 +197,14 @@ public: QKmsOutput output; }; + struct OrderedScreen + { + OrderedScreen(); + OrderedScreen(QPlatformScreen *screen, const ScreenInfo &vinfo); + QPlatformScreen *screen = nullptr; + ScreenInfo vinfo; + }; + QKmsDevice(QKmsScreenConfig *screenConfig, const QString &path = QString()); virtual ~QKmsDevice(); @@ -210,6 +219,8 @@ public: bool threadLocalAtomicCommit(void *user_data); void threadLocalAtomicReset(); #endif + void checkConnectedScreens(); + void updateScreens(); void createScreens(); int fd() const; @@ -218,6 +229,7 @@ public: QKmsScreenConfig *screenConfig() const; protected: + void registerScreens(QList<uint32_t> newConnects = QList<uint32_t>()); virtual QPlatformScreen *createScreen(const QKmsOutput &output) = 0; virtual QPlatformScreen *createHeadlessScreen(); virtual void registerScreenCloning(QPlatformScreen *screen, @@ -227,12 +239,15 @@ protected: bool isPrimary, const QPoint &virtualPos, const QList<QPlatformScreen *> &virtualSiblings) = 0; + virtual void unregisterScreen(QPlatformScreen *screen); + virtual void updateScreen(QPlatformScreen *screen, const QPoint &virtualPos, + const QList<QPlatformScreen *> &virtualSiblings); + virtual void updateScreenOutput(QPlatformScreen *screen, const QKmsOutput &output); void setFd(int fd); int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); - QPlatformScreen *createScreenForConnector(drmModeResPtr resources, - drmModeConnectorPtr connector, - ScreenInfo *vinfo); + bool createScreenInfoForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, + ScreenInfo &vinfo); drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name); drmModePropertyBlobPtr connectorPropertyBlob(drmModeConnectorPtr connector, const QByteArray &name); typedef std::function<void(drmModePropertyPtr, quint64)> PropCallback; @@ -257,6 +272,8 @@ protected: quint32 m_crtc_allocator; QList<QKmsPlane> m_planes; + QMap<uint32_t, OrderedScreen> m_registeredScreens; + QPlatformScreen *m_headlessScreen = nullptr; private: Q_DISABLE_COPY(QKmsDevice) diff --git a/src/plugins/networkinformation/android/jar/build.gradle b/src/plugins/networkinformation/android/jar/build.gradle index 99e835c6d43..f1f470b6635 100644 --- a/src/plugins/networkinformation/android/jar/build.gradle +++ b/src/plugins/networkinformation/android/jar/build.gradle @@ -7,7 +7,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.8.0' + classpath 'com.android.tools.build:gradle:8.10.1' } } diff --git a/src/plugins/platforms/CMakeLists.txt b/src/plugins/platforms/CMakeLists.txt index f30c27c24be..498a0772bc9 100644 --- a/src/plugins/platforms/CMakeLists.txt +++ b/src/plugins/platforms/CMakeLists.txt @@ -4,10 +4,10 @@ if(ANDROID) add_subdirectory(android) endif() -if(NOT ANDROID AND NOT WASM) +if(NOT WASM) add_subdirectory(minimal) endif() -if(QT_FEATURE_freetype AND NOT ANDROID AND NOT WASM) +if(QT_FEATURE_freetype AND NOT WASM) add_subdirectory(offscreen) endif() if(QT_FEATURE_xcb) diff --git a/src/plugins/platforms/android/CMakeLists.txt b/src/plugins/platforms/android/CMakeLists.txt index 0160e12c26c..0d2a048abde 100644 --- a/src/plugins/platforms/android/CMakeLists.txt +++ b/src/plugins/platforms/android/CMakeLists.txt @@ -51,7 +51,12 @@ qt_internal_add_plugin(QAndroidIntegrationPlugin qandroidplatformdialoghelpers.cpp # Conflicting JNI classes, and types androidcontentfileengine.cpp + qandroidplatformforeignwindow.cpp qandroidplatformintegration.cpp + qandroidplatformscreen.cpp + qandroidplatformservices.cpp + qandroidplatformwindow.cpp + qandroidsystemlocale.cpp INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} ${QtBase_SOURCE_DIR}/src/3rdparty/android diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index 200c2f7a47b..b3ff0a4f06e 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -28,6 +28,7 @@ using namespace Qt::StringLiterals; namespace QtAndroidAccessibility { + static jmethodID m_setClassNameMethodID = 0; static jmethodID m_addActionMethodID = 0; static jmethodID m_setCheckableMethodID = 0; static jmethodID m_setCheckedMethodID = 0; @@ -421,6 +422,130 @@ namespace QtAndroidAccessibility return jstr; } + static QString classNameForRole(QAccessible::Role role, QAccessible::State state) { + switch (role) { + case QAccessible::Role::Button: + case QAccessible::Role::Link: + { + if (state.checkable) + // There is also a android.widget.Switch for which we have no match. + return QStringLiteral("android.widget.ToggleButton"); + return QStringLiteral("android.widget.Button"); + } + case QAccessible::Role::CheckBox: + // As of android/accessibility/utils/Role.java::getRole a CheckBox + // is NOT android.widget.CheckBox + return QStringLiteral("android.widget.CompoundButton"); + case QAccessible::Role::Clock: + return QStringLiteral("android.widget.TextClock"); + case QAccessible::Role::ComboBox: + return QStringLiteral("android.widget.Spinner"); + case QAccessible::Role::Graphic: + // QQuickImage does not provide this role it inherits Client from QQuickItem + return QStringLiteral("android.widget.ImageView"); + case QAccessible::Role::Grouping: + return QStringLiteral("android.view.ViewGroup"); + case QAccessible::Role::List: + // As of android/accessibility/utils/Role.java::getRole a List + // is NOT android.widget.ListView + return QStringLiteral("android.widget.AbsListView"); + case QAccessible::Role::MenuItem: + return QStringLiteral("android.view.MenuItem"); + case QAccessible::Role::PopupMenu: + return QStringLiteral("android.widget.PopupMenu"); + case QAccessible::Role::Separator: + return QStringLiteral("android.widget.Space"); + case QAccessible::Role::ToolBar: + return QStringLiteral("android.view.Toolbar"); + case QAccessible::Role::Heading: [[fallthrough]]; + case QAccessible::Role::StaticText: + // Heading vs. regular Text is finally determined by AccessibilityNodeInfo.isHeading() + return QStringLiteral("android.widget.TextView"); + case QAccessible::Role::EditableText: + return QStringLiteral("android.widget.EditText"); + case QAccessible::Role::RadioButton: + return QStringLiteral("android.widget.RadioButton"); + case QAccessible::Role::ProgressBar: + return QStringLiteral("android.widget.ProgressBar"); + // Range information need to be filled to announce percentages + case QAccessible::Role::SpinBox: + return QStringLiteral("android.widget.NumberPicker"); + case QAccessible::Role::WebDocument: + return QStringLiteral("android.webkit.WebView"); + case QAccessible::Role::Dialog: + return QStringLiteral("android.app.AlertDialog"); + case QAccessible::Role::PageTab: + return QStringLiteral("android.app.ActionBar.Tab"); + case QAccessible::Role::PageTabList: + return QStringLiteral("android.widget.TabWidget"); + case QAccessible::Role::ScrollBar: [[fallthrough]]; + case QAccessible::Role::Slider: + return QStringLiteral("android.widget.SeekBar"); + case QAccessible::Role::Table: + // #TODO Evaluate the usage of AccessibleNodeInfo.setCollectionItemInfo() to provide + // infos about colums, rows und items. + return QStringLiteral("android.widget.GridView"); + case QAccessible::Role::Pane: + // #TODO QQuickScrollView, QQuickListView (see QTBUG-137806) + return QStringLiteral("android.view.ViewGroup"); + case QAccessible::Role::AlertMessage: + case QAccessible::Role::Animation: + case QAccessible::Role::Application: + case QAccessible::Role::Assistant: + case QAccessible::Role::BlockQuote: + case QAccessible::Role::Border: + case QAccessible::Role::ButtonDropGrid: + case QAccessible::Role::ButtonDropDown: + case QAccessible::Role::ButtonMenu: + case QAccessible::Role::Canvas: + case QAccessible::Role::Caret: + case QAccessible::Role::Cell: + case QAccessible::Role::Chart: + case QAccessible::Role::Client: + case QAccessible::Role::ColorChooser: + case QAccessible::Role::Column: + case QAccessible::Role::ColumnHeader: + case QAccessible::Role::ComplementaryContent: + case QAccessible::Role::Cursor: + case QAccessible::Role::Desktop: + case QAccessible::Role::Dial: + case QAccessible::Role::Document: + case QAccessible::Role::Equation: + case QAccessible::Role::Footer: + case QAccessible::Role::Form: + case QAccessible::Role::Grip: + case QAccessible::Role::HelpBalloon: + case QAccessible::Role::HotkeyField: + case QAccessible::Role::Indicator: + case QAccessible::Role::LayeredPane: + case QAccessible::Role::ListItem: + case QAccessible::Role::MenuBar: + case QAccessible::Role::NoRole: + case QAccessible::Role::Note: + case QAccessible::Role::Notification: + case QAccessible::Role::Paragraph: + case QAccessible::Role::PropertyPage: + case QAccessible::Role::Row: + case QAccessible::Role::RowHeader: + case QAccessible::Role::Section: + case QAccessible::Role::Sound: + case QAccessible::Role::Splitter: + case QAccessible::Role::StatusBar: + case QAccessible::Role::Terminal: + case QAccessible::Role::TitleBar: + case QAccessible::Role::ToolTip: + case QAccessible::Role::Tree: + case QAccessible::Role::TreeItem: + case QAccessible::Role::UserRole: + case QAccessible::Role::Whitespace: + case QAccessible::Role::Window: + // If unsure, every visible or interactive element in Android + // inherits android.view.View and by many extends also TextView. + // Android itself does a similar thing e.g. in its Settings-App. + return QStringLiteral("android.view.TextView"); + } + } + static QString descriptionForInterface(QAccessibleInterface *iface) { QString desc; @@ -513,6 +638,10 @@ namespace QtAndroidAccessibility return false; } + const QString role = classNameForRole(info.role, info.state); + jstring jrole = env->NewString((jchar*)role.constData(), (jsize)role.size()); + env->CallVoidMethod(node, m_setClassNameMethodID, jrole); + const bool hasClickableAction = info.actions.contains(QAccessibleActionInterface::pressAction()) || info.actions.contains(QAccessibleActionInterface::toggleAction()); @@ -590,6 +719,7 @@ namespace QtAndroidAccessibility } jclass nodeInfoClass = env->FindClass("android/view/accessibility/AccessibilityNodeInfo"); + GET_AND_CHECK_STATIC_METHOD(m_setClassNameMethodID, nodeInfoClass, "setClassName", "(Ljava/lang/CharSequence;)V"); GET_AND_CHECK_STATIC_METHOD(m_addActionMethodID, nodeInfoClass, "addAction", "(I)V"); GET_AND_CHECK_STATIC_METHOD(m_setCheckableMethodID, nodeInfoClass, "setCheckable", "(Z)V"); GET_AND_CHECK_STATIC_METHOD(m_setCheckedMethodID, nodeInfoClass, "setChecked", "(Z)V"); diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index 4105b1030c8..194a08ee09f 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -168,16 +168,6 @@ void QAndroidPlatformWindow::setVisible(bool visible) return; if (window()->isTopLevel()) { - // Do not hide last Qt for Android window. - // We don't want the splash screen to be shown during the app's - // exit because it would be the foremost visible screen. - if (QtAndroid::isQtApplication() && !visible) { - bool lastVisibleWindow = - m_nativeQtWindow.callMethod<bool>("isLastVisibleTopLevelWindow"); - m_nativeQtWindow.callMethod<void>("setToDestroy", !lastVisibleWindow); - if (lastVisibleWindow) - return; - } if (!visible && window() == qGuiApp->focusWindow()) { platformScreen()->topVisibleWindowChanged(); } else { diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp index 9c10c1a998c..0b9db8039f1 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp @@ -79,8 +79,10 @@ void QEglFSContext::swapBuffers(QPlatformSurface *surface) // draw the cursor if (surface->surface()->surfaceClass() == QSurface::Window) { QPlatformWindow *window = static_cast<QPlatformWindow *>(surface); - if (QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(window->screen()->cursor())) - cursor->paintOnScreen(); + if (QPlatformScreen *screen = window->screen()) { + if (QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(screen->cursor())) + cursor->paintOnScreen(); + } } qt_egl_device_integration()->waitForVSync(surface); diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp index 4abe948117e..2f278a474e0 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp @@ -154,6 +154,7 @@ QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *wi if (!window->handle()) window->create(); static_cast<QEglFSWindow *>(window->handle())->setBackingStore(bs); + m_bs = bs; return bs; #else Q_UNUSED(window); @@ -175,6 +176,9 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen()) w->requestActivateWindow(); + if (window->isTopLevel()) + w->setBackingStore(static_cast<QOpenGLCompositorBackingStore *>(m_bs)); + return w; } diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h index 2359b7f29f1..3865b7130b7 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h @@ -112,6 +112,7 @@ private: QScopedPointer<QFbVtHandler> m_vtHandler; QPointer<QWindow> m_pointerWindow; bool m_disableInputHandlers; + mutable QPlatformBackingStore *m_bs = nullptr; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor_p.h index a0f78bb3103..cca9097e2f0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor_p.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor_p.h @@ -62,6 +62,8 @@ public: void reevaluateVisibilityForScreens() { setPos(pos()); } + QEglFSKmsGbmScreen *screen() const { return m_screen; } + private: void initCursorAtlas(); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp index a7592ed55e4..9f19e649f85 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp @@ -113,13 +113,27 @@ QPlatformScreen *QEglFSKmsGbmDevice::createScreen(const QKmsOutput &output) { QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(this, output, false); - createGlobalCursor(screen); + + // On some platforms (e.g. rpi4), you'll get a kernel warning/error + // if the cursor is created 'at the same time' as the screen is created. + // (drmModeMoveCursor is the specific call that causes the issue) + // When this issue is triggered, the screen's connector is unusable until reboot + // + // Below is a work-around (without negative implications for other platforms). + // + // interval of 0 and QMetaObject::invokeMethod (w/o Qt::QueuedConnection) + // do no help / will still trigger issue + QTimer::singleShot(1, [screen, this](){ + createGlobalCursor(screen); + }); return screen; } QPlatformScreen *QEglFSKmsGbmDevice::createHeadlessScreen() { + destroyGlobalCursor(); + return new QEglFSKmsGbmScreen(this, QKmsOutput(), true); } @@ -127,9 +141,6 @@ void QEglFSKmsGbmDevice::registerScreenCloning(QPlatformScreen *screen, QPlatformScreen *screenThisScreenClones, const QList<QPlatformScreen *> &screensCloningThisScreen) { - if (!screenThisScreenClones && screensCloningThisScreen.isEmpty()) - return; - QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen *>(screen); gbmScreen->initCloning(screenThisScreenClones, screensCloningThisScreen); } @@ -144,6 +155,32 @@ void QEglFSKmsGbmDevice::registerScreen(QPlatformScreen *screen, m_globalCursor->reevaluateVisibilityForScreens(); } +void QEglFSKmsGbmDevice::unregisterScreen(QPlatformScreen *screen) +{ + // The global cursor holds a pointer to a QEglFSKmsGbmScreen. + // If that screen is being unregistered, + // this will recreate the global cursor with the first sibling screen. + if (m_globalCursor && screen == m_globalCursor->screen()) { + qCDebug(qLcEglfsKmsDebug) << "Destroying global GBM mouse cursor due to unregistering" + << "it's screen - will probably be recreated right away"; + delete m_globalCursor; + m_globalCursor = nullptr; + + QList<QPlatformScreen *> siblings = screen->virtualSiblings(); + siblings.removeOne(screen); + if (siblings.count() > 0) { + QEglFSKmsGbmScreen *kmsScreen = static_cast<QEglFSKmsGbmScreen *>(siblings.first()); + m_globalCursor = new QEglFSKmsGbmCursor(kmsScreen); + qCDebug(qLcEglfsKmsDebug) << "Creating new global GBM mouse cursor on sibling screen"; + } else { + qCWarning(qLcEglfsKmsDebug) << "Couldn't find a sibling to recreate" + << "the GBM mouse cursor - it might vanish"; + } + } + + QEglFSKmsDevice::unregisterScreen(screen); +} + bool QEglFSKmsGbmDevice::usesEventReader() const { static const bool eventReaderThreadDisabled = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_NO_EVENT_READER_THREAD"); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h index e00992ed291..0ffed0ec4ef 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h @@ -51,6 +51,7 @@ public: bool isPrimary, const QPoint &virtualPos, const QList<QPlatformScreen *> &virtualSiblings) override; + void unregisterScreen(QPlatformScreen *screen) override; bool usesEventReader() const; QEglFSKmsEventReader *eventReader() { return &m_eventReader; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp index 05ffb3b212e..eb61de3c534 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp @@ -11,6 +11,7 @@ #include "private/qeglfscursor_p.h" #include <QtCore/QLoggingCategory> +#include <QtCore/QFileSystemWatcher> #include <QtGui/QScreen> #include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h> @@ -23,6 +24,10 @@ QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration() qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via GBM integration created"); } +QEglFSKmsGbmIntegration::~QEglFSKmsGbmIntegration() +{ +} + #ifndef EGL_EXT_platform_base typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); #endif @@ -94,14 +99,16 @@ void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface) QKmsDevice *QEglFSKmsGbmIntegration::createDevice() { + + m_deviceDiscovery = std::unique_ptr<QDeviceDiscovery>(QDeviceDiscovery::create(QDeviceDiscovery::Device_VideoMask)); + m_kmsConfigWatcher = std::unique_ptr<QFileSystemWatcher>(new QFileSystemWatcher()); + QString path = screenConfig()->devicePath(); if (!path.isEmpty()) { qCDebug(qLcEglfsKmsDebug) << "GBM: Using DRM device" << path << "specified in config file"; } else { - QDeviceDiscovery *d = QDeviceDiscovery::create(QDeviceDiscovery::Device_VideoMask); - const QStringList devices = d->scanConnectedDevices(); + const QStringList devices = m_deviceDiscovery->scanConnectedDevices(); qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices; - d->deleteLater(); if (Q_UNLIKELY(devices.isEmpty())) qFatal("Could not find DRM device!"); @@ -110,6 +117,35 @@ QKmsDevice *QEglFSKmsGbmIntegration::createDevice() qCDebug(qLcEglfsKmsDebug) << "Using" << path; } + bool hotreload = !qEnvironmentVariable("QT_QPA_EGLFS_HOTPLUG_ENABLED").isEmpty(); + if (hotreload) { + qCWarning(qLcEglfsKmsDebug) << "EGLFS/KMS: Hot-Reload on KMS-events enabled, be aware that" + << "this requires actions in UI code for proper functionallity" + << "(e.g. close/open windows on screen's disconnect/connect)"; + QObject::connect(m_deviceDiscovery.get(), &QDeviceDiscovery::deviceChanged, + m_deviceDiscovery.get(), [this](const QString &deviceNode) { + qCDebug(qLcEglfsKmsDebug) << "KMS device changed:" << deviceNode; + m_device->checkConnectedScreens(); + }); + } + + QString json = qEnvironmentVariable("QT_QPA_EGLFS_KMS_CONFIG"); + if (json.isEmpty()) + json = qEnvironmentVariable("QT_QPA_KMS_CONFIG"); + + if (!json.isEmpty()) { + m_kmsConfigWatcher->addPath(json); + QObject::connect(m_kmsConfigWatcher.get(), &QFileSystemWatcher::fileChanged, + m_kmsConfigWatcher.get(), [this, json]() { + qCDebug(qLcEglfsKmsDebug) << "KMS config-file has changed! path:" + << json; + m_screenConfig->refreshConfig(); + m_device->updateScreens(); + m_kmsConfigWatcher->addPath(json); // as per QFileSystemWatcher doc we have to re-add + // the path in case it's a new file + }); + } + return new QEglFSKmsGbmDevice(screenConfig(), path); } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration_p.h index fb118438d25..7c2c2a474d7 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration_p.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration_p.h @@ -24,11 +24,14 @@ QT_BEGIN_NAMESPACE class QEglFSKmsDevice; +class QDeviceDiscovery; +class QFileSystemWatcher; class Q_EGLFS_EXPORT QEglFSKmsGbmIntegration : public QEglFSKmsIntegration { public: QEglFSKmsGbmIntegration(); + ~QEglFSKmsGbmIntegration() override; EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) override; EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format) override; @@ -42,6 +45,8 @@ protected: QKmsDevice *createDevice() override; private: + std::unique_ptr<QDeviceDiscovery> m_deviceDiscovery; + std::unique_ptr<QFileSystemWatcher> m_kmsConfigWatcher; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 00fecb87f1f..332030f03f2 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -20,7 +20,7 @@ QT_BEGIN_NAMESPACE -QMutex QEglFSKmsGbmScreen::m_nonThreadedFlipMutex; +QMutex QEglFSKmsGbmScreen::s_nonThreadedFlipMutex; static inline uint32_t drmFormatToGbmFormat(uint32_t drmFormat) { @@ -92,9 +92,26 @@ QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const QKmsOutput QEglFSKmsGbmScreen::~QEglFSKmsGbmScreen() { const int remainingScreenCount = qGuiApp->screens().count(); - qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount); + qCDebug(qLcEglfsKmsDebug, "Screen dtor. %p Remaining screens: %d", this, remainingScreenCount); if (!remainingScreenCount && !device()->screenConfig()->separateScreens()) static_cast<QEglFSKmsGbmDevice *>(device())->destroyGlobalCursor(); + + if (m_cloneSource) { + // Remove this screen from the screen that has it as a clone destination + QList<CloneDestination> &dests = m_cloneSource->m_cloneDests; + auto newEnd = std::remove_if(dests.begin(), dests.end(), + [this](CloneDestination &dest) { + return dest.screen == this; + }); + dests.erase(newEnd, dests.end()); + } + + // Other screens can no longer have this screen as a clone source + for (CloneDestination &dest : m_cloneDests) { + dest.screen->m_cloneSource = nullptr; + // Mode must be set again before flipping + dest.screen->m_output.mode_set = false; + } } QPlatformCursor *QEglFSKmsGbmScreen::cursor() const @@ -206,9 +223,12 @@ void QEglFSKmsGbmScreen::initCloning(QPlatformScreen *screenThisScreenClones, if (clonesAnother) { m_cloneSource = static_cast<QEglFSKmsGbmScreen *>(screenThisScreenClones); qCDebug(qLcEglfsKmsDebug, "Screen %s clones %s", qPrintable(name()), qPrintable(m_cloneSource->name())); + } else { + m_cloneSource = nullptr; } // clone sources need to know their additional destinations + m_cloneDests.clear(); for (QPlatformScreen *s : screensCloningThisScreen) { CloneDestination d; d.screen = static_cast<QEglFSKmsGbmScreen *>(s); @@ -271,8 +291,11 @@ void QEglFSKmsGbmScreen::nonThreadedPageFlipHandler(int fd, // note that with cloning involved this callback is called also for screens that clone another one Q_UNUSED(fd); QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(user_data); - screen->flipFinished(); - screen->pageFlipped(sequence, tv_sec, tv_usec); + // The screen might have been deleted when DRM calls this handler + if (QEglFSKmsScreen::isScreenKnown(screen)) { + screen->flipFinished(); + screen->pageFlipped(sequence, tv_sec, tv_usec); + } } void QEglFSKmsGbmScreen::waitForFlipWithEventReader(QEglFSKmsGbmScreen *screen) @@ -280,7 +303,21 @@ void QEglFSKmsGbmScreen::waitForFlipWithEventReader(QEglFSKmsGbmScreen *screen) m_flipMutex.lock(); QEglFSKmsGbmDevice *dev = static_cast<QEglFSKmsGbmDevice *>(device()); dev->eventReader()->startWaitFlip(screen, &m_flipMutex, &m_flipCond); - m_flipCond.wait(&m_flipMutex); + + // We should only wait forever on this screen, clones should have a timeout + // (e.g. I clone might have been created just before the flip, + // we might wait for it but it might not know about waking us up) + bool succ = false; + if (screen == this) + succ = m_flipCond.wait(&m_flipMutex); + else + succ = m_flipCond.wait(&m_flipMutex, 300); + + if (!succ) + qCWarning(qLcEglfsKmsDebug) << "timeout on waitForFlipWithEventReader, screen to wait for:" + << screen << ", screen waiting (shouldn't be the same screen):" + << this; + m_flipMutex.unlock(); screen->flipFinished(); } @@ -306,7 +343,7 @@ void QEglFSKmsGbmScreen::waitForFlip() waitForFlipWithEventReader(d.screen); } } else { - QMutexLocker lock(&m_nonThreadedFlipMutex); + QMutexLocker lock(&s_nonThreadedFlipMutex); while (m_gbm_bo_next) { drmEventContext drmEvent; memset(&drmEvent, 0, sizeof(drmEvent)); @@ -359,15 +396,10 @@ static void addAtomicFlip(drmModeAtomicReq *request, const QKmsOutput &output, u void QEglFSKmsGbmScreen::flip() { - // For headless screen just return silently. It is not necessarily an error + // For headless or cloned screen just return silently. It is not necessarily an error // to end up here, so show no warnings. - if (m_headless) - return; - - if (m_cloneSource) { - qWarning("Screen %s clones another screen. swapBuffers() not allowed.", qPrintable(name())); + if (m_headless || m_cloneSource) return; - } if (!m_gbm_surface) { qWarning("Cannot sync before platform init!"); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen_p.h index aca34fcae21..65625a3c1cd 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen_p.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen_p.h @@ -67,7 +67,7 @@ protected: QMutex m_flipMutex; QWaitCondition m_flipCond; - static QMutex m_nonThreadedFlipMutex; + static QMutex s_nonThreadedFlipMutex; QScopedPointer<QEglFSKmsGbmCursor> m_cursor; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index ece19f46a49..ff4921c2b15 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -213,9 +213,13 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const QEglFSKmsEglDeviceWindow *eglWindow = new QEglFSKmsEglDeviceWindow(window, this); m_funcs->initialize(eglWindow->screen()->display()); - if (Q_UNLIKELY(!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm && m_funcs->has_egl_stream && - m_funcs->has_egl_stream_producer_eglsurface && m_funcs->has_egl_stream_consumer_egloutput))) + if (Q_UNLIKELY(!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm + && m_funcs->has_egl_stream && m_funcs->has_egl_stream_producer_eglsurface + && m_funcs->has_egl_stream_consumer_egloutput))) { + qCDebug(qLcEglfsKmsDebug, "EGL_EXTENSIONS %s", + eglQueryString(eglWindow->screen()->display(), EGL_EXTENSIONS)); qFatal("Required extensions missing!"); + } return eglWindow; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp index 5af45e63a2f..5775ac3607a 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp @@ -71,7 +71,7 @@ QEglFSKmsEglDeviceScreen::~QEglFSKmsEglDeviceScreen() } const int remainingScreenCount = qGuiApp->screens().size(); - qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount); + qCDebug(qLcEglfsKmsDebug, "Screen dtor. %p Remaining screens: %d", this, remainingScreenCount); if (!remainingScreenCount && !device()->screenConfig()->separateScreens()) static_cast<QEglFSKmsEglDevice *>(device())->destroyGlobalCursor(); } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp index 037b26f023e..59ca53355d6 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp @@ -25,4 +25,39 @@ void QEglFSKmsDevice::registerScreen(QPlatformScreen *screen, QWindowSystemInterface::handleScreenAdded(s, isPrimary); } +void QEglFSKmsDevice::unregisterScreen(QPlatformScreen *screen) +{ + QEglFSKmsScreen *s = static_cast<QEglFSKmsScreen *>(screen); + for (QPlatformScreen *sibling : s->virtualSiblings()) + static_cast<QEglFSKmsScreen *>(sibling)->removeSibling(s); + + QWindowSystemInterface::handleScreenRemoved(screen); +} + +void QEglFSKmsDevice::updateScreen(QPlatformScreen *screen, const QPoint &virtualPos, + const QList<QPlatformScreen *> &virtualSiblings) +{ + QEglFSKmsScreen *s = static_cast<QEglFSKmsScreen *>(screen); + QRect before = s->geometry(); + s->setVirtualPosition(virtualPos); + s->setVirtualSiblings(virtualSiblings); + QRect after = s->geometry(); + + if (before != after) + QWindowSystemInterface::handleScreenGeometryChange(s->screen(), after, + s->availableGeometry()); +} + +void QEglFSKmsDevice::updateScreenOutput(QPlatformScreen *screen, const QKmsOutput &output) +{ + QEglFSKmsScreen *s = static_cast<QEglFSKmsScreen *>(screen); + QRect before = s->geometry(); + s->updateOutput(output); + QRect after = s->geometry(); + + if (before != after) + QWindowSystemInterface::handleScreenGeometryChange(s->screen(), after, + s->availableGeometry()); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice_p.h index 6e11953a699..49b82d8baad 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice_p.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice_p.h @@ -30,6 +30,13 @@ public: bool isPrimary, const QPoint &virtualPos, const QList<QPlatformScreen *> &virtualSiblings) override; + + void unregisterScreen(QPlatformScreen *screen) override; + + void updateScreen(QPlatformScreen *screen, const QPoint &virtualPos, + const QList<QPlatformScreen *> &virtualSiblings) override; + + void updateScreenOutput(QPlatformScreen *screen, const QKmsOutput &output) override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp index c0c96554962..fa735388bc0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp @@ -20,7 +20,10 @@ static void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, t->eventHost()->handlePageFlipCompleted(user_data); QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(user_data); - screen->pageFlipped(sequence, tv_sec, tv_usec); + if (QEglFSKmsScreen::isScreenKnown(screen)) + screen->pageFlipped(sequence, tv_sec, tv_usec); + else + qWarning("Deleted screen got it's pageFlipHandler called; Dead pointer: %p", user_data); } class RegisterWaitFlipEvent : public QEvent diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp index cc7381fb701..a40287bdfed 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp @@ -16,6 +16,8 @@ QT_BEGIN_NAMESPACE +QSet<QEglFSKmsScreen *> QEglFSKmsScreen::s_screens; + class QEglFSKmsInterruptHandler : public QObject { public: @@ -59,10 +61,14 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsDevice *device, const QKmsOutput &outp } else { qCDebug(qLcEglfsKmsDebug) << "No EDID data for output" << name(); } + + s_screens.insert(this); } QEglFSKmsScreen::~QEglFSKmsScreen() { + s_screens.remove(this); + m_output.cleanup(m_device); delete m_interruptHandler; } @@ -166,6 +172,11 @@ void QEglFSKmsScreen::waitForFlip() { } +void QEglFSKmsScreen::updateOutput(QKmsOutput output) +{ + m_output = output; +} + void QEglFSKmsScreen::restoreMode() { m_output.restoreMode(m_device); @@ -180,6 +191,11 @@ qreal QEglFSKmsScreen::refreshRate() const return refresh > 0 ? refresh : 60; } +void QEglFSKmsScreen::removeSibling(QPlatformScreen *screen) +{ + m_siblings.removeAll(screen); +} + QList<QPlatformScreen::Mode> QEglFSKmsScreen::modes() const { QList<QPlatformScreen::Mode> list; @@ -227,4 +243,9 @@ void QEglFSKmsScreen::pageFlipped(unsigned int sequence, unsigned int tv_sec, un Q_UNUSED(tv_usec); } +bool QEglFSKmsScreen::isScreenKnown(QEglFSKmsScreen *s) +{ + return s_screens.contains(s); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen_p.h index 6fb1f9a1348..2dc49152a97 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen_p.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen_p.h @@ -58,6 +58,7 @@ public: QList<QPlatformScreen *> virtualSiblings() const override { return m_siblings; } void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; } + void removeSibling(QPlatformScreen *screen); QList<QPlatformScreen::Mode> modes() const override; @@ -68,6 +69,7 @@ public: virtual void waitForFlip(); + void updateOutput(QKmsOutput output); QKmsOutput &output() { return m_output; } void restoreMode(); @@ -80,6 +82,8 @@ public: void setCursorOutOfRange(bool b) { m_cursorOutOfRange = b; } virtual void pageFlipped(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec); + static bool isScreenKnown(QEglFSKmsScreen *s); + protected: QEglFSKmsDevice *m_device; @@ -95,6 +99,8 @@ protected: QEglFSKmsInterruptHandler *m_interruptHandler; bool m_headless; + + static QSet<QEglFSKmsScreen *> s_screens; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasminputcontext.cpp b/src/plugins/platforms/wasm/qwasminputcontext.cpp index 27641195cae..2df7066b8e2 100644 --- a/src/plugins/platforms/wasm/qwasminputcontext.cpp +++ b/src/plugins/platforms/wasm/qwasminputcontext.cpp @@ -383,6 +383,16 @@ void QWasmInputContext::setFocusObject(QObject *object) { qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << object << inputMethodAccepted(); + QInputMethodQueryEvent query(Qt::InputMethodQueries(Qt::ImEnabled | Qt::ImHints)); + QCoreApplication::sendEvent(object, &query); + if (query.value(Qt::ImEnabled).toBool() + && Qt::InputMethodHints(query.value(Qt::ImHints).toInt()).testFlag(Qt::ImhHiddenText)) { + m_inputElement.set("type", "password"); + } else { + if (m_inputElement["type"].as<std::string>() != std::string("text")) + m_inputElement.set("type", "text"); + } + // Commit the previous composition before change m_focusObject if (m_focusObject && !m_preeditString.isEmpty()) commitPreeditAndClear(); diff --git a/src/plugins/platforms/wayland/CMakeLists.txt b/src/plugins/platforms/wayland/CMakeLists.txt index ac90eeadfa2..254a43c0dc6 100644 --- a/src/plugins/platforms/wayland/CMakeLists.txt +++ b/src/plugins/platforms/wayland/CMakeLists.txt @@ -77,6 +77,7 @@ qt_internal_add_module(WaylandClient qwaylandplatformservices.cpp qwaylandplatformservices_p.h qwaylandpointergestures.cpp qwaylandpointergestures_p.h qwaylandscreen.cpp qwaylandscreen_p.h + qwaylandsessionmanager.cpp qwaylandsessionmanager_p.h qwaylandshellsurface.cpp qwaylandshellsurface_p.h qwaylandshm.cpp qwaylandshm_p.h qwaylandshmbackingstore.cpp qwaylandshmbackingstore_p.h @@ -124,6 +125,8 @@ qt_internal_add_module(WaylandClient ../../../3rdparty/wayland/protocols/viewporter ../../../3rdparty/wayland/protocols/xdg-shell ../../../3rdparty/wayland/protocols/wlr-data-control + ../../../3rdparty/wayland/protocols/session-management + ) qt_internal_add_plugin(QWaylandIntegrationPlugin @@ -163,6 +166,8 @@ qt6_generate_wayland_protocol_client_sources(WaylandClient ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/extensions/hardware-integration.xml ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/extensions/server-buffer-extension.xml ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/protocols/color-management/xx-color-management-v4.xml + ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/protocols/pointer-warp/pointer-warp-v1.xml + ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wayland/protocols/session-management/xx-session-management-v1.xml ) #### Keys ignored in scope 1:.:.:client.pro:<TRUE>: diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index 1356d93abab..b19899db59a 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -8,6 +8,7 @@ #include "qwaylandxdgexporterv2_p.h" #include "qwaylandxdgdialogv1_p.h" #include "qwaylandxdgtopleveliconv1_p.h" +#include "qwaylandsessionmanager_p.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtWaylandClient/private/qwaylandwindow_p.h> @@ -23,6 +24,16 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { +template <typename T, auto f> +struct WithDestructor : public T +{ + using T::T; + ~WithDestructor() + { + f(this->object()); + } +}; + QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface) : QtWayland::xdg_toplevel(xdgSurface->get_toplevel()) , m_xdgSurface(xdgSurface) @@ -45,6 +56,12 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface) m_xdgDialog.reset(m_xdgSurface->m_shell->m_xdgDialogWm->getDialog(object())); m_xdgDialog->set_modal(); } + +#ifndef QT_NO_SESSIONMANAGER + const QString sessionRestoreId = xdgSurface->window()->sessionRestoreId(); + if (!sessionRestoreId.isEmpty() && QWaylandSessionManager::instance()->session()) + m_session.reset(new WithDestructor<QtWayland::xx_toplevel_session_v1, xx_toplevel_session_v1_destroy>(QWaylandSessionManager::instance()->session()->restore_toplevel(object(), sessionRestoreId))); +#endif } QWaylandXdgSurface::Toplevel::~Toplevel() @@ -314,23 +331,13 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s Qt::WindowType type = static_cast<Qt::WindowType>(int(window->windowFlags() & Qt::WindowType_Mask)); auto *transientParent = window->transientParent(); - if (type == Qt::ToolTip) { - if (transientParent) { - setPopup(transientParent); - } else { - qCWarning(lcQpaWayland) << "Failed to create popup. Ensure popup " << window->window() << "has a transientParent set."; - QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::AsynchronousDelivery>(m_window->window()); - } - } else if (type == Qt::Popup ) { - if (transientParent && display->lastInputDevice()) { - setGrabPopup(transientParent, display->lastInputDevice(), display->lastInputSerial()); - } else { - qCWarning(lcQpaWayland) << "Failed to create grabbing popup. Ensure popup " << window->window() << "has a transientParent set and that parent window has received input."; - QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::AsynchronousDelivery>(m_window->window()); - } - } else { + if (type == Qt::ToolTip) + setPopup(transientParent); + else if (type == Qt::Popup ) + setGrabPopup(transientParent, display->lastInputDevice(), display->lastInputSerial()); + else setToplevel(); - } + setSizeHints(); } diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h index 236d34c351c..4595940508c 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -30,6 +30,10 @@ QT_BEGIN_NAMESPACE +namespace QtWayland { + class xx_toplevel_session_v1; +} + namespace QtWaylandClient { class QWaylandDisplay; @@ -41,6 +45,7 @@ class QWaylandXdgExporterV2; class QWaylandXdgDialogWmV1; class QWaylandXdgDialogV1; class QWaylandXdgToplevelIconManagerV1; +class QWaylandTopLevelSession; class Q_WAYLANDCLIENT_EXPORT QWaylandXdgSurface : public QWaylandShellSurface, public QtWayland::xdg_surface { @@ -114,6 +119,7 @@ private: QWaylandXdgToplevelDecorationV1 *m_decoration = nullptr; QScopedPointer<QWaylandXdgExportedV2> m_exported; QScopedPointer<QWaylandXdgDialogV1> m_xdgDialog; + QScopedPointer<QtWayland::xx_toplevel_session_v1> m_session; }; class Positioner : public QtWayland::xdg_positioner { diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp index f1bb8bee478..90a5965bba6 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp @@ -8,6 +8,8 @@ #include <QtWaylandClient/private/qwaylandwindow_p.h> #include <QtWaylandClient/private/qwaylanddisplay_p.h> +#include <qpa/qwindowsysteminterface.h> + QT_BEGIN_NAMESPACE namespace QtWaylandClient { @@ -43,6 +45,22 @@ void QWaylandXdgShellIntegration::xdg_wm_base_ping(uint32_t serial) QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWindow *window) { + QWaylandDisplay *display = window->display(); + Qt::WindowType type = static_cast<Qt::WindowType>(int(window->windowFlags() & Qt::WindowType_Mask)); + auto *transientParent = window->transientParent(); + + if (type == Qt::ToolTip && !transientParent) { + qCWarning(lcQpaWayland) << "Failed to create popup. Ensure popup " << window->window() << "has a transientParent set."; + QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::AsynchronousDelivery>(window->window()); + return new QWaylandShellSurface(window); + } + + if (type == Qt::Popup && (!transientParent || !display->lastInputDevice())) { + qCWarning(lcQpaWayland) << "Failed to create grabbing popup. Ensure popup " << window->window() << "has a transientParent set and that parent window has received input."; + QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::AsynchronousDelivery>(window->window()); + return new QWaylandShellSurface(window); + } + return new QWaylandXdgSurface(mXdgShell.get(), get_xdg_surface(window->wlSurface()), window); } diff --git a/src/plugins/platforms/wayland/qwaylandcursor.cpp b/src/plugins/platforms/wayland/qwaylandcursor.cpp index 7a25b10bd4d..4967f9d46f4 100644 --- a/src/plugins/platforms/wayland/qwaylandcursor.cpp +++ b/src/plugins/platforms/wayland/qwaylandcursor.cpp @@ -7,6 +7,7 @@ #include "qwaylanddisplay_p.h" #include "qwaylandinputdevice_p.h" #include "qwaylandshmbackingstore_p.h" +#include "qwayland-pointer-warp-v1.h" #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformtheme.h> @@ -329,6 +330,8 @@ void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) if (device->pointer() && device->pointer()->focusWindow() == waylandWindow) device->setCursor(cursor, bitmapBuffer, qCeil(waylandWindow->devicePixelRatio())); } + + mDisplay->flushRequests(); } } @@ -344,8 +347,22 @@ QPoint QWaylandCursor::pos() const void QWaylandCursor::setPos(const QPoint &pos) { - Q_UNUSED(pos); - qCWarning(lcQpaWayland) << "Setting cursor position is not possible on wayland"; + if (mDisplay->pointerWarp()) { + const auto seats = mDisplay->inputDevices(); + for (auto *seat : seats) { + if (!seat->pointer() || !seat->pointer()->focusWindow()) { + continue; + } + const auto focus = seat->pointer()->focusWindow(); + if (!focus->windowFrameGeometry().contains(pos)) { + continue; + } + mDisplay->pointerWarp()->warp_pointer(focus->surface(), seat->pointer()->object(), wl_fixed_from_double(pos.x() - focus->windowFrameGeometry().x()), wl_fixed_from_double(pos.y() - focus->windowFrameGeometry().y()), seat->pointer()->mEnterSerial); + return; + } + } else { + qCWarning(lcQpaWayland) << "Setting cursor position requires pointer warp v1 protocol support"; + } } void QWaylandCursor::setPosFromEnterEvent(const QPoint &pos) diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index c4cdbecf6ae..d853fc673e5 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -53,9 +53,11 @@ #include <QtWaylandClient/private/qwayland-fractional-scale-v1.h> #include <QtWaylandClient/private/qwayland-viewporter.h> #include <QtWaylandClient/private/qwayland-cursor-shape-v1.h> +#include <QtWaylandClient/private/qwayland-xx-session-management-v1.h> #include <QtWaylandClient/private/qwayland-xdg-system-bell-v1.h> #include <QtWaylandClient/private/qwayland-xdg-toplevel-drag-v1.h> #include <QtWaylandClient/private/qwayland-wlr-data-control-unstable-v1.h> +#include <QtWaylandClient/private/qwayland-pointer-warp-v1.h> #include <QtCore/private/qcore_unix_p.h> @@ -798,7 +800,19 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mGlobals.colorManager = std::make_unique<ColorManager>(registry, id, 1); // we need a roundtrip to receive the features the compositor supports forceRoundTrip(); + } else if (interface == QLatin1String(QtWayland::wp_pointer_warp_v1::interface()->name)) { + mGlobals.pointerWarp.reset(new WithDestructor<QtWayland::wp_pointer_warp_v1, wp_pointer_warp_v1_destroy>( + registry, id, 1)); } +#ifndef QT_NO_SESSIONMANAGER + else if (interface == QLatin1String(QtWayland::xx_session_manager_v1::interface()->name) + && qEnvironmentVariableIntValue("QT_WAYLAND_ENABLE_XX_SESSION_MANAGER") > 0) { + mGlobals.xxSessionManager.reset( + new WithDestructor<QtWayland::xx_session_manager_v1, xx_session_manager_v1_destroy>( + registry, id, 1)); + } +#endif + mRegistryGlobals.append(RegistryGlobal(id, interface, version, registry)); emit globalAdded(mRegistryGlobals.back()); diff --git a/src/plugins/platforms/wayland/qwaylanddisplay_p.h b/src/plugins/platforms/wayland/qwaylanddisplay_p.h index c8ba4935cf6..91d3497fe51 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay_p.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay_p.h @@ -56,8 +56,10 @@ namespace QtWayland { class wp_cursor_shape_manager_v1; class wp_fractional_scale_manager_v1; class wp_viewporter; + class xx_session_manager_v1; class xdg_system_bell_v1; class xdg_toplevel_drag_manager_v1; + class wp_pointer_warp_v1; } namespace QtWaylandClient { @@ -85,6 +87,7 @@ class QWaylandPointerGestures; class QWaylandWindow; class QWaylandIntegration; class QWaylandHardwareIntegration; +class QWaylandSessionManager; class QWaylandSurface; class QWaylandShellIntegration; class QWaylandCursor; @@ -213,6 +216,10 @@ public: { return mGlobals.xdgToplevelDragManager.get(); } + QtWayland::xx_session_manager_v1 *xxSessionManager() const + { + return mGlobals.xxSessionManager.get(); + } QtWayland::xdg_system_bell_v1 *systemBell() const { return mGlobals.systemBell.get(); @@ -225,6 +232,10 @@ public: { return mGlobals.colorManager.get(); } + QtWayland::wp_pointer_warp_v1 *pointerWarp() const + { + return mGlobals.pointerWarp.get(); + } struct RegistryGlobal { uint32_t id; @@ -355,11 +366,13 @@ private: std::unique_ptr<QtWayland::wp_viewporter> viewporter; std::unique_ptr<QtWayland::wp_fractional_scale_manager_v1> fractionalScaleManager; std::unique_ptr<QtWayland::wp_cursor_shape_manager_v1> cursorShapeManager; + std::unique_ptr<QtWayland::xx_session_manager_v1> xxSessionManager; std::unique_ptr<QtWayland::xdg_system_bell_v1> systemBell; std::unique_ptr<QtWayland::xdg_toplevel_drag_manager_v1> xdgToplevelDragManager; std::unique_ptr<QWaylandWindowManagerIntegration> windowManagerIntegration; std::unique_ptr<QWaylandAppMenuManager> appMenuManager; std::unique_ptr<ColorManager> colorManager; + std::unique_ptr<QtWayland::wp_pointer_warp_v1> pointerWarp; } mGlobals; int mFd = -1; diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 9158013fe78..d66710f4e55 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -56,6 +56,7 @@ #include "qwaylandinputdeviceintegration_p.h" #include "qwaylandinputdeviceintegrationfactory_p.h" #include "qwaylandwindow_p.h" +#include "qwaylandsessionmanager_p.h" #include <QtWaylandClient/private/qwayland-xdg-system-bell-v1.h> @@ -529,6 +530,12 @@ QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QStr } } +QPlatformSessionManager *QWaylandIntegration::createPlatformSessionManager(const QString &id, const QString &key) const +{ + Q_UNUSED(key); + return new QWaylandSessionManager(mDisplay.data(), id); +} + void QWaylandIntegration::reset() { mServerBufferIntegration.reset(); diff --git a/src/plugins/platforms/wayland/qwaylandintegration_p.h b/src/plugins/platforms/wayland/qwaylandintegration_p.h index d799555570d..04a0787d1ef 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration_p.h +++ b/src/plugins/platforms/wayland/qwaylandintegration_p.h @@ -36,6 +36,7 @@ class QWaylandInputDevice; class QWaylandScreen; class QWaylandCursor; class QWaylandPlatformServices; +class QWaylandSessionManager; class Q_WAYLANDCLIENT_EXPORT QWaylandIntegration : public QPlatformIntegration #if QT_CONFIG(opengl) @@ -131,6 +132,7 @@ private: void initializeShellIntegration(); void initializeInputDeviceIntegration(); QWaylandShellIntegration *createShellIntegration(const QString& interfaceName); + QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const override; const QString mPlatformName; QScopedPointer<QPlatformFontDatabase> mFontDb; diff --git a/src/plugins/platforms/wayland/qwaylandsessionmanager.cpp b/src/plugins/platforms/wayland/qwaylandsessionmanager.cpp new file mode 100644 index 00000000000..9539bb15221 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandsessionmanager.cpp @@ -0,0 +1,91 @@ +// Copyright (C) 2024 David Edmundson <davidedmundson@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qwaylandsessionmanager_p.h" + +#ifndef QT_NO_SESSIONMANAGER + +#include "qwaylanddisplay_p.h" +#include "qwaylandwindow_p.h" + +#include <private/qsessionmanager_p.h> +#include <private/qguiapplication_p.h> + +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +QWaylandSessionManager::QWaylandSessionManager(QWaylandDisplay *display, const QString &id) + : QObject(nullptr) + , QPlatformSessionManager(id, QString()) + , mDisplay(display) +{ + if (!display->xxSessionManager()) + return; + + // The protocol also exposes a way of supporting crash handling to expose later + startSession(); +} + +QWaylandSession *QWaylandSessionManager::session() const +{ + return mSession.data(); +} + +QWaylandSessionManager *QWaylandSessionManager::instance() +{ + auto *qGuiAppPriv = QGuiApplicationPrivate::instance(); + auto *managerPrivate = static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(qGuiAppPriv->session_manager)); + return static_cast<QWaylandSessionManager *>(managerPrivate->platformSessionManager); +} + +void QWaylandSessionManager::setSessionId(const QString &id) +{ + m_sessionId = id; +} + +void QWaylandSessionManager::startSession() +{ + QtWayland::xx_session_manager_v1::reason restoreReason = QtWayland::xx_session_manager_v1::reason_launch; + if (!sessionId().isEmpty()) { + restoreReason = QtWayland::xx_session_manager_v1::reason_session_restore; + } + mSession.reset(new QWaylandSession(this)); + mSession->init(mDisplay->xxSessionManager()->get_session(restoreReason, sessionId())); + mDisplay->forceRoundTrip(); +} + +QWaylandSession::QWaylandSession(QWaylandSessionManager *sessionManager) + : mSessionManager(sessionManager) +{ +} + +QWaylandSession::~QWaylandSession() { + // There's also remove which is another dtor + // depending on whether we're meant to clean up server side or not + // we might need to expose that later + destroy(); +} + +void QWaylandSession::xx_session_v1_created(const QString &id) { + qCDebug(lcQpaWayland) << "Session created" << id; + mSessionManager->setSessionId(id); +} + +void QWaylandSession::xx_session_v1_restored() { + qCDebug(lcQpaWayland) << "Session restored"; + // session Id won't have change, do nothing +} + +void QWaylandSession::xx_session_v1_replaced() { + qCDebug(lcQpaWayland) << "Session replaced"; + mSessionManager->setSessionId(QString()); +} + +} + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/wayland/qwaylandsessionmanager_p.h b/src/plugins/platforms/wayland/qwaylandsessionmanager_p.h new file mode 100644 index 00000000000..aa9e0eec001 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandsessionmanager_p.h @@ -0,0 +1,71 @@ +// Copyright (C) 2024 David Edmundson <davidedmundson@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QWAYLANDSESSIONMANAGER_H +#define QWAYLANDSESSIONMANAGER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QT_NO_SESSIONMANAGER + +#include <QtGui/qpa/qplatformsessionmanager.h> +#include <QtWaylandClient/qtwaylandclientglobal.h> +#include <QtWaylandClient/private/qwayland-xx-session-management-v1.h> + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +class QWaylandDisplay; +class QWaylandWindow; +class QWaylandSession; +class QWaylandSessionManager; + + +class Q_WAYLANDCLIENT_EXPORT QWaylandSession : public QObject, public QtWayland::xx_session_v1 +{ + Q_OBJECT +public: + QWaylandSession(QWaylandSessionManager *sessionManager); + ~QWaylandSession(); + +protected: + void xx_session_v1_created(const QString &id) override; + void xx_session_v1_restored() override; + void xx_session_v1_replaced() override; +private: + QWaylandSessionManager *mSessionManager; +}; + +class Q_WAYLANDCLIENT_EXPORT QWaylandSessionManager : public QObject, public QPlatformSessionManager +{ + Q_OBJECT +public: + static QWaylandSessionManager *instance(); + QWaylandSessionManager(QWaylandDisplay *display, const QString &id); + + QWaylandSession* session() const; +private: + void setSessionId(const QString &id); + void startSession(); + + QWaylandDisplay *mDisplay = nullptr; + QScopedPointer<QWaylandSession> mSession; + friend class QWaylandSession; +}; + +} + +QT_END_NAMESPACE + +#endif +#endif diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 73d90b6c321..cfbc392c319 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qwaylandsessionmanager_p.h" #include "qwaylandwindow_p.h" #include "qwaylandbuffer_p.h" @@ -1934,6 +1935,16 @@ QSurfaceFormat QWaylandWindow::format() const return mSurfaceFormat; } +void QWaylandWindow::setSessionRestoreId(const QString &role) +{ + mSessionRestoreId = role; +} + +QString QWaylandWindow::sessionRestoreId() const +{ + return mSessionRestoreId; +} + } QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index 5ad826018bb..23c5ed04b8f 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -252,6 +252,8 @@ public: bool windowEvent(QEvent *event) override; QSurfaceFormat format() const override; + void setSessionRestoreId(const QString &role) override; + QString sessionRestoreId() const; public Q_SLOTS: void applyConfigure(); @@ -346,6 +348,7 @@ protected: QWaylandShmBackingStore *mBackingStore = nullptr; QMargins mCustomMargins; + QString mSessionRestoreId; QPointer<QWaylandWindow> mTransientParent; QList<QPointer<QWaylandWindow>> mChildPopups; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index c484d97479a..3fe837a2c03 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -43,6 +43,7 @@ #include <QtCore/qsysinfo.h> #include <QtCore/qscopedpointer.h> #include <QtCore/quuid.h> +#include <QtCore/qscopeguard.h> #include <QtCore/private/qwinregistry_p.h> #if QT_CONFIG(cpp_winrt) # include <QtCore/private/qfactorycacheregistration_p.h> @@ -428,6 +429,10 @@ QDebug operator<<(QDebug d, QtWindows::DpiAwareness dpiAwareness) bool QWindowsContext::setProcessDpiAwareness(QtWindows::DpiAwareness dpiAwareness) { qCDebug(lcQpaWindow) << __FUNCTION__ << dpiAwareness; + [[maybe_unused]] const auto updatePMv2Status = qScopeGuard([](){ + QWindowsContextPrivate::m_v2DpiAware = + processDpiAwareness() == QtWindows::DpiAwareness::PerMonitorVersion2; + }); if (processDpiAwareness() == dpiAwareness) return true; const auto context = qtDpiAwarenessToDpiAwarenessContext(dpiAwareness); @@ -445,8 +450,6 @@ bool QWindowsContext::setProcessDpiAwareness(QtWindows::DpiAwareness dpiAwarenes << "(https://doc.qt.io/qt-6/highdpi.html#configuring-windows)."; return false; } - QWindowsContextPrivate::m_v2DpiAware - = processDpiAwareness() == QtWindows::DpiAwareness::PerMonitorVersion2; return true; } @@ -1216,6 +1219,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::FocusInEvent: // see QWindowsWindow::requestActivateWindow(). if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) return false; + [[fallthrough]]; case QtWindows::FocusOutEvent: handleFocusEvent(et, platformWindow); return true; diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp index 75da805c2d7..f7be6a17bfd 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp +++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp @@ -1782,7 +1782,7 @@ void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int p painter.setPen(Qt::NoPen); painter.setBrush(fill); if (gcMode == BrushGC) - painter.setBrushOrigin(q->painter()->brushOrigin()); + painter.setBrushOrigin(q->painter()->brushOriginF()); painter.drawPolygon(poly); painter.end(); diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp index 953fb1618a1..82e978862f8 100644 --- a/src/plugins/styles/modernwindows/qwindows11style.cpp +++ b/src/plugins/styles/modernwindows/qwindows11style.cpp @@ -38,27 +38,13 @@ QT_BEGIN_NAMESPACE static constexpr int topLevelRoundingRadius = 8; //Radius for toplevel items like popups for round corners static constexpr int secondLevelRoundingRadius = 4; //Radius for second level items like hovered menu item round corners - -enum WINUI3Color { - subtleHighlightColor, //Subtle highlight based on alpha used for hovered elements - subtlePressedColor, //Subtle highlight based on alpha used for pressed elements - frameColorLight, //Color of frame around flyouts and controls except for Checkbox and Radiobutton - frameColorStrong, //Color of frame around Checkbox and Radiobuttons - controlStrongFill, //Color of controls with strong filling such as the right side of a slider - controlStrokeSecondary, - controlStrokePrimary, - controlFillTertiary, //Color of filled sunken controls - controlFillSecondary, //Color of filled hovered controls - menuPanelFill, //Color of menu panel - textOnAccentPrimary, //Color of text on controls filled in accent color - textOnAccentSecondary, //Color of text of sunken controls in accent color - controlTextSecondary, //Color of text of sunken controls - controlStrokeOnAccentSecondary, //Color of frame around Buttons in accent color - controlFillSolid, //Color for solid fill - surfaceStroke, //Color of MDI window frames - controlAccentDisabled, - textAccentDisabled -}; +template <typename R, typename P, typename B> +static inline void drawRoundedRect(QPainter *p, R &&rect, P &&pen, B &&brush) +{ + p->setPen(pen); + p->setBrush(brush); + p->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius); +} static const QColor WINUI3ColorsLight [] { QColor(0x00,0x00,0x00,0x09), //subtleHighlightColor @@ -161,6 +147,9 @@ QWindows11Style::QWindows11Style() : QWindows11Style(*new QWindows11StylePrivate */ QWindows11Style::QWindows11Style(QWindows11StylePrivate &dd) : QWindowsVistaStyle(dd) { + Q_D(QWindows11Style); + d->assetFont = QFont("Segoe Fluent Icons"); + d->assetFont.setStyleStrategy(QFont::NoFontMerging); highContrastTheme = QGuiApplicationPrivate::styleHints->colorScheme() == Qt::ColorScheme::Unknown; colorSchemeIndex = QGuiApplicationPrivate::styleHints->colorScheme() == Qt::ColorScheme::Light ? 0 : 1; } @@ -253,43 +242,25 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt QCachedPainter cp(painter, QLatin1StringView("win11_spinbox") % HexString<uint8_t>(colorSchemeIndex), sb, sb->rect.size()); if (cp.needsPainting()) { - if (sb->frame && (sub & SC_SpinBoxFrame)) { - const qreal sublineOffset = secondLevelRoundingRadius + 2.0; - cp->save(); - cp->setClipRect(option->rect.adjusted(-2, -2, 2, 2)); - cp->setPen(editSublineColor(option, colorSchemeIndex)); - cp->drawLine(option->rect.bottomLeft() + QPointF(sublineOffset, 0.5), - option->rect.bottomRight() + QPointF(-sublineOffset, 0.5)); - cp->restore(); - } - const QRectF frameRect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5)); - cp->setBrush(option->palette.brush(QPalette::Base)); - cp->setPen(highContrastTheme == true ? sb->palette.buttonText().color() - : WINUI3Colors[colorSchemeIndex][frameColorLight]); - cp->drawRoundedRect(frameRect, secondLevelRoundingRadius, secondLevelRoundingRadius); - const QPoint mousePos = widget ? widget->mapFromGlobal(QCursor::pos()) : QPoint(); - if (sub & SC_SpinBoxEditField) { - const QRect rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, - widget).adjusted(0, 0, 0, 1); - if (!(state & State_HasFocus) && rect.contains(mousePos)) { - cp->setPen(Qt::NoPen); - cp->setBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]); - cp->drawRoundedRect(option->rect.adjusted(2, 2, -2, -2), secondLevelRoundingRadius, - secondLevelRoundingRadius); - } - } + const auto frameRect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1)); + drawRoundedRect(cp.painter(), frameRect, Qt::NoPen, option->palette.brush(QPalette::Base)); + + if (sb->frame && (sub & SC_SpinBoxFrame)) + drawLineEditFrame(cp.painter(), option); + + const bool isMouseOver = state & State_MouseOver; + const bool hasFocus = state & State_HasFocus; + if (isMouseOver && !hasFocus && !highContrastTheme) + drawRoundedRect(cp.painter(), frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor)); + const auto drawUpDown = [&](QStyle::SubControl sc) { const bool isUp = sc == SC_SpinBoxUp; - QRect rect = proxy()->subControlRect(CC_SpinBox, option, isUp ? SC_SpinBoxUp : SC_SpinBoxDown, widget); - if (isUp) - rect.adjust(0, 0, 0, 1); - if (rect.contains(mousePos)) { - cp->setPen(Qt::NoPen); - cp->setBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]); - cp->drawRoundedRect(rect.adjusted(1, 1, -1, -1), secondLevelRoundingRadius, - secondLevelRoundingRadius); - } - cp->setFont(assetFont); + const QRect rect = proxy()->subControlRect(CC_SpinBox, option, sc, widget); + if (sb->activeSubControls & sc) + drawRoundedRect(cp.painter(), rect.adjusted(1, 1, -1, -2), Qt::NoPen, + winUI3Color(subtleHighlightColor)); + + cp->setFont(d->assetFont); cp->setPen(sb->palette.buttonText().color()); cp->setBrush(Qt::NoBrush); const auto str = isUp ? QStringLiteral(u"\uE70E") : QStringLiteral(u"\uE70D"); @@ -441,36 +412,23 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt #if QT_CONFIG(combobox) case CC_ComboBox: if (const QStyleOptionComboBox *combobox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { - QRectF rect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1)); - painter->setBrush(combobox->palette.brush(QPalette::Base)); - painter->setPen(Qt::NoPen); - painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius); + const auto frameRect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1)); + drawRoundedRect(painter, frameRect, Qt::NoPen, option->palette.brush(QPalette::Base)); - const bool comboboxHovered = state & State_MouseOver; - // In case the QComboBox is hovered overdraw the background with a alpha mask to - // highlight the QComboBox. - if (comboboxHovered && !highContrastTheme) { - painter->setBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]); - painter->setPen(Qt::NoPen); - painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius); - } + if (combobox->frame) + drawLineEditFrame(painter, option); + + const bool isMouseOver = state & State_MouseOver; + const bool hasFocus = state & State_HasFocus; + if (isMouseOver && !hasFocus && !highContrastTheme) + drawRoundedRect(painter, frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor)); - rect.adjust(0.5,0.5,-0.5,-0.5); - painter->setBrush(Qt::NoBrush); - painter->setPen(highContrastTheme ? (comboboxHovered ? combobox->palette.accent().color() : combobox->palette.buttonText().color()) : WINUI3Colors[colorSchemeIndex][frameColorLight]); - painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius); if (sub & SC_ComboBoxArrow) { QRectF rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget).adjusted(4, 0, -4, 1); - painter->setFont(assetFont); + painter->setFont(d->assetFont); painter->setPen(combobox->palette.text().color()); painter->drawText(rect, QStringLiteral(u"\uE70D"), Qt::AlignVCenter | Qt::AlignHCenter); } - - if (combobox->editable) { - const qreal sublineOffset = secondLevelRoundingRadius; - painter->setPen(editSublineColor(option, colorSchemeIndex)); - painter->drawLine(rect.bottomLeft() + QPointF(sublineOffset, 1.0), rect.bottomRight() + QPointF(-sublineOffset, 1.0)); - } } break; #endif // QT_CONFIG(combobox) @@ -522,7 +480,7 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt if (sub & SC_ScrollBarAddLine) { if (isMouseOver) { const QRectF rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget); - QFont f = QFont(assetFont); + QFont f = QFont(d->assetFont); f.setPointSize(6); cp->setFont(f); cp->setPen(Qt::gray); @@ -534,7 +492,7 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt if (sub & SC_ScrollBarSubLine) { if (isMouseOver) { const QRectF rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget); - QFont f = QFont(assetFont); + QFont f = QFont(d->assetFont); f.setPointSize(6); cp->setFont(f); cp->setPen(Qt::gray); @@ -547,7 +505,7 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt } break; case CC_MdiControls:{ - QFont buttonFont = QFont(assetFont); + QFont buttonFont = QFont(d->assetFont); buttonFont.setPointSize(8); QPoint mousePos = widget->mapFromGlobal(QCursor::pos()); if (option->subControls.testFlag(SC_MdiCloseButton)) { @@ -603,7 +561,7 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt QString title = painter->fontMetrics().elidedText(titlebar->text, Qt::ElideRight, textRect.width() - 14); painter->drawText(textRect.adjusted(1, 1, -1, -1), title, QTextOption(Qt::AlignHCenter | Qt::AlignVCenter)); - QFont buttonFont = QFont(assetFont); + QFont buttonFont = QFont(d->assetFont); buttonFont.setPointSize(8); auto drawButton = [&](SubControl sc, const QString &str, QColor col = {}) { const QRect buttonRect = proxy()->subControlRect(CC_TitleBar, option, sc, widget); @@ -793,7 +751,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption break; case PE_IndicatorHeaderArrow: if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { - QFont f(assetFont); + QFont f(d->assetFont); f.setPointSize(6); painter->setFont(f); painter->setPen(header->palette.text().color()); @@ -809,7 +767,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption { const bool isRtl = option->direction == Qt::RightToLeft; QNumberStyleAnimation* animation = qobject_cast<QNumberStyleAnimation*>(d->animation(option->styleObject)); - QFontMetrics fm(assetFont); + QFontMetrics fm(d->assetFont); QRectF rect = isRtl ? option->rect.adjusted(0, 0, -2, 0) : option->rect.adjusted(2, 0, 0, 0); QPointF center = QPointF(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2); @@ -832,7 +790,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption painter->setBrush(Qt::NoBrush); painter->drawRoundedRect(rect, secondLevelRoundingRadius + 0.5, secondLevelRoundingRadius + 0.5, Qt::AbsoluteSize); - painter->setFont(assetFont); + painter->setFont(d->assetFont); painter->setPen(option->palette.highlightedText().color()); painter->setBrush(option->palette.highlightedText()); if (option->state & State_On) @@ -845,7 +803,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption if (option->state & State_Children) { const bool isReverse = option->direction == Qt::RightToLeft; const bool isOpen = option->state & QStyle::State_Open; - QFont f(assetFont); + QFont f(d->assetFont); f.setPointSize(6); painter->setFont(f); painter->setPen(option->palette.color(isOpen ? QPalette::Active : QPalette::Disabled, @@ -951,64 +909,39 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption break; } case PE_PanelLineEdit: - if (widget && widget->objectName() == QStringLiteral(u"qt_spinbox_lineedit")) - break; if (const auto *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - QRectF frameRect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1)); - painter->setBrush(option->palette.brush(QPalette::Base)); - painter->setPen(Qt::NoPen); - painter->drawRoundedRect(frameRect, secondLevelRoundingRadius, secondLevelRoundingRadius); - // In case the QLineEdit is hovered overdraw the background with a alpha mask to - // highlight the QLineEdit. - if (state & State_MouseOver && !(state & State_HasFocus)) { - painter->setBrush(WINUI3Colors[colorSchemeIndex][subtleHighlightColor]); - painter->setPen(Qt::NoPen); - painter->drawRoundedRect(frameRect, secondLevelRoundingRadius, secondLevelRoundingRadius); - } + const auto frameRect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1)); + drawRoundedRect(painter, frameRect, Qt::NoPen, option->palette.brush(QPalette::Base)); + if (panel->lineWidth > 0) proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget); + + const bool isMouseOver = state & State_MouseOver; + const bool hasFocus = state & State_HasFocus; + if (isMouseOver && !hasFocus && !highContrastTheme) + drawRoundedRect(painter, frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor)); } break; - case PE_FrameLineEdit: { - const qreal sublineOffset = secondLevelRoundingRadius + 1.5; - if (widget && widget->parent() && qobject_cast<QComboBox*>(widget->parent())) - break; - QRectF rect = option->rect; - rect.adjust(1.5, 1.5, -1.5, -1.5); - painter->setBrush(Qt::NoBrush); - painter->setPen(highContrastTheme == true ? option->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]); - painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius); - painter->setPen(editSublineColor(option, colorSchemeIndex)); - painter->drawLine(option->rect.bottomLeft() + QPointF(sublineOffset, 0.5), option->rect.bottomRight() + QPointF(-sublineOffset, 0.5)); - } + case PE_FrameLineEdit: + drawLineEditFrame(painter, option); break; case PE_Frame: { if (const auto *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - if (frame->frameShape == QFrame::NoFrame) - break; - QRectF rect = option->rect.adjusted(1,1,-1,-1); + const auto rect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1)); if (qobject_cast<const QComboBoxPrivateContainer *>(widget)) { + QPen pen; if (highContrastTheme) - painter->setPen(QPen(option->palette.windowText().color(), 2)); + pen = QPen(option->palette.windowText().color(), 2); else - painter->setPen(Qt::NoPen); - painter->setBrush(WINUI3Colors[colorSchemeIndex][menuPanelFill]); - painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius); - } - painter->setBrush(option->palette.base()); - painter->setPen(Qt::NoPen); - painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius); + pen = Qt::NoPen; + drawRoundedRect(painter, rect, pen, WINUI3Colors[colorSchemeIndex][menuPanelFill]); + } else + drawRoundedRect(painter, rect, Qt::NoPen, option->palette.brush(QPalette::Base)); - painter->setBrush(Qt::NoBrush); - painter->setPen(WINUI3Colors[colorSchemeIndex][frameColorLight]); - painter->drawRoundedRect(rect.marginsRemoved(QMarginsF(0.5,0.5,0.5,0.5)), secondLevelRoundingRadius, secondLevelRoundingRadius); + if (frame->frameShape == QFrame::NoFrame) + break; - if (qobject_cast<const QTextEdit *>(widget)) { - QRegion clipRegion = option->rect; - QColor lineColor = state & State_HasFocus ? option->palette.accent().color() : option->palette.base().color(); - painter->setPen(lineColor); - painter->drawLine(option->rect.bottomLeft() + QPoint(1,-1), option->rect.bottomRight() + QPoint(-1,-1)); - } + drawLineEditFrame(painter, option, qobject_cast<const QTextEdit *>(widget) != nullptr); } break; } @@ -1418,7 +1351,7 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op QLineF menuSplitter; QRectF indicatorRect; painter->save(); - painter->setFont(assetFont); + painter->setFont(d->assetFont); if (btn->direction == Qt::LeftToRight) { indicatorRect = QRect(textRect.x() + textRect.width() - indicatorSize - 4, textRect.y(),2 * 4 + indicatorSize, textRect.height()); @@ -1536,7 +1469,7 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op newMbi.font.setPointSize(10); if (enabled && active) { if (down) - painter->setBrushOrigin(painter->brushOrigin() + QPoint(1, 1)); + painter->setBrushOrigin(painter->brushOriginF() + QPoint(1, 1)); if (hasFocus) { if (highContrastTheme) painter->setPen(QPen(newMbi.palette.highlight().color(), 2)); @@ -1616,7 +1549,7 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op painter->save(); if (dis) painter->setPen(menuitem->palette.text().color()); - painter->setFont(assetFont); + painter->setFont(d->assetFont); const int text_flags = Qt::AlignVCenter | Qt::AlignHCenter | Qt::TextDontClip | Qt::TextSingleLine; const auto textToDraw = QStringLiteral(u"\uE73E"); painter->setPen(option->palette.text().color()); @@ -1678,7 +1611,7 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op newMI.palette.setColor(QPalette::ButtonText, newMI.palette.highlightedText().color()); painter->save(); - painter->setFont(assetFont); + painter->setFont(d->assetFont); int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget)) text_flags |= Qt::TextHideMnemonic; @@ -1729,128 +1662,123 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op } case CE_ItemViewItem: { if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) { - if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget)) { - QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget); - QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget); - QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget); + QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget); + QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget); + QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget); - // draw the background - proxy()->drawPrimitive(PE_PanelItemViewItem, option, painter, widget); + // draw the background + proxy()->drawPrimitive(PE_PanelItemViewItem, option, painter, widget); - const QRect &rect = vopt->rect; - const bool isRtl = option->direction == Qt::RightToLeft; - bool onlyOne = vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne || - vopt->viewItemPosition == QStyleOptionViewItem::Invalid; - bool isFirst = vopt->viewItemPosition == QStyleOptionViewItem::Beginning; - bool isLast = vopt->viewItemPosition == QStyleOptionViewItem::End; + const QRect &rect = vopt->rect; + const bool isRtl = option->direction == Qt::RightToLeft; + bool onlyOne = vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne || + vopt->viewItemPosition == QStyleOptionViewItem::Invalid; + bool isFirst = vopt->viewItemPosition == QStyleOptionViewItem::Beginning; + bool isLast = vopt->viewItemPosition == QStyleOptionViewItem::End; - // the tree decoration already painted the left side of the rounded rect - if (vopt->features.testFlag(QStyleOptionViewItem::IsDecoratedRootColumn) && - vopt->showDecorationSelected) { - isFirst = false; - if (onlyOne) { - onlyOne = false; - isLast = true; - } + // the tree decoration already painted the left side of the rounded rect + if (vopt->features.testFlag(QStyleOptionViewItem::IsDecoratedRootColumn) && + vopt->showDecorationSelected) { + isFirst = false; + if (onlyOne) { + onlyOne = false; + isLast = true; } + } - if (isRtl) { - if (isFirst) { - isFirst = false; - isLast = true; - } else if (isLast) { - isFirst = true; - isLast = false; - } + if (isRtl) { + if (isFirst) { + isFirst = false; + isLast = true; + } else if (isLast) { + isFirst = true; + isLast = false; } - const bool highlightCurrent = vopt->state.testAnyFlags(State_Selected | State_MouseOver); - if (highlightCurrent) { - const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); - if (highContrastTheme) - painter->setBrush(vopt->palette.highlight()); - else - painter->setBrush(view->alternatingRowColors() ? vopt->palette.highlight() : WINUI3Colors[colorSchemeIndex][subtleHighlightColor]); - QWidget *editorWidget = view ? view->indexWidget(view->currentIndex()) : nullptr; - if (editorWidget) { - QPalette pal = editorWidget->palette(); - QColor editorBgColor = vopt->backgroundBrush == Qt::NoBrush ? vopt->palette.color(widget->backgroundRole()) : vopt->backgroundBrush.color(); - editorBgColor.setAlpha(255); - pal.setColor(editorWidget->backgroundRole(), editorBgColor); - editorWidget->setPalette(pal); - } - } else { - painter->setBrush(vopt->backgroundBrush); + } + const bool highlightCurrent = vopt->state.testAnyFlags(State_Selected | State_MouseOver); + if (highlightCurrent) { + const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); + if (highContrastTheme) + painter->setBrush(vopt->palette.highlight()); + else + painter->setBrush(view->alternatingRowColors() ? vopt->palette.highlight() : WINUI3Colors[colorSchemeIndex][subtleHighlightColor]); + QWidget *editorWidget = view ? view->indexWidget(view->currentIndex()) : nullptr; + if (editorWidget) { + QPalette pal = editorWidget->palette(); + QColor editorBgColor = vopt->backgroundBrush == Qt::NoBrush ? vopt->palette.color(widget->backgroundRole()) : vopt->backgroundBrush.color(); + editorBgColor.setAlpha(255); + pal.setColor(editorWidget->backgroundRole(), editorBgColor); + editorWidget->setPalette(pal); } - painter->setPen(Qt::NoPen); + } else { + painter->setBrush(vopt->backgroundBrush); + } + painter->setPen(Qt::NoPen); - if (onlyOne) { - painter->drawRoundedRect(rect.marginsRemoved(QMargins(2, 2, 2, 2)), - secondLevelRoundingRadius, secondLevelRoundingRadius); - } else if (isFirst) { - painter->save(); - painter->setClipRect(rect); - painter->drawRoundedRect(rect.marginsRemoved(QMargins(2, 2, -secondLevelRoundingRadius, 2)), - secondLevelRoundingRadius, secondLevelRoundingRadius); - painter->restore(); - } else if (isLast) { - painter->save(); - painter->setClipRect(rect); - painter->drawRoundedRect(rect.marginsRemoved(QMargins(-secondLevelRoundingRadius, 2, 2, 2)), - secondLevelRoundingRadius, secondLevelRoundingRadius); - painter->restore(); - } else { - painter->drawRect(rect.marginsRemoved(QMargins(0, 2, 0, 2))); - } + if (onlyOne) { + painter->drawRoundedRect(rect.marginsRemoved(QMargins(2, 2, 2, 2)), + secondLevelRoundingRadius, secondLevelRoundingRadius); + } else if (isFirst) { + painter->save(); + painter->setClipRect(rect); + painter->drawRoundedRect(rect.marginsRemoved(QMargins(2, 2, -secondLevelRoundingRadius, 2)), + secondLevelRoundingRadius, secondLevelRoundingRadius); + painter->restore(); + } else if (isLast) { + painter->save(); + painter->setClipRect(rect); + painter->drawRoundedRect(rect.marginsRemoved(QMargins(-secondLevelRoundingRadius, 2, 2, 2)), + secondLevelRoundingRadius, secondLevelRoundingRadius); + painter->restore(); + } else { + painter->drawRect(rect.marginsRemoved(QMargins(0, 2, 0, 2))); + } - // draw the check mark - if (vopt->features & QStyleOptionViewItem::HasCheckIndicator) { - QStyleOptionViewItem option(*vopt); - option.rect = checkRect; - option.state = option.state & ~QStyle::State_HasFocus; + // draw the check mark + if (vopt->features & QStyleOptionViewItem::HasCheckIndicator) { + QStyleOptionViewItem option(*vopt); + option.rect = checkRect; + option.state = option.state & ~QStyle::State_HasFocus; - switch (vopt->checkState) { - case Qt::Unchecked: - option.state |= QStyle::State_Off; - break; - case Qt::PartiallyChecked: - option.state |= QStyle::State_NoChange; - break; - case Qt::Checked: - option.state |= QStyle::State_On; - break; - } - proxy()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, painter, widget); + switch (vopt->checkState) { + case Qt::Unchecked: + option.state |= QStyle::State_Off; + break; + case Qt::PartiallyChecked: + option.state |= QStyle::State_NoChange; + break; + case Qt::Checked: + option.state |= QStyle::State_On; + break; } + proxy()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, painter, widget); + } - // draw the icon - QIcon::Mode mode = QIcon::Normal; - if (!(vopt->state & QStyle::State_Enabled)) - mode = QIcon::Disabled; - else if (vopt->state & QStyle::State_Selected) - mode = QIcon::Selected; - QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off; - vopt->icon.paint(painter, iconRect, vopt->decorationAlignment, mode, state); - - if (!view || !view->isPersistentEditorOpen(vopt->index)) { - painter->setPen(highlightCurrent && highContrastTheme ? vopt->palette.base().color() : option->palette.text().color()); - d->viewItemDrawText(painter, vopt, textRect); - } - // paint a vertical marker for QListView - if (vopt->state & State_Selected) { - if (const QListView *lv = qobject_cast<const QListView *>(widget); - lv && lv->viewMode() != QListView::IconMode && !highContrastTheme) { - painter->setPen(vopt->palette.accent().color()); - const auto xPos = isRtl ? rect.right() - 1 : rect.left(); - const QLineF lines[2] = { - QLineF(xPos, rect.y() + 2, xPos, rect.y() + rect.height() - 2), - QLineF(xPos + 1, rect.y() + 2, xPos + 1, rect.y() + rect.height() - 2), - }; - painter->drawLines(lines, 2); - } + // draw the icon + QIcon::Mode mode = QIcon::Normal; + if (!(vopt->state & QStyle::State_Enabled)) + mode = QIcon::Disabled; + else if (vopt->state & QStyle::State_Selected) + mode = QIcon::Selected; + QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off; + vopt->icon.paint(painter, iconRect, vopt->decorationAlignment, mode, state); + + painter->setPen(highlightCurrent && highContrastTheme ? vopt->palette.base().color() + : vopt->palette.text().color()); + d->viewItemDrawText(painter, vopt, textRect); + + // paint a vertical marker for QListView + if (vopt->state & State_Selected) { + if (const QListView *lv = qobject_cast<const QListView *>(widget); + lv && lv->viewMode() != QListView::IconMode && !highContrastTheme) { + painter->setPen(vopt->palette.accent().color()); + const auto xPos = isRtl ? rect.right() - 1 : rect.left(); + const QLineF lines[2] = { + QLineF(xPos, rect.y() + 2, xPos, rect.y() + rect.height() - 2), + QLineF(xPos + 1, rect.y() + 2, xPos + 1, rect.y() + rect.height() - 2), + }; + painter->drawLines(lines, 2); } - } else { - QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget); - d->viewItemDrawText(painter, vopt, textRect); } } break; @@ -2410,6 +2338,12 @@ void QWindows11Style::polish(QPalette& result) if (highContrastTheme) result.setColor(QPalette::Active, QPalette::HighlightedText, result.windowText().color()); + + auto *d = const_cast<QWindows11StylePrivate *>(d_func()); + d->m_titleBarMinIcon = QIcon(); + d->m_titleBarMaxIcon = QIcon(); + d->m_titleBarCloseIcon = QIcon(); + d->m_titleBarNormalIcon = QIcon(); } QBrush QWindows11Style::buttonFillBrush(const QStyleOption *option) @@ -2442,12 +2376,33 @@ QColor QWindows11Style::buttonLabelColor(const QStyleOption *option, int colorSc : option->palette.buttonText().color(); } -QColor QWindows11Style::editSublineColor(const QStyleOption *option, int colorSchemeIndex) +void QWindows11Style::drawLineEditFrame(QPainter *p, const QStyleOption *o, bool isEditable) const +{ + const auto rect = QRectF(o->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5)); + const bool isHovered = o->state & State_MouseOver; + const auto frameCol = highContrastTheme + ? o->palette.color(isHovered ? QPalette::Accent + : QPalette::ButtonText) + : winUI3Color(frameColorLight); + drawRoundedRect(p, rect, frameCol, Qt::NoBrush); + + if (!isEditable) + return; + + QPainterStateGuard psg(p); + p->setClipRect(rect.marginsRemoved(QMarginsF(0, rect.height() - 0.5, 0, -1))); + const bool hasFocus = o->state & State_HasFocus; + const auto underlineCol = hasFocus + ? o->palette.color(QPalette::Accent) + : colorSchemeIndex == 0 ? QColor(0x80, 0x80, 0x80) + : QColor(0xa0, 0xa0, 0xa0); + const auto penUnderline = QPen(underlineCol, hasFocus ? 2 : 1); + drawRoundedRect(p, rect, penUnderline, Qt::NoBrush); +} + +QColor QWindows11Style::winUI3Color(enum WINUI3Color col) const { - const State state = option->state; - return state & State_HasFocus ? option->palette.accent().color() - : (colorSchemeIndex == 0 ? QColor(0x80, 0x80, 0x80) - : QColor(0xa0, 0xa0, 0xa0)); + return WINUI3Colors[colorSchemeIndex][col]; } #undef SET_IF_UNRESOLVED diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h index 1be56fe3aa5..51514737259 100644 --- a/src/plugins/styles/modernwindows/qwindows11style_p.h +++ b/src/plugins/styles/modernwindows/qwindows11style_p.h @@ -21,7 +21,27 @@ QT_BEGIN_NAMESPACE class QWindows11StylePrivate; -class QWindows11Style; + +enum WINUI3Color { + subtleHighlightColor, //Subtle highlight based on alpha used for hovered elements + subtlePressedColor, //Subtle highlight based on alpha used for pressed elements + frameColorLight, //Color of frame around flyouts and controls except for Checkbox and Radiobutton + frameColorStrong, //Color of frame around Checkbox and Radiobuttons + controlStrongFill, //Color of controls with strong filling such as the right side of a slider + controlStrokeSecondary, + controlStrokePrimary, + controlFillTertiary, //Color of filled sunken controls + controlFillSecondary, //Color of filled hovered controls + menuPanelFill, //Color of menu panel + textOnAccentPrimary, //Color of text on controls filled in accent color + textOnAccentSecondary, //Color of text of sunken controls in accent color + controlTextSecondary, //Color of text of sunken controls + controlStrokeOnAccentSecondary, //Color of frame around Buttons in accent color + controlFillSolid, //Color for solid fill + surfaceStroke, //Color of MDI window frames + controlAccentDisabled, + textAccentDisabled +}; class QWindows11Style : public QWindowsVistaStyle { @@ -55,7 +75,8 @@ protected: private: static inline QBrush buttonFillBrush(const QStyleOption *option); static inline QColor buttonLabelColor(const QStyleOption *option, int colorSchemeIndex); - static inline QColor editSublineColor(const QStyleOption *option, int colorSchemeIndex); + void drawLineEditFrame(QPainter *p, const QStyleOption *o, bool isEditable = true) const; + inline QColor winUI3Color(enum WINUI3Color col) const; private: Q_DISABLE_COPY_MOVE(QWindows11Style) @@ -64,7 +85,6 @@ private: bool highContrastTheme = false; int colorSchemeIndex = 0; - const QFont assetFont = QFont("Segoe Fluent Icons"); //Font to load icons from }; class QWindows11StylePrivate : public QWindowsVistaStylePrivate { diff --git a/src/printsupport/kernel/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp index 4c34457570e..bf7e9779cf7 100644 --- a/src/printsupport/kernel/qpaintengine_alpha.cpp +++ b/src/printsupport/kernel/qpaintengine_alpha.cpp @@ -120,7 +120,7 @@ void QAlphaPaintEngine::updateState(const QPaintEngineState &state) const QPainter *p = painter(); d->m_picpainter->setPen(p->pen()); d->m_picpainter->setBrush(p->brush()); - d->m_picpainter->setBrushOrigin(p->brushOrigin()); + d->m_picpainter->setBrushOrigin(p->brushOriginF()); d->m_picpainter->setFont(p->font()); d->m_picpainter->setOpacity(p->opacity()); d->m_picpainter->setTransform(p->combinedTransform()); @@ -322,7 +322,7 @@ void QAlphaPaintEngine::flushAndInit(bool init) // painter back to the m_picpainter d->m_picpainter->setPen(painter()->pen()); d->m_picpainter->setBrush(painter()->brush()); - d->m_picpainter->setBrushOrigin(painter()->brushOrigin()); + d->m_picpainter->setBrushOrigin(painter()->brushOriginF()); d->m_picpainter->setFont(painter()->font()); d->m_picpainter->setOpacity(painter()->opacity()); d->m_picpainter->setTransform(painter()->combinedTransform()); diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp index d8e10343854..6f4611d9139 100644 --- a/src/sql/models/qsqlquerymodel.cpp +++ b/src/sql/models/qsqlquerymodel.cpp @@ -561,9 +561,9 @@ QSqlError QSqlQueryModel::lastError() const \sa lastError() */ -void QSqlQueryModel::setLastError(const QSqlError &error) +void QSqlQueryModel::setLastError(const QSqlError &error) const { - Q_D(QSqlQueryModel); + Q_D(const QSqlQueryModel); d->error = error; } diff --git a/src/sql/models/qsqlquerymodel.h b/src/sql/models/qsqlquerymodel.h index 72b9b053f03..24877118865 100644 --- a/src/sql/models/qsqlquerymodel.h +++ b/src/sql/models/qsqlquerymodel.h @@ -79,7 +79,7 @@ protected: virtual void queryChange(); virtual QModelIndex indexInQuery(const QModelIndex &item) const; - void setLastError(const QSqlError &error); + void setLastError(const QSqlError &error) const; QSqlQueryModel(QSqlQueryModelPrivate &dd, QObject *parent = nullptr); }; diff --git a/src/testlib/3rdparty/valgrind/qt_attribution.json b/src/testlib/3rdparty/valgrind/qt_attribution.json index 3146fd82c57..262bc8380b4 100644 --- a/src/testlib/3rdparty/valgrind/qt_attribution.json +++ b/src/testlib/3rdparty/valgrind/qt_attribution.json @@ -11,7 +11,7 @@ "Description": "An instrumentation framework for building dynamic analysis tools.", "Homepage": "http://valgrind.org/", - "Version": "3.24.0", + "Version": "3.25.1", "PURL": "pkg:generic/valgrind@$<VERSION>?download_url=https://valgrind.org/", "License": "BSD 4-clause \"Original\" or \"Old\" License", "LicenseId": "BSD-4-Clause", diff --git a/src/testlib/3rdparty/valgrind/valgrind_p.h b/src/testlib/3rdparty/valgrind/valgrind_p.h index 77ca3ad8692..ab49937ccd4 100644 --- a/src/testlib/3rdparty/valgrind/valgrind_p.h +++ b/src/testlib/3rdparty/valgrind/valgrind_p.h @@ -89,7 +89,7 @@ || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6)) */ #define __VALGRIND_MAJOR__ 3 -#define __VALGRIND_MINOR__ 24 +#define __VALGRIND_MINOR__ 25 #include <stdarg.h> @@ -126,6 +126,7 @@ #undef PLAT_mips32_linux #undef PLAT_mips64_linux #undef PLAT_nanomips_linux +#undef PLAT_riscv64_linux #undef PLAT_x86_solaris #undef PLAT_amd64_solaris @@ -172,6 +173,8 @@ # define PLAT_mips32_linux 1 #elif defined(__linux__) && defined(__nanomips__) # define PLAT_nanomips_linux 1 +#elif defined(__linux__) && defined(__riscv) && (__riscv_xlen == 64) +# define PLAT_riscv64_linux 1 #elif defined(__sun) && defined(__i386__) # define PLAT_x86_solaris 1 #elif defined(__sun) && defined(__x86_64__) @@ -1129,6 +1132,87 @@ typedef } while (0) #endif + +/* ----------------------- riscv64-linux ------------------------ */ + +#if defined(PLAT_riscv64_linux) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + ".option push\n\t" \ + ".option norvc\n\t" \ + "srli zero, zero, 3\n\t" \ + "srli zero, zero, 13\n\t" \ + "srli zero, zero, 51\n\t" \ + "srli zero, zero, 61\n\t" + +#define __SPECIAL_INSTRUCTION_POSTAMBLE \ + ".option pop\n\t" \ + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({volatile unsigned long int _zzq_args[6]; \ + volatile unsigned long int _zzq_result; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + __asm__ volatile("mv a3, %1\n\t" /*default*/ \ + "mv a4, %2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* a3 = client_request ( a4 ) */ \ + "or a0, a0, a0\n\t" \ + __SPECIAL_INSTRUCTION_POSTAMBLE \ + "mv %0, a3" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" ((unsigned long int)(_zzq_default)), \ + "r" (&_zzq_args[0]) \ + : "memory", "a3", "a4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* a3 = guest_NRADDR */ \ + "or a1, a1, a1\n\t" \ + __SPECIAL_INSTRUCTION_POSTAMBLE \ + "mv %0, a3" \ + : "=r" (__addr) \ + : \ + : "memory", "a3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir t0 */ \ + "or a2, a2, a2\n\t" \ + __SPECIAL_INSTRUCTION_POSTAMBLE + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or a3, a3, a3\n\t" \ + __SPECIAL_INSTRUCTION_POSTAMBLE \ + : : : "memory" \ + ); \ + } while (0) + +#endif /* PLAT_riscv64_linux */ + /* Insert assembly code for other platforms here... */ #endif /* NVALGRIND */ @@ -6606,6 +6690,456 @@ typedef #endif /* PLAT_mips64_linux */ +/* ----------------------- riscv64-linux ----------------------- */ + +#if defined(PLAT_riscv64_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "ra", \ + "t0", "t1", "t2", "t3", "t4", "t5", "t6", \ + "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", \ + "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", \ + "ft8", "ft9", "ft10", "ft11", \ + "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7" + +/* s11 is callee-saved, so we can use it to save and restore sp around + the hidden call. */ +#define VALGRIND_ALIGN_STACK \ + "mv s11, sp\n\t" \ + "andi sp, sp, 0xfffffffffffffff0\n\t" +#define VALGRIND_RESTORE_STACK \ + "mv sp, s11\n\t" + +/* These CALL_FN_ macros assume that on riscv64-linux, + sizeof(unsigned long) == 8. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ld a0, 8(%1) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld a3, 32(%1) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld a3, 32(%1) \n\t" \ + "ld a4, 40(%1) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld a3, 32(%1) \n\t" \ + "ld a4, 40(%1) \n\t" \ + "ld a5, 48(%1) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld a3, 32(%1) \n\t" \ + "ld a4, 40(%1) \n\t" \ + "ld a5, 48(%1) \n\t" \ + "ld a6, 56(%1) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld a3, 32(%1) \n\t" \ + "ld a4, 40(%1) \n\t" \ + "ld a5, 48(%1) \n\t" \ + "ld a6, 56(%1) \n\t" \ + "ld a7, 64(%1) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "addi sp, sp, -16 \n\t" \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld a3, 32(%1) \n\t" \ + "ld a4, 40(%1) \n\t" \ + "ld a5, 48(%1) \n\t" \ + "ld a6, 56(%1) \n\t" \ + "ld a7, 64(%1) \n\t" \ + "ld t0, 72(%1) \n\t" \ + "sd t0, 0(sp) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "addi sp, sp, -16 \n\t" \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld a3, 32(%1) \n\t" \ + "ld a4, 40(%1) \n\t" \ + "ld a5, 48(%1) \n\t" \ + "ld a6, 56(%1) \n\t" \ + "ld a7, 64(%1) \n\t" \ + "ld t0, 72(%1) \n\t" \ + "sd t0, 0(sp) \n\t" \ + "ld t0, 80(%1) \n\t" \ + "sd t0, 8(sp) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "addi sp, sp, -32 \n\t" \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld a3, 32(%1) \n\t" \ + "ld a4, 40(%1) \n\t" \ + "ld a5, 48(%1) \n\t" \ + "ld a6, 56(%1) \n\t" \ + "ld a7, 64(%1) \n\t" \ + "ld t0, 72(%1) \n\t" \ + "sd t0, 0(sp) \n\t" \ + "ld t0, 80(%1) \n\t" \ + "sd t0, 8(sp) \n\t" \ + "ld t0, 88(%1) \n\t" \ + "sd t0, 16(sp) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11, \ + arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "addi sp, sp, -32 \n\t" \ + "ld a0, 8(%1) \n\t" \ + "ld a1, 16(%1) \n\t" \ + "ld a2, 24(%1) \n\t" \ + "ld a3, 32(%1) \n\t" \ + "ld a4, 40(%1) \n\t" \ + "ld a5, 48(%1) \n\t" \ + "ld a6, 56(%1) \n\t" \ + "ld a7, 64(%1) \n\t" \ + "ld t0, 72(%1) \n\t" \ + "sd t0, 0(sp) \n\t" \ + "ld t0, 80(%1) \n\t" \ + "sd t0, 8(sp) \n\t" \ + "ld t0, 88(%1) \n\t" \ + "sd t0, 16(sp) \n\t" \ + "ld t0, 96(%1) \n\t" \ + "sd t0, 24(sp) \n\t" \ + "ld t0, 0(%1) \n\t" /* target->t0 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_T0 \ + VALGRIND_RESTORE_STACK \ + "mv %0, a0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS, "s11" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_riscv64_linux */ + /* ------------------------------------------------------------------ */ /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ /* */ @@ -7162,6 +7696,7 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...) #undef PLAT_mips32_linux #undef PLAT_mips64_linux #undef PLAT_nanomips_linux +#undef PLAT_riscv64_linux #undef PLAT_x86_solaris #undef PLAT_amd64_solaris diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc index 65bdd96e784..78157afa151 100644 --- a/src/testlib/doc/src/qttestlib-manual.qdoc +++ b/src/testlib/doc/src/qttestlib-manual.qdoc @@ -373,9 +373,11 @@ \list \li \c -callgrind \br - Uses Callgrind to time benchmarks (Linux only). + Uses Callgrind to time benchmarks (Linux and \macos). + \li \c -perf \br + Uses Linux perf events to time benchmarks \li \c -tickcounter \br - Uses CPU tick counters to time benchmarks. + Uses CPU tick counters to time benchmarks. Requires hardware support. \li \c -eventcounter \br Counts events received during benchmarks. \li \c -minimumvalue \e n \br @@ -452,7 +454,7 @@ The code inside the QBENCHMARK macro will be measured, and possibly also repeated several times in order to get an accurate measurement. This depends on the selected measurement back-end. Several back-ends are available. They can be selected on the - command line: + command line (see \l{Benchmarking Options}): \target testlib-benchmarking-measurement diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index f4aa45be73e..53cc849e23c 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1176,10 +1176,10 @@ class WatchDog : public QThread public: WatchDog() + : expecting{ThreadStart} { setObjectName("QtTest Watchdog"_L1); auto locker = qt_unique_lock(mutex); - expecting.store(ThreadStart, std::memory_order_relaxed); start(); waitFor(locker, ThreadStart); } diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 560ddd9a640..29cafe9aea4 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -77,14 +77,14 @@ namespace { class LoggerRegistry { using LoggersContainer = std::vector<std::shared_ptr<QAbstractTestLogger>>; - using SharedLoggersContainer = std::shared_ptr<LoggersContainer>; + using SharedLoggersContainer = std::shared_ptr<const LoggersContainer>; public: void addLogger(std::unique_ptr<QAbstractTestLogger> logger) { // read/update/clone const SharedLoggersContainer currentLoggers = load(); - SharedLoggersContainer newLoggers = currentLoggers + auto newLoggers = currentLoggers ? std::make_shared<LoggersContainer>(*currentLoggers) : std::make_shared<LoggersContainer>(); newLoggers->emplace_back(std::move(logger)); @@ -115,20 +115,20 @@ public: private: #ifdef __cpp_lib_atomic_shared_ptr - SharedLoggersContainer load() const { return loggers.load(std::memory_order_relaxed); } + SharedLoggersContainer load() const { return loggers.load(std::memory_order_acquire); } void store(SharedLoggersContainer newLoggers) { - loggers.store(std::move(newLoggers), std::memory_order_relaxed); + loggers.store(std::move(newLoggers), std::memory_order_release); } - std::atomic<SharedLoggersContainer> loggers; + std::atomic<SharedLoggersContainer> loggers = nullptr; #else SharedLoggersContainer load() const { - return std::atomic_load_explicit(&loggers, std::memory_order_relaxed); + return std::atomic_load_explicit(&loggers, std::memory_order_acquire); } void store(SharedLoggersContainer newLoggers) { - std::atomic_store_explicit(&loggers, std::move(newLoggers), std::memory_order_relaxed); + std::atomic_store_explicit(&loggers, std::move(newLoggers), std::memory_order_release); } SharedLoggersContainer loggers; #endif @@ -187,14 +187,14 @@ namespace QTest { inline bool matches(QtMsgType tp, const QString &message) const { - return tp == type - && (pattern.userType() == QMetaType::QString ? - stringsMatch(pattern.toString(), message) : + if (tp != type) + return false; #if QT_CONFIG(regularexpression) - pattern.toRegularExpression().match(message).hasMatch()); -#else - false); + if (const auto *regex = get_if<QRegularExpression>(&pattern)) + return regex->match(message).hasMatch(); #endif + Q_ASSERT(pattern.metaType() == QMetaType::fromType<QString>()); + return stringsMatch(pattern.toString(), message); } QtMsgType type; @@ -258,16 +258,18 @@ namespace QTest { // failOnWarning can be called multiple times per test function, so let // each call cause a failure if required. for (const auto &pattern : failOnWarningList) { - if (pattern.metaType() == QMetaType::fromType<QString>()) { - if (message != pattern.toString()) + if (const auto *text = get_if<QString>(&pattern)) { + if (message != *text) continue; - } #if QT_CONFIG(regularexpression) - else if (pattern.metaType() == QMetaType::fromType<QRegularExpression>()) { - if (!message.contains(pattern.toRegularExpression())) + } else if (const auto *regex = get_if<QRegularExpression>(&pattern)) { + if (!message.contains(*regex)) continue; - } #endif + } else { + // The no-arg clearFailOnWarnings()'s null pattern matches all messages. + Q_ASSERT(pattern.isNull()); + } const size_t maxMsgLen = 1024; char msg[maxMsgLen] = {'\0'}; @@ -398,13 +400,16 @@ void QTestLog::printUnhandledIgnoreMessages() QString message; QTest::IgnoreResultList *list = QTest::ignoreResultList; while (list) { - if (list->pattern.userType() == QMetaType::QString) { - message = "Did not receive message: \"%1\""_L1.arg(list->pattern.toString()); - } else { + if (const auto *text = get_if<QString>(&list->pattern)) { + message = "Did not receive message: \"%1\""_L1.arg(*text); #if QT_CONFIG(regularexpression) - message = "Did not receive any message matching: \"%1\""_L1.arg( - list->pattern.toRegularExpression().pattern()); + } else if (const auto *regex = get_if<QRegularExpression>(&list->pattern)) { + message = "Did not receive any message matching: \"%1\""_L1.arg(regex->pattern()); #endif + } else { + Q_UNREACHABLE(); + message = "Missing message of unrecognized pattern type: \"%1\""_L1.arg( + list->pattern.metaType().name()); } for (auto &logger : QTest::loggers->allLoggers()) logger->addMessage(QAbstractTestLogger::Info, message); diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 14280712154..64fd334d467 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -259,6 +259,7 @@ bool Moc::parseEnum(EnumDef *def, ClassDef *containingClass) return false; // anonymous enum isTypdefEnum = true; } + def->lineNumber = symbol().lineNum; if (test(COLON)) { // C++11 strongly typed enum // enum Foo : unsigned long { ... }; def->type = normalizeType(parseType().name); @@ -464,6 +465,8 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro) } next(LPAREN, "Not a signal or slot declaration"); def->name = tempType.name; + def->lineNumber = symbol().lineNum; + scopedFunctionName = tempType.isScoped; if (!test(RPAREN)) { @@ -1366,6 +1369,7 @@ void Moc::createPropertyDef(PropertyDef &propDef, int propertyIndex, Moc::Proper { propDef.location = index; propDef.relativeIndex = propertyIndex; + propDef.lineNumber = symbol().lineNum; Type t = parseType(); QByteArray type = t.name; @@ -2156,6 +2160,7 @@ QJsonObject FunctionDef::toJson(int index) const if (revision > 0) fdef["revision"_L1] = revision; + fdef["lineNumber"_L1] = lineNumber; if (wasCloned) fdef["isCloned"_L1] = true; @@ -2220,6 +2225,7 @@ QJsonObject PropertyDef::toJson() const prop["final"_L1] = final; prop["required"_L1] = required; prop["index"_L1] = relativeIndex; + prop["lineNumber"_L1] = lineNumber; if (revision > 0) prop["revision"_L1] = revision; @@ -2231,6 +2237,7 @@ QJsonObject EnumDef::toJson(const ClassDef &cdef) const QJsonObject def; uint flags = this->flags | cdef.enumDeclarations.value(name); def["name"_L1] = QString::fromUtf8(name); + def["lineNumber"_L1] = lineNumber; if (!enumName.isEmpty()) def["alias"_L1] = QString::fromUtf8(enumName); if (!type.isEmpty()) diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index f08edb3f0d2..fcf000c655f 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -58,6 +58,7 @@ struct EnumDef QFlags<QtMocConstants::EnumFlags> flags = {}; QJsonObject toJson(const ClassDef &cdef) const; QByteArray qualifiedType(const ClassDef *cdef) const; + int lineNumber = 0; }; Q_DECLARE_TYPEINFO(EnumDef, Q_RELOCATABLE_TYPE); @@ -84,6 +85,7 @@ struct FunctionDef enum Access { Private, Protected, Public }; Access access = Private; int revision = 0; + int lineNumber = 0; bool isConst = false; bool isVirtual = false; @@ -130,6 +132,7 @@ struct PropertyDef bool final = false; bool required = false; int relativeIndex = -1; // property index in current metaobject + int lineNumber = 0; qsizetype location = -1; // token index, used for error reporting diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp index 39da1538376..190c7b624f6 100644 --- a/src/widgets/accessible/simplewidgets.cpp +++ b/src/widgets/accessible/simplewidgets.cpp @@ -289,19 +289,32 @@ QToolButton *QAccessibleToolButton::toolButton() const bool QAccessibleToolButton::isSplitButton() const { #if QT_CONFIG(menu) - return toolButton()->menu() && toolButton()->popupMode() == QToolButton::MenuButtonPopup; + return menu() && toolButton()->popupMode() == QToolButton::MenuButtonPopup; #else return false; #endif } +#if QT_CONFIG(menu) +QMenu *QAccessibleToolButton::menu() const +{ + if (QMenu *menu = toolButton()->menu()) + return menu; + + if (QAction *defaultAction = toolButton()->defaultAction()) + return defaultAction->menu(); + + return nullptr; +} +#endif + QAccessible::State QAccessibleToolButton::state() const { QAccessible::State st = QAccessibleButton::state(); if (toolButton()->autoRaise()) st.hotTracked = true; #if QT_CONFIG(menu) - if (toolButton()->menu()) + if (menu()) st.hasPopup = true; #endif return st; @@ -315,9 +328,8 @@ int QAccessibleToolButton::childCount() const QAccessible::Role QAccessibleToolButton::role() const { #if QT_CONFIG(menu) - QAbstractButton *ab = button(); - QToolButton *tb = qobject_cast<QToolButton*>(ab); - if (!tb->menu()) + QToolButton *tb = toolButton(); + if (!menu()) return tb->isCheckable() ? QAccessible::CheckBox : QAccessible::PushButton; else if (tb->popupMode() == QToolButton::DelayedPopup) return QAccessible::ButtonDropDown; @@ -329,10 +341,8 @@ QAccessible::Role QAccessibleToolButton::role() const QAccessibleInterface *QAccessibleToolButton::child(int index) const { #if QT_CONFIG(menu) - if (index == 0 && toolButton()->menu()) - { - return QAccessible::queryAccessibleInterface(toolButton()->menu()); - } + if (index == 0 && menu()) + return QAccessible::queryAccessibleInterface(menu()); #else Q_UNUSED(index); #endif diff --git a/src/widgets/accessible/simplewidgets_p.h b/src/widgets/accessible/simplewidgets_p.h index 02c23f8cba7..356ef9101b2 100644 --- a/src/widgets/accessible/simplewidgets_p.h +++ b/src/widgets/accessible/simplewidgets_p.h @@ -27,6 +27,7 @@ class QAbstractButton; class QLineEdit; class QToolButton; class QGroupBox; +class QMenu; class QMessageBox; class QProgressBar; @@ -71,6 +72,9 @@ protected: QToolButton *toolButton() const; bool isSplitButton() const; +#if QT_CONFIG(menu) + QMenu *menu() const; +#endif }; #endif // QT_CONFIG(toolbutton) diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc index 4a5978566ed..df64db9f2cf 100644 --- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -1341,6 +1341,19 @@ for an example. \row + \li QToolBox \target qtoolbox-widget + \li Supports the \l{box model}. + \br + \br + The individual tabs can by styled using the + \l{#tab-sub}{::tab} subcontrol. The tabs support the + \l{#only-one-ps}{:only-one}, \l{#first-ps}{:first}, + \l{#last-ps}{:last}, \l{#middle-ps}{:middle}, + \l{#previous-selected-ps}{:previous-selected}, + \l{#next-selected-ps}{:next-selected}, + \l{#selected-ps}{:selected} pseudo states. + + \row \li QToolButton \target qtoolbutton-widget \li Supports the \l{box model}. \br @@ -1374,19 +1387,6 @@ for an example. \row - \li QToolBox \target qtoolbox-widget - \li Supports the \l{box model}. - \br - \br - The individual tabs can by styled using the - \l{#tab-sub}{::tab} subcontrol. The tabs support the - \l{#only-one-ps}{:only-one}, \l{#first-ps}{:first}, - \l{#last-ps}{:last}, \l{#middle-ps}{:middle}, - \l{#previous-selected-ps}{:previous-selected}, - \l{#next-selected-ps}{:next-selected}, - \l{#selected-ps}{:selected} pseudo states. - - \row \li QToolTip \target qtooltip-widget \li Supports the \l{box model}. The \l{#opacity-prop}{opacity} property controls the opacity of the tooltip. diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h index 83dfdc50bcd..c2c5f7264d4 100644 --- a/src/widgets/kernel/qapplication.h +++ b/src/widgets/kernel/qapplication.h @@ -141,6 +141,7 @@ public Q_SLOTS: protected: bool event(QEvent *) override; # if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + QT_DEPRECATED_VERSION_X_6_10("This feature will be removed in Qt 7") bool compressEvent(QEvent *, QObject *receiver, QPostEventList *) override; # endif diff --git a/src/widgets/kernel/qtestsupport_widgets.cpp b/src/widgets/kernel/qtestsupport_widgets.cpp index f7b25b6643b..5a7200e58aa 100644 --- a/src/widgets/kernel/qtestsupport_widgets.cpp +++ b/src/widgets/kernel/qtestsupport_widgets.cpp @@ -16,14 +16,14 @@ QT_BEGIN_NAMESPACE -template <typename FunctorWindowGetter, typename FunctorPredicate, typename Timeout> -static bool qWaitForWidgetWindow(FunctorWindowGetter windowGetter, FunctorPredicate predicate, Timeout timeout) +template <typename Predicate> +static bool qWaitForWidgetWindow(QWidget *w, Predicate predicate, QDeadlineTimer timeout) { - if (!windowGetter()) + if (!w->window()->windowHandle()) return false; return QTest::qWaitFor([&]() { - if (QWindow *window = windowGetter()) + if (QWindow *window = w->window()->windowHandle()) return predicate(window); return false; }, timeout); @@ -55,9 +55,9 @@ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout) << "Falling back to qWaitForWindowExposed."; return qWaitForWindowExposed(widget, timeout); } - return qWaitForWidgetWindow([&]() { return widget->window()->windowHandle(); }, + return qWaitForWidgetWindow(widget, [&](QWindow *window) { return window->isActive(); }, - timeout); + QDeadlineTimer{timeout, Qt::TimerType::PreciseTimer}); } @@ -79,11 +79,10 @@ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout) */ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowFocused(QWidget *widget, QDeadlineTimer timeout) { - return qWaitForWidgetWindow([&]() { - return widget->window()->windowHandle(); - }, [&](QWindow *window) { - return qGuiApp->focusWindow() == window; - }, timeout); + return qWaitForWidgetWindow(widget, + [&](QWindow *window) { + return qGuiApp->focusWindow() == window; + }, timeout); } /*! @@ -102,9 +101,9 @@ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowFocused(QWidget *widget, QDeadlineTim */ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout) { - return qWaitForWidgetWindow([&]() { return widget->window()->windowHandle(); }, + return qWaitForWidgetWindow(widget, [&](QWindow *window) { return window->isExposed(); }, - timeout); + QDeadlineTimer{timeout, Qt::TimerType::PreciseTimer}); } namespace QTest { diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 1155172a0a8..22ca1d238fe 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1360,6 +1360,12 @@ void QWidgetPrivate::create() xcbWindow->setWindowRole(topData()->role); } #endif +#if QT_CONFIG(wayland) + if (!topData()->role.isNull()) { + if (auto *waylandWindow = dynamic_cast<QWaylandWindow*>(win->handle())) + waylandWindow->setSessionRestoreId(topData()->role); + } +#endif QBackingStore *store = q->backingStore(); usesRhiFlush = false; @@ -6359,17 +6365,24 @@ QString QWidget::windowRole() const */ void QWidget::setWindowRole(const QString &role) { -#if QT_CONFIG(xcb) +#if QT_CONFIG(xcb) || QT_CONFIG(wayland) Q_D(QWidget); d->createTLExtra(); d->topData()->role = role; +#else + Q_UNUSED(role); +#endif + if (windowHandle()) { +#if QT_CONFIG(xcb) if (auto *xcbWindow = dynamic_cast<QXcbWindow*>(windowHandle()->handle())) xcbWindow->setWindowRole(role); - } -#else - Q_UNUSED(role); #endif +#if QT_CONFIG(wayland) + if (auto *waylandWindow = dynamic_cast<QWaylandWindow*>(windowHandle()->handle())) + waylandWindow->setSessionRestoreId(role); +#endif + } } /*! diff --git a/src/widgets/kernel/qwidgetsvariant.cpp b/src/widgets/kernel/qwidgetsvariant.cpp index 17a19aa780d..c843927d366 100644 --- a/src/widgets/kernel/qwidgetsvariant.cpp +++ b/src/widgets/kernel/qwidgetsvariant.cpp @@ -11,18 +11,16 @@ QT_BEGIN_NAMESPACE namespace { - -// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor): this is not a base class -static constexpr struct : QMetaTypeModuleHelper +struct QVariantWidgetsHelper : QMetaTypeModuleHelper { - const QtPrivate::QMetaTypeInterface *interfaceForType(int type) const override { + static const QtPrivate::QMetaTypeInterface *interfaceForType(int type) + { switch (type) { QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_METATYPE_CONVERT_ID_TO_TYPE) default: return nullptr; } } -} qVariantWidgetsHelper; - +}; #undef QT_IMPL_METATYPEINTERFACE_WIDGETS_TYPES @@ -30,7 +28,9 @@ static constexpr struct : QMetaTypeModuleHelper void qRegisterWidgetsVariant() { - qMetaTypeWidgetsHelper = &qVariantWidgetsHelper; + qMetaTypeWidgetsHelper = QMetaTypeModuleHelper{ + &QVariantWidgetsHelper::interfaceForType, + }; } Q_CONSTRUCTOR_FUNCTION(qRegisterWidgetsVariant) diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index e9cc250c517..c341a025115 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -591,7 +591,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) painter->setPen(highlightedOutline); else - painter->setPen(colorScheme() == Qt::ColorScheme::Dark ? outline.lighter(150) + painter->setPen(colorScheme() == Qt::ColorScheme::Dark ? outline.lighter(240) : outline.lighter(110)); painter->drawRect(rect); diff --git a/src/widgets/styles/qfusionstyle_p_p.h b/src/widgets/styles/qfusionstyle_p_p.h index 67abdd74dc8..62641609d59 100644 --- a/src/widgets/styles/qfusionstyle_p_p.h +++ b/src/widgets/styles/qfusionstyle_p_p.h @@ -70,10 +70,7 @@ public: } if (pal.window().style() == Qt::TexturePattern) return QColor(0, 0, 0, 160); - if (colorScheme() == Qt::ColorScheme::Dark) - return pal.window().color().lighter(140); - else - return pal.window().color().darker(140); + return pal.window().color().darker(140); } QColor highlightedOutline(const QPalette &pal) const { diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index c8c8cb21851..907628f224e 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -1137,23 +1137,24 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai #if QT_CONFIG(menubar) case CE_MenuBarItem: if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { - bool active = mbi->state & State_Selected; - bool hasFocus = mbi->state & State_HasFocus; - bool down = mbi->state & State_Sunken; + const bool active = mbi->state & State_Selected; + const QBrush buttonBrush = mbi->palette.brush(QPalette::Button); QStyleOptionMenuItem newMbi = *mbi; - p->fillRect(mbi->rect, mbi->palette.brush(QPalette::Button)); - if (active || hasFocus) { - QBrush b = mbi->palette.brush(QPalette::Button); - if (active && down) - p->setBrushOrigin(p->brushOrigin() + QPoint(1, 1)); - if (active && hasFocus) + p->fillRect(mbi->rect, buttonBrush); + if (active) { + const bool hasFocus = mbi->state & State_HasFocus; + const bool down = mbi->state & State_Sunken; + QPainterStateGuard psg(p, QPainterStateGuard::InitialState::NoSave); + if (down) { + psg.save(); + p->setBrushOrigin(p->brushOriginF() + QPointF(1, 1)); + } + if (hasFocus) qDrawShadeRect(p, mbi->rect.x(), mbi->rect.y(), mbi->rect.width(), - mbi->rect.height(), mbi->palette, active && down, 1, 0, &b); - if (active && down) { + mbi->rect.height(), mbi->palette, active && down, 1, 0, &buttonBrush); + if (down) newMbi.rect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, mbi, widget), - proxy()->pixelMetric(PM_ButtonShiftVertical, mbi, widget)); - p->setBrushOrigin(p->brushOrigin() - QPoint(1, 1)); - } + proxy()->pixelMetric(PM_ButtonShiftVertical, mbi, widget)); } QCommonStyle::drawControl(ce, &newMbi, p, widget); } diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index ed6f6f6193b..a1a4cfc2ce0 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -147,7 +147,7 @@ QDebug operator<<(QDebug debug, const QDockAreaLayout &layout) QDebug operator<<(QDebug debug, const QMainWindowLayout *layout) { if (layout) - return debug << layout->layoutState.dockAreaLayout; + return std::move(debug) << layout->layoutState.dockAreaLayout; return debug << "QMainWindowLayout(0x0)"; } @@ -2673,8 +2673,10 @@ void QMainWindowLayout::animationFinished(QWidget *widget) parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); #if QT_CONFIG(tabbar) const auto usedTabBarsCopy = usedTabBars; // list potentially modified by animations - for (QTabBar *tab_bar : usedTabBarsCopy) - tab_bar->show(); + for (QTabBar *tab_bar : usedTabBarsCopy) { + if (usedTabBars.contains(tab_bar)) // Showing a tab bar can cause another to be deleted. + tab_bar->show(); + } #endif // QT_CONFIG(tabbar) #endif // QT_CONFIG(dockwidget) } diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp index 431faf9e24d..af7a2e011b8 100644 --- a/src/widgets/widgets/qscrollbar.cpp +++ b/src/widgets/widgets/qscrollbar.cpp @@ -382,7 +382,7 @@ QMenu *QScrollBar::createStandardContextMenu(QPoint position) { #if QT_CONFIG(menu) const bool horiz = HORIZONTAL; - QMenu *menu = new QMenu(); + QMenu *menu = new QMenu(this); menu->setObjectName("qt_scrollbar_menu"_L1); if (window() && window()->windowHandle()) { diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index f3c7e2d9938..a6a502e5b47 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include <qplatformdefs.h> #include <qdom.h> diff --git a/src/xml/dom/qdomhelpers.cpp b/src/xml/dom/qdomhelpers.cpp index c41529f289d..dae25aa07d0 100644 --- a/src/xml/dom/qdomhelpers.cpp +++ b/src/xml/dom/qdomhelpers.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2019 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:critical reason:data-parser #include <QtXml/qtxmlglobal.h> diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 4028fc2c1bb..7c4f33cddb6 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -86,12 +86,6 @@ endif() set(required_packages Core Network Xml Sql Test TestInternalsPrivate) set(optional_packages DBus Gui Widgets PrintSupport OpenGL Concurrent) -# Setup the test when called as a completely standalone project. -if(TARGET Qt6::Core) - # Tests are built as part of the qtbase build tree. - # Setup paths so that the Qt packages are found, similar to examples. - qt_internal_set_up_build_dir_package_paths() -endif() find_package(Qt6 REQUIRED COMPONENTS ${required_packages}) find_package(Qt6 OPTIONAL_COMPONENTS ${optional_packages}) diff --git a/tests/auto/cmake/RunCMake/CMakeLists.txt b/tests/auto/cmake/RunCMake/CMakeLists.txt index bb826775b2d..17a3a3b0c69 100644 --- a/tests/auto/cmake/RunCMake/CMakeLists.txt +++ b/tests/auto/cmake/RunCMake/CMakeLists.txt @@ -2,6 +2,8 @@ add_RunCMake_test(QtFlagHandlingHelpers "-DQt6_DIR=${Qt6_DIR}") +add_RunCMake_test(find_package "-DQt6_DIR=${Qt6_DIR}") + set(extra_run_cmake_args "-DQt6_DIR=${Qt6_DIR}") if(TARGET Qt::Gui) list(APPEND extra_run_cmake_args "-DHAS_GUI=TRUE") diff --git a/tests/auto/cmake/RunCMake/find_package/CMakeLists.txt b/tests/auto/cmake/RunCMake/find_package/CMakeLists.txt new file mode 100644 index 00000000000..223fe15adae --- /dev/null +++ b/tests/auto/cmake/RunCMake/find_package/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.16) +project(${RunCMake_TEST} LANGUAGES CXX) + +# Setting AUTOMOC to true to make sure Qt package is used +set(CMAKE_AUTOMOC ON) + +include(${RunCMake_TEST}.cmake) diff --git a/tests/auto/cmake/RunCMake/find_package/RunCMakeTest.cmake b/tests/auto/cmake/RunCMake/find_package/RunCMakeTest.cmake new file mode 100644 index 00000000000..1f6d1ae10bc --- /dev/null +++ b/tests/auto/cmake/RunCMake/find_package/RunCMakeTest.cmake @@ -0,0 +1,12 @@ +include(RunCMake) + +function(run_cmake_and_build case) + # Set common build directory for configure and build + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build) + run_cmake_with_options(${case} "-DQt6_DIR=${Qt6_DIR}") + # Do not remove the current RunCMake_TEST_BINARY_DIR + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(${case}-build ${CMAKE_COMMAND} --build .) +endfunction() + +run_cmake_and_build(find_package_basic) diff --git a/tests/auto/cmake/RunCMake/find_package/dummy.cpp b/tests/auto/cmake/RunCMake/find_package/dummy.cpp new file mode 100644 index 00000000000..3a338be94b2 --- /dev/null +++ b/tests/auto/cmake/RunCMake/find_package/dummy.cpp @@ -0,0 +1,3 @@ +#include <QtCore/QString> + +int foo() { return 1; } diff --git a/tests/auto/cmake/RunCMake/find_package/find_package_basic.cmake b/tests/auto/cmake/RunCMake/find_package/find_package_basic.cmake new file mode 100644 index 00000000000..e6f16e307ca --- /dev/null +++ b/tests/auto/cmake/RunCMake/find_package/find_package_basic.cmake @@ -0,0 +1,5 @@ +find_package(Qt6 REQUIRED COMPONENTS Core) + +qt_add_library(foo) +target_sources(foo PRIVATE dummy.cpp) +target_link_libraries(foo PRIVATE Qt6::Core) diff --git a/tests/auto/cmake/test_qt_extract_metatypes/test_qt_extract_metatypes_project/testdata/qt6metatypetest_metatypesQ_OBJECTandQ_PROPERTY.json b/tests/auto/cmake/test_qt_extract_metatypes/test_qt_extract_metatypes_project/testdata/qt6metatypetest_metatypesQ_OBJECTandQ_PROPERTY.json index 2a6d80aa34c..fe80985f796 100644 --- a/tests/auto/cmake/test_qt_extract_metatypes/test_qt_extract_metatypes_project/testdata/qt6metatypetest_metatypesQ_OBJECTandQ_PROPERTY.json +++ b/tests/auto/cmake/test_qt_extract_metatypes/test_qt_extract_metatypes_project/testdata/qt6metatypetest_metatypesQ_OBJECTandQ_PROPERTY.json @@ -11,6 +11,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 11, "name": "test", "read": "test", "required": false, diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index 1e423f21bec..0ea2be1b147 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -430,7 +430,7 @@ void tst_QDir::mkdirRmdir() void tst_QDir::mkdirOnSymlink() { -#if !defined(Q_OS_UNIX) || defined(Q_NO_SYMLINKS) || defined(Q_OS_INTEGRITY) || defined(Q_OS_WASM) +#if !defined(Q_OS_UNIX) || defined(Q_NO_SYMLINKS) || defined(Q_OS_INTEGRITY) QSKIP("Test only valid on an OS that supports symlinks"); #else // Create the structure: @@ -477,9 +477,6 @@ void tst_QDir::mkdirOnSymlink() #if defined(Q_OS_QNX) QSKIP("Fails on QNX QTBUG-98561"); #endif -#if defined (Q_OS_WASM) - QEXPECT_FAIL("", "fails on wasm, see bug: QTBUG-127766", Continue); -#endif QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData()); #endif } diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 781f64a31ab..66c3db2e2f0 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -228,6 +228,7 @@ private slots: void getCharFF(); void remove_and_exists(); void removeOpenFile(); + void removedFileDoesntExist(); void fullDisk(); void writeLargeDataBlock_data(); void writeLargeDataBlock(); @@ -2526,6 +2527,37 @@ void tst_QFile::removeOpenFile() } } +void tst_QFile::removedFileDoesntExist() +{ +#ifdef Q_OS_WIN + QSKIP("Not relevant for Windows - can't remove still-open files"); +#endif + QFile::remove("remove_unclosed.txt"); + QFile f("remove_unclosed.txt"); + QVERIFY(!f.exists()); + bool opened = f.open(QIODevice::ReadWrite | QIODevice::Unbuffered); + QVERIFY(opened); + f.write("blah blah blah"); + + QVERIFY(f.exists()); + + // delete by path, not using f.remove() (that's tested above) + QVERIFY(QFile::remove(f.fileName())); + QVERIFY(!QFile::exists(f.fileName())); + QVERIFY(!f.exists()); + +#ifdef Q_OS_LINUX + QString procPath = u"/proc/self/fd/"_s; + if (QFile::exists(procPath)) { + // reopen the deleted file + procPath += QString::number(f.handle()); + QFile f2(procPath); + QVERIFY(f2.open(QIODevice::ReadOnly)); + QVERIFY(!f2.exists()); + } +#endif +} + void tst_QFile::fullDisk() { QFile file("/dev/full"); diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 761f0552eec..e2190477441 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -141,6 +141,7 @@ private slots: void exists_data(); void exists(); + void deletedFileLinuxProcExists(); void absolutePath_data(); void absolutePath(); @@ -615,6 +616,34 @@ void tst_QFileInfo::exists() QVERIFY(!exists); } +void tst_QFileInfo::deletedFileLinuxProcExists() +{ +#ifdef Q_OS_LINUX + static const char msg[] = "Hello, World\n"; + QFileInfo fi("/proc/self/fd/"); + if (!fi.isDir()) + QSKIP("/proc appears not to be mounted"); + + QFile f("removed_file.txt"); + QVERIFY(f.open(QIODevice::ReadWrite | QIODevice::Unbuffered)); + f.write(msg, strlen(msg)); + + fi.setFile(fi.filePath() + QString::number(f.handle())); + QVERIFY(fi.exists()); + QCOMPARE(fi.size(), strlen(msg)); + + QFile::remove("removed_file.txt"); + fi.refresh(); + QVERIFY(fi.exists()); + + fi.refresh(); + QCOMPARE(fi.size(), strlen(msg)); // this stats, so may change flags + QVERIFY(fi.exists()); +#else + QSKIP("Linux-only test"); +#endif +} + void tst_QFileInfo::absolutePath_data() { QTest::addColumn<QString>("file"); diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 282c7f2e360..71389abc976 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -513,6 +513,7 @@ void tst_QUrl::comparison2() QCOMPARE(url1.toString(), url2.toString()); QCOMPARE(url1, url2); QCOMPARE(qHash(url1), qHash(url2)); + QCOMPARE(qHash(url1, 1), qHash(url2, 1)); } else if (ordering < 0) { QCOMPARE_LT(url1.toString(), url2.toString()); QCOMPARE_NE(url1, url2); @@ -1387,12 +1388,14 @@ void tst_QUrl::toString_constructed() QUrl parsed(asString); QCOMPARE(url, parsed); QCOMPARE(qHash(url), qHash(parsed)); + QCOMPARE(qHash(url, 1), qHash(parsed, 1)); } // clear it and ensure no memory of the previous state remains url.setUrl(QString()); QCOMPARE(url, QUrl()); QCOMPARE(qHash(url), qHash(QUrl())); + QCOMPARE(qHash(url, 1), qHash(QUrl(), 1)); } void tst_QUrl::toDisplayString_PreferLocalFile_data() @@ -4265,6 +4268,7 @@ void tst_QUrl::setComponents() QUrl recreated(toString); QCOMPARE(copy, recreated); QCOMPARE(qHash(copy), qHash(recreated)); + QCOMPARE(qHash(copy, 1), qHash(recreated, 1)); } else { QVERIFY(copy.toString().isEmpty()); } diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp index c99242c927b..79d94c9b45c 100644 --- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -67,6 +67,7 @@ private slots: void testSetHandleLayoutChanges(); void testSetHandleDataChanges(); + void matchCustomRole(); protected: void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex()); @@ -576,5 +577,38 @@ void tst_QIdentityProxyModel::testSetHandleDataChanges() QVERIFY(!model.isConnected(signal)); } +class CustomRoleProxyModel : public QIdentityProxyModel +{ +public: + using QIdentityProxyModel::QIdentityProxyModel; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + Q_ASSERT(index.isValid()); + if (role == Qt::UserRole) + return QStringLiteral("CustomUserData-%1").arg(index.row()); + return QIdentityProxyModel::data(index, role); + } +}; + +void tst_QIdentityProxyModel::matchCustomRole() +{ + QStandardItemModel sourceModel; + for (int i = 0; i < 5; ++i) + sourceModel.appendRow(new QStandardItem(QString("Item %1").arg(i))); + + CustomRoleProxyModel proxyModel; + proxyModel.setSourceModel(&sourceModel); + + const QString targetValue = QStringLiteral("CustomUserData-3"); + + const QModelIndexList matches = proxyModel.match(proxyModel.index(0, 0), Qt::UserRole, + targetValue, 1, Qt::MatchExactly); + + QCOMPARE(matches.size(), 1); + QCOMPARE(matches.first().row(), 3); + QCOMPARE(proxyModel.data(matches.first(), Qt::UserRole).toString(), targetValue); +} + QTEST_MAIN(tst_QIdentityProxyModel) #include "tst_qidentityproxymodel.moc" diff --git a/tests/auto/corelib/itemmodels/qrangemodel/tst_qrangemodel.cpp b/tests/auto/corelib/itemmodels/qrangemodel/tst_qrangemodel.cpp index 5a49d9cf024..878fd173675 100644 --- a/tests/auto/corelib/itemmodels/qrangemodel/tst_qrangemodel.cpp +++ b/tests/auto/corelib/itemmodels/qrangemodel/tst_qrangemodel.cpp @@ -286,6 +286,7 @@ private slots: void ranges(); void json(); void ownership(); + void overrideRoleNames(); void dimensions_data() { createTestData(); } void dimensions(); @@ -1008,6 +1009,45 @@ void tst_QRangeModel::ownership() } } +void tst_QRangeModel::overrideRoleNames() +{ + // verify that an overridden roleNames() gets called consistently + class RoleModel : public QRangeModel + { + public: + RoleModel() : QRangeModel(QList<SingleColumn<Object *>>{ + new Object, + new Object, + new Object, + }) { + } + + QHash<int, QByteArray> roleNames() const override + { + return { + {Qt::UserRole, "string"}, + {Qt::UserRole + 1, "number"} + }; + } + }; + + RoleModel model; + const QList<int> expectedKeys = {Qt::UserRole, Qt::UserRole + 1}; + QCOMPARE(model.roleNames().size(), expectedKeys.size()); + + const QModelIndex index = model.index(0, 0); + QVERIFY(model.setData(index, "string value", Qt::UserRole)); + QVERIFY(model.setData(index, 42, Qt::UserRole + 1)); + QVERIFY(!model.setData(index, "display")); + + const auto itemData = model.itemData(index); + QCOMPARE(itemData.keys(), expectedKeys); + QCOMPARE(itemData.value(Qt::UserRole), "string value"); + QCOMPARE(itemData.value(Qt::UserRole + 1), 42); + + QVERIFY(model.setItemData(model.index(1, 0), itemData)); +} + void tst_QRangeModel::dimensions() { QFETCH(Factory, factory); diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index f8f978585a1..83ce49d93ba 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -2395,6 +2395,9 @@ void tst_QMetaObject::normalizedType_data() QTest::addColumn<QString>("type"); QTest::addColumn<QString>("result"); + QTest::newRow("null") << QString() << QString(); + QTest::newRow("empty") << "" << ""; + QTest::newRow("all_whitespaces") << " " << ""; QTest::newRow("simple") << "int" << "int"; QTest::newRow("white") << " int " << "int"; QTest::newRow("const1") << "int const *" << "const int*"; @@ -2465,7 +2468,15 @@ void tst_QMetaObject::normalizedType() QFETCH(QString, type); QFETCH(QString, result); - QCOMPARE(QMetaObject::normalizedType(type.toLatin1()), result.toLatin1()); + QByteArray latin1Type = type.toLatin1(); + + const char *typePtr; + if (type.isNull()) + typePtr = nullptr; + else + typePtr = latin1Type.constData(); + + QCOMPARE(QMetaObject::normalizedType(typePtr), result.toLatin1()); QCOMPARE(QMetaObject::normalizedType(result.toLatin1()), result.toLatin1()); } diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index b1e2e8164af..f2d281ae0a4 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -708,6 +708,8 @@ void tst_QMetaObjectBuilder::property() prop2.setEnumOrFlag(false); \ prop2.setConstant(false); \ prop2.setFinal(false); \ + prop2.setBindable(false); \ + prop2.setRequired(false); \ } while (0) #define COUNT_FLAGS() \ ((prop2.isReadable() ? 1 : 0) + \ @@ -720,7 +722,9 @@ void tst_QMetaObjectBuilder::property() (prop2.hasStdCppSet() ? 1 : 0) + \ (prop2.isEnumOrFlag() ? 1 : 0) + \ (prop2.isConstant() ? 1 : 0) + \ - (prop2.isFinal() ? 1 : 0)) + (prop2.isFinal() ? 1 : 0) + \ + (prop2.isBindable() ? 1 : 0) + \ + (prop2.isRequired() ? 1 : 0)) #define CHECK_FLAG(setFunc,isFunc) \ do { \ CLEAR_FLAGS(); \ diff --git a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp index f66bea72828..d53d0d1713d 100644 --- a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp +++ b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp @@ -16,6 +16,23 @@ using namespace std::chrono_literals; +class Interface +{ +public: + virtual ~Interface() = default; + virtual void meep() const = 0; +}; + +class ObjectImplementingInterface : public QObject, public Interface +{ + Q_OBJECT +public: + using QObject::QObject; + +public Q_SLOTS: + void meep() const override {} +}; + class tst_QPointer : public QObject { Q_OBJECT @@ -31,6 +48,7 @@ private slots: void assignment_operators(); void compareCompiles(); void equality_operators(); + void equality_operators_interface(); void swap(); void isNull(); void dereference_operators(); @@ -218,6 +236,7 @@ void tst_QPointer::compareCompiles() QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, QWidget*>(); QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, QPointer<QWidget>>(); QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, std::nullptr_t>(); + QTestPrivate::testEqualityOperatorsCompile<QPointer<ObjectImplementingInterface>, Interface*>(); } void tst_QPointer::equality_operators() @@ -259,6 +278,25 @@ void tst_QPointer::equality_operators() #endif } +void tst_QPointer::equality_operators_interface() +{ + QObject reaper; + QPointer<ObjectImplementingInterface> p(new ObjectImplementingInterface(&reaper)); + Interface *i = p.get(); + + ObjectImplementingInterface otherP; + Interface *otherI = &otherP; + + // things that are equal + QT_TEST_EQUALITY_OPS(p, p, true); + QT_TEST_EQUALITY_OPS(p, i, true); + + // things that are not equal + QT_TEST_EQUALITY_OPS(p, nullptr, false); + QT_TEST_EQUALITY_OPS(p, &otherP, false); + QT_TEST_EQUALITY_OPS(p, otherI, false); +} + void tst_QPointer::swap() { QPointer<QObject> c1, c2; diff --git a/tests/auto/corelib/platform/android_legacy_packaging/testdata/build.gradle b/tests/auto/corelib/platform/android_legacy_packaging/testdata/build.gradle index 806614e113f..cbdd833e2ae 100644 --- a/tests/auto/corelib/platform/android_legacy_packaging/testdata/build.gradle +++ b/tests/auto/corelib/platform/android_legacy_packaging/testdata/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.8.0' + classpath 'com.android.tools.build:gradle:8.10.1' } } diff --git a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp index 8c129a93c71..d976191406d 100644 --- a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp +++ b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp @@ -242,7 +242,7 @@ constexpr bool CanConvertFromWCharT = #endif ; -static_assert(CanConvert<wchar_t> == CanConvertFromWCharT); // ### FIXME: should work everywhere +static_assert(CanConvert<wchar_t>); static_assert(CanConvert< wchar_t[123]> == CanConvertFromWCharT); static_assert(CanConvert<const wchar_t[123]> == CanConvertFromWCharT); @@ -414,7 +414,10 @@ private Q_SLOTS: fromCharacter(U'\x1F0A0', 2, true); // U+1F0A0: PLAYING CARD BACK } void fromWCharT() const { - ONLY_WIN(fromCharacter(L'ä', 1)); // should work on Unix, too (char32_t does) + fromCharacter(L'ä', 1, sizeof(L'ä') == sizeof(char32_t)); +#ifndef Q_OS_WIN // sizedof(wchar_t) == 2 on Windows, so L'\x1F0A0' would be out-of-range + fromCharacter(L'\x1F0A0', 2, true); // U+1F0A0: PLAYING CARD BACK +#endif } void fromQChar() const { fromCharacter(QChar(u'ä'), 1); } void fromQLatin1Char() const { fromCharacter(QLatin1Char('\xE4'), 1, true); } diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 35eda3ad709..bfc6074689b 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -445,14 +445,16 @@ void tst_QLocale::defaulted_ctor() TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates); TEST_CTOR(English, France, QLocale::English, QLocale::France); TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom); + // Used in tests below to check we pick the likely-best substitute consistently: + TEST_CTOR(Arabic, UnitedStates, QLocale::Arabic, QLocale::Egypt); TEST_CTOR(French, France, QLocale::French, QLocale::France); TEST_CTOR(C, France, QLocale::C, QLocale::AnyTerritory); TEST_CTOR(Spanish, LatinAmerica, QLocale::Spanish, QLocale::LatinAmerica); - QLocale::setDefault(QLocale(QLocale::English, QLocale::France)); - CHECK_DEFAULT(QLocale::English, QLocale::France); + QLocale::setDefault(QLocale(QLocale::Arabic, QLocale::UnitedStates)); + CHECK_DEFAULT(QLocale::Arabic, QLocale::Egypt); TEST_CTOR(French, France, QLocale::French, QLocale::France); TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom); @@ -460,7 +462,7 @@ void tst_QLocale::defaulted_ctor() TEST_CTOR(French, France, QLocale::French, QLocale::France); TEST_CTOR(C, AnyTerritory, QLocale::C, QLocale::AnyTerritory); TEST_CTOR(C, France, QLocale::C, QLocale::AnyTerritory); - TEST_CTOR(Aymara, AnyTerritory, QLocale::English, QLocale::France); + TEST_CTOR(Aymara, AnyTerritory, QLocale::Arabic, QLocale::Egypt); QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom)); CHECK_DEFAULT(QLocale::English, QLocale::UnitedKingdom); @@ -481,6 +483,7 @@ void tst_QLocale::defaulted_ctor() TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates); TEST_CTOR(English, France, QLocale::English, QLocale::France); TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom); + TEST_CTOR(Arabic, UnitedStates, QLocale::Arabic, QLocale::Egypt); TEST_CTOR(French, France, QLocale::French, QLocale::France); TEST_CTOR(C, AnyTerritory, QLocale::C, QLocale::AnyTerritory); @@ -496,6 +499,7 @@ void tst_QLocale::defaulted_ctor() TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates); TEST_CTOR(English, France, QLocale::English, QLocale::France); TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom); + TEST_CTOR(Arabic, UnitedStates, QLocale::Arabic, QLocale::Egypt); TEST_CTOR(French, France, QLocale::French, QLocale::France); TEST_CTOR(C, AnyTerritory, QLocale::C, QLocale::AnyTerritory); @@ -2466,7 +2470,8 @@ void tst_QLocale::formatTimeZone() // Time definitely in Standard Time const QStringList knownCETus = { u"GMT+1"_s, // ICU - u"CET"_s // Standard abbreviation + u"CET"_s, // Standard abbreviation + u"UTC+0100"_s, // used by Emscripten }; const QString cet = enUS.toString(QDate(2013, 1, 1).startOfDay(), u"t"); QVERIFY2(knownCETus.contains(cet), cet.isEmpty() ? "[empty]" : qPrintable(cet)); @@ -2474,7 +2479,8 @@ void tst_QLocale::formatTimeZone() // Time definitely in Daylight Time const QStringList knownCESTus = { u"GMT+2"_s, // ICU - u"CEST"_s // Standard abbreviation + u"CEST"_s, // Standard abbreviation + u"UTC+0200"_s, // used by Emscripten }; const QString cest = enUS.toString(QDate(2013, 6, 1).startOfDay(), u"t"); QVERIFY2(knownCESTus.contains(cest), cest.isEmpty() ? "[empty]" : qPrintable(cest)); diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index cfc0ec1cc07..2cd1398e7f9 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -6859,10 +6859,7 @@ void tst_QString::arg() // char-ish overloads QCOMPARE(s4.arg('\xE4'), QStringView(u"[ä]")); QCOMPARE(s4.arg(u'ø'), QStringView(u"[ø]")); -#ifdef Q_OS_WIN QCOMPARE(QLatin1String("[%1]").arg(L'ø'), QStringView(u"[ø]")); -#endif - QEXPECT_FAIL("", "QTBUG-126054", Continue); QCOMPARE(s4.arg(L'ø'), QStringView(u"[ø]")); #ifndef __cpp_char8_t #ifndef QT_NO_CAST_FROM_ASCII diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 0b2aaa8281e..7b5b468df0d 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -603,6 +603,8 @@ private Q_SLOTS: void arg1_QString_char16_t() { arg1_impl<QString, char16_t>(); } + void arg1_QString_wchar_t_data() { arg1_data(false); } + void arg1_QString_wchar_t() { arg1_impl<QString, wchar_t>(); } void arg1_QStringView_QString_data() { arg1_data(); } void arg1_QStringView_QString() { arg1_impl<QStringView, QString>(); } @@ -638,6 +640,8 @@ private Q_SLOTS: void arg1_QStringView_QLatin1Char() { arg1_impl<QStringView, QLatin1Char>(); } void arg1_QStringView_char16_t_data() { arg1_data(false); } void arg1_QStringView_char16_t() { arg1_impl<QStringView, char16_t>(); } + void arg1_QStringView_wchar_t_data() { arg1_data(false); } + void arg1_QStringView_wchar_t() { arg1_impl<QStringView, wchar_t>(); } void arg1_QLatin1StringView_QString_data() { arg1_data(); } void arg1_QLatin1StringView_QString() { arg1_impl<QLatin1StringView, QString>(); } @@ -673,6 +677,8 @@ private Q_SLOTS: void arg1_QLatin1StringView_QLatin1Char() { arg1_impl<QLatin1StringView, QLatin1Char>(); } void arg1_QLatin1StringView_char16_t_data() { arg1_data(false); } void arg1_QLatin1StringView_char16_t() { arg1_impl<QLatin1StringView, char16_t>(); } + void arg1_QLatin1StringView_wchar_t_data() { arg1_data(false); } + void arg1_QLatin1StringView_wchar_t() { arg1_impl<QLatin1StringView, wchar_t>(); } void arg1_QUtf8StringView_QString_data() { arg1_data(); } void arg1_QUtf8StringView_QString() { arg1_impl<QUtf8StringView, QString>(); } @@ -708,6 +714,8 @@ private Q_SLOTS: void arg1_QUtf8StringView_QLatin1Char() { arg1_impl<QUtf8StringView, QLatin1Char>(); } void arg1_QUtf8StringView_char16_t_data() { arg1_data(false); } void arg1_QUtf8StringView_char16_t() { arg1_impl<QUtf8StringView, char16_t>(); } + void arg1_QUtf8StringView_wchar_t_data() { arg1_data(false); } + void arg1_QUtf8StringView_wchar_t() { arg1_impl<QUtf8StringView, wchar_t>(); } void arg1_QAnyStringViewUsingL1_QString_data() { arg1_data(); } void arg1_QAnyStringViewUsingL1_QString() { arg1_impl<QAnyStringViewUsingL1, QString>(); } @@ -743,6 +751,8 @@ private Q_SLOTS: void arg1_QAnyStringViewUsingL1_QLatin1Char() { arg1_impl<QAnyStringViewUsingL1, QLatin1Char>(); } void arg1_QAnyStringViewUsingL1_char16_t_data() { arg1_data(false); } void arg1_QAnyStringViewUsingL1_char16_t() { arg1_impl<QAnyStringViewUsingL1, char16_t>(); } + void arg1_QAnyStringViewUsingL1_wchar_t_data() { arg1_data(false); } + void arg1_QAnyStringViewUsingL1_wchar_t() { arg1_impl<QAnyStringViewUsingL1, wchar_t>(); } void arg1_QAnyStringViewUsingU8_QString_data() { arg1_data(); } void arg1_QAnyStringViewUsingU8_QString() { arg1_impl<QAnyStringViewUsingU8, QString>(); } @@ -778,6 +788,8 @@ private Q_SLOTS: void arg1_QAnyStringViewUsingU8_QLatin1Char() { arg1_impl<QAnyStringViewUsingU8, QLatin1Char>(); } void arg1_QAnyStringViewUsingU8_char16_t_data() { arg1_data(false); } void arg1_QAnyStringViewUsingU8_char16_t() { arg1_impl<QAnyStringViewUsingU8, char16_t>(); } + void arg1_QAnyStringViewUsingU8_wchar_t_data() { arg1_data(false); } + void arg1_QAnyStringViewUsingU8_wchar_t() { arg1_impl<QAnyStringViewUsingU8, wchar_t>(); } void arg1_QAnyStringViewUsingU16_QString_data() { arg1_data(); } void arg1_QAnyStringViewUsingU16_QString() { arg1_impl<QAnyStringViewUsingU16, QString>(); } @@ -813,6 +825,8 @@ private Q_SLOTS: void arg1_QAnyStringViewUsingU16_QLatin1Char() { arg1_impl<QAnyStringViewUsingU16, QLatin1Char>(); } void arg1_QAnyStringViewUsingU16_char16_t_data() { arg1_data(false); } void arg1_QAnyStringViewUsingU16_char16_t() { arg1_impl<QAnyStringViewUsingU16, char16_t>(); } + void arg1_QAnyStringViewUsingU16_wchar_t_data() { arg1_data(false); } + void arg1_QAnyStringViewUsingU16_wchar_t() { arg1_impl<QAnyStringViewUsingU16, wchar_t>(); } private: void split_data(bool rhsHasVariableLength = true); @@ -1627,6 +1641,7 @@ template <class Str> Str make(QStringView sf, QLatin1String l1, const QByteArra MAKE(QChar) { return sv.isEmpty() ? QChar() : sv.at(0); } MAKE(char) { return sv.isEmpty() ? char() : char(sv.at(0).unicode()); } MAKE(char16_t) { return sv.isEmpty() ? char16_t() : char16_t{sv.at(0).unicode()}; } +MAKE(wchar_t) { return make<char16_t>(sv, l1, u8); } MAKE(QLatin1Char) { return l1.isEmpty() ? QLatin1Char('\0') : l1.at(0); } MAKE(QString) { return sv.toString(); } MAKE(QStringView) { return sv; } diff --git a/tests/auto/corelib/thread/CMakeLists.txt b/tests/auto/corelib/thread/CMakeLists.txt index d27a9461578..e0aa411cf23 100644 --- a/tests/auto/corelib/thread/CMakeLists.txt +++ b/tests/auto/corelib/thread/CMakeLists.txt @@ -25,6 +25,7 @@ if(QT_FEATURE_thread) add_subdirectory(qatomicint) add_subdirectory(qatomicinteger) add_subdirectory(qatomicpointer) + add_subdirectory(qatomicwait) if(QT_FEATURE_future) add_subdirectory(qresultstore) add_subdirectory(qfuturesynchronizer) @@ -36,6 +37,7 @@ if(QT_FEATURE_thread) add_subdirectory(qfuturewatcher) endif() endif() + add_subdirectory(qlatch) add_subdirectory(qmutex) add_subdirectory(qmutexlocker) add_subdirectory(qreadlocker) diff --git a/tests/auto/corelib/thread/qatomicwait/CMakeLists.txt b/tests/auto/corelib/thread/qatomicwait/CMakeLists.txt new file mode 100644 index 00000000000..4307cbb60db --- /dev/null +++ b/tests/auto/corelib/thread/qatomicwait/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (C) 2025 Intel Corporatin +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qatomicwait LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_test(tst_qatomicwait + SOURCES + tst_qatomicwait.cpp + ../../../../../src/corelib/thread/qatomicwait.cpp + DEFINES + QATOMICWAIT_USE_FALLBACK + LIBRARIES + Qt::CorePrivate +) diff --git a/tests/auto/corelib/thread/qatomicwait/tst_qatomicwait.cpp b/tests/auto/corelib/thread/qatomicwait/tst_qatomicwait.cpp new file mode 100644 index 00000000000..4b3ac2591e7 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicwait/tst_qatomicwait.cpp @@ -0,0 +1,303 @@ +// Copyright (C) 2025 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <private/qatomicwait_p.h> + +#include <QRandomGenerator> +#include <QSemaphore> +#include <QThread> + +#include <QtTest> + +#include <condition_variable> +#include <mutex> +#include <thread> + +using namespace std::chrono_literals; +using namespace QtFallbackAtomicWait; + +constexpr int Repeats = 9; +constexpr int MaxThreads = 8; +constexpr auto Delay = 10ms; + +// moc can expand this +#define DEF_TEST(name) \ + void name ## _int() { name<int>(); } \ + void name ## _qint64() { name<qint64>(); } \ + void name ## _qint8() { name<qint8>(); } \ + void name ## _voidp() { name<void *>(); } \ + /* */ + +class tst_QAtomicWait : public QObject +{ + Q_OBJECT +private slots: + DEF_TEST(noWaiterWake) + DEF_TEST(failedWait) + DEF_TEST(singleWaiterWakeOne) + DEF_TEST(singleWaiterWakeAll) + DEF_TEST(multiWaiterWakeAll) + DEF_TEST(multiWaiterWakeSequentially) + DEF_TEST(aliasingTest) + +private: + template <typename T> void noWaiterWake(); + template <typename T> void failedWait(); + template <typename T> void singleWaiterWakeOne(); + template <typename T> void singleWaiterWakeAll(); + template <typename T> void multiWaiterWakeAll(); + template <typename T> void multiWaiterWakeSequentially(); + template <typename T> void aliasingTest(); +}; + +class SimpleLatch +{ + std::mutex mutex; + int counter = 0; + std::condition_variable cond; + +public: + SimpleLatch(int n) : counter(n) {} + + void countDown(int n = 1) + { + std::unique_lock l(mutex); + counter -= n; + if (counter == 0) + cond.notify_all(); + } + + void wait() + { + std::unique_lock l(mutex); + if (counter) + cond.wait(l); + } +}; + +class JThread +{ + std::thread thr; +public: + template <typename... Args> JThread(Args &&... args) + : thr(std::forward<Args>(args)...) + { } + + ~JThread() + { + if (thr.joinable()) + thr.join(); + } + + void wait() { thr.join(); } +}; + +template <typename T> static T otherValue(int i = 1) +{ + if constexpr (std::is_pointer_v<T>) { + return reinterpret_cast<T>(otherValue<quintptr>(i)); + } else if constexpr (sizeof(T) > sizeof(int)) { + return (T(i) << 32) + ~T(i); + } else { + return T(i); + } +} + +template <typename T> static T badValue() +{ + if constexpr (std::is_pointer_v<T>) { + return reinterpret_cast<T *>(0xfefefefe); + } else { + return T(0xfefefefe); + } +} + +template <typename T> void spinlockWait(std::atomic<T> &a) +{ + while (a.load(std::memory_order_relaxed) == T{}) { + qYieldCpu(); + } +} + +template <typename T> void tst_QAtomicWait::noWaiterWake() +{ + // Verify that there's no side-effect when there are no waiters. These + // tests should do absolutely nothing (not even call the out-of-line + // function). + std::atomic<T> a{}; + q20::atomic_notify_one(&a); + q20::atomic_notify_all(&a); +} + +template<typename T> +void tst_QAtomicWait::failedWait() +{ + // Verify that we don't go into wait if the value in the atomic is + // different from the value we expected to wait on. + + std::atomic<T> a{}; + q20::atomic_wait_explicit(&a, otherValue<T>(), std::memory_order_relaxed); + + a.store(otherValue<T>(), std::memory_order_relaxed); + q20::atomic_wait_explicit(&a, {}, std::memory_order_relaxed); +} + +template <typename T, void (*wakeFn)(std::atomic<T> *a)> static void singleWaiterWake() +{ + std::atomic<T> a{}; + + for (int repetition = 0; repetition < Repeats; ++repetition) { + SimpleLatch latch(1); + a.store({}, std::memory_order_relaxed); + + JThread thr([&] { + latch.countDown(); + QTest::qSleep(Delay); + a.store(otherValue<T>()); + wakeFn(&a); + }); + + // wait for the thread to start + latch.wait(); + + // wait for the atomic to change + // Note: it may have already changed if the qSleep() above has already + // finished. + q20::atomic_wait_explicit(&a, {}, std::memory_order_relaxed); + + QCOMPARE(a.load(), otherValue<T>()); + } +} + +template <typename T> void tst_QAtomicWait::singleWaiterWakeOne() +{ + singleWaiterWake<T, q20::atomic_notify_one<T>>(); +} + +template <typename T> void tst_QAtomicWait::singleWaiterWakeAll() +{ + singleWaiterWake<T, q20::atomic_notify_all<T>>(); +} + +template <typename T, typename Wake> void multiWaiterWake(Wake &&wakeFn) +{ + std::atomic<T> a{}; + + for (int repetition = 0; repetition < Repeats; ++repetition) { + std::array<T, MaxThreads> loadedValues; + loadedValues.fill(badValue<T>()); + a.store({}, std::memory_order_relaxed); + + { + std::unique_ptr<JThread> threads[MaxThreads]; + SimpleLatch latch(MaxThreads); + auto l = [&](T *loadedValue) { + latch.countDown(); + q20::atomic_wait_explicit(&a, {}, std::memory_order_relaxed); + *loadedValue = a.load(std::memory_order_relaxed); + }; + + for (int i = 0; i < MaxThreads; ++i) + threads[i] = std::make_unique<JThread>(l, &loadedValues[i]); + + // wait for the threads to start + latch.wait(); + + QTest::qSleep(Delay); + a.store(otherValue<T>()); + wakeFn(a); + + // wait for the threads to finish + } + + std::array<T, MaxThreads> expected; + expected.fill(otherValue<T>()); + QCOMPARE(loadedValues, expected); + } +} + +template <typename T> void tst_QAtomicWait::multiWaiterWakeAll() +{ + multiWaiterWake<T>([](std::atomic<T> &a) { + q20::atomic_notify_all(&a); + }); +} + +template <typename T> void tst_QAtomicWait::multiWaiterWakeSequentially() +{ + multiWaiterWake<T>([](std::atomic<T> &a) { + auto delay = Delay; + for (int i = 0; i < MaxThreads; ++i) { + q20::atomic_notify_one(&a); + delay /= 4; + if (delay > 0ms) + QTest::qSleep(delay); + } + }); +} + +template <typename T> void tst_QAtomicWait::aliasingTest() +{ + // There is a limited number of locks available, so let's try atomics whose + // addresses are very similar. We can't ask for high alignment values on + // the stack in all platforms, so we just pad the structure to 256 bytes. + struct Atomics { + std::atomic<T> a; + T loadedValue; + void reset() + { + a.store({}, std::memory_order_relaxed); + loadedValue = badValue<T>(); + } + }; + struct Padded : Atomics { + char padding[256 - sizeof(Atomics)]; + }; + static_assert(sizeof(Padded) == 256); + Padded atomics[MaxThreads]{}; + + for (int repetition = 0; repetition < Repeats; ++repetition) { + for (Atomics &s : atomics) + s.reset(); + + std::array<int, MaxThreads> order; + std::iota(order.begin(), order.end(), 0); + std::shuffle(order.begin(), order.end(), *QRandomGenerator::global()); + + std::unique_ptr<JThread> threads[MaxThreads]; + SimpleLatch latch(MaxThreads); + auto l = [&](Atomics *atomic) { + latch.countDown(); + q20::atomic_wait_explicit(&atomic->a, {}, std::memory_order_relaxed); + atomic->loadedValue = atomic->a.load(std::memory_order_relaxed); + }; + for (int i = 0; i < MaxThreads; ++i) + threads[i] = std::make_unique<JThread>(l, &atomics[order[i]]); + + // wait for the threads to start + latch.wait(); + + QTest::qSleep(Delay); + + std::array<T, MaxThreads> expected, actual; + actual.fill({}); + expected.fill({}); + for (int i = 0; i < MaxThreads; ++i) { + expected[i] = otherValue<T>(i + MaxThreads); + Atomics &atomic = atomics[order[i]]; + atomic.a.store(expected[i], std::memory_order_relaxed); + q20::atomic_notify_one(&atomic.a); + + // wait for this thread + threads[i]->wait(); + + actual[i] = atomic.loadedValue; + QCOMPARE(actual, expected); + } + } +} + +QTEST_MAIN(tst_QAtomicWait) + +#include "tst_qatomicwait.moc" + diff --git a/tests/auto/corelib/thread/qlatch/CMakeLists.txt b/tests/auto/corelib/thread/qlatch/CMakeLists.txt new file mode 100644 index 00000000000..020653135c9 --- /dev/null +++ b/tests/auto/corelib/thread/qlatch/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (C) 2025 Intel Corporation. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_test(tst_qlatch + SOURCES + tst_qlatch.cpp + LIBRARIES + Qt::CorePrivate + Qt::Test +) + +qt_internal_add_test(tst_qlatch_fallback + SOURCES + tst_qlatch.cpp + ../../../../../src/corelib/thread/qatomicwait.cpp + ../../../../../src/corelib/thread/qlatch.cpp + DEFINES + QATOMICWAIT_USE_FALLBACK + LIBRARIES + Qt::CorePrivate + Qt::Test +) + +qt_internal_extend_target(tst_qlatch_fallback CONDITION WIN32 + LIBRARIES + synchronization +) diff --git a/tests/auto/corelib/thread/qlatch/tst_qlatch.cpp b/tests/auto/corelib/thread/qlatch/tst_qlatch.cpp new file mode 100644 index 00000000000..6609fdbdb36 --- /dev/null +++ b/tests/auto/corelib/thread/qlatch/tst_qlatch.cpp @@ -0,0 +1,261 @@ +// Copyright (C) 2025 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "private/qlatch_p.h" +#include <QtTest> + +#include <thread> + +#ifdef QATOMICWAIT_USE_FALLBACK +# define tst_QLatch tst_QLatch_Fallback +#endif + +using namespace std::chrono_literals; + +constexpr int Repeats = 16; +constexpr int MaxThreads = 4; + +class tst_QLatch : public QObject +{ + Q_OBJECT +private slots: + void basics(); + void simple(); + void multipleWorkersSingleWaiter_data(); + void multipleWorkersSingleWaiter(); + void singleWorkerMultipleWaiters_data(); + void singleWorkerMultipleWaiters(); + void multipleWorkersAndWaiters_data(); + void multipleWorkersAndWaiters(); +}; + +class JThread +{ + std::thread thr; +public: + template <typename... Args> JThread(Args &&... args) + : thr(std::forward<Args>(args)...) + { } + + ~JThread() + { + wait(); + } + + void wait() + { + if (thr.joinable()) + thr.join(); + } +}; + +void maybeSleep(std::chrono::milliseconds ms) +{ + if (ms > 0s) + QTest::qSleep(ms); +} + +void tst_QLatch::basics() +{ + { + QLatch latch(0); + QCOMPARE(latch.pending(), 0); + QVERIFY(latch.tryWait()); + latch.wait(); // doesn't deadlock + } + + { + QLatch latch(1); + QCOMPARE(latch.pending(), 1); + QVERIFY(!latch.tryWait()); + latch.countDown(); + QVERIFY(latch.tryWait()); + QCOMPARE(latch.pending(), 0); + latch.wait(); // doesn't deadlock + } + + { + QLatch latch(2); + QCOMPARE(latch.pending(), 2); + QVERIFY(!latch.tryWait()); + latch.countDown(2); + QVERIFY(latch.tryWait()); + QCOMPARE(latch.pending(), 0); + latch.wait(); // doesn't deadlock + } +} + +void tst_QLatch::simple() +{ + // simple thread synchronization + for (int i = 0; i < Repeats; ++i) { + int j = 0, k = 0; + + QLatch latch(1); + auto waiterCode = [&]() { latch.wait(); k = j; }; + auto workerCode = [&]() { j += i; latch.countDown(); }; + + if (i & 1) { + // waiter first + JThread waiter(waiterCode); + JThread worker(workerCode); + } else { + // worker first + JThread worker(workerCode); + JThread waiter(waiterCode); + } + + QCOMPARE(j, i); + QCOMPARE(k, i); + } +} + +void tst_QLatch::multipleWorkersSingleWaiter_data() +{ + QTest::addColumn<int>("count"); + QTest::newRow("1") << 1; + QTest::newRow("2") << 2; + QTest::newRow("32768") << 32768; +} + +void tst_QLatch::multipleWorkersSingleWaiter() +{ + QFETCH(int, count); + for (int i = 0; i < Repeats; ++i) { + int pendingValue = 0xbadbad; + Q_ASSERT(qint64(count) * MaxThreads <= std::numeric_limits<int>::max()); + + QLatch latch(MaxThreads * count); + std::unique_ptr<JThread> workers[MaxThreads]; + std::unique_ptr<JThread> waiter; + + auto waiterCode = [&]() { + latch.wait(); + pendingValue = latch.pending(); + }; + if (i & 1) + waiter.reset(new JThread(waiterCode)); + + for (auto &ptr : workers) + ptr.reset(new JThread([&]() { latch.countDown(count); })); + + if ((i & 1) == 0) + waiter.reset(new JThread(waiterCode)); + + waiter->wait(); + QCOMPARE(latch.pending(), 0); + QCOMPARE(pendingValue, 0); + } +} + +void tst_QLatch::singleWorkerMultipleWaiters_data() +{ + multipleWorkersSingleWaiter_data(); +} + +void tst_QLatch::singleWorkerMultipleWaiters() +{ + QFETCH(int, count); + for (int i = 0; i < Repeats; ++i) { + QLatch latch(count); + std::unique_ptr<JThread> waiters[MaxThreads]; + std::unique_ptr<JThread> worker; + std::array<int, MaxThreads> pendingValues; + pendingValues.fill(0xcdcdcdcd); + + auto workerCode = [&]() { latch.countDown(count); }; + auto waiterCode = [&](int *ptr) { + latch.wait(); + *ptr = latch.pending(); + }; + if (i & 1) + worker.reset(new JThread(workerCode)); + + for (int i = 0; i < MaxThreads; ++i) + waiters[i].reset(new JThread(waiterCode, &pendingValues[i])); + + if ((i & 1) == 0) + worker.reset(new JThread(workerCode)); + + // wait for an arbitrary waiter + waiters[i % MaxThreads]->wait(); + + QCOMPARE(latch.pending(), 0); + QCOMPARE(pendingValues[i % MaxThreads], 0); + + // wait for all waiters to finish + for (auto &waiter : waiters) + waiter->wait(); + QCOMPARE(latch.pending(), 0); + QCOMPARE(pendingValues, decltype(pendingValues){}); + } +} + +void tst_QLatch::multipleWorkersAndWaiters_data() +{ + multipleWorkersSingleWaiter_data(); +} + +void tst_QLatch::multipleWorkersAndWaiters() +{ + QFETCH(int, count); + for (int i = 0; i < Repeats; ++i) { + Q_ASSERT(qint64(count) * MaxThreads <= std::numeric_limits<int>::max()); + std::array<int, MaxThreads> pendingValues; + pendingValues.fill(0xfefefefe); + + QLatch latch(MaxThreads * count); + std::unique_ptr<JThread> workers[MaxThreads]; + std::unique_ptr<JThread> waiters[MaxThreads]; + auto waiterCode = [&](int *ptr) { + if (i > MaxThreads / 2) + QTest::qSleep((i * 2 / MaxThreads) * 1ms); + latch.wait(); + *ptr = latch.pending(); + }; + auto workerCode = [&]() { latch.countDown(count); }; + + if ((i % 4) == 0) { + // start waiters first + for (int i = 0; i < MaxThreads; ++i) + waiters[i].reset(new JThread(waiterCode, &pendingValues[i])); + for (int i = 0; i < MaxThreads; ++i) + workers[i].reset(new JThread(workerCode)); + } else if ((i % 4) == 1) { + // start workers first + for (int i = 0; i < MaxThreads; ++i) + workers[i].reset(new JThread(workerCode)); + for (int i = 0; i < MaxThreads; ++i) + waiters[i].reset(new JThread(waiterCode, &pendingValues[i])); + } else if ((i % 4) == 2) { + // interleave, with workers first + for (int i = 0; i < MaxThreads; ++i) { + workers[i].reset(new JThread(workerCode)); + waiters[i].reset(new JThread(waiterCode, &pendingValues[i])); + } + } else { + // interleave, with waiters first + for (int i = 0; i < MaxThreads; ++i) { + waiters[i].reset(new JThread(waiterCode, &pendingValues[i])); + workers[i].reset(new JThread(workerCode)); + } + } + + // wait for one waiter + int id = i % MaxThreads; + waiters[id]->wait(); + + QCOMPARE(pendingValues[id], 0); + QCOMPARE(latch.pending(), 0); + + // wait for all waiters to finish + for (auto &waiter : waiters) + waiter->wait(); + QCOMPARE(latch.pending(), 0); + QCOMPARE(pendingValues, decltype(pendingValues){}); + } +} + +QTEST_MAIN(tst_QLatch) + +#include "tst_qlatch.moc" diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 5804aeeb1e5..87d48d56e6b 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -73,22 +73,22 @@ void tst_QArrayData::referenceCounting() // Reference counting initialized to 1 (owned) QArrayData array = { Q_BASIC_ATOMIC_INITIALIZER(1), {}, 0 }; - QCOMPARE(array.ref_.loadRelaxed(), 1); + QCOMPARE(array.m_ref.loadRelaxed(), 1); QVERIFY(array.ref()); - QCOMPARE(array.ref_.loadRelaxed(), 2); + QCOMPARE(array.m_ref.loadRelaxed(), 2); QVERIFY(array.deref()); - QCOMPARE(array.ref_.loadRelaxed(), 1); + QCOMPARE(array.m_ref.loadRelaxed(), 1); QVERIFY(array.ref()); - QCOMPARE(array.ref_.loadRelaxed(), 2); + QCOMPARE(array.m_ref.loadRelaxed(), 2); QVERIFY(array.deref()); - QCOMPARE(array.ref_.loadRelaxed(), 1); + QCOMPARE(array.m_ref.loadRelaxed(), 1); QVERIFY(!array.deref()); - QCOMPARE(array.ref_.loadRelaxed(), 0); + QCOMPARE(array.m_ref.loadRelaxed(), 0); // Now would be a good time to free/release allocated data } diff --git a/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp b/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp index 89bd1d7ff61..b53362b43e9 100644 --- a/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp +++ b/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp @@ -5,6 +5,10 @@ #include <QTest> +#include <chrono> + +using namespace std::chrono_literals; + class tst_QAtomicScopedValueRollback : public QObject { Q_OBJECT @@ -15,6 +19,7 @@ private Q_SLOTS: void rollbackToPreviousCommit(); void exceptions(); void earlyExitScope(); + void mixedTypes(); private: void earlyExitScope_helper(int exitpoint, std::atomic<int> &member); }; @@ -132,6 +137,90 @@ void tst_QAtomicScopedValueRollback::earlyExitScope() } } +template <typename T> +struct Wrap { +#if __cpp_deduction_guides < 201907L // no CTAD for aggregates + Q_IMPLICIT Wrap(T &t) : t{t} {} + Q_IMPLICIT Wrap(T &&t) : t{std::move(t)} {} +#endif + T t; + Q_IMPLICIT operator T() const { return t; } +}; + +void tst_QAtomicScopedValueRollback::mixedTypes() +{ + const auto relaxed = std::memory_order_relaxed; + { + std::atomic a{10'000ms}; + { + QAtomicScopedValueRollback rb(a, 5s); + QCOMPARE(a.load(relaxed), 5s); + } + QCOMPARE(a.load(relaxed), 10s); + { + QAtomicScopedValueRollback rb(a, 5s, relaxed); + QCOMPARE(a.load(relaxed), 5s); + } + QCOMPARE(a.load(relaxed), 10s); + } + { + QBasicAtomicInteger a{10'000}; + { + QAtomicScopedValueRollback rb(a, Wrap{5'000}); + QCOMPARE(a.loadRelaxed(), 5'000); + } + QCOMPARE(a.loadRelaxed(), 10'000); + { + QAtomicScopedValueRollback rb(a, Wrap{5'000}, relaxed); + QCOMPARE(a.loadRelaxed(), 5'000); + } + QCOMPARE(a.loadRelaxed(), 10'000); + } + { + QAtomicInteger a{10'000}; + { + QAtomicScopedValueRollback rb(a, Wrap{5'000}); + QCOMPARE(a.loadRelaxed(), 5'000); + } + QCOMPARE(a.loadRelaxed(), 10'000); + { + QAtomicScopedValueRollback rb(a, Wrap{5'000}, relaxed); + QCOMPARE(a.loadRelaxed(), 5'000); + } + QCOMPARE(a.loadRelaxed(), 10'000); + } + { + int i = 10'000; + int j = 5'000; + QBasicAtomicPointer a{&i}; + { + QAtomicScopedValueRollback rb(a, Wrap{&j}); + QCOMPARE(a.loadRelaxed(), &j); + } + QCOMPARE(a.loadRelaxed(), &i); + { + QAtomicScopedValueRollback rb(a, Wrap{&j}, relaxed); + QCOMPARE(a.loadRelaxed(), &j); + } + QCOMPARE(a.loadRelaxed(), &i); + } + { + int i = 10'000; + int j = 5'000; + QAtomicPointer a{&i}; + { + QAtomicScopedValueRollback rb(a, Wrap{&j}); + QCOMPARE(a.loadRelaxed(), &j); + } + QCOMPARE(a.loadRelaxed(), &i); + { + QAtomicScopedValueRollback rb(a, Wrap{&j}, relaxed); + QCOMPARE(a.loadRelaxed(), &j); + } + QCOMPARE(a.loadRelaxed(), &i); + } +} + static void operator*=(std::atomic<int> &lhs, int rhs) { int expected = lhs.load(); diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 39051276371..1c8dd14eba4 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -3264,12 +3264,14 @@ void tst_QWindow::windowExposedAfterReparent() QVERIFY(QTest::qWaitForWindowExposed(&parent)); QVERIFY(QTest::qWaitForWindowExposed(&child)); + // Close the child before reparenting it to ensure it is correctly converted + // to a toplevel window by the window manager. + child.close(); child.setParent(nullptr); - QCoreApplication::processEvents(); + child.show(); QVERIFY(QTest::qWaitForWindowExposed(&child)); child.setParent(&parent); - QCoreApplication::processEvents(); QVERIFY(QTest::qWaitForWindowExposed(&child)); } diff --git a/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp index e761f8cb3cc..f8a0167efad 100644 --- a/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp +++ b/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp @@ -3,7 +3,9 @@ #include <QTest> #include <QtCore/qmath.h> + #include <QtGui/qmatrix4x4.h> +#include <QtGui/qquaternion.h> class tst_QMatrixNxN : public QObject { diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp index 06b6ffc2700..d4dc6544a0e 100644 --- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp @@ -894,6 +894,13 @@ void tst_QQuaternion::fromAxes() QQuaternion result = QQuaternion::fromAxisAndAngle(QVector3D(x1, y1, z1), angle); + { + const auto axes = result.toAxes(); + QVERIFY(myFuzzyCompare(axes.x, xAxis)); + QVERIFY(myFuzzyCompare(axes.y, yAxis)); + QVERIFY(myFuzzyCompare(axes.z, zAxis)); + } + QVector3D axes[3]; result.getAxes(&axes[0], &axes[1], &axes[2]); QVERIFY(myFuzzyCompare(axes[0], xAxis)); @@ -985,8 +992,7 @@ void tst_QQuaternion::fromDirection_data() // othonormal up and dir for (QQuaternion q : orientations) { - QVector3D xAxis, yAxis, zAxis; - q.getAxes(&xAxis, &yAxis, &zAxis); + const auto [xAxis, yAxis, zAxis] = q.toAxes(); QTest::addRow("ortho dirs: (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f)", xAxis.x(), xAxis.y(), xAxis.z(), @@ -1007,8 +1013,7 @@ void tst_QQuaternion::fromDirection_data() // invalid up for (QQuaternion q : orientations) { - QVector3D xAxis, yAxis, zAxis; - q.getAxes(&xAxis, &yAxis, &zAxis); + const auto [xAxis, yAxis, zAxis] = q.toAxes(); QTest::addRow("bad dirs: (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f)", xAxis.x(), xAxis.y(), xAxis.z(), @@ -1022,22 +1027,21 @@ void tst_QQuaternion::fromDirection() QFETCH(QVector3D, direction); QFETCH(QVector3D, up); - QVector3D expextedZ(direction != QVector3D() ? direction.normalized() : QVector3D(0, 0, 1)); - QVector3D expextedY(up.normalized()); + const QVector3D expectedZ = direction != QVector3D() ? direction.normalized() + /* else */ : QVector3D(0, 0, 1); + const QVector3D expectedY = up.normalized(); QQuaternion result = QQuaternion::fromDirection(direction, up); QVERIFY(myFuzzyCompare(result, result.normalized())); - QVector3D xAxis, yAxis, zAxis; - result.getAxes(&xAxis, &yAxis, &zAxis); - - QVERIFY(myFuzzyCompare(zAxis, expextedZ)); + const auto axes = result.toAxes(); - if (!qFuzzyIsNull(QVector3D::crossProduct(expextedZ, expextedY).lengthSquared())) { - QVector3D expextedX(QVector3D::crossProduct(expextedY, expextedZ)); + QVERIFY(myFuzzyCompare(axes.z, expectedZ)); - QVERIFY(myFuzzyCompare(yAxis, expextedY)); - QVERIFY(myFuzzyCompare(xAxis, expextedX)); + const QVector3D expectedX = QVector3D::crossProduct(expectedY, expectedZ); + if (!qFuzzyIsNull(expectedX.lengthSquared())) { + QVERIFY(myFuzzyCompare(axes.x, expectedX)); + QVERIFY(myFuzzyCompare(axes.y, expectedY)); } } diff --git a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp index 5e0ca4bae60..80a78de9bd1 100644 --- a/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp +++ b/tests/auto/network/kernel/qnetworkinterface/tst_qnetworkinterface.cpp @@ -192,11 +192,16 @@ void tst_QNetworkInterface::localAddress_data() if (addr.isLoopback()) continue; // added above - if (addr.protocol() == QAbstractSocket::IPv4Protocol) { + int prefixLength = entry.prefixLength(); + if (prefixLength > 0 && addr.protocol() == QAbstractSocket::IPv4Protocol) { // add an IPv4 address with bits in the host portion of the address flipped + // (for point-to-point, we flip the least significant bit) quint32 ip4 = entry.ip().toIPv4Address(); - addr.setAddress(ip4 ^ ~entry.netmask().toIPv4Address()); - } else if (!ipv6 || entry.prefixLength() != 64) { + quint32 hostmask = 0x1; + if (prefixLength != 32) + hostmask = ~0U >> prefixLength; + addr.setAddress(ip4 ^ hostmask); + } else if (!ipv6 || prefixLength != 64) { continue; } else { #ifdef Q_OS_ANDROID @@ -257,7 +262,7 @@ void tst_QNetworkInterface::localAddress() << "pmtu" << pmtu; // check that the Path MTU is less than or equal the interface's MTU - QVERIFY(pmtu <= outgoingIface->maximumTransmissionUnit()); + QCOMPARE_LE(pmtu, outgoingIface->maximumTransmissionUnit()); #endif // QT_CONFIG(udpsocket) } diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 851fef2e05a..a293023f2c6 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -10,7 +10,7 @@ #endif #include <QScopeGuard> #include <QVersionNumber> -#include <QSemaphore> +#include <private/qlatch_p.h> #include <qcoreapplication.h> #include <qfileinfo.h> @@ -1926,13 +1926,13 @@ void tst_QUdpSocket::readyReadConnectionThrottling() QUdpSocket receiver; QVERIFY(receiver.bind(QHostAddress(QHostAddress::LocalHost), 0)); - QSemaphore semaphore; + QLatch latch(1); // Repro-ing deterministically eludes me, so we are bruteforcing it: // The thread acts as a remote sender, flooding the receiver with datagrams, // and at some point the receiver would get into the broken state mentioned // earlier. - std::unique_ptr<QThread> thread(QThread::create([&semaphore, port = receiver.localPort()]() { + std::unique_ptr<QThread> thread(QThread::create([&latch, port = receiver.localPort()]() { QUdpSocket sender; sender.connectToHost(QHostAddress(QHostAddress::LocalHost), port); QCOMPARE(sender.state(), QUdpSocket::ConnectedState); @@ -1940,7 +1940,7 @@ void tst_QUdpSocket::readyReadConnectionThrottling() constexpr qsizetype PayloadSize = 242; const QByteArray payload(PayloadSize, 'a'); - semaphore.acquire(); // Wait for main thread to be ready + latch.wait(); // Wait for main thread to be ready while (true) { // We send 100 datagrams at a time, then sleep. // This is mostly to let the main thread catch up between bursts so @@ -1975,7 +1975,7 @@ void tst_QUdpSocket::readyReadConnectionThrottling() }, Qt::QueuedConnection); - semaphore.release(); + latch.countDown(); constexpr qsizetype MaxCount = 500; QVERIFY2(QTest::qWaitFor([&] { return count >= MaxCount; }, 10s), QByteArray::number(count).constData()); diff --git a/tests/auto/testlib/selftests/CMakeLists.txt b/tests/auto/testlib/selftests/CMakeLists.txt index bd2d42ec7cb..9d013e6f757 100644 --- a/tests/auto/testlib/selftests/CMakeLists.txt +++ b/tests/auto/testlib/selftests/CMakeLists.txt @@ -51,7 +51,6 @@ qt_internal_apply_testlib_coverage_options(tst_selftests) set(subprograms assert badxml - benchlibcallgrind benchlibcounting benchlibeventcounter benchliboptions @@ -112,6 +111,14 @@ set(subprograms watchdog ) +if(NOT QT_FEATURE_sanitize_address) + list(APPEND subprograms + # valgrind and asan are incompatible: + # "ASan runtime does not come first in initial library list;" + benchlibcallgrind + ) +endif() + if(FEATURE_cxx20) list(APPEND subprograms threewaycompare diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.junitxml b/tests/auto/testlib/selftests/expected_threewaycompare.junitxml index e10872ef1ba..37551ecd23d 100644 --- a/tests/auto/testlib/selftests/expected_threewaycompare.junitxml +++ b/tests/auto/testlib/selftests/expected_threewaycompare.junitxml @@ -25,8 +25,8 @@ </testcase> <testcase name="compareFloats(Qt::partial_ordering::equivalent)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"> <failure type="fail" message="The result of operator<=>() is not what was expected"> - <![CDATA[ Left (lhs): 1 - Right (rhs): 1 + <![CDATA[ Left (lhs): 1 (0x1p+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::less]]> </failure> @@ -34,24 +34,24 @@ <testcase name="compareFloats(Qt::partial_ordering::less)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"/> <testcase name="compareFloats(Qt::partial_ordering::greater)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"> <failure type="fail" message="The result of operator<=>() is not what was expected"> - <![CDATA[ Left (lhs): 1.1 - Right (rhs): 1 + <![CDATA[ Left (lhs): 1.1 (0x1.19999ap+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): Qt::partial_ordering::less]]> </failure> </testcase> <testcase name="compareDoubles(Qt::partial_ordering::equivalent)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"> <failure type="fail" message="The result of operator<=>() is not what was expected"> - <![CDATA[ Left (lhs): 0 - Right (rhs): 0 + <![CDATA[ Left (lhs): 0 (0x0p+0) + Right (rhs): 0 (0x0p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::greater]]> </failure> </testcase> <testcase name="compareDoubles(Qt::partial_ordering::less)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"> <failure type="fail" message="The result of operator<=>() is not what was expected"> - <![CDATA[ Left (lhs): 0 - Right (rhs): 0.1 + <![CDATA[ Left (lhs): 0 (0x0p+0) + Right (rhs): 0.1 (0x1.999999999999ap-4) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): Qt::partial_ordering::greater]]> </failure> @@ -161,16 +161,16 @@ </testcase> <testcase name="stdCompareFloats(std::partial_ordering::equivalent)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"> <failure type="fail" message="The result of operator<=>() is not what was expected"> - <![CDATA[ Left (lhs): 2 - Right (rhs): 2 + <![CDATA[ Left (lhs): 2 (0x1p+1) + Right (rhs): 2 (0x1p+1) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::less]]> </failure> </testcase> <testcase name="stdCompareFloats(std::partial_ordering::less)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"> <failure type="fail" message="The result of operator<=>() is not what was expected"> - <![CDATA[ Left (lhs): 2 - Right (rhs): 1.1 + <![CDATA[ Left (lhs): 2 (0x1p+1) + Right (rhs): 1.1 (0x1.19999ap+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): std::partial_ordering::less]]> </failure> @@ -178,16 +178,16 @@ <testcase name="stdCompareFloats(std::partial_ordering::greater)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"/> <testcase name="stdCompareDoubles(std::partial_ordering::equivalent)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"> <failure type="fail" message="The result of operator<=>() is not what was expected"> - <![CDATA[ Left (lhs): 0.15 - Right (rhs): 0.15 + <![CDATA[ Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.15 (0x1.3333333333333p-3) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::greater]]> </failure> </testcase> <testcase name="stdCompareDoubles(std::partial_ordering::less)" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"> <failure type="fail" message="The result of operator<=>() is not what was expected"> - <![CDATA[ Left (lhs): 0.15 - Right (rhs): 0.25 + <![CDATA[ Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.25 (0x1p-2) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): std::partial_ordering::greater]]> </failure> @@ -288,8 +288,8 @@ </testcase> <testcase name="checkWeakComparison" classname="tst_ThreeWayCompare" time="@TEST_DURATION@"> <failure type="fail" message="The result of operator<=>() is not what was expected"> - <![CDATA[ Left (june) : 2012/06/20 14:33:02.500[CEST] - Right (juneLater): 2012/06/20 14:33:02.501[CEST] + <![CDATA[ Left (june) : 2012/06/20 14:33:02.500[UTC] + Right (juneLater): 2012/06/20 14:33:02.501[UTC] Actual (june <=> juneLater) : std::weak_ordering::less Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater]]> </failure> diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.lightxml b/tests/auto/testlib/selftests/expected_threewaycompare.lightxml index 75679c5e374..082255a2c41 100644 --- a/tests/auto/testlib/selftests/expected_threewaycompare.lightxml +++ b/tests/auto/testlib/selftests/expected_threewaycompare.lightxml @@ -33,8 +33,8 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[Qt::partial_ordering::equivalent]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 1 - Right (rhs): 1 + Left (lhs): 1 (0x1p+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::less]]></Description> </Incident> @@ -44,8 +44,8 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[Qt::partial_ordering::greater]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 1.1 - Right (rhs): 1 + Left (lhs): 1.1 (0x1.19999ap+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): Qt::partial_ordering::less]]></Description> </Incident> @@ -55,16 +55,16 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[Qt::partial_ordering::equivalent]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 0 - Right (rhs): 0 + Left (lhs): 0 (0x0p+0) + Right (rhs): 0 (0x0p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::greater]]></Description> </Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[Qt::partial_ordering::less]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 0 - Right (rhs): 0.1 + Left (lhs): 0 (0x0p+0) + Right (rhs): 0.1 (0x1.999999999999ap-4) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): Qt::partial_ordering::greater]]></Description> </Incident> @@ -209,16 +209,16 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[std::partial_ordering::equivalent]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 2 - Right (rhs): 2 + Left (lhs): 2 (0x1p+1) + Right (rhs): 2 (0x1p+1) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::less]]></Description> </Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[std::partial_ordering::less]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 2 - Right (rhs): 1.1 + Left (lhs): 2 (0x1p+1) + Right (rhs): 1.1 (0x1.19999ap+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): std::partial_ordering::less]]></Description> </Incident> @@ -231,16 +231,16 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[std::partial_ordering::equivalent]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 0.15 - Right (rhs): 0.15 + Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.15 (0x1.3333333333333p-3) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::greater]]></Description> </Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[std::partial_ordering::less]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 0.15 - Right (rhs): 0.25 + Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.25 (0x1p-2) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): std::partial_ordering::greater]]></Description> </Incident> @@ -372,8 +372,8 @@ <TestFunction name="checkWeakComparison"> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (june) : 2012/06/20 14:33:02.500[CEST] - Right (juneLater): 2012/06/20 14:33:02.501[CEST] + Left (june) : 2012/06/20 14:33:02.500[UTC] + Right (juneLater): 2012/06/20 14:33:02.501[UTC] Actual (june <=> juneLater) : std::weak_ordering::less Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater]]></Description> </Incident> diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.tap b/tests/auto/testlib/selftests/expected_threewaycompare.tap index daeae42c06f..5d464e0e648 100644 --- a/tests/auto/testlib/selftests/expected_threewaycompare.tap +++ b/tests/auto/testlib/selftests/expected_threewaycompare.tap @@ -27,8 +27,8 @@ not ok 4 - compareInts(Qt::strong_ordering::greater) not ok 5 - compareFloats(Qt::partial_ordering::equivalent) --- # The result of operator<=>() is not what was expected - Left (lhs): 1 - Right (rhs): 1 + Left (lhs): 1 (0x1p+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::less at: tst_ThreeWayCompare::compareFloats() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0) @@ -39,8 +39,8 @@ ok 6 - compareFloats(Qt::partial_ordering::less) not ok 7 - compareFloats(Qt::partial_ordering::greater) --- # The result of operator<=>() is not what was expected - Left (lhs): 1.1 - Right (rhs): 1 + Left (lhs): 1.1 (0x1.19999ap+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): Qt::partial_ordering::less at: tst_ThreeWayCompare::compareFloats() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0) @@ -50,8 +50,8 @@ not ok 7 - compareFloats(Qt::partial_ordering::greater) not ok 8 - compareDoubles(Qt::partial_ordering::equivalent) --- # The result of operator<=>() is not what was expected - Left (lhs): 0 - Right (rhs): 0 + Left (lhs): 0 (0x0p+0) + Right (rhs): 0 (0x0p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::greater at: tst_ThreeWayCompare::compareDoubles() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0) @@ -61,8 +61,8 @@ not ok 8 - compareDoubles(Qt::partial_ordering::equivalent) not ok 9 - compareDoubles(Qt::partial_ordering::less) --- # The result of operator<=>() is not what was expected - Left (lhs): 0 - Right (rhs): 0.1 + Left (lhs): 0 (0x0p+0) + Right (rhs): 0.1 (0x1.999999999999ap-4) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): Qt::partial_ordering::greater at: tst_ThreeWayCompare::compareDoubles() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0) @@ -211,8 +211,8 @@ not ok 28 - stdCompareInts(std::strong_ordering::greater) not ok 29 - stdCompareFloats(std::partial_ordering::equivalent) --- # The result of operator<=>() is not what was expected - Left (lhs): 2 - Right (rhs): 2 + Left (lhs): 2 (0x1p+1) + Right (rhs): 2 (0x1p+1) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::less at: tst_ThreeWayCompare::stdCompareFloats() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0) @@ -222,8 +222,8 @@ not ok 29 - stdCompareFloats(std::partial_ordering::equivalent) not ok 30 - stdCompareFloats(std::partial_ordering::less) --- # The result of operator<=>() is not what was expected - Left (lhs): 2 - Right (rhs): 1.1 + Left (lhs): 2 (0x1p+1) + Right (rhs): 1.1 (0x1.19999ap+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): std::partial_ordering::less at: tst_ThreeWayCompare::stdCompareFloats() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0) @@ -234,8 +234,8 @@ ok 31 - stdCompareFloats(std::partial_ordering::greater) not ok 32 - stdCompareDoubles(std::partial_ordering::equivalent) --- # The result of operator<=>() is not what was expected - Left (lhs): 0.15 - Right (rhs): 0.15 + Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.15 (0x1.3333333333333p-3) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::greater at: tst_ThreeWayCompare::stdCompareDoubles() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0) @@ -245,8 +245,8 @@ not ok 32 - stdCompareDoubles(std::partial_ordering::equivalent) not ok 33 - stdCompareDoubles(std::partial_ordering::less) --- # The result of operator<=>() is not what was expected - Left (lhs): 0.15 - Right (rhs): 0.25 + Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.25 (0x1p-2) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): std::partial_ordering::greater at: tst_ThreeWayCompare::stdCompareDoubles() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0) @@ -383,8 +383,8 @@ not ok 50 - checkComparisonForTemporaryObjects() not ok 51 - checkWeakComparison() --- # The result of operator<=>() is not what was expected - Left (june) : 2012/06/20 14:33:02.500[CEST] - Right (juneLater): 2012/06/20 14:33:02.501[CEST] + Left (june) : 2012/06/20 14:33:02.500[UTC] + Right (juneLater): 2012/06/20 14:33:02.501[UTC] Actual (june <=> juneLater) : std::weak_ordering::less Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater at: tst_ThreeWayCompare::checkWeakComparison() (qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp:0) diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.teamcity b/tests/auto/testlib/selftests/expected_threewaycompare.teamcity index 2eed5bdb422..6b92880418e 100644 --- a/tests/auto/testlib/selftests/expected_threewaycompare.teamcity +++ b/tests/auto/testlib/selftests/expected_threewaycompare.teamcity @@ -10,18 +10,18 @@ ##teamcity[testFailed name='compareInts(Qt::strong_ordering::greater)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2|n Right (rhs): 1|n Actual (lhs <=> rhs) : std::strong_ordering::greater|n Expected (expectedOrder): Qt::strong_ordering::equal' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='compareInts(Qt::strong_ordering::greater)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='compareFloats(Qt::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare'] -##teamcity[testFailed name='compareFloats(Qt::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 1|n Right (rhs): 1|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): Qt::partial_ordering::less' flowId='tst_ThreeWayCompare'] +##teamcity[testFailed name='compareFloats(Qt::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 1 (0x1p+0)|n Right (rhs): 1 (0x1p+0)|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): Qt::partial_ordering::less' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='compareFloats(Qt::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='compareFloats(Qt::partial_ordering::less)' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='compareFloats(Qt::partial_ordering::less)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='compareFloats(Qt::partial_ordering::greater)' flowId='tst_ThreeWayCompare'] -##teamcity[testFailed name='compareFloats(Qt::partial_ordering::greater)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 1.1|n Right (rhs): 1|n Actual (lhs <=> rhs) : std::partial_ordering::greater|n Expected (expectedOrder): Qt::partial_ordering::less' flowId='tst_ThreeWayCompare'] +##teamcity[testFailed name='compareFloats(Qt::partial_ordering::greater)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 1.1 (0x1.19999ap+0)|n Right (rhs): 1 (0x1p+0)|n Actual (lhs <=> rhs) : std::partial_ordering::greater|n Expected (expectedOrder): Qt::partial_ordering::less' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='compareFloats(Qt::partial_ordering::greater)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='compareDoubles(Qt::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare'] -##teamcity[testFailed name='compareDoubles(Qt::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0|n Right (rhs): 0|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): Qt::partial_ordering::greater' flowId='tst_ThreeWayCompare'] +##teamcity[testFailed name='compareDoubles(Qt::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0 (0x0p+0)|n Right (rhs): 0 (0x0p+0)|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): Qt::partial_ordering::greater' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='compareDoubles(Qt::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='compareDoubles(Qt::partial_ordering::less)' flowId='tst_ThreeWayCompare'] -##teamcity[testFailed name='compareDoubles(Qt::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0|n Right (rhs): 0.1|n Actual (lhs <=> rhs) : std::partial_ordering::less|n Expected (expectedOrder): Qt::partial_ordering::greater' flowId='tst_ThreeWayCompare'] +##teamcity[testFailed name='compareDoubles(Qt::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0 (0x0p+0)|n Right (rhs): 0.1 (0x1.999999999999ap-4)|n Actual (lhs <=> rhs) : std::partial_ordering::less|n Expected (expectedOrder): Qt::partial_ordering::greater' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='compareDoubles(Qt::partial_ordering::less)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='compareDoubles(Qt::partial_ordering::greater)' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='compareDoubles(Qt::partial_ordering::greater)' flowId='tst_ThreeWayCompare'] @@ -74,18 +74,18 @@ ##teamcity[testFailed name='stdCompareInts(std::strong_ordering::greater)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): -2|n Right (rhs): 1|n Actual (lhs <=> rhs) : std::strong_ordering::less|n Expected (expectedOrder): std::strong_ordering::equal' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='stdCompareInts(std::strong_ordering::greater)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='stdCompareFloats(std::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare'] -##teamcity[testFailed name='stdCompareFloats(std::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2|n Right (rhs): 2|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): std::partial_ordering::less' flowId='tst_ThreeWayCompare'] +##teamcity[testFailed name='stdCompareFloats(std::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2 (0x1p+1)|n Right (rhs): 2 (0x1p+1)|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): std::partial_ordering::less' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='stdCompareFloats(std::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='stdCompareFloats(std::partial_ordering::less)' flowId='tst_ThreeWayCompare'] -##teamcity[testFailed name='stdCompareFloats(std::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2|n Right (rhs): 1.1|n Actual (lhs <=> rhs) : std::partial_ordering::greater|n Expected (expectedOrder): std::partial_ordering::less' flowId='tst_ThreeWayCompare'] +##teamcity[testFailed name='stdCompareFloats(std::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 2 (0x1p+1)|n Right (rhs): 1.1 (0x1.19999ap+0)|n Actual (lhs <=> rhs) : std::partial_ordering::greater|n Expected (expectedOrder): std::partial_ordering::less' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='stdCompareFloats(std::partial_ordering::less)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='stdCompareFloats(std::partial_ordering::greater)' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='stdCompareFloats(std::partial_ordering::greater)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='stdCompareDoubles(std::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare'] -##teamcity[testFailed name='stdCompareDoubles(std::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0.15|n Right (rhs): 0.15|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): std::partial_ordering::greater' flowId='tst_ThreeWayCompare'] +##teamcity[testFailed name='stdCompareDoubles(std::partial_ordering::equivalent)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0.15 (0x1.3333333333333p-3)|n Right (rhs): 0.15 (0x1.3333333333333p-3)|n Actual (lhs <=> rhs) : std::partial_ordering::equivalent|n Expected (expectedOrder): std::partial_ordering::greater' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='stdCompareDoubles(std::partial_ordering::equivalent)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='stdCompareDoubles(std::partial_ordering::less)' flowId='tst_ThreeWayCompare'] -##teamcity[testFailed name='stdCompareDoubles(std::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0.15|n Right (rhs): 0.25|n Actual (lhs <=> rhs) : std::partial_ordering::less|n Expected (expectedOrder): std::partial_ordering::greater' flowId='tst_ThreeWayCompare'] +##teamcity[testFailed name='stdCompareDoubles(std::partial_ordering::less)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (lhs): 0.15 (0x1.3333333333333p-3)|n Right (rhs): 0.25 (0x1p-2)|n Actual (lhs <=> rhs) : std::partial_ordering::less|n Expected (expectedOrder): std::partial_ordering::greater' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='stdCompareDoubles(std::partial_ordering::less)' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='stdCompareDoubles(std::partial_ordering::greater)' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='stdCompareDoubles(std::partial_ordering::greater)' flowId='tst_ThreeWayCompare'] @@ -133,7 +133,7 @@ ##teamcity[testFailed name='checkComparisonForTemporaryObjects()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (getClassForValue(0).getValuePointer()): MyClass(2) on memory address with index 0|n Right (getClassForValue(1).getValuePointer()): MyClass(1) on memory address with index 1|n Actual (getClassForValue(0).getValuePointer() <=> getClassForValue(1).getValuePointer()): std::strong_ordering::less|n Expected (std::strong_ordering::equal) : std::strong_ordering::equal' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='checkComparisonForTemporaryObjects()' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='checkWeakComparison()' flowId='tst_ThreeWayCompare'] -##teamcity[testFailed name='checkWeakComparison()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (june) : 2012/06/20 14:33:02.500|[CEST|]|n Right (juneLater): 2012/06/20 14:33:02.501|[CEST|]|n Actual (june <=> juneLater) : std::weak_ordering::less|n Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater' flowId='tst_ThreeWayCompare'] +##teamcity[testFailed name='checkWeakComparison()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)|]' details='The result of operator<=>() is not what was expected|n Left (june) : 2012/06/20 14:33:02.500|[UTC|]|n Right (juneLater): 2012/06/20 14:33:02.501|[UTC|]|n Actual (june <=> juneLater) : std::weak_ordering::less|n Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='checkWeakComparison()' flowId='tst_ThreeWayCompare'] ##teamcity[testStarted name='cleanupTestCase()' flowId='tst_ThreeWayCompare'] ##teamcity[testFinished name='cleanupTestCase()' flowId='tst_ThreeWayCompare'] diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.txt b/tests/auto/testlib/selftests/expected_threewaycompare.txt index 896cec72819..45496e4420c 100644 --- a/tests/auto/testlib/selftests/expected_threewaycompare.txt +++ b/tests/auto/testlib/selftests/expected_threewaycompare.txt @@ -15,27 +15,27 @@ FAIL! : tst_ThreeWayCompare::compareInts(Qt::strong_ordering::greater) The resu Expected (expectedOrder): Qt::strong_ordering::equal Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] FAIL! : tst_ThreeWayCompare::compareFloats(Qt::partial_ordering::equivalent) The result of operator<=>() is not what was expected - Left (lhs): 1 - Right (rhs): 1 + Left (lhs): 1 (0x1p+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::less Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] PASS : tst_ThreeWayCompare::compareFloats(Qt::partial_ordering::less) FAIL! : tst_ThreeWayCompare::compareFloats(Qt::partial_ordering::greater) The result of operator<=>() is not what was expected - Left (lhs): 1.1 - Right (rhs): 1 + Left (lhs): 1.1 (0x1.19999ap+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): Qt::partial_ordering::less Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] FAIL! : tst_ThreeWayCompare::compareDoubles(Qt::partial_ordering::equivalent) The result of operator<=>() is not what was expected - Left (lhs): 0 - Right (rhs): 0 + Left (lhs): 0 (0x0p+0) + Right (rhs): 0 (0x0p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::greater Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] FAIL! : tst_ThreeWayCompare::compareDoubles(Qt::partial_ordering::less) The result of operator<=>() is not what was expected - Left (lhs): 0 - Right (rhs): 0.1 + Left (lhs): 0 (0x0p+0) + Right (rhs): 0.1 (0x1.999999999999ap-4) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): Qt::partial_ordering::greater Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] @@ -119,27 +119,27 @@ FAIL! : tst_ThreeWayCompare::stdCompareInts(std::strong_ordering::greater) The Expected (expectedOrder): std::strong_ordering::equal Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] FAIL! : tst_ThreeWayCompare::stdCompareFloats(std::partial_ordering::equivalent) The result of operator<=>() is not what was expected - Left (lhs): 2 - Right (rhs): 2 + Left (lhs): 2 (0x1p+1) + Right (rhs): 2 (0x1p+1) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::less Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] FAIL! : tst_ThreeWayCompare::stdCompareFloats(std::partial_ordering::less) The result of operator<=>() is not what was expected - Left (lhs): 2 - Right (rhs): 1.1 + Left (lhs): 2 (0x1p+1) + Right (rhs): 1.1 (0x1.19999ap+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): std::partial_ordering::less Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] PASS : tst_ThreeWayCompare::stdCompareFloats(std::partial_ordering::greater) FAIL! : tst_ThreeWayCompare::stdCompareDoubles(std::partial_ordering::equivalent) The result of operator<=>() is not what was expected - Left (lhs): 0.15 - Right (rhs): 0.15 + Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.15 (0x1.3333333333333p-3) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::greater Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] FAIL! : tst_ThreeWayCompare::stdCompareDoubles(std::partial_ordering::less) The result of operator<=>() is not what was expected - Left (lhs): 0.15 - Right (rhs): 0.25 + Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.25 (0x1p-2) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): std::partial_ordering::greater Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] @@ -216,8 +216,8 @@ FAIL! : tst_ThreeWayCompare::checkComparisonForTemporaryObjects() The result of Expected (std::strong_ordering::equal) : std::strong_ordering::equal Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] FAIL! : tst_ThreeWayCompare::checkWeakComparison() The result of operator<=>() is not what was expected - Left (june) : 2012/06/20 14:33:02.500[CEST] - Right (juneLater): 2012/06/20 14:33:02.501[CEST] + Left (june) : 2012/06/20 14:33:02.500[UTC] + Right (juneLater): 2012/06/20 14:33:02.501[UTC] Actual (june <=> juneLater) : std::weak_ordering::less Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater Loc: [qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp(0)] diff --git a/tests/auto/testlib/selftests/expected_threewaycompare.xml b/tests/auto/testlib/selftests/expected_threewaycompare.xml index 5e8f1f93bac..a3f4d38ee5a 100644 --- a/tests/auto/testlib/selftests/expected_threewaycompare.xml +++ b/tests/auto/testlib/selftests/expected_threewaycompare.xml @@ -35,8 +35,8 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[Qt::partial_ordering::equivalent]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 1 - Right (rhs): 1 + Left (lhs): 1 (0x1p+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::less]]></Description> </Incident> @@ -46,8 +46,8 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[Qt::partial_ordering::greater]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 1.1 - Right (rhs): 1 + Left (lhs): 1.1 (0x1.19999ap+0) + Right (rhs): 1 (0x1p+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): Qt::partial_ordering::less]]></Description> </Incident> @@ -57,16 +57,16 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[Qt::partial_ordering::equivalent]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 0 - Right (rhs): 0 + Left (lhs): 0 (0x0p+0) + Right (rhs): 0 (0x0p+0) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): Qt::partial_ordering::greater]]></Description> </Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[Qt::partial_ordering::less]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 0 - Right (rhs): 0.1 + Left (lhs): 0 (0x0p+0) + Right (rhs): 0.1 (0x1.999999999999ap-4) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): Qt::partial_ordering::greater]]></Description> </Incident> @@ -211,16 +211,16 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[std::partial_ordering::equivalent]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 2 - Right (rhs): 2 + Left (lhs): 2 (0x1p+1) + Right (rhs): 2 (0x1p+1) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::less]]></Description> </Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[std::partial_ordering::less]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 2 - Right (rhs): 1.1 + Left (lhs): 2 (0x1p+1) + Right (rhs): 1.1 (0x1.19999ap+0) Actual (lhs <=> rhs) : std::partial_ordering::greater Expected (expectedOrder): std::partial_ordering::less]]></Description> </Incident> @@ -233,16 +233,16 @@ <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[std::partial_ordering::equivalent]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 0.15 - Right (rhs): 0.15 + Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.15 (0x1.3333333333333p-3) Actual (lhs <=> rhs) : std::partial_ordering::equivalent Expected (expectedOrder): std::partial_ordering::greater]]></Description> </Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <DataTag><![CDATA[std::partial_ordering::less]]></DataTag> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (lhs): 0.15 - Right (rhs): 0.25 + Left (lhs): 0.15 (0x1.3333333333333p-3) + Right (rhs): 0.25 (0x1p-2) Actual (lhs <=> rhs) : std::partial_ordering::less Expected (expectedOrder): std::partial_ordering::greater]]></Description> </Incident> @@ -374,8 +374,8 @@ <TestFunction name="checkWeakComparison"> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp" line="0"> <Description><![CDATA[The result of operator<=>() is not what was expected - Left (june) : 2012/06/20 14:33:02.500[CEST] - Right (juneLater): 2012/06/20 14:33:02.501[CEST] + Left (june) : 2012/06/20 14:33:02.500[UTC] + Right (juneLater): 2012/06/20 14:33:02.501[UTC] Actual (june <=> juneLater) : std::weak_ordering::less Expected (Qt::weak_ordering::greater): Qt::weak_ordering::greater]]></Description> </Incident> diff --git a/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp b/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp index bcc544d33a1..4a290f9f2fb 100644 --- a/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp +++ b/tests/auto/testlib/selftests/threewaycompare/tst_threewaycompare.cpp @@ -231,7 +231,7 @@ void tst_ThreeWayCompare::checkWeakComparison() QCOMPARE_3WAY(example_left, example_right, std::weak_ordering::less); - QDateTime june(QDate(2012, 6, 20), QTime(14, 33, 2, 500)); + QDateTime june(QDate(2012, 6, 20), QTime(14, 33, 2, 500), QTimeZone::UTC); QDateTime juneLater = june.addMSecs(1); QCOMPARE_3WAY(june, juneLater, Qt::weak_ordering::greater); #endif diff --git a/tests/auto/tools/moc/CMakeLists.txt b/tests/auto/tools/moc/CMakeLists.txt index c8344dad081..037488095b1 100644 --- a/tests/auto/tools/moc/CMakeLists.txt +++ b/tests/auto/tools/moc/CMakeLists.txt @@ -28,7 +28,6 @@ set(JSON_HEADERS gadgetwithnoenums.h grand-parent-gadget-class.h moc_include.h - name_collision.h namespace.h namespaced-flags.h namespaced-base-class.h @@ -67,6 +66,8 @@ qt_wrap_cpp(comparison_relevant_moc_list ${JSON_HEADERS} "-DDEFINE_CMDLINE_EMPTY=" "-DDEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap<int, int> &i)" "--output-json" + DEPENDS + ${QT_CMAKE_EXPORT_NAMESPACE}::moc ) list(TRANSFORM comparison_relevant_moc_list APPEND ".json" OUTPUT_VARIABLE moc_json_files) @@ -75,6 +76,7 @@ qt_internal_add_test(tst_moc SOURCES cxx-attributes.h single_function_keyword.h + name_collision.h tst_moc.cpp ${comparison_relevant_moc_list} INCLUDE_DIRECTORIES diff --git a/tests/auto/tools/moc/allmocs_baseline_in.json b/tests/auto/tools/moc/allmocs_baseline_in.json index 28feba8dba9..3dcecc1002d 100644 --- a/tests/auto/tools/moc/allmocs_baseline_in.json +++ b/tests/auto/tools/moc/allmocs_baseline_in.json @@ -10,6 +10,7 @@ { "access": "public", "index": 0, + "lineNumber": 21, "name": "works", "returnType": "void" } @@ -51,6 +52,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 12, "name": "Baz", "values": [ "Foo", @@ -60,6 +62,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 13, "name": "Baz2", "values": [ "Foo2", @@ -83,6 +86,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 12, "name": "EnumClass", "values": [ "A0", @@ -94,6 +98,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 13, "name": "TypedEnum", "type": "char", "values": [ @@ -106,6 +111,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 14, "name": "TypedEnumClass", "type": "char", "values": [ @@ -118,6 +124,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 15, "name": "NormalEnum", "values": [ "D2", @@ -130,6 +137,7 @@ "alias": "ClassFlag", "isClass": true, "isFlag": true, + "lineNumber": 16, "name": "ClassFlags", "values": [ "F0", @@ -141,6 +149,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 18, "name": "EnumStruct", "values": [ "G0", @@ -152,6 +161,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 19, "name": "TypedEnumStruct", "type": "char", "values": [ @@ -165,6 +175,7 @@ "alias": "StructFlag", "isClass": true, "isFlag": true, + "lineNumber": 20, "name": "StructFlags", "values": [ "I0", @@ -184,6 +195,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 40, "name": "EnumClass", "values": [ "A0", @@ -195,6 +207,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 41, "name": "TypedEnum", "type": "char", "values": [ @@ -207,6 +220,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 42, "name": "TypedEnumClass", "type": "char", "values": [ @@ -219,6 +233,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 43, "name": "NormalEnum", "values": [ "D2", @@ -231,6 +246,7 @@ "alias": "ClassFlag", "isClass": true, "isFlag": true, + "lineNumber": 44, "name": "ClassFlags", "values": [ "F0", @@ -250,6 +266,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 54, "name": "EnumClass", "values": [ "A0", @@ -261,6 +278,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 55, "name": "TypedEnum", "type": "char", "values": [ @@ -273,6 +291,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 56, "name": "TypedEnumClass", "type": "char", "values": [ @@ -285,6 +304,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 57, "name": "NormalEnum", "values": [ "D2", @@ -319,12 +339,14 @@ { "access": "private", "index": 0, + "lineNumber": 25, "name": "pureSlot0", "returnType": "void" }, { "access": "private", "index": 1, + "lineNumber": 26, "name": "pureSlot1", "returnType": "void" }, @@ -332,6 +354,7 @@ "access": "private", "index": 2, "isConst": true, + "lineNumber": 27, "name": "pureSlot2", "returnType": "void" }, @@ -339,6 +362,7 @@ "access": "private", "index": 3, "isConst": true, + "lineNumber": 28, "name": "pureSlot3", "returnType": "void" } @@ -359,12 +383,14 @@ { "access": "private", "index": 0, + "lineNumber": 47, "name": "pureSlot0", "returnType": "void" }, { "access": "private", "index": 1, + "lineNumber": 48, "name": "pureSlot1", "returnType": "void" }, @@ -372,6 +398,7 @@ "access": "private", "index": 2, "isConst": true, + "lineNumber": 49, "name": "pureSlot2", "returnType": "void" }, @@ -379,6 +406,7 @@ "access": "private", "index": 3, "isConst": true, + "lineNumber": 50, "name": "pureSlot3", "returnType": "void" } @@ -399,12 +427,14 @@ { "access": "private", "index": 0, + "lineNumber": 69, "name": "pureSlot0", "returnType": "void" }, { "access": "private", "index": 1, + "lineNumber": 70, "name": "pureSlot1", "returnType": "void" }, @@ -412,6 +442,7 @@ "access": "private", "index": 2, "isConst": true, + "lineNumber": 71, "name": "pureSlot2", "returnType": "void" }, @@ -419,6 +450,7 @@ "access": "private", "index": 3, "isConst": true, + "lineNumber": 72, "name": "pureSlot3", "returnType": "void" } @@ -439,12 +471,14 @@ { "access": "private", "index": 0, + "lineNumber": 91, "name": "pureSlot0", "returnType": "void" }, { "access": "private", "index": 1, + "lineNumber": 92, "name": "pureSlot1", "returnType": "void" }, @@ -452,6 +486,7 @@ "access": "private", "index": 2, "isConst": true, + "lineNumber": 93, "name": "pureSlot2", "returnType": "void" }, @@ -459,6 +494,7 @@ "access": "private", "index": 3, "isConst": true, + "lineNumber": 94, "name": "pureSlot3", "returnType": "void" } @@ -479,12 +515,14 @@ { "access": "private", "index": 0, + "lineNumber": 113, "name": "pureSlot0", "returnType": "void" }, { "access": "private", "index": 1, + "lineNumber": 114, "name": "pureSlot1", "returnType": "void" }, @@ -492,6 +530,7 @@ "access": "private", "index": 2, "isConst": true, + "lineNumber": 115, "name": "pureSlot2", "returnType": "void" }, @@ -499,6 +538,7 @@ "access": "private", "index": 3, "isConst": true, + "lineNumber": 116, "name": "pureSlot3", "returnType": "void" } @@ -519,12 +559,14 @@ { "access": "private", "index": 0, + "lineNumber": 135, "name": "pureSlot0", "returnType": "void" }, { "access": "private", "index": 1, + "lineNumber": 136, "name": "pureSlot1", "returnType": "void" }, @@ -532,6 +574,7 @@ "access": "private", "index": 2, "isConst": true, + "lineNumber": 137, "name": "pureSlot2", "returnType": "void" }, @@ -539,6 +582,7 @@ "access": "private", "index": 3, "isConst": true, + "lineNumber": 138, "name": "pureSlot3", "returnType": "void" } @@ -559,12 +603,14 @@ { "access": "private", "index": 0, + "lineNumber": 157, "name": "pureSlot0", "returnType": "void" }, { "access": "private", "index": 1, + "lineNumber": 158, "name": "pureSlot1", "returnType": "void" }, @@ -572,6 +618,7 @@ "access": "private", "index": 2, "isConst": true, + "lineNumber": 159, "name": "pureSlot2", "returnType": "void" }, @@ -579,6 +626,7 @@ "access": "private", "index": 3, "isConst": true, + "lineNumber": 160, "name": "pureSlot3", "returnType": "void" } @@ -599,12 +647,14 @@ { "access": "private", "index": 0, + "lineNumber": 179, "name": "pureSlot0", "returnType": "void" }, { "access": "private", "index": 1, + "lineNumber": 180, "name": "pureSlot1", "returnType": "void" }, @@ -612,6 +662,7 @@ "access": "private", "index": 2, "isConst": true, + "lineNumber": 181, "name": "pureSlot2", "returnType": "void" }, @@ -619,6 +670,7 @@ "access": "private", "index": 3, "isConst": true, + "lineNumber": 182, "name": "pureSlot3", "returnType": "void" } @@ -639,12 +691,14 @@ { "access": "private", "index": 0, + "lineNumber": 201, "name": "pureSlot0", "returnType": "void" }, { "access": "private", "index": 1, + "lineNumber": 202, "name": "pureSlot1", "returnType": "void" }, @@ -652,6 +706,7 @@ "access": "private", "index": 2, "isConst": true, + "lineNumber": 203, "name": "pureSlot2", "returnType": "void" }, @@ -659,6 +714,7 @@ "access": "private", "index": 3, "isConst": true, + "lineNumber": 204, "name": "pureSlot3", "returnType": "void" } @@ -805,6 +861,7 @@ } ], "index": 0, + "lineNumber": 30, "name": "trailingSignalReturn", "returnType": "void" } @@ -813,6 +870,7 @@ { "access": "public", "index": 1, + "lineNumber": 12, "name": "fun", "returnType": "void" }, @@ -829,6 +887,7 @@ } ], "index": 2, + "lineNumber": 13, "name": "arguments", "returnType": "int" }, @@ -841,12 +900,14 @@ } ], "index": 3, + "lineNumber": 14, "name": "inlineFunc", "returnType": "int" }, { "access": "public", "index": 4, + "lineNumber": 19, "name": "constRefReturn", "returnType": "void" }, @@ -854,6 +915,7 @@ "access": "public", "index": 5, "isConst": true, + "lineNumber": 24, "name": "constConstRefReturn", "returnType": "void" } @@ -877,6 +939,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 23, "name": "GadEn", "values": [ "Value" @@ -893,6 +956,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 27, "name": "NamEn", "values": [ "Value" @@ -1003,6 +1067,7 @@ } ], "index": 0, + "lineNumber": 35, "name": "signalNaked", "returnType": "void" }, @@ -1014,6 +1079,7 @@ } ], "index": 1, + "lineNumber": 36, "name": "signalFDC", "returnType": "void" }, @@ -1025,6 +1091,7 @@ } ], "index": 2, + "lineNumber": 37, "name": "signalFDC", "returnType": "void" }, @@ -1036,6 +1103,7 @@ } ], "index": 3, + "lineNumber": 38, "name": "signalFDC", "returnType": "void" }, @@ -1047,6 +1115,7 @@ } ], "index": 4, + "lineNumber": 39, "name": "signalFDC", "returnType": "void" }, @@ -1058,6 +1127,7 @@ } ], "index": 5, + "lineNumber": 40, "name": "signalQSet", "returnType": "void" }, @@ -1069,6 +1139,7 @@ } ], "index": 6, + "lineNumber": 41, "name": "signalQSet", "returnType": "void" }, @@ -1080,6 +1151,7 @@ } ], "index": 7, + "lineNumber": 42, "name": "signalQSet", "returnType": "void" }, @@ -1091,6 +1163,7 @@ } ], "index": 8, + "lineNumber": 43, "name": "signalQSet", "returnType": "void" } @@ -1104,6 +1177,7 @@ } ], "index": 9, + "lineNumber": 24, "name": "slotNaked", "returnType": "void" }, @@ -1115,6 +1189,7 @@ } ], "index": 10, + "lineNumber": 25, "name": "slotFDC", "returnType": "void" }, @@ -1126,6 +1201,7 @@ } ], "index": 11, + "lineNumber": 26, "name": "slotFDC", "returnType": "void" }, @@ -1137,6 +1213,7 @@ } ], "index": 12, + "lineNumber": 27, "name": "slotFDC", "returnType": "void" }, @@ -1148,6 +1225,7 @@ } ], "index": 13, + "lineNumber": 28, "name": "slotFDC", "returnType": "void" }, @@ -1159,6 +1237,7 @@ } ], "index": 14, + "lineNumber": 29, "name": "slotQSet", "returnType": "void" }, @@ -1170,6 +1249,7 @@ } ], "index": 15, + "lineNumber": 30, "name": "slotQSet", "returnType": "void" }, @@ -1181,6 +1261,7 @@ } ], "index": 16, + "lineNumber": 31, "name": "slotQSet", "returnType": "void" }, @@ -1192,6 +1273,7 @@ } ], "index": 17, + "lineNumber": 32, "name": "slotQSet", "returnType": "void" } @@ -1218,12 +1300,14 @@ { "access": "public", "index": 0, + "lineNumber": 26, "name": "test1", "returnType": "void" }, { "access": "public", "index": 1, + "lineNumber": 27, "name": "test2", "returnType": "void" } @@ -1253,6 +1337,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 22, "name": "FooEnum", "values": [ "FooValue" @@ -1321,6 +1406,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 23, "name": "prop1", "read": "getProp1", "required": false, @@ -1335,6 +1421,7 @@ "designable": true, "final": false, "index": 1, + "lineNumber": 24, "name": "prop2", "read": "getProp2", "required": false, @@ -1349,6 +1436,7 @@ "designable": true, "final": false, "index": 2, + "lineNumber": 25, "name": "prop3", "read": "getProp3", "required": false, @@ -1380,78 +1468,12 @@ { "classes": [ { - "className": "NameCollision", - "lineNumber": 11, - "object": true, - "properties": [ - { - "constant": false, - "designable": true, - "final": false, - "index": 0, - "name": "Status", - "read": "Status", - "required": false, - "scriptable": true, - "stored": true, - "type": "Status", - "user": false, - "write": "setStatus" - }, - { - "constant": false, - "designable": true, - "final": false, - "index": 1, - "member": "m_decorationMode", - "name": "decorationMode", - "required": false, - "scriptable": true, - "stored": true, - "type": "DecorationMode", - "user": false - } - - ], - "qualifiedClassName": "myns::NameCollision", - "slots": [ - { - "access": "public", - "arguments": [ - { - "type": "Status" - } - ], - "index": 0, - "name": "setStatus", - "returnType": "void" - }, - { - "access": "public", - "index": 1, - "name": "Status", - "returnType": "Status" - } - ], - "superClasses": [ - { - "access": "public", - "name": "QObject" - } - ] - } - ], - "inputFile": "name_collision.h", - "outputRevision": 69 - }, - { - "classes": [ - { "className": "FooNamespace", "enums": [ { "isClass": true, "isFlag": false, + "lineNumber": 14, "name": "Enum1", "values": [ "Key1", @@ -1469,6 +1491,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 22, "name": "Enum2", "values": [ "Key3", @@ -1478,6 +1501,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 35, "name": "Enum3", "values": [ "Key5", @@ -1495,6 +1519,7 @@ { "isClass": true, "isFlag": false, + "lineNumber": 43, "name": "Enum4", "values": [ "Key7", @@ -1550,6 +1575,7 @@ "alias": "Flag", "isClass": false, "isFlag": true, + "lineNumber": 15, "name": "Flags", "values": [ "Read", @@ -1565,6 +1591,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 11, "name": "flags", "read": "flags", "required": false, @@ -1593,6 +1620,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 30, "name": "flags", "read": "flags", "required": false, @@ -1607,6 +1635,7 @@ "designable": true, "final": false, "index": 1, + "lineNumber": 31, "name": "flagsList", "read": "flagsList", "required": false, @@ -1640,6 +1669,7 @@ { "access": "public", "index": 0, + "lineNumber": 41, "name": "mySignal", "returnType": "void" } @@ -1648,6 +1678,7 @@ { "access": "public", "index": 1, + "lineNumber": 44, "name": "mySlot", "returnType": "void" } @@ -1692,6 +1723,7 @@ { "access": "public", "index": 0, + "lineNumber": 17, "name": "foo", "returnType": "void" }, @@ -1715,6 +1747,7 @@ } ], "index": 1, + "lineNumber": 18, "name": "bar", "returnType": "int" }, @@ -1729,6 +1762,7 @@ } ], "index": 2, + "lineNumber": 19, "name": "slot", "returnType": "void" } @@ -1775,12 +1809,14 @@ } ], "index": 0, + "lineNumber": 105, "name": "cmdlineSignal", "returnType": "void" }, { "access": "public", "index": 1, + "lineNumber": 109, "name": "signalQTBUG55853", "returnType": "void" } @@ -1789,30 +1825,35 @@ { "access": "public", "index": 2, + "lineNumber": 64, "name": "voidFunction", "returnType": "void" }, { "access": "public", "index": 3, + "lineNumber": 66, "name": "stringMethod", "returnType": "QString" }, { "access": "public", "index": 4, + "lineNumber": 68, "name": "combined1", "returnType": "void" }, { "access": "public", "index": 5, + "lineNumber": 69, "name": "combined2", "returnType": "void" }, { "access": "public", "index": 6, + "lineNumber": 70, "name": "combined3", "returnType": "void" }, @@ -1827,24 +1868,28 @@ } ], "index": 7, + "lineNumber": 71, "name": "combined4", "returnType": "void" }, { "access": "public", "index": 8, + "lineNumber": 73, "name": "combined5", "returnType": "void" }, { "access": "public", "index": 9, + "lineNumber": 75, "name": "combined6", "returnType": "void" }, { "access": "public", "index": 10, + "lineNumber": 77, "name": "vararg1", "returnType": "void" }, @@ -1856,6 +1901,7 @@ } ], "index": 11, + "lineNumber": 78, "name": "vararg2", "returnType": "void" }, @@ -1870,12 +1916,14 @@ } ], "index": 12, + "lineNumber": 79, "name": "vararg3", "returnType": "void" }, { "access": "public", "index": 13, + "lineNumber": 81, "name": "vararg4", "returnType": "void" }, @@ -1887,6 +1935,7 @@ } ], "index": 14, + "lineNumber": 82, "name": "vararg5", "returnType": "void" }, @@ -1901,6 +1950,7 @@ } ], "index": 15, + "lineNumber": 83, "name": "vararg6", "returnType": "void" }, @@ -1912,6 +1962,7 @@ } ], "index": 16, + "lineNumber": 89, "name": "INNERFUNCTION", "returnType": "void" }, @@ -1923,6 +1974,7 @@ } ], "index": 17, + "lineNumber": 90, "name": "inner_expanded", "returnType": "void" }, @@ -1934,12 +1986,14 @@ } ], "index": 18, + "lineNumber": 91, "name": "expanded_method", "returnType": "void" }, { "access": "public", "index": 19, + "lineNumber": 99, "name": "conditionSlot", "returnType": "void" }, @@ -1951,6 +2005,7 @@ } ], "index": 20, + "lineNumber": 102, "name": "PD_DEFINE_ITSELF_SUFFIX", "returnType": "void" } @@ -2000,6 +2055,7 @@ } ], "index": 0, + "lineNumber": 18, "name": "setProp1", "returnType": "void" }, @@ -2011,6 +2067,7 @@ } ], "index": 1, + "lineNumber": 19, "name": "setProp2", "returnType": "void" }, @@ -2022,6 +2079,7 @@ } ], "index": 2, + "lineNumber": 20, "name": "setProp3", "returnType": "void" }, @@ -2033,6 +2091,7 @@ } ], "index": 3, + "lineNumber": 21, "name": "setProp4", "returnType": "void" }, @@ -2044,6 +2103,7 @@ } ], "index": 4, + "lineNumber": 22, "name": "setProp5", "returnType": "void" }, @@ -2055,6 +2115,7 @@ } ], "index": 5, + "lineNumber": 23, "name": "setProp6", "returnType": "void" }, @@ -2066,6 +2127,7 @@ } ], "index": 6, + "lineNumber": 24, "name": "setProp7", "returnType": "void" } @@ -2092,12 +2154,14 @@ { "access": "public", "index": 0, + "lineNumber": 13, "name": "mySignal", "returnType": "void" }, { "access": "public", "index": 1, + "lineNumber": 14, "name": "myOtherSignal", "returnType": "void" }, @@ -2110,6 +2174,7 @@ } ], "index": 2, + "lineNumber": 15, "name": "mySignal2", "returnType": "void" } @@ -2130,6 +2195,7 @@ { "access": "public", "index": 0, + "lineNumber": 23, "name": "mySignal", "returnType": "void" }, @@ -2142,6 +2208,7 @@ } ], "index": 1, + "lineNumber": 24, "name": "mySignal2", "returnType": "void" } @@ -2165,6 +2232,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 12, "name": "LargeEnum", "type": "qint64", "values": [ @@ -2191,6 +2259,7 @@ "alias": "LargeFlag", "isClass": false, "isFlag": true, + "lineNumber": 24, "name": "LargeFlags", "type": "qint64", "values": [ @@ -2203,6 +2272,7 @@ "alias": "ScopedLargeFlag", "isClass": true, "isFlag": true, + "lineNumber": 32, "name": "ScopedLargeFlags", "type": "quint64", "values": [ @@ -2236,6 +2306,7 @@ "access": "public", "index": 0, "isConst": true, + "lineNumber": 0, "name": "foo", "returnType": "const char*" } @@ -2256,12 +2327,14 @@ { "access": "public", "index": 0, + "lineNumber": 0, "name": "foo", "returnType": "void" }, { "access": "public", "index": 1, + "lineNumber": 0, "name": "bar", "returnType": "void" } @@ -2302,6 +2375,7 @@ } ], "index": 0, + "lineNumber": 17, "name": "f", "returnType": "void" } @@ -2326,6 +2400,7 @@ { "access": "private", "index": 1, + "lineNumber": 0, "name": "method1", "returnType": "void" } @@ -2336,6 +2411,7 @@ { "access": "private", "index": 0, + "lineNumber": 21, "name": "_q_privateslot", "returnType": "void" } @@ -2359,6 +2435,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 14, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2385,6 +2462,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 14, "name": "blah", "read": "blah", "required": false, @@ -2414,6 +2492,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 14, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2440,6 +2519,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 20, "name": "blah", "read": "blah", "required": false, @@ -2469,6 +2549,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 48, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2485,6 +2566,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 48, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2507,6 +2589,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 53, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2523,6 +2606,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 53, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2545,6 +2629,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 57, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2561,6 +2646,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 57, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2583,6 +2669,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 60, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2599,6 +2686,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 60, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2625,6 +2713,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 61, "name": "gadgetPoperty", "read": "gadgetPoperty", "required": false, @@ -2638,6 +2727,7 @@ "designable": true, "final": false, "index": 1, + "lineNumber": 61, "name": "objectPoperty", "read": "objectPoperty", "required": false, @@ -2665,6 +2755,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 61, "name": "nestedGadgetPoperty", "read": "nestedGadgetPoperty", "required": false, @@ -2692,6 +2783,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 61, "name": "nestedObjectPoperty", "read": "nestedObjectPoperty", "required": false, @@ -2715,6 +2807,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 67, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2731,6 +2824,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 67, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2753,6 +2847,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 71, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2769,6 +2864,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 71, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2791,6 +2887,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 74, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2807,6 +2904,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 74, "name": "SomeEnum", "values": [ "SomeEnumValue" @@ -2833,6 +2931,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 75, "name": "gadgetPoperty", "read": "gadgetPoperty", "required": false, @@ -2846,6 +2945,7 @@ "designable": true, "final": false, "index": 1, + "lineNumber": 75, "name": "objectPoperty", "read": "objectPoperty", "required": false, @@ -2873,6 +2973,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 75, "name": "nestedGadgetPoperty", "read": "nestedGadgetPoperty", "required": false, @@ -2900,6 +3001,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 75, "name": "nestedObjectPoperty", "read": "nestedObjectPoperty", "required": false, @@ -2938,6 +3040,7 @@ } ], "index": 0, + "lineNumber": 13, "name": "signalWithDefaultArg", "returnType": "void" }, @@ -2945,6 +3048,7 @@ "access": "public", "index": 1, "isCloned": true, + "lineNumber": 13, "name": "signalWithDefaultArg", "returnType": "void" } @@ -2968,6 +3072,7 @@ { "isClass": false, "isFlag": false, + "lineNumber": 16, "name": "Salaries", "values": [ "Steve" @@ -3004,18 +3109,21 @@ } ], "index": 0, + "lineNumber": 23, "name": "mySignal", "returnType": "void" }, { "access": "public", "index": 1, + "lineNumber": 24, "name": "myVoidSignal", "returnType": "void" }, { "access": "public", "index": 2, + "lineNumber": 25, "name": "myVoidSignal2", "returnType": "void" } @@ -3024,12 +3132,14 @@ { "access": "public", "index": 3, + "lineNumber": 18, "name": "dummySlot", "returnType": "void" }, { "access": "public", "index": 4, + "lineNumber": 19, "name": "dummySlot2", "returnType": "void" }, @@ -3041,12 +3151,14 @@ } ], "index": 5, + "lineNumber": 20, "name": "anotherSlot", "returnType": "void" }, { "access": "public", "index": 6, + "lineNumber": 21, "name": "mySlot", "returnType": "TestTemplate<void>" } @@ -3126,6 +3238,7 @@ } ], "index": 0, + "lineNumber": 19, "name": "a", "returnType": "void" }, @@ -3138,6 +3251,7 @@ } ], "index": 1, + "lineNumber": 20, "name": "b", "returnType": "void" }, @@ -3149,6 +3263,7 @@ } ], "index": 2, + "lineNumber": 21, "name": "c", "returnType": "void" }, @@ -3161,6 +3276,7 @@ } ], "index": 3, + "lineNumber": 22, "name": "d", "returnType": "void" }, @@ -3172,6 +3288,7 @@ } ], "index": 4, + "lineNumber": 23, "name": "e", "returnType": "void" }, @@ -3184,6 +3301,7 @@ } ], "index": 5, + "lineNumber": 24, "name": "f", "returnType": "void" }, @@ -3195,6 +3313,7 @@ } ], "index": 6, + "lineNumber": 25, "name": "g", "returnType": "void" }, @@ -3207,6 +3326,7 @@ } ], "index": 7, + "lineNumber": 26, "name": "h", "returnType": "void" }, @@ -3221,6 +3341,7 @@ } ], "index": 8, + "lineNumber": 27, "name": "i", "returnType": "void" }, @@ -3235,6 +3356,7 @@ } ], "index": 9, + "lineNumber": 28, "name": "j", "returnType": "void" }, @@ -3246,6 +3368,7 @@ } ], "index": 10, + "lineNumber": 29, "name": "k", "returnType": "void" }, @@ -3258,6 +3381,7 @@ } ], "index": 11, + "lineNumber": 30, "name": "l", "returnType": "void" } @@ -3300,6 +3424,7 @@ { "access": "public", "index": 4, + "lineNumber": 0, "name": "myTPInvokable1", "returnType": "void", "tag": "QT_TECH_PREVIEW_API" @@ -3307,6 +3432,7 @@ { "access": "public", "index": 5, + "lineNumber": 0, "name": "myTPInvokable2", "returnType": "void", "tag": "QT_TECH_PREVIEW_API" @@ -3319,6 +3445,7 @@ "designable": true, "final": false, "index": 0, + "lineNumber": 19, "member": "m_status", "name": "status", "required": false, @@ -3333,12 +3460,14 @@ { "access": "public", "index": 0, + "lineNumber": 38, "name": "mySignal", "returnType": "void" }, { "access": "public", "index": 1, + "lineNumber": 39, "name": "myTPSignal", "returnType": "void", "tag": "QT_TECH_PREVIEW_API" @@ -3348,12 +3477,14 @@ { "access": "public", "index": 2, + "lineNumber": 42, "name": "mySlot", "returnType": "void" }, { "access": "public", "index": 3, + "lineNumber": 43, "name": "myTPSlot", "returnType": "void", "tag": "QT_TECH_PREVIEW_API" @@ -3386,6 +3517,7 @@ } ], "index": 0, + "lineNumber": 19, "name": "foo", "returnType": "void" }, @@ -3397,6 +3529,7 @@ } ], "index": 1, + "lineNumber": 20, "name": "foo2", "returnType": "void" }, @@ -3408,6 +3541,7 @@ } ], "index": 2, + "lineNumber": 23, "name": "bar", "returnType": "void" }, @@ -3419,6 +3553,7 @@ } ], "index": 3, + "lineNumber": 24, "name": "bar2", "returnType": "void" }, @@ -3430,6 +3565,7 @@ } ], "index": 4, + "lineNumber": 25, "name": "bar3", "returnType": "void" } diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 9a428e59f06..ab88dd78111 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -3,6 +3,14 @@ // Copyright (C) 2024 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +/* upstream MSVC bug + https://developercommunity.visualstudio.com/t/Regression:-c-compilation-failure-in-c/10926790 +*/ +#include <QtCore/qcompilerdetection.h> +#if defined(Q_CC_MSVC_ONLY) && (_MSC_FULL_VER >= 194435209) && (_MSC_FULL_VER < 194500000) +# define MSVC_ENUM_BUG +#endif + #include <QTest> #include <QSignalSpy> #include <stdio.h> @@ -67,7 +75,9 @@ #include "tech-preview.h" -#include "name_collision.h" +#ifndef MSVC_ENUM_BUG +# include "name_collision.h" +#endif using namespace Qt::StringLiterals; @@ -989,7 +999,9 @@ void tst_Moc::initTestCase() QVERIFY(QmlMacro::staticMetaObject.className()); QVERIFY(SignalWithDefaultArg::staticMetaObject.className()); QVERIFY(TestPointeeCanBeIncomplete::staticMetaObject.className()); +#ifndef MSVC_ENUM_BUG QVERIFY(myns::NameCollision::staticMetaObject.className()); +#endif } void tst_Moc::hasIncludeSupport() @@ -4923,6 +4935,11 @@ QTEST_MAIN(tst_Moc) #undef slots #undef emit +// needs to be included conditionally +#ifndef MSVC_ENUM_BUG +#include "moc_name_collision.cpp" +#endif + QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wvolatile") // should moc itself add this in generated code? #include "tst_moc.moc" diff --git a/tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist b/tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist new file mode 100644 index 00000000000..5468597e2b4 --- /dev/null +++ b/tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist @@ -0,0 +1 @@ +<invalid> diff --git a/tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro b/tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro new file mode 100644 index 00000000000..0230f9c6736 --- /dev/null +++ b/tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro @@ -0,0 +1,2 @@ +SOURCES += main.cpp +QMAKE_INFO_PLIST = Info.plist diff --git a/tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp b/tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp new file mode 100644 index 00000000000..905869dfa38 --- /dev/null +++ b/tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp index 278cf4ad232..080f0abbdaa 100644 --- a/tests/auto/tools/qmake/tst_qmake.cpp +++ b/tests/auto/tools/qmake/tst_qmake.cpp @@ -47,6 +47,7 @@ private slots: void rawString(); #if defined(Q_OS_DARWIN) void bundle_spaces(); + void invalid_info_plist(); #elif defined(Q_OS_WIN) void windowsResources(); #endif @@ -534,6 +535,23 @@ void tst_qmake::bundle_spaces() QVERIFY( test_compiler.removeMakefile(workDir) ); } +void tst_qmake::invalid_info_plist() +{ + QString workDir = base_path + "/testdata/invalid-info-plist"; + + // We set up alternate arguments here, to make sure we're testing Mac + // Bundles. We need to actually run make to check whether the failing + // plutil invocation breaks the build. + + test_compiler.setArguments(QStringList(), + QStringList() << "-spec" << "macx-clang"); + + QVERIFY( test_compiler.qmake(workDir, "invalid-info-plist") ); + + // Make fails: plutil fails to parse the Info.plist file + QVERIFY( test_compiler.make(workDir, QString(), true) ); +} + #elif defined(Q_OS_WIN) // defined(Q_OS_DARWIN) void tst_qmake::windowsResources() diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/BLACKLIST index aca3147b2d6..fde971443d4 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/BLACKLIST @@ -1,3 +1,2 @@ [layoutDirection] ubuntu-22.04 -ubuntu-24.04 diff --git a/tests/auto/widgets/kernel/qapplication/BLACKLIST b/tests/auto/widgets/kernel/qapplication/BLACKLIST deleted file mode 100644 index c68c7d6b149..00000000000 --- a/tests/auto/widgets/kernel/qapplication/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -[touchEventPropagation] -# QTBUG-66745 -opensuse-leap diff --git a/tests/benchmarks/corelib/io/qfile/tst_bench_qfile.cpp b/tests/benchmarks/corelib/io/qfile/tst_bench_qfile.cpp index d7da02b4ea2..ae45cc4843c 100644 --- a/tests/benchmarks/corelib/io/qfile/tst_bench_qfile.cpp +++ b/tests/benchmarks/corelib/io/qfile/tst_bench_qfile.cpp @@ -426,6 +426,7 @@ void tst_qfile::open() QBENCHMARK { QFile file; + [[maybe_unused]] const auto r = file.open(cfile, QIODevice::ReadOnly); file.close(); } diff --git a/tests/manual/rhi/rhiwidgetproto/examplewidget.cpp b/tests/manual/rhi/rhiwidgetproto/examplewidget.cpp index 6a6fd5b326e..34765c2e784 100644 --- a/tests/manual/rhi/rhiwidgetproto/examplewidget.cpp +++ b/tests/manual/rhi/rhiwidgetproto/examplewidget.cpp @@ -3,8 +3,11 @@ #include "examplewidget.h" #include "../shared/cube.h" + #include <QFile> + #include <QPainter> +#include <QtGui/qquaternion.h> static const QSize CUBE_TEX_SIZE(512, 512); diff --git a/tests/manual/stereographicsview/mygraphicsview.cpp b/tests/manual/stereographicsview/mygraphicsview.cpp index 933ee008354..5401baf862b 100644 --- a/tests/manual/stereographicsview/mygraphicsview.cpp +++ b/tests/manual/stereographicsview/mygraphicsview.cpp @@ -2,9 +2,12 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "mygraphicsview.h" + #include <QResizeEvent> #include <QFileDialog> +#include <QtGui/qquaternion.h> + Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); MyGraphicsView::MyGraphicsView(QWidget *parent) : diff --git a/util/json_schema/check_qt_module_json_schemas.py b/util/json_schema/check_qt_module_json_schemas.py new file mode 100755 index 00000000000..ba30c61285d --- /dev/null +++ b/util/json_schema/check_qt_module_json_schemas.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +# Copyright (C) 2025 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +# /// script +# dependencies = ["check-jsonschema", "click"] +# /// + +from __future__ import annotations + +from pathlib import Path + +import click +from check_jsonschema import main as check_jsonschema_main + + +SCHEMA_FILES = [ + "modules.json", +] + +@click.command( + context_settings=dict( + ignore_unknown_options=True, + ) +) +@click.option( + "--install-prefix", + type=click.Path( + exists=True, + file_okay=False, + dir_okay=True, + path_type=Path, + ), + required=True, + metavar="PATH", + help="Path to the Qt install prefix.", +) +# TODO: Use qtpaths to extract these paths instead +@click.option( + "--qt-sharedir", + default="share/qt6", + metavar="PATH", + help="The equivalent INSTALL_QT_SHAREDIR that was used.", +) +@click.option( + "--descriptionsdir", + default="modules", + metavar="PATH", + help="The equivalent INSTALL_DESCRIPTIONSDIR that was used.", +) +@click.argument( + "check_jsonschema_args", + nargs=-1, + type=click.UNPROCESSED, +) +def run( + install_prefix: Path, + check_jsonschema_args: list[str], + qt_sharedir: str, + descriptionsdir: str, +): + """ + Validate the module json files after installation. + + Unknown options are passed directly to check-jsonschema. + """ + + # Get the appropriate directory containing the schemas (order is important) + # If we run the script directly from source, we take the schemas available next to the script + # to simplify editing the schemas, otherwise we use the installed schema files + for schemas_dir in [ + Path(__file__).parent, + install_prefix / f"{qt_sharedir}/json_schema", + ]: + # check that all expected schema files are present + if all((schemas_dir/file).exists() for file in SCHEMA_FILES): + break + else: + click.secho("Error: missing schema files", fg="red") + raise SystemExit(1) + + module_files = [str(file) for file in (install_prefix / descriptionsdir).glob("*.json")] + click.echo("Checking modules") + check_jsonschema_main( + [ + "--schemafile", + str(schemas_dir / "modules.json"), + *check_jsonschema_args, + *module_files, + ], + ) + + +if __name__ == "__main__": + run() diff --git a/util/json_schema/modules.json b/util/json_schema/modules.json new file mode 100644 index 00000000000..3226924d3d4 --- /dev/null +++ b/util/json_schema/modules.json @@ -0,0 +1,251 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Qt modules", + "description": "Schema for the modules/*.json files", + "$comment": "Implemented in qt_describe_module() function from QtModuleHelpers.cmake", + "type": "object", + "oneOf": [ + { + "$ref": "#/$defs/modules_v2" + }, + { + "$ref": "#/$defs/modules_v3" + } + ], + "$defs": { + "modules_base": { + "$comment": "Common schema fields for all modules versions", + "allOf": [ + { + "type": "object", + "properties": { + "name": { + "description": "Name of the Qt module", + "type": "string" + }, + "version": { + "description": "Qt project version that built the module", + "type": "string" + }, + "repository": { + "description": "Qt repository where the module is defined in", + "type": "string" + } + }, + "required": [ + "name", + "version", + "repository" + ] + }, + { + "$ref": "#/$defs/extra_module_information" + } + ] + }, + "modules_v2": { + "$comment": "Introduced in https://codereview.qt-project.org/c/qt/qtbase/+/602617", + "allOf": [ + { + "$ref": "#/$defs/modules_base" + }, + { + "type": "object", + "properties": { + "schema_version": { + "const": 2 + }, + "platforms": { + "description": "", + "type": "array", + "items": { + "$ref": "#/$defs/platform_v2" + } + } + }, + "required": [ + "schema_version", + "platforms" + ] + } + ], + "unevaluatedProperties": false + }, + "modules_v3": { + "$comment": "Introduced in https://codereview.qt-project.org/c/qt/qtbase/+/654550", + "allOf": [ + { + "$ref": "#/$defs/modules_base" + }, + { + "type": "object", + "properties": { + "schema_version": { + "const": 3 + }, + "platforms": { + "description": "", + "type": "array", + "items": { + "$ref": "#/$defs/platform_v3" + } + } + }, + "required": [ + "schema_version", + "platforms" + ] + } + ], + "unevaluatedProperties": false + }, + "platform_base": { + "description": "", + "type": "object", + "properties": { + "name": { + "description": "", + "type": "string" + }, + "variant": { + "description": "", + "type": "string" + }, + "compiler_id": { + "description": "", + "type": "string" + }, + "compiler_version": { + "description": "", + "type": "string" + }, + "targets": { + "description": "", + "type": "array", + "items": { + "$ref": "#/$defs/platform_target" + } + } + }, + "required": [ + "name", + "compiler_id", + "compiler_version", + "targets" + ] + }, + "platform_v2": { + "allOf": [ + { + "$ref": "#/$defs/platform_base" + }, + { + "type": "object", + "properties": { + "version": { + "description": "The CMAKE_SYSTEM_VERSION of the builder if available", + "type": "string" + } + } + } + ], + "unevaluatedProperties": false + }, + "platform_v3": { + "allOf": [ + { + "$ref": "#/$defs/platform_base" + }, + { + "type": "object", + "properties": { + "version": { + "description": "The CMAKE_SYSTEM_VERSION. Maybe null if it cannot be shared, see: https://codereview.qt-project.org/c/qt/qtbase/+/654550", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "version" + ] + } + ], + "unevaluatedProperties": false + }, + "platform_target": { + "description": "", + "type": "object", + "properties": { + "architecture": { + "description": "", + "type": "string" + }, + "abi": { + "description": "", + "type": "string" + }, + "static": { + "description": "", + "type": "boolean" + }, + "api_version": { + "description": "", + "type": "string" + }, + "ndk_version": { + "description": "", + "type": "string" + } + }, + "required": [ + "architecture", + "abi" + ], + "additionalProperties": false + }, + "extra_module_information": { + "$comment": "Constructed from extra_module_information in QtModuleHelpers.cmake", + "type": "object", + "properties": { + "plugin_types": { + "description": "", + "type": "array", + "items": { + "type": "string" + } + }, + "internal": { + "description": "", + "type": "boolean" + }, + "bundle_type": { + "description": "", + "type": "string" + }, + "namespace": { + "description": "", + "type": "string" + }, + "qpa": { + "description": "", + "type": "object", + "properties": { + "platforms": { + "description": "", + "type": "array", + "items": { + "type": "string" + } + }, + "default_platform": { + "description": "", + "type": "string" + } + } + } + } + } + } +} diff --git a/util/locale_database/cldr2qlocalexml.py b/util/locale_database/cldr2qlocalexml.py index d4ba6960517..0aa04b64b05 100755 --- a/util/locale_database/cldr2qlocalexml.py +++ b/util/locale_database/cldr2qlocalexml.py @@ -83,7 +83,7 @@ def main(argv: list[str], out: TextIO, err: TextIO) -> int: parser.error(f'Please use a .xml extension on your output file name, not {xml}') else: try: - emit = open(xml, 'w') + emit = open(xml, 'w', encoding="utf-8") except IOError as e: parser.error(f'Failed to open "{xml}" to write output to it') diff --git a/util/locale_database/localetools.py b/util/locale_database/localetools.py index 10937df5485..818880d6efa 100644 --- a/util/locale_database/localetools.py +++ b/util/locale_database/localetools.py @@ -110,7 +110,7 @@ def AtomicRenameTemporaryFile(originalLocation: Path, *, prefix: str, dir: Path) On success closes the temporary file and moves its content to the original location. On error, removes temporary file, without disturbing the original. """ - tempFile = NamedTemporaryFile('w', prefix=prefix, dir=dir, delete=False) + tempFile = NamedTemporaryFile('w', prefix=prefix, dir=dir, delete=False, encoding='utf-8') try: yield tempFile tempFile.close() @@ -174,7 +174,7 @@ class Transcriber: self.writer = resources.enter_context( AtomicRenameTemporaryFile(self.path, prefix=self.path.name, dir=self.tempDir)) # Open the old file - self.reader = resources.enter_context(open(self.path)) + self.reader = resources.enter_context(open(self.path, encoding='utf-8')) self.onEnter() |