Revision control

++ # Copyright (C) 2022 The Qt Company Ltd.
++ # SPDX-License-Identifier: BSD-3-Clause
++ cmake_minimum_required(VERSION 3.16)
++
++ get_filename_component(output_directory "${OUTPUT_FILE}" DIRECTORY)
++ file(MAKE_DIRECTORY "${output_directory}")
++
++ find_program(xmlstarlet NAMES xmlstarlet xml)
++ if(xmlstarlet)
++ set(XML_STARLET_COMMAND COMMAND "${xmlstarlet}" sel -D -B -t -c / "${INPUT_FILE}")
++ else()
++ get_filename_component(mime_types_resource_filename "${INPUT_FILE}" NAME)
++ message(STATUS "xmlstarlet command was not found. ${mime_types_resource_filename}"
++ " will not be minified.")
++ endif()
++
++ # The function tries to minify 'input_file' using the globally defined 'XML_STARLET_COMMAND'.
++ # Sets the full path of the output file to the 'out_var' argument. If 'XML_STARLET_COMMAND' fails
++ # to minify the 'input_file', 'out_var' is set to 'input_file'.
++ function(try_minify_xml out_var input_file output_directory)
++ get_filename_component(output_filename "${input_file}" NAME)
++ set(minified_output "${output_directory}/${output_filename}")
++
++ # Assume XML_STARLET_COMMAND is globally defined.
++ if(XML_STARLET_COMMAND)
++ execute_process(${XML_STARLET_COMMAND}
++ OUTPUT_FILE "${minified_output}"
++ RESULT_VARIABLE failed_to_minify
++ )
++ if(NOT failed_to_minify)
++ set(${out_var} "${minified_output}" PARENT_SCOPE)
++ return()
++ endif()
++ endif()
++ set(${out_var} "${input_file}" PARENT_SCOPE)
++ endfunction()
++
++ unset(archive_command)
++
++ if(COMPRESSION_TYPE STREQUAL "none")
++ try_minify_xml(qmimeprovider_db_data_file "${INPUT_FILE}" "${output_directory}")
++ else()
++ # CMake versions less than 3.26 don't support the value of the zstd compression level higher
++ # than 9. We want zstd to compress with level 19 if it's possible, so if zstd executable is
++ # found on a file system we prefer to use the 'External' archiving API instead of the CMake API.
++ if(COMPRESSION_TYPE STREQUAL "zstd" AND CMAKE_VERSION VERSION_LESS 3.26)
++ find_program(archive_command NAMES zstd zstd.exe)
++ if(archive_command)
++ set(ARCHIVING_API "External")
++ endif()
++ endif()
++
++ set(qmimeprovider_db_data_file "${OUTPUT_FILE}.archive")
++ if(ARCHIVING_API STREQUAL "External")
++ message(STATUS "Using external archive command to compress the mime type database")
++ if(COMPRESSION_TYPE STREQUAL "zstd")
++ find_program(archive_command NAMES zstd zstd.exe)
++ if(archive_command)
++ set(archive_command_args -cq19 -T1)
++ else()
++ message(WARNING
++ "Unable to use the preffered ${COMPRESSION_TYPE} compression for the mime type database."
++ " ${COMPRESSION_TYPE} binary is not found. Trying gzip.")
++ endif()
++ endif()
++ if(NOT archive_command)
++ # Trying to use gzip if zstd is binary is not found.
++ set(COMPRESSION_TYPE "gzip")
++ find_program(archive_command NAMES gzip gzip.exe)
++ set(archive_command_args -nc9)
++ endif()
++ if(archive_command)
++ if(NOT XML_STARLET_COMMAND)
++ set(intput_file_arg INPUT_FILE "${INPUT_FILE}")
++ endif()
++ execute_process(${XML_STARLET_COMMAND}
++ COMMAND ${archive_command}
++ ${archive_command_args}
++ ${intput_file_arg}
++ OUTPUT_FILE "${qmimeprovider_db_data_file}"
++ RESULTS_VARIABLE results
++ ERROR_VARIABLE error_string
++ )
++
++ foreach(result IN LISTS results)
++ if(NOT result EQUAL 0)
++ message(WARNING "Unable to compress mime type database: ${error_string}")
++ endif()
++ endforeach()
++ else()
++ message(WARNING "Unable to find ${COMPRESSION_TYPE} binary."
++ " Please make sure that the ${COMPRESSION_TYPE} binary is in PATH."
++ " Adding the uncompressed mime type database.")
++ set(COMPRESSION_TYPE "none")
++ set(qmimeprovider_db_data_file "${INPUT_FILE}")
++ endif()
++ else()
++ message(STATUS "Using CMake archive command to compress the mime type database")
++
++ try_minify_xml(mimetypes_resource_file_minified "${INPUT_FILE}" "${output_directory}")
++
++ if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.26 AND COMPRESSION_TYPE STREQUAL "zstd")
++ set(additional_file_archive_create_parameters COMPRESSION_LEVEL 19)
++ elseif(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19)
++ set(additional_file_archive_create_parameters COMPRESSION_LEVEL 9)
++ endif()
++
++ if(COMPRESSION_TYPE STREQUAL "gzip")
++ set(cmake_compression_type "GZip")
++ elseif(COMPRESSION_TYPE STREQUAL "zstd")
++ set(cmake_compression_type "Zstd")
++ endif()
++
++ file(ARCHIVE_CREATE OUTPUT "${qmimeprovider_db_data_file}"
++ PATHS "${mimetypes_resource_file_minified}"
++ FORMAT raw
++ COMPRESSION ${cmake_compression_type}
++ ${additional_file_archive_create_parameters}
++ )
++ if(NOT mimetypes_resource_file_minified STREQUAL INPUT_FILE)
++ file(REMOVE "${mimetypes_resource_file_minified}")
++ endif()
++ endif()
++ endif()
++ file(READ "${qmimeprovider_db_data_file}" qmime_db_data HEX)
++ file(SIZE "${qmimeprovider_db_data_file}" qmime_db_data_size)
++ if(NOT qmimeprovider_db_data_file STREQUAL INPUT_FILE)
++ file(SIZE "${INPUT_FILE}" qmime_db_resource_size)
++ file(REMOVE "${qmimeprovider_db_data_file}")
++ else()
++ set(qmime_db_resource_size ${qmime_db_data_size})
++ endif()
++
++ string(REGEX MATCHALL "([a-f0-9][a-f0-9])" qmime_db_hex "${qmime_db_data}")
++
++ list(TRANSFORM qmime_db_hex PREPEND "0x")
++ math(EXPR qmime_db_data_size "${qmime_db_data_size} - 1")
++ foreach(index RANGE 0 ${qmime_db_data_size} 12)
++ list(APPEND index_list ${index})
++ endforeach()
++ list(TRANSFORM qmime_db_hex PREPEND "\n " AT ${index_list})
++ list(JOIN qmime_db_hex ", " qmime_db_hex_joined)
++
++ if(NOT COMPRESSION_TYPE STREQUAL "none")
++ string(TOUPPER "${COMPRESSION_TYPE}" compression_type_upper)
++ set(qmime_db_content "#define MIME_DATABASE_IS_${compression_type_upper}\n")
++ endif()
++ string(APPEND qmime_db_content
++ "static const unsigned char mimetype_database[] = {"
++ "${qmime_db_hex_joined}"
++ "\n};\n"
++ "static constexpr size_t MimeTypeDatabaseOriginalSize = ${qmime_db_resource_size};\n"
++ )
++
++ file(WRITE "${OUTPUT_FILE}" "${qmime_db_content}")