Revision control
++ # Copyright (C) 2026 The Qt Company Ltd.
++ # SPDX-License-Identifier: BSD-3-Clause
++
++ # Regenerate the row for the current Qt release in the QDoc manual's
++ # supported-Clang-versions table (qdoc-clang-versions.qdocinc) from the
++ # QDOC_SUPPORTED_CLANG_VERSIONS variable in QDocConfiguration.cmake.
++ #
++ # Usage:
++ # cmake -P GenerateQdocClangVersions.cmake
++ #
++ # Optional -D arguments (the defaults are relative to this file):
++ # QDOC_CONFIGURATION_FILE Path to QDocConfiguration.cmake
++ # QDOC_VERSIONS_DOC Path to qdoc-clang-versions.qdocinc
++ # QDOC_QT_VERSION Qt release for the row to update, as
++ # "major.minor". If not given, the current
++ # release is read from the QT_REPO_MODULE_VERSION
++ # variable in the repository's .cmake.conf file.
++ #
++ # The row for the given release is replaced in place. If the table does
++ # not yet contain a row for the release, one is inserted before
++ # \endtable. All other content is left untouched.
++
++ if(NOT DEFINED QDOC_CONFIGURATION_FILE)
++ set(QDOC_CONFIGURATION_FILE "${CMAKE_CURRENT_LIST_DIR}/QDocConfiguration.cmake")
++ endif()
++ if(NOT DEFINED QDOC_VERSIONS_DOC)
++ set(QDOC_VERSIONS_DOC
++ "${CMAKE_CURRENT_LIST_DIR}/../qdoc/doc/qdoc-guide/qdoc-clang-versions.qdocinc")
++ endif()
++ get_filename_component(QDOC_CONFIGURATION_FILE "${QDOC_CONFIGURATION_FILE}" ABSOLUTE)
++ get_filename_component(QDOC_VERSIONS_DOC "${QDOC_VERSIONS_DOC}" ABSOLUTE)
++
++ if(NOT EXISTS "${QDOC_CONFIGURATION_FILE}")
++ message(FATAL_ERROR "QDocConfiguration.cmake not found: ${QDOC_CONFIGURATION_FILE}")
++ endif()
++ if(NOT EXISTS "${QDOC_VERSIONS_DOC}")
++ message(FATAL_ERROR "Clang versions documentation file not found: ${QDOC_VERSIONS_DOC}\n"
++ "Commit the qdoc-clang-versions.qdocinc file first.")
++ endif()
++
++ if(NOT DEFINED QDOC_QT_VERSION)
++ get_filename_component(__qdoc_conf_dir "${QDOC_CONFIGURATION_FILE}" DIRECTORY)
++ get_filename_component(__qdoc_repo_root "${__qdoc_conf_dir}/../../.." ABSOLUTE)
++ unset(__qdoc_conf_dir)
++ if(NOT EXISTS "${__qdoc_repo_root}/.cmake.conf")
++ message(FATAL_ERROR "No .cmake.conf found at ${__qdoc_repo_root}; "
++ "pass -DQDOC_QT_VERSION=major.minor instead.")
++ endif()
++ file(READ "${__qdoc_repo_root}/.cmake.conf" __qdoc_cmake_conf)
++ string(REGEX MATCH "set\\(QT_REPO_MODULE_VERSION[ ]+\"[^\"]+\""
++ __qdoc_version_line "${__qdoc_cmake_conf}")
++ string(REGEX MATCH "[0-9]+\\.[0-9]+" __qdoc_version "${__qdoc_version_line}")
++ string(REGEX MATCH "^[0-9]+\\.[0-9]+" QDOC_QT_VERSION "${__qdoc_version}")
++ unset(__qdoc_cmake_conf)
++ unset(__qdoc_version_line)
++ unset(__qdoc_version)
++ unset(__qdoc_repo_root)
++ endif()
++
++ # Read QDOC_SUPPORTED_CLANG_VERSIONS. The list is parsed line by line so
++ # that this script can run in CMake script mode, where QDocConfiguration.cmake
++ # must not be included.
++ file(READ "${QDOC_CONFIGURATION_FILE}" __qdoc_config_content)
++ string(REPLACE "\n" ";" __qdoc_config_lines "${__qdoc_config_content}")
++ set(__qdoc_versions "")
++ set(__qdoc_in_list FALSE)
++ foreach(__qdoc_line IN LISTS __qdoc_config_lines)
++ if(__qdoc_line MATCHES "set\\(QDOC_SUPPORTED_CLANG_VERSIONS")
++ set(__qdoc_in_list TRUE)
++ elseif(__qdoc_in_list)
++ if(__qdoc_line MATCHES "^[ ]*\\)")
++ set(__qdoc_in_list FALSE)
++ else()
++ string(REGEX MATCHALL "\"[^\"]+\"" __qdoc_quoted "${__qdoc_line}")
++ foreach(__qdoc_v IN LISTS __qdoc_quoted)
++ string(REPLACE "\"" "" __qdoc_v "${__qdoc_v}")
++ list(APPEND __qdoc_versions "${__qdoc_v}")
++ endforeach()
++ unset(__qdoc_quoted)
++ unset(__qdoc_v)
++ endif()
++ endif()
++ endforeach()
++ unset(__qdoc_config_content)
++ unset(__qdoc_config_lines)
++ unset(__qdoc_line)
++ unset(__qdoc_in_list)
++
++ if(__qdoc_versions STREQUAL "")
++ message(FATAL_ERROR "Could not parse QDOC_SUPPORTED_CLANG_VERSIONS from "
++ "${QDOC_CONFIGURATION_FILE}")
++ endif()
++
++ set(__qdoc_floor "")
++ set(__qdoc_ceiling "")
++ foreach(__qdoc_version IN LISTS __qdoc_versions)
++ if(__qdoc_floor STREQUAL "" OR
++ __qdoc_version VERSION_LESS __qdoc_floor)
++ set(__qdoc_floor "${__qdoc_version}")
++ endif()
++ if(__qdoc_ceiling STREQUAL "" OR
++ __qdoc_version VERSION_GREATER __qdoc_ceiling)
++ set(__qdoc_ceiling "${__qdoc_version}")
++ endif()
++ endforeach()
++ unset(__qdoc_versions)
++ unset(__qdoc_version)
++
++ set(__qdoc_row "\\row \\li ${QDOC_QT_VERSION} \\li ${__qdoc_floor} - ${__qdoc_ceiling}")
++ set(__qdoc_row_prefix "\\row \\li ${QDOC_QT_VERSION} \\li")
++ unset(__qdoc_floor)
++ unset(__qdoc_ceiling)
++
++ file(READ "${QDOC_VERSIONS_DOC}" __qdoc_doc_content)
++ string(REPLACE "\n" ";" __qdoc_doc_lines "${__qdoc_doc_content}")
++ set(__qdoc_new_lines "")
++ set(__qdoc_row_replaced FALSE)
++ foreach(__qdoc_line IN LISTS __qdoc_doc_lines)
++ if(__qdoc_row_replaced)
++ list(APPEND __qdoc_new_lines "${__qdoc_line}")
++ continue()
++ endif()
++ if(__qdoc_line MATCHES "endtable")
++ if(NOT __qdoc_row_replaced)
++ list(APPEND __qdoc_new_lines " ${__qdoc_row}")
++ endif()
++ list(APPEND __qdoc_new_lines "${__qdoc_line}")
++ else()
++ string(FIND "${__qdoc_line}" "${__qdoc_row_prefix}" __qdoc_row_position)
++ if(__qdoc_row_position GREATER -1)
++ list(APPEND __qdoc_new_lines " ${__qdoc_row}")
++ set(__qdoc_row_replaced TRUE)
++ else()
++ list(APPEND __qdoc_new_lines "${__qdoc_line}")
++ endif()
++ unset(__qdoc_row_position)
++ endif()
++ endforeach()
++ unset(__qdoc_doc_content)
++ unset(__qdoc_doc_lines)
++ unset(__qdoc_line)
++
++ # A file that ends with a newline yields a trailing empty element when
++ # split, so the joined content retains the original line structure,
++ # including the final newline.
++ string(REPLACE ";" "\n" __qdoc_new_content "${__qdoc_new_lines}")
++
++ file(READ "${QDOC_VERSIONS_DOC}" __qdoc_old_content)
++ if(__qdoc_new_content STREQUAL __qdoc_old_content)
++ message(STATUS "Clang versions documentation already up to date "
++ "(Qt ${QDOC_QT_VERSION}).")
++ else()
++ file(WRITE "${QDOC_VERSIONS_DOC}" "${__qdoc_new_content}")
++ message(STATUS "Updated Clang versions documentation for Qt ${QDOC_QT_VERSION}:\n"
++ " ${__qdoc_row}\n"
++ "Do not forget to stage ${QDOC_VERSIONS_DOC} in your commit.")
++ unset(__qdoc_row)
++ endif()
++ unset(__qdoc_new_lines)
++ unset(__qdoc_new_content)
++ unset(__qdoc_old_content)
++ unset(__qdoc_row_replaced)