Merge topic 'improve-doc-consistency' 277c12a4c7 Help: Improve command usage formatting consistency Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !11687
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c39cd71..3b19851 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml
@@ -1550,7 +1550,7 @@ variables: CMAKE_CI_JOB_NIGHTLY: "true" -t:windows-clang19.1-cl-ninja: +t:windows-clang21.1-cl-ninja: extends: - .windows_clang_ninja - .cmake_test_windows_external @@ -1560,10 +1560,10 @@ needs: - t:windows-vs2026-x64-ninja variables: - CMAKE_CI_BUILD_NAME: windows_clang19.1_cl_ninja + CMAKE_CI_BUILD_NAME: windows_clang21.1_cl_ninja CMAKE_CI_JOB_NIGHTLY: "true" -t:windows-clang19.1-cl-nmake: +t:windows-clang21.1-cl-nmake: extends: - .windows_clang_nmake - .cmake_test_windows_external @@ -1573,10 +1573,10 @@ needs: - t:windows-vs2026-x64-ninja variables: - CMAKE_CI_BUILD_NAME: windows_clang19.1_cl_nmake + CMAKE_CI_BUILD_NAME: windows_clang21.1_cl_nmake CMAKE_CI_JOB_NIGHTLY: "true" -t:windows-clang19.1-gnu-ninja: +t:windows-clang21.1-gnu-ninja: extends: - .windows_clang_ninja - .cmake_test_windows_external @@ -1586,10 +1586,10 @@ needs: - t:windows-vs2026-x64-ninja variables: - CMAKE_CI_BUILD_NAME: windows_clang19.1_gnu_ninja + CMAKE_CI_BUILD_NAME: windows_clang21.1_gnu_ninja CMAKE_CI_JOB_NIGHTLY: "true" -t:windows-clang19.1-gnu-nmake: +t:windows-clang21.1-gnu-nmake: extends: - .windows_clang_nmake - .cmake_test_windows_external @@ -1599,7 +1599,7 @@ needs: - t:windows-vs2026-x64-ninja variables: - CMAKE_CI_BUILD_NAME: windows_clang19.1_gnu_nmake + CMAKE_CI_BUILD_NAME: windows_clang21.1_gnu_nmake CMAKE_CI_JOB_NIGHTLY: "true" t:windows-intel2021.9-ninja:
diff --git a/.gitlab/ci/clang.ps1 b/.gitlab/ci/clang.ps1 index 61361b1..327fe3b 100644 --- a/.gitlab/ci/clang.ps1 +++ b/.gitlab/ci/clang.ps1
@@ -1,10 +1,10 @@ $erroractionpreference = "stop" -if ("$env:CMAKE_CI_BUILD_NAME".Contains("clang19.1")) { - # LLVM/Clang 19.1.0 - # https://github.com/llvm/llvm-project/releases/tag/llvmorg-19.1.0 - $filename = "llvm-19.1.0-win-x86_64-1" - $sha256sum = "C1F974511A6FA2DC5B4892996C064A55BF81D7F244514F8AB5A453110ADEC0EC" +if ("$env:CMAKE_CI_BUILD_NAME".Contains("clang21.1")) { + # LLVM/Clang 21.1.8 + # https://github.com/llvm/llvm-project/releases/tag/llvmorg-21.1.8 + $filename = "llvm-21.1.8-win-x86_64-1" + $sha256sum = "3DB0063A6E434C694799CDD70052F27F08A758F1FF4B4C04D9910AD4198F6064" } else { throw ('unknown CMAKE_CI_BUILD_NAME: ' + "$env:CMAKE_CI_BUILD_NAME") }
diff --git a/.gitlab/ci/configure_fedora43_makefiles.cmake b/.gitlab/ci/configure_fedora43_makefiles.cmake index b5a9f30..3ddf236 100644 --- a/.gitlab/ci/configure_fedora43_makefiles.cmake +++ b/.gitlab/ci/configure_fedora43_makefiles.cmake
@@ -108,6 +108,7 @@ if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "") set(CMake_TEST_ISPC "ON" CACHE STRING "") endif() +set(CMake_TEST_LOCALE_CHARSET "ISO-8859-1" CACHE STRING "") set(CMake_TEST_Qt5 "ON" CACHE BOOL "") set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "") set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
diff --git a/.gitlab/ci/configure_fedora43_ninja.cmake b/.gitlab/ci/configure_fedora43_ninja.cmake index 5c75c1e..a67e40a 100644 --- a/.gitlab/ci/configure_fedora43_ninja.cmake +++ b/.gitlab/ci/configure_fedora43_ninja.cmake
@@ -4,6 +4,7 @@ set(CMake_TEST_CPACK_APPIMAGE_RUNTIME_FILE "$ENV{CI_PROJECT_DIR}/.gitlab/appimagetool/lib/appimagetool/runtime" CACHE FILEPATH "") set(CMake_TEST_ISPC "ON" CACHE STRING "") endif() +set(CMake_TEST_LOCALE_CHARSET "UTF-8" CACHE STRING "") set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "") set(CMake_TEST_Rust "ON" CACHE STRING "") set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake index 75e94df..eb728ed 100644 --- a/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake +++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake
@@ -2,7 +2,7 @@ # `CMAKE_CXX_STDLIB_MODULES_JSON` is needed to use `import std`. set(gcc_prefix "/opt/gcc-importstd") set(CMake_TEST_CXX_STDLIB_MODULES_JSON - "${gcc_prefix}/lib64/libstdc++.modules.json" + "${gcc_prefix}/lib64.reloc/libstdc++.modules.json" CACHE FILEPATH "") file(MAKE_DIRECTORY "${gcc_prefix}/lib64.reloc")
diff --git a/.gitlab/ci/configure_macos_arm64_ninja.cmake b/.gitlab/ci/configure_macos_arm64_ninja.cmake index 3bfdcf2..c1924fe 100644 --- a/.gitlab/ci/configure_macos_arm64_ninja.cmake +++ b/.gitlab/ci/configure_macos_arm64_ninja.cmake
@@ -6,6 +6,7 @@ set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "") set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "") set(CMake_TEST_GUI "ON" CACHE BOOL "") +set(CMake_TEST_LOCALE_CHARSET "UTF-8" CACHE STRING "") set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "") set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "") set(CMake_TEST_TLS_VERSION "1.2" CACHE STRING "")
diff --git a/.gitlab/ci/configure_macos_x86_64_ninja.cmake b/.gitlab/ci/configure_macos_x86_64_ninja.cmake index 48f9dcb..1af144f 100644 --- a/.gitlab/ci/configure_macos_x86_64_ninja.cmake +++ b/.gitlab/ci/configure_macos_x86_64_ninja.cmake
@@ -9,6 +9,7 @@ if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "") set(CMake_TEST_ISPC "ON" CACHE STRING "") endif() +set(CMake_TEST_LOCALE_CHARSET "UTF-8" CACHE STRING "") set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "") set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "") set(CMake_TEST_TLS_VERSION "1.2" CACHE STRING "")
diff --git a/.gitlab/ci/configure_windows_common.cmake b/.gitlab/ci/configure_windows_common.cmake index 7467cfd..1246885 100644 --- a/.gitlab/ci/configure_windows_common.cmake +++ b/.gitlab/ci/configure_windows_common.cmake
@@ -2,6 +2,7 @@ set(BUILD_CursesDialog ON CACHE BOOL "") set(CMAKE_PREFIX_PATH "$ENV{CI_PROJECT_DIR}/.gitlab/qt" CACHE STRING "") set(CMake_TEST_Java OFF CACHE BOOL "") +set(CMake_TEST_LOCALE_CHARSET "UTF-8" CACHE STRING "") set(Python_FIND_REGISTRY NEVER CACHE STRING "") include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/env_fedora43_makefiles.sh b/.gitlab/ci/env_fedora43_makefiles.sh index 217ff30..f02e487 100644 --- a/.gitlab/ci/env_fedora43_makefiles.sh +++ b/.gitlab/ci/env_fedora43_makefiles.sh
@@ -1,3 +1,6 @@ if test "$CMAKE_CI_NIGHTLY" = "true"; then source .gitlab/ci/ispc-env.sh fi + +# Test in a Latin-1 locale. +export LANG=en_US.ISO-8859-1
diff --git a/.gitlab/ci/env_fedora43_ninja.sh b/.gitlab/ci/env_fedora43_ninja.sh index a2b941b..0ef4bce 100644 --- a/.gitlab/ci/env_fedora43_ninja.sh +++ b/.gitlab/ci/env_fedora43_ninja.sh
@@ -2,3 +2,6 @@ source .gitlab/ci/appimagetool-env.sh source .gitlab/ci/ispc-env.sh fi + +# Test in a UTF-8 locale. +export LANG=en_US.UTF-8
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index adcfed4..280dd9b 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim
@@ -3539,7 +3539,6 @@ \ APPENDIX \ AUTO \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES - \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO \ CMAKE_MAP_IMPORTED_CONFIG_ \ COMPAT_VERSION \ CONFIG @@ -3835,7 +3834,6 @@ \ BYPASS_PROVIDER \ CATEGORY \ CMAKE_DISABLE_FIND_PACKAGE_ - \ CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES \ CMAKE_FIND_ROOT_PATH_BOTH \ CMAKE_FIND_USE_ \ CMAKE_REQUIRE_FIND_PACKAGE_ @@ -4149,7 +4147,6 @@ \ BUILD_TYPE \ BUNDLE_EXECUTABLE \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES - \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO \ CMAKE_INSTALL_BINDIR \ CMAKE_INSTALL_DATADIR \ CMAKE_INSTALL_DATAROOTDIR @@ -4417,7 +4414,6 @@ \ ASM_MASM \ ASM_NASM \ ATT - \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO \ CMAKE_PROJECT_ \ COMPAT_VERSION \ CPS
diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst index 73effab..35360c2 100644 --- a/Help/command/cmake_host_system_information.rst +++ b/Help/command/cmake_host_system_information.rst
@@ -137,6 +137,17 @@ Human readable full processor description +``LOCALE_CHARSET`` + .. versionadded:: 4.3 + + The locale's character set, if known, otherwise empty. + + This is the :ref:`encoding <CMake Language Encoding>` expected + in :manual:`cmake-language(7)` files and scripts: + + * On Windows, this is always ``UTF-8``. + * On UNIX and macOS, this is based on the current locale. + ``OS_NAME`` .. versionadded:: 3.10
diff --git a/Help/command/cmake_path.rst b/Help/command/cmake_path.rst index 3fc3b7c..5fb0ef1 100644 --- a/Help/command/cmake_path.rst +++ b/Help/command/cmake_path.rst
@@ -169,6 +169,7 @@ be empty. A ``relative-part`` refers to the full path with any ``root-path`` removed. +.. _Creating a Path Variable: Creating A Path Variable ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,6 +194,16 @@ keyword. All other sub-commands store the result in a mandatory ``<out-var>`` variable. +.. note:: + + The ``cmake_path`` command can be used directly with variables provided by + CMake representing paths (e.g., :variable:`CMAKE_SOURCE_DIR`). However, since + the command can modify these variables, and many of them have undefined + behavior when modified, they should never be specified as an ``<out-var>``, + and only as the ``<path-var>`` when a separate ``<out-var>`` is specified. + See :manual:`cmake-variables(7)` for the list of CMake variables and + identifiers reserved by CMake. + .. _Normalization: Normalization @@ -395,7 +406,7 @@ Query ^^^^^ -Each of the `cmake_path(GET) <GET_>`_ subcommands has a corresponding +Each of the :cref:`GET` subcommands has a corresponding ``HAS_...`` subcommand which can be used to discover whether a particular path component is present. See `Path Structure And Terminology`_ for the meaning of each path component. @@ -500,7 +511,7 @@ cmake_path(SET <path-var> [NORMALIZE] <input>) Assigns the ``<input>`` path to ``<path-var>``. If ``<input>`` is a native - path, it is converted into a cmake-style path with forward-slashes + path, it is converted into a CMake-style path with forward-slashes (``/``). On Windows, the long filename marker is taken into account. When the ``NORMALIZE`` option is specified, the path is :ref:`normalized @@ -550,12 +561,16 @@ append <input> omitting any root-name to <path> + See :ref:`Creating a Path Variable` for details on the output variable. + .. signature:: cmake_path(APPEND_STRING <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) Appends all the ``<input>`` arguments to the ``<path-var>`` without adding any ``directory-separator``. + See :ref:`Creating a Path Variable` for details on the output variable. + .. signature:: cmake_path(REMOVE_FILENAME <path-var> [OUTPUT_VARIABLE <out-var>]) @@ -563,8 +578,8 @@ :cref:`GET ... FILENAME`) from ``<path-var>``. After removal, any trailing ``directory-separator`` is left alone, if present. - If ``OUTPUT_VARIABLE`` is not given, then after this function returns, - :cref:`HAS_FILENAME` returns false for ``<path-var>``. + :cref:`HAS_FILENAME` will return false for the result, whether stored in + ``<out-var>`` or ``<path-var>``. For example: @@ -583,6 +598,8 @@ First path is "/a/" Second path is "/a/" + See :ref:`Creating a Path Variable` for details on the output variable. + .. signature:: cmake_path(REPLACE_FILENAME <path-var> <input> [OUTPUT_VARIABLE <out-var>]) @@ -599,12 +616,16 @@ cmake_path(APPEND path "${input}") endif() + See :ref:`Creating a Path Variable` for details on the output variable. + .. signature:: cmake_path(REMOVE_EXTENSION <path-var> [LAST_ONLY] [OUTPUT_VARIABLE <out-var>]) Removes the :ref:`extension <EXTENSION_DEF>`, if any, from ``<path-var>``. + See :ref:`Creating a Path Variable` for details on the output variable. + .. signature:: cmake_path(REPLACE_EXTENSION <path-var> [LAST_ONLY] <input> [OUTPUT_VARIABLE <out-var>]) @@ -620,6 +641,8 @@ endif() cmake_path(APPEND_STRING path "${input}") + See :ref:`Creating a Path Variable` for details on the output variable. + .. _Path Generation: @@ -632,6 +655,8 @@ Normalizes ``<path-var>`` according the steps described in :ref:`Normalization`. + See :ref:`Creating a Path Variable` for details on the output variable. + .. signature:: cmake_path(RELATIVE_PATH <path-var> [BASE_DIRECTORY <input>] [OUTPUT_VARIABLE <out-var>]) @@ -645,6 +670,8 @@ `std::filesystem::path::lexically_relative <https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal>`_. + See :ref:`Creating a Path Variable` for details on the output variable. + .. signature:: cmake_path(ABSOLUTE_PATH <path-var> [BASE_DIRECTORY <input>] [NORMALIZE] [OUTPUT_VARIABLE <out-var>]) @@ -662,6 +689,8 @@ with symbolic links resolved and leading tildes expanded, use the :command:`file(REAL_PATH)` command instead. + See :ref:`Creating a Path Variable` for details on the output variable. + Native Conversion ^^^^^^^^^^^^^^^^^ @@ -671,12 +700,14 @@ .. signature:: cmake_path(NATIVE_PATH <path-var> [NORMALIZE] <out-var>) - Converts a cmake-style ``<path-var>`` into a native path with + Converts a CMake-style ``<path-var>`` into a native path with platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere). When the ``NORMALIZE`` option is specified, the path is :ref:`normalized <Normalization>` before the conversion. + See :ref:`Creating a Path Variable` for details on the output variable. + .. _CONVERT: .. signature:: @@ -684,17 +715,20 @@ :target: CONVERT ... TO_CMAKE_PATH_LIST - Converts a native ``<input>`` path into a cmake-style path with forward - slashes (``/``). On Windows hosts, the long filename marker is taken into + Converts a native ``<input>`` path into a CMake-style path with forward + slashes (``/``). + + On Windows hosts, the long filename marker is taken into account. The input can be a single path or a system search path like - ``$ENV{PATH}``. A search path will be converted to a cmake-style list - separated by ``;`` characters (on non-Windows platforms, this essentially - means ``:`` separators are replaced with ``;``). The result of the - conversion is stored in the ``<out-var>`` variable. + ``$ENV{PATH}``. A search path will be converted to a + :ref:`semicolon-separated list <CMake Language Lists>` (on non-Windows + platforms, this essentially means ``:`` separators are replaced with ``;``). When the ``NORMALIZE`` option is specified, the path is :ref:`normalized <Normalization>` before the conversion. + See :ref:`Creating a Path Variable` for details on the output variable. + .. note:: Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand takes a literal string as input, not the name of a variable. @@ -704,16 +738,18 @@ :target: CONVERT ... TO_NATIVE_PATH_LIST - Converts a cmake-style ``<input>`` path into a native path with + Converts a CMake-style ``<input>`` path into a native path with platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere). - The input can be a single path or a cmake-style list. A list will be - converted into a native search path (``;``-separated on Windows, - ``:``-separated on other platforms). The result of the conversion is - stored in the ``<out-var>`` variable. + + The input can be a single path or a :ref:`semicolon-separated list + <CMake Language Lists>`. A list will be converted into a native search path + (``;``-separated on Windows, ``:``-separated on other platforms). When the ``NORMALIZE`` option is specified, the path is :ref:`normalized <Normalization>` before the conversion. + See :ref:`Creating a Path Variable` for details on the output variable. + .. note:: Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand takes a literal string as input, not the name of a variable. @@ -744,3 +780,5 @@ ``p2`` that compare equal (:cref:`COMPARE ... EQUAL`), the hash value of ``p1`` is equal to the hash value of ``p2``. The path is always :ref:`normalized <Normalization>` before the hash is computed. + + See :ref:`Creating a Path Variable` for details on the output variable.
diff --git a/Help/command/export.rst b/Help/command/export.rst index 91c3cd8..0ecdbd9 100644 --- a/Help/command/export.rst +++ b/Help/command/export.rst
@@ -153,9 +153,6 @@ [CXX_MODULES_DIRECTORY <directory>]) .. versionadded:: 4.3 -.. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. Creates a file in the |CPS|_ that may be included by outside projects to import targets named by ``<target>...`` from the current project's build tree. See
diff --git a/Help/command/file.rst b/Help/command/file.rst index 75335dc..9334fa0 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst
@@ -710,12 +710,12 @@ file(TO_CMAKE_PATH "<path>" <variable>) file(TO_NATIVE_PATH "<path>" <variable>) - The ``TO_CMAKE_PATH`` mode converts a native ``<path>`` into a cmake-style + The ``TO_CMAKE_PATH`` mode converts a native ``<path>`` into a CMake-style path with forward-slashes (``/``). The input can be a single path or a system search path like ``$ENV{PATH}``. A search path will be converted - to a cmake-style list separated by ``;`` characters. + to a :ref:`semicolon-separated list <CMake Language Lists>`. - The ``TO_NATIVE_PATH`` mode converts a cmake-style ``<path>`` into a native + The ``TO_NATIVE_PATH`` mode converts a CMake-style ``<path>`` into a native path with platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere).
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index 2a6df20..2432434 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst
@@ -75,23 +75,25 @@ .. _`Config mode`: **Config mode** - In this mode, CMake searches for a file called - ``<lowercasePackageName>-config.cmake`` or ``<PackageName>Config.cmake``. - It will also look for ``<lowercasePackageName>-config-version.cmake`` or + In this mode, CMake searches for a file matching any of: + + * ``<lowercasePackageName>-config.cmake`` + * ``<PackageName>Config.cmake`` + * ``<PackageName>.cps`` + * ``<lowercasePackageName>.cps`` + + If one of the first two is found, CMake will also look respectively, for + ``<lowercasePackageName>-config-version.cmake`` or ``<PackageName>ConfigVersion.cmake`` if version details were specified (see :ref:`version selection` for an explanation of how these separate - version files are used). + version files are used). The first two options are CMake-script package + descriptions. The latter two are |CPS|_ (CPS) package descriptions, which + are more portable and include version information in the 'base' file. Aside + from any explicitly noted exceptions, any references to "config files", + "config mode", "package configuration files", and so forth refer equally to + both CPS and CMake-script files. .. note:: - If the experimental ``CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES`` is enabled, - files named ``<PackageName>.cps`` and ``<lowercasePackageName>.cps`` are - also considered. These files provide package information according to the - |CPS|_ (CPS), which is more portable than CMake script. Aside from any - explicitly noted exceptions, any references to "config files", "config - mode", "package configuration files", and so forth refer equally to both - CPS and CMake-script files. This functionality is a work in progress, and - some features may be missing. - Search is implemented in a manner that will tend to prefer |CPS| files over CMake-script config files in most cases. Specifying ``CONFIGS`` suppresses consideration of CPS files. @@ -312,8 +314,14 @@ also considered when determining whether to redirect the call to a package provided by :module:`FetchContent`. -The command searches for a file called ``<PackageName>Config.cmake`` or -``<lowercasePackageName>-config.cmake`` for each name specified. +The command searches for a file whose name, for each package name specified, +matches any of: + +* ``<PackageName>Config.cmake`` +* ``<lowercasePackageName>-config.cmake`` +* ``<PackageName>.cps`` +* ``<lowercasePackageName>.cps`` + A replacement set of possible configuration file names may be given using the ``CONFIGS`` option. The :ref:`search procedure` is specified below. Once found, any :ref:`version constraint <version selection>` is checked, @@ -324,9 +332,8 @@ .. note:: - If the experimental ``CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES`` is enabled, - files named ``<PackageName>.cps`` and ``<lowercasePackageName>.cps`` are - also considered, unless ``CONFIGS`` is given. + Because CPS files are not permitted to have names that do *not* match the + package name, specifying ``CONFIGS`` will suppress searcing for CPS files. All configuration files which have been considered by CMake while searching for the package with an appropriate version are stored in the @@ -396,7 +403,7 @@ .. [#p1] .. versionadded:: 3.25 -.. [#p2] .. versionadded:: 4.0 +.. [#p2] .. versionadded:: 4.3 On systems supporting macOS :prop_tgt:`FRAMEWORK` and :prop_tgt:`BUNDLE`, the following directories are searched for Frameworks or Application Bundles @@ -416,7 +423,7 @@ ``<prefix>/<name>.app/Contents/Resources/CMake/`` A =============================================================== ========== -.. [#p3] .. versionadded:: 4.0 +.. [#p3] .. versionadded:: 4.3 When searching the above paths, ``find_package`` will only look for ``.cps`` files in search paths which contain ``/cps/``, and will only look for @@ -986,15 +993,6 @@ ``<PackageName>_FOUND`` to false to tell ``find_package`` that component requirements are not satisfied. -.. _CPS: https://cps-org.github.io/cps/ -.. |CPS| replace:: Common Package Specification - -.. _cps-compat_version: https://cps-org.github.io/cps/schema.html#compat-version -.. |cps-compat_version| replace:: ``compat_version`` - -.. _cps-version_schema: https://cps-org.github.io/cps/schema.html#version-schema -.. |cps-version_schema| replace:: ``version_schema`` - CPS Transitive Requirements ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1028,3 +1026,12 @@ targets. Those targets must be named ``<PackageName>::<ComponentName>``, in conformance with CPS convention, or the check will consider the package not found. + +.. _CPS: https://cps-org.github.io/cps/ +.. |CPS| replace:: Common Package Specification + +.. _cps-compat_version: https://cps-org.github.io/cps/schema.html#compat-version +.. |cps-compat_version| replace:: ``compat_version`` + +.. _cps-version_schema: https://cps-org.github.io/cps/schema.html#version-schema +.. |cps-version_schema| replace:: ``version_schema``
diff --git a/Help/command/install.rst b/Help/command/install.rst index b2ac69a..68fda6c 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst
@@ -975,10 +975,7 @@ .. signature:: install(PACKAGE_INFO <package-name> [...]) - .. versionadded:: 3.31 - .. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. + .. versionadded:: 4.3 Installs a |CPS|_ ("CPS") file exporting targets for dependent projects: @@ -1275,6 +1272,11 @@ In any case, any metadata values specified in the ``install`` command will take precedence. + Note that an SBOM file cannot be generated for targets with generator + expressions contained in their :prop_tgt:`LINK_LIBRARIES` or + :prop_tgt:`INTERFACE_LINK_LIBRARIES` properties, unless the generator + expressions are guarded by :genex:`LINK_ONLY`. + Examples ^^^^^^^^
diff --git a/Help/command/project.rst b/Help/command/project.rst index a77e0b1..ad4f32e 100644 --- a/Help/command/project.rst +++ b/Help/command/project.rst
@@ -89,10 +89,7 @@ :variable:`CMAKE_PROJECT_VERSION`. ``COMPAT_VERSION <version>`` - .. versionadded:: 4.1 - .. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. + .. versionadded:: 4.3 Optional; requires ``VERSION`` also be set. @@ -101,17 +98,14 @@ and sets the variables * :variable:`PROJECT_COMPAT_VERSION`, - :variable:`<PROJECT-NAME>_COMPAT_VERSION` + :variable:`<PROJECT-NAME>_COMPAT_VERSION`. - When the ``project()`` command is called from the top-level - ``CMakeLists.txt``, then the compatibility version is also stored in the - variable :variable:`CMAKE_PROJECT_COMPAT_VERSION`. + When the ``project()`` command is called from the top-level + ``CMakeLists.txt``, then the compatibility version is also stored in the + variable :variable:`CMAKE_PROJECT_COMPAT_VERSION`. ``SPDX_LICENSE <license-string>`` - .. versionadded:: 4.2 - .. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. + .. versionadded:: 4.3 Optional. Sets the variables
diff --git a/Help/cpack_gen/wix.rst b/Help/cpack_gen/wix.rst index fce5c38..738ee7c 100644 --- a/Help/cpack_gen/wix.rst +++ b/Help/cpack_gen/wix.rst
@@ -408,8 +408,9 @@ In 32-bit builds the token will expand empty while in 64-bit builds it will expand to ``64``. - When unset generated installers will default installing to - ``ProgramFiles<64>Folder``. + When unset generated installers will install to + ``LocalAppDataFolder`` if :variable:`CPACK_WIX_INSTALL_SCOPE` is ``perUser``, + and to ``ProgramFiles<64>Folder`` otherwise. .. variable:: CPACK_WIX_ROOT @@ -451,7 +452,7 @@ .. versionadded:: 3.29 This variable can be optionally set to specify the ``InstallScope`` - of the installer: + of the installer (see https://docs.firegiant.com/wix3/xsd/wix/package/): ``perMachine`` Create an installer that installs for all users and requires @@ -461,7 +462,20 @@ This is the default. See policy :policy:`CMP0172`. ``perUser`` - Not yet supported. This is reserved for future use. + Create an installer that installs only for the current user + and does not require administrative privileges. Start menu entries created + by the installer are visible only to the current user. + + To enable per-user installation, the installer has to generate some + additional registry entries to serve as "key paths" for installed + components (see https://learn.microsoft.com/en-us/windows/win32/msi/ice38). + These registry entries are created under ``HKEY_CURRENT_USER``, using the + path specified by the :variable:`CPACK_WIX_COMPONENT_KEYS_REGISTRY_PATH` + variable. + + .. versionchanged:: 4.3 + + Before CMake 4.3, this value was reserved for future use and not supported. ``NONE`` Create an installer without any ``InstallScope`` attribute. @@ -477,16 +491,30 @@ but the start menu entry and uninstaller registration are created only for the current user. - .. warning:: + .. warning:: + Installations performed by installers created with different + ``InstallScope`` values cannot be cleanly updated or replaced by each other. + For example, to transition a project's installers from ``NONE`` to + ``perMachine``, or from ``perMachine`` to ``perUser``, the latter installer + should be distributed with instructions to first manually uninstall + any older version. - An installation performed by an installer created without any - ``InstallScope`` cannot be cleanly updated or replaced by an - installer with an ``InstallScope``. In order to transition - a project's installers from ``NONE`` to ``perMachine``, the - latter installer should be distributed with instructions to - first manually uninstall any older version. +.. variable:: CPACK_WIX_COMPONENT_KEYS_REGISTRY_PATH - See https://docs.firegiant.com/wix3/xsd/wix/package/ + .. versionadded:: 4.3 + + This variable determines the registry path under ``HKEY_CURRENT_USER`` + where the installer will create registry entries to serve as "key paths" + for components if :variable:`CPACK_WIX_INSTALL_SCOPE` is set to ``perUser``. + + Use forward slashes (``/``) as path separators to avoid issues with escapes; + they will be converted to backslashes (``\``) by the WIX generator. + + Default value is ``Software/<Vendor>/<PackageName>/Components``, + where ``<Vendor>`` is taken from :variable:`CPACK_PACKAGE_VENDOR`, + and ``<PackageName>`` is taken from :variable:`CPACK_PACKAGE_NAME`. + + Example: ``Software/MyCompany/MyProduct/Components`` .. variable:: CPACK_WIX_CAB_PER_COMPONENT
diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index fd85b81..caa089d 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst
@@ -39,31 +39,11 @@ using the ``CMAKE_EXPORT_FIND_PACKAGE_NAME`` variable and/or ``EXPORT_FIND_PACKAGE_NAME`` target property. -Export |CPS| Package Information -================================ - -In order to activate support for this experimental feature, set - -* variable ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO`` to -* value ``7fa7d13b-8308-4dc7-af39-9e450456d68f``. - -This UUID may change in future versions of CMake. Be sure to use the value -documented here by the source tree of the version of CMake with which you are -experimenting. - -When activated, this experimental feature provides the following: - -* The experimental ``export(PACKAGE_INFO)`` and ``install(PACKAGE_INFO)`` - commands are available to export package information in the |CPS|_ format. - See :command:`install(PACKAGE_INFO)` for a complete overview of the command. - Export |CPS| Package Information for ``install(EXPORT)`` -"""""""""""""""""""""""""""""""""""""""""""""""""""""""" +======================================================== In order to activate support for this experimental feature, set -* variable ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO`` to -* value ``b80be207-778e-46ba-8080-b23bba22639e``. * variable ``CMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO`` to * value ``ababa1b5-7099-495f-a9cd-e22d38f274f2``. @@ -76,24 +56,6 @@ * Setting ``CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO`` enables generation of package information in the |CPS|_ format via the ``install(EXPORT)`` command. -Find/Import |CPS| Packages -========================== - -In order to activate support for this experimental feature, set - -* variable ``CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES`` to -* value ``e82e467b-f997-4464-8ace-b00808fff261``. - -This UUID may change in future versions of CMake. Be sure to use the value -documented here by the source tree of the version of CMake with which you are -experimenting. - -When activated, this experimental feature provides the following: - -* The :command:`find_package` command will also search for packages which are - described using |CPS|_. Refer to the :command:`find_package` documentation - for details. - Build database support ======================
diff --git a/Help/manual/cmake-cxxmodules.7.rst b/Help/manual/cmake-cxxmodules.7.rst index c676296..35ad2a2 100644 --- a/Help/manual/cmake-cxxmodules.7.rst +++ b/Help/manual/cmake-cxxmodules.7.rst
@@ -88,6 +88,10 @@ The :variable:`CMAKE_CXX_COMPILER_IMPORT_STD` variable lists standard levels which have support for ``import std`` in the active C++ toolchain. +Additionally, only the :ref:`Ninja Generators` currently support +``import std`` at this time because :ref:`Visual Studio Generators` do not +support building :term:`BMIs <BMI>` for ``IMPORTED`` targets. + Generator Support =================
diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst index 908c46c..777ef0b 100644 --- a/Help/manual/cmake-language.7.rst +++ b/Help/manual/cmake-language.7.rst
@@ -78,6 +78,11 @@ .. _Byte-Order Mark: https://en.wikipedia.org/wiki/Byte_order_mark +.. versionadded:: 4.3 + + The :command:`cmake_host_system_information` command's ``LOCALE_CHARSET`` + query returns the expected character set encoding. + Source Files ------------
diff --git a/Help/release/dev/cmake-locale.rst b/Help/release/dev/cmake-locale.rst new file mode 100644 index 0000000..ce91492 --- /dev/null +++ b/Help/release/dev/cmake-locale.rst
@@ -0,0 +1,6 @@ +cmake-locale +------------ + +* The :command:`cmake_host_system_information` command gained a + ``LOCALE_CHARSET`` query for the expected :manual:`cmake-language(7)` + script encoding.
diff --git a/Help/release/dev/cpack-wix-perUser.rst b/Help/release/dev/cpack-wix-perUser.rst new file mode 100644 index 0000000..b35aef0 --- /dev/null +++ b/Help/release/dev/cpack-wix-perUser.rst
@@ -0,0 +1,5 @@ +cpack-wix-perUser +----------------- + +* The :cpack_gen:`CPack WIX Generator` now supports per-user installers + by setting :variable:`CPACK_WIX_INSTALL_SCOPE` to ``perUser``.
diff --git a/Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst b/Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst index e32d381..1b5e96a 100644 --- a/Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst +++ b/Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst
@@ -1,24 +1,20 @@ CMAKE_PROJECT_COMPAT_VERSION ---------------------------- -.. versionadded:: 4.1 - -.. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. +.. versionadded:: 4.3 The compatibility version of the top level project. -This variable holds the compatibility version of the project as specified in the -top level CMakeLists.txt file by a :command:`project` command. In the event -that the top level CMakeLists.txt contains multiple :command:`project` calls, -the most recently called one from that top level CMakeLists.txt will determine -the value that ``CMAKE_PROJECT_COMPAT_VERSION`` contains. For example, consider -the following top level CMakeLists.txt: +This variable holds the compatibility version of the project as specified in +the top level CMakeLists.txt file by a :command:`project` command. In the +event that the top level CMakeLists.txt contains multiple :command:`project` +calls, the most recently called one from that top level CMakeLists.txt will +determine the value that ``CMAKE_PROJECT_COMPAT_VERSION`` contains. For +example, consider the following top level CMakeLists.txt: .. code-block:: cmake - cmake_minimum_required(VERSION 4.1) + cmake_minimum_required(VERSION 4.3) project(First VERSION 9.0 COMPAT_VERSION 1.2.3) project(Second VERSION 9.0 COMPAT_VERSION 3.4.5) add_subdirectory(sub) @@ -36,6 +32,6 @@ CMAKE_PROJECT_COMPAT_VERSION = 3.4.5 -To obtain the version from the most recent call to :command:`project` in -the current directory scope or above, see the :variable:`PROJECT_COMPAT_VERSION` -variable. +To obtain the version from the most recent call to :command:`project` +in the current directory scope or above, see the +:variable:`PROJECT_COMPAT_VERSION` variable.
diff --git a/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst b/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst index 0cbde7c..3164b7e 100644 --- a/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst +++ b/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst
@@ -1,11 +1,7 @@ CMAKE_PROJECT_SPDX_LICENSE -------------------------- -.. versionadded:: 4.2 - -.. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. +.. versionadded:: 4.3 The license(s) of the top level project. @@ -18,7 +14,7 @@ .. code-block:: cmake - cmake_minimum_required(VERSION 4.2) + cmake_minimum_required(VERSION 4.3) project(First SPDX_LICENSE "BSD-3-Clause") project(Second SPDX_LICENSE "BSD-3-Clause AND CC-BY-SA-4.0") add_subdirectory(sub)
diff --git a/Help/variable/CTEST_BINARY_DIRECTORY.rst b/Help/variable/CTEST_BINARY_DIRECTORY.rst index 8413e37..ec30f2d 100644 --- a/Help/variable/CTEST_BINARY_DIRECTORY.rst +++ b/Help/variable/CTEST_BINARY_DIRECTORY.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``BuildDirectory`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_BUILD_COMMAND.rst b/Help/variable/CTEST_BUILD_COMMAND.rst index 31c44e2..e4110c7 100644 --- a/Help/variable/CTEST_BUILD_COMMAND.rst +++ b/Help/variable/CTEST_BUILD_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``MakeCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_BUILD_NAME.rst b/Help/variable/CTEST_BUILD_NAME.rst index 3d08397..d6b0636 100644 --- a/Help/variable/CTEST_BUILD_NAME.rst +++ b/Help/variable/CTEST_BUILD_NAME.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``BuildName`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_BZR_COMMAND.rst b/Help/variable/CTEST_BZR_COMMAND.rst index 0c05d1a..8927886 100644 --- a/Help/variable/CTEST_BZR_COMMAND.rst +++ b/Help/variable/CTEST_BZR_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``BZRCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst index 4dd5e5b..475dab2 100644 --- a/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst +++ b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``BZRUpdateOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CHANGE_ID.rst b/Help/variable/CTEST_CHANGE_ID.rst index a6d15f7..5202020 100644 --- a/Help/variable/CTEST_CHANGE_ID.rst +++ b/Help/variable/CTEST_CHANGE_ID.rst
@@ -4,7 +4,7 @@ .. versionadded:: 3.4 Specify the CTest ``ChangeId`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script. This setting allows CTest to pass arbitrary information about this build up to CDash. One use of this feature is to allow CDash to
diff --git a/Help/variable/CTEST_CHECKOUT_COMMAND.rst b/Help/variable/CTEST_CHECKOUT_COMMAND.rst index 852c28e..2203d6b 100644 --- a/Help/variable/CTEST_CHECKOUT_COMMAND.rst +++ b/Help/variable/CTEST_CHECKOUT_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Tell the :command:`ctest_start` command how to checkout or initialize -the source directory in a :manual:`ctest(1)` dashboard client script. +the source directory in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CONFIGURATION_TYPE.rst b/Help/variable/CTEST_CONFIGURATION_TYPE.rst index 932f81d..6ae4a34 100644 --- a/Help/variable/CTEST_CONFIGURATION_TYPE.rst +++ b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
@@ -4,7 +4,7 @@ .. versionadded:: 3.1 Specify the CTest ``DefaultCTestConfigurationType`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script. If the configuration type is set via :option:`-C \<cfg\> <ctest -C>` from the command line then this variable is populated accordingly.
diff --git a/Help/variable/CTEST_CONFIGURE_COMMAND.rst b/Help/variable/CTEST_CONFIGURE_COMMAND.rst index 992ef47..90c50f4 100644 --- a/Help/variable/CTEST_CONFIGURE_COMMAND.rst +++ b/Help/variable/CTEST_CONFIGURE_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``ConfigureCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_COVERAGE_COMMAND.rst b/Help/variable/CTEST_COVERAGE_COMMAND.rst index 3df2262..8168b33 100644 --- a/Help/variable/CTEST_COVERAGE_COMMAND.rst +++ b/Help/variable/CTEST_COVERAGE_COMMAND.rst
@@ -4,7 +4,7 @@ .. versionadded:: 3.1 Specify the CTest ``CoverageCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script. Cobertura '''''''''
diff --git a/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst index 39d9b5d..bae5c79 100644 --- a/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst +++ b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``CoverageExtraFlags`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CURL_OPTIONS.rst b/Help/variable/CTEST_CURL_OPTIONS.rst index 45e84ed..07557e9 100644 --- a/Help/variable/CTEST_CURL_OPTIONS.rst +++ b/Help/variable/CTEST_CURL_OPTIONS.rst
@@ -8,4 +8,4 @@ .. versionadded:: 3.1 Specify the CTest ``CurlOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CVS_COMMAND.rst b/Help/variable/CTEST_CVS_COMMAND.rst index 7932070..797a4e7 100644 --- a/Help/variable/CTEST_CVS_COMMAND.rst +++ b/Help/variable/CTEST_CVS_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``CVSCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst index 359e708..6d9288a 100644 --- a/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst +++ b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``CVSUpdateOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_LOCATION.rst b/Help/variable/CTEST_DROP_LOCATION.rst index f66793b..3955193 100644 --- a/Help/variable/CTEST_DROP_LOCATION.rst +++ b/Help/variable/CTEST_DROP_LOCATION.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``DropLocation`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_METHOD.rst b/Help/variable/CTEST_DROP_METHOD.rst index 3a84658..6a0d0a7 100644 --- a/Help/variable/CTEST_DROP_METHOD.rst +++ b/Help/variable/CTEST_DROP_METHOD.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``DropMethod`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_SITE.rst b/Help/variable/CTEST_DROP_SITE.rst index 9c871e3..be64d72 100644 --- a/Help/variable/CTEST_DROP_SITE.rst +++ b/Help/variable/CTEST_DROP_SITE.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``DropSite`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_SITE_CDASH.rst b/Help/variable/CTEST_DROP_SITE_CDASH.rst index dcdb286..7d09a36 100644 --- a/Help/variable/CTEST_DROP_SITE_CDASH.rst +++ b/Help/variable/CTEST_DROP_SITE_CDASH.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``IsCDash`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_SITE_PASSWORD.rst b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst index 8259651..b2f684e 100644 --- a/Help/variable/CTEST_DROP_SITE_PASSWORD.rst +++ b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``DropSitePassword`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_SITE_USER.rst b/Help/variable/CTEST_DROP_SITE_USER.rst index 8d2e3a3..07f115e 100644 --- a/Help/variable/CTEST_DROP_SITE_USER.rst +++ b/Help/variable/CTEST_DROP_SITE_USER.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``DropSiteUser`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_EXTRA_SUBMIT_FILES.rst b/Help/variable/CTEST_EXTRA_SUBMIT_FILES.rst index 21f801f..a721ecf 100644 --- a/Help/variable/CTEST_EXTRA_SUBMIT_FILES.rst +++ b/Help/variable/CTEST_EXTRA_SUBMIT_FILES.rst
@@ -2,4 +2,4 @@ ------------------------ Specify files for :command:`ctest_submit(PARTS ExtraFiles)` to submit -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_GIT_COMMAND.rst b/Help/variable/CTEST_GIT_COMMAND.rst index eb9b440..01ffca7 100644 --- a/Help/variable/CTEST_GIT_COMMAND.rst +++ b/Help/variable/CTEST_GIT_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``GITCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst b/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst index 529bfc7..6e4b9c1 100644 --- a/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst +++ b/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.6 Specify the CTest ``GITInitSubmodules`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst index 82a8a6a..1ae1099 100644 --- a/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst +++ b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``GITUpdateCustom`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst index 1568239..a063ba3 100644 --- a/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst +++ b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``GITUpdateOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_HG_COMMAND.rst b/Help/variable/CTEST_HG_COMMAND.rst index 3372fe4..426cfd5 100644 --- a/Help/variable/CTEST_HG_COMMAND.rst +++ b/Help/variable/CTEST_HG_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``HGCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst index 85c6b03..751b300 100644 --- a/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst +++ b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``HGUpdateOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst b/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst index dd6d125..4c1ec4b 100644 --- a/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst +++ b/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.10 Specify the CTest ``LabelsForSubprojects`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst index 25f1bd9..1c86357 100644 --- a/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst +++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``MemoryCheckCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst index 51830d5..f2c91e3 100644 --- a/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst +++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``MemoryCheckCommandOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst index b6fee2e..d9f3eea 100644 --- a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst +++ b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
@@ -4,7 +4,7 @@ .. versionadded:: 3.1 Specify the CTest ``MemoryCheckSanitizerOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script. CTest prepends correct sanitizer options ``*_OPTIONS`` environment variable to executed command. CTests adds
diff --git a/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst index a61a3ef..fe54eb9 100644 --- a/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst +++ b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``MemoryCheckSuppressionFile`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst index 80353a4..d412e79 100644 --- a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst +++ b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
@@ -4,7 +4,7 @@ .. versionadded:: 3.1 Specify the CTest ``MemoryCheckType`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script. Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, ``DrMemory``, ``CudaSanitizer``, ``ThreadSanitizer``, ``AddressSanitizer``, ``LeakSanitizer``, ``MemorySanitizer`` and ``UndefinedBehaviorSanitizer``.
diff --git a/Help/variable/CTEST_NIGHTLY_START_TIME.rst b/Help/variable/CTEST_NIGHTLY_START_TIME.rst index 2d707d5..3ccf50a 100644 --- a/Help/variable/CTEST_NIGHTLY_START_TIME.rst +++ b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
@@ -4,7 +4,7 @@ .. versionadded:: 3.1 Specify the CTest ``NightlyStartTime`` setting in a :manual:`ctest(1)` -dashboard client script. +:ref:`Dashboard Client` script. Note that this variable must always be set for a nightly build in a dashboard script. It is needed so that nightly builds can be properly grouped
diff --git a/Help/variable/CTEST_NOTES_FILES.rst b/Help/variable/CTEST_NOTES_FILES.rst index 301b78a..cc66345 100644 --- a/Help/variable/CTEST_NOTES_FILES.rst +++ b/Help/variable/CTEST_NOTES_FILES.rst
@@ -2,4 +2,4 @@ ----------------- Specify files for :command:`ctest_submit(PARTS Notes)` to submit -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_P4_CLIENT.rst b/Help/variable/CTEST_P4_CLIENT.rst index 0778c5b..63c1739 100644 --- a/Help/variable/CTEST_P4_CLIENT.rst +++ b/Help/variable/CTEST_P4_CLIENT.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``P4Client`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_P4_COMMAND.rst b/Help/variable/CTEST_P4_COMMAND.rst index 5cc2a81..61cd4a1 100644 --- a/Help/variable/CTEST_P4_COMMAND.rst +++ b/Help/variable/CTEST_P4_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``P4Command`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_P4_OPTIONS.rst b/Help/variable/CTEST_P4_OPTIONS.rst index 01b6534..b4889f8 100644 --- a/Help/variable/CTEST_P4_OPTIONS.rst +++ b/Help/variable/CTEST_P4_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``P4Options`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst index 365aa3f..5dec345 100644 --- a/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst +++ b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``P4UpdateOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst index 8e9bf01..294e138 100644 --- a/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst +++ b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
@@ -4,7 +4,7 @@ .. versionadded:: 3.18 Specify the CTest ``ResourceSpecFile`` setting in a :manual:`ctest(1)` -dashboard client script. +:ref:`Dashboard Client` script. This can also be used to specify the resource spec file from a CMake build. If no ``RESOURCE_SPEC_FILE`` is passed to :command:`ctest_test`, and
diff --git a/Help/variable/CTEST_SITE.rst b/Help/variable/CTEST_SITE.rst index 526e6ed..7875b30 100644 --- a/Help/variable/CTEST_SITE.rst +++ b/Help/variable/CTEST_SITE.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``Site`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SOURCE_DIRECTORY.rst b/Help/variable/CTEST_SOURCE_DIRECTORY.rst index 4c6ac54..84fd1f8 100644 --- a/Help/variable/CTEST_SOURCE_DIRECTORY.rst +++ b/Help/variable/CTEST_SOURCE_DIRECTORY.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``SourceDirectory`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SUBMIT_INACTIVITY_TIMEOUT.rst b/Help/variable/CTEST_SUBMIT_INACTIVITY_TIMEOUT.rst index 175885a..cdc4ff4 100644 --- a/Help/variable/CTEST_SUBMIT_INACTIVITY_TIMEOUT.rst +++ b/Help/variable/CTEST_SUBMIT_INACTIVITY_TIMEOUT.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.23 Specify the CTest ``SubmitInactivityTimeout`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SUBMIT_URL.rst b/Help/variable/CTEST_SUBMIT_URL.rst index b6e7f68..3147b4a 100644 --- a/Help/variable/CTEST_SUBMIT_URL.rst +++ b/Help/variable/CTEST_SUBMIT_URL.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.14 Specify the CTest ``SubmitURL`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SVN_COMMAND.rst b/Help/variable/CTEST_SVN_COMMAND.rst index e97acd0..8d8b263 100644 --- a/Help/variable/CTEST_SVN_COMMAND.rst +++ b/Help/variable/CTEST_SVN_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``SVNCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SVN_OPTIONS.rst b/Help/variable/CTEST_SVN_OPTIONS.rst index 5326e20..3d111cc 100644 --- a/Help/variable/CTEST_SVN_OPTIONS.rst +++ b/Help/variable/CTEST_SVN_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``SVNOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst index 24e0bbf..0830c2f 100644 --- a/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst +++ b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``SVNUpdateOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_TEST_LOAD.rst b/Help/variable/CTEST_TEST_LOAD.rst index b6a9d62..fed4042 100644 --- a/Help/variable/CTEST_TEST_LOAD.rst +++ b/Help/variable/CTEST_TEST_LOAD.rst
@@ -4,6 +4,6 @@ .. versionadded:: 3.4 Specify the ``TestLoad`` setting in the :ref:`CTest Test Step` -of a :manual:`ctest(1)` dashboard client script. This sets the +of a :manual:`ctest(1)` :ref:`Dashboard Client` script. This sets the default value for the ``TEST_LOAD`` option of the :command:`ctest_test` command.
diff --git a/Help/variable/CTEST_TEST_TIMEOUT.rst b/Help/variable/CTEST_TEST_TIMEOUT.rst index 61d9191..f6a1daa 100644 --- a/Help/variable/CTEST_TEST_TIMEOUT.rst +++ b/Help/variable/CTEST_TEST_TIMEOUT.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``TimeOut`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_UPDATE_COMMAND.rst b/Help/variable/CTEST_UPDATE_COMMAND.rst index c4ed645..1084065 100644 --- a/Help/variable/CTEST_UPDATE_COMMAND.rst +++ b/Help/variable/CTEST_UPDATE_COMMAND.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``UpdateCommand`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_UPDATE_OPTIONS.rst b/Help/variable/CTEST_UPDATE_OPTIONS.rst index 96c4b6c..ef2dad3 100644 --- a/Help/variable/CTEST_UPDATE_OPTIONS.rst +++ b/Help/variable/CTEST_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``UpdateOptions`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst index f7c863c..c778338 100644 --- a/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst +++ b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest :ref:`UpdateVersionOnly <UpdateVersionOnly>` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst index 87918cb..9f4ecc3 100644 --- a/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst +++ b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.15 Specify the CTest :ref:`UpdateVersionOverride <UpdateVersionOverride>` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_USE_LAUNCHERS.rst b/Help/variable/CTEST_USE_LAUNCHERS.rst index 728cdc5..3326bad 100644 --- a/Help/variable/CTEST_USE_LAUNCHERS.rst +++ b/Help/variable/CTEST_USE_LAUNCHERS.rst
@@ -4,4 +4,4 @@ .. versionadded:: 3.1 Specify the CTest ``UseLaunchers`` setting -in a :manual:`ctest(1)` dashboard client script. +in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/PROJECT-NAME_COMPAT_VERSION.rst b/Help/variable/PROJECT-NAME_COMPAT_VERSION.rst index 29c24b8..5bcd8d5 100644 --- a/Help/variable/PROJECT-NAME_COMPAT_VERSION.rst +++ b/Help/variable/PROJECT-NAME_COMPAT_VERSION.rst
@@ -1,11 +1,7 @@ <PROJECT-NAME>_COMPAT_VERSION ----------------------------- -.. versionadded:: 4.1 - -.. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. +.. versionadded:: 4.3 Value given to the ``COMPAT_VERSION`` option of the most recent call to the :command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst b/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst index 06c395d..0febd48 100644 --- a/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst +++ b/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst
@@ -1,11 +1,7 @@ <PROJECT-NAME>_SPDX_LICENSE --------------------------- -.. versionadded:: 4.2 - -.. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. +.. versionadded:: 4.3 Value given to the ``SPDX_LICENSE`` option of the most recent call to the :command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT_COMPAT_VERSION.rst b/Help/variable/PROJECT_COMPAT_VERSION.rst index cab800c..94bea94 100644 --- a/Help/variable/PROJECT_COMPAT_VERSION.rst +++ b/Help/variable/PROJECT_COMPAT_VERSION.rst
@@ -1,11 +1,7 @@ PROJECT_COMPAT_VERSION ---------------------- -.. versionadded:: 4.1 - -.. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. +.. versionadded:: 4.3 Value given to the ``COMPAT_VERSION`` option of the most recent call to the :command:`project` command, if any. To obtain the compatibility version of the
diff --git a/Help/variable/PROJECT_SPDX_LICENSE.rst b/Help/variable/PROJECT_SPDX_LICENSE.rst index 4f62e94..947e753 100644 --- a/Help/variable/PROJECT_SPDX_LICENSE.rst +++ b/Help/variable/PROJECT_SPDX_LICENSE.rst
@@ -1,11 +1,7 @@ PROJECT_SPDX_LICENSE -------------------- -.. versionadded:: 4.2 - -.. note:: - - Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``. +.. versionadded:: 4.3 Value given to the ``SPDX_LICENSE`` option of the most recent call to the :command:`project` command, if any. To obtain the compatibility version of the
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index 677402b..7642c09 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -98,6 +98,4 @@ set(CMAKE_CXX_COMPILER_IMPORT_STD "@CMAKE_CXX_COMPILER_IMPORT_STD@") set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "@CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE@") -if(CMAKE_CXX_STDLIB_MODULES_JSON) - set(CMAKE_CXX_STDLIB_MODULES_JSON "@CMAKE_CXX_STDLIB_MODULES_JSON@") -endif() +set(CMAKE_CXX_STDLIB_MODULES_JSON "@CMAKE_CXX_STDLIB_MODULES_JSON@")
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake index 06d11bb..66f6cda 100644 --- a/Modules/CTest.cmake +++ b/Modules/CTest.cmake
@@ -7,7 +7,7 @@ Configure a project for testing with CTest/CDash -Include this module in the top CMakeLists.txt file of a project to +Include this module in the top ``CMakeLists.txt`` file of a project to enable testing with CTest and dashboard submissions to CDash: .. code-block:: cmake @@ -41,8 +41,8 @@ set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") set(CTEST_SUBMIT_URL "http://my.cdash.org/submit.php?project=MyProject") -(the CDash server can provide the file to a project administrator who -configures ``MyProject``). Settings in the config file are shared by +The CDash server can provide the file to a project administrator who +configures ``MyProject``. Settings in the config file are shared by both this ``CTest`` module and the :manual:`ctest(1)` command-line :ref:`Dashboard Client` mode (:option:`ctest -S`).
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake index 24b7157..b7359b2 100644 --- a/Modules/Compiler/Clang-C.cmake +++ b/Modules/Compiler/Clang-C.cmake
@@ -5,11 +5,6 @@ set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -TC) set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl") set(CMAKE_C_INCLUDE_WHAT_YOU_USE_DRIVER_MODE "cl") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_C) - set(CMAKE_C_DEPENDS_USE_COMPILER TRUE) - endif() elseif("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c) if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
diff --git a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake index 4099a35..95b53d0 100644 --- a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake +++ b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
@@ -8,7 +8,7 @@ return () endif () - if (NOT DEFINED CMAKE_CXX_STDLIB_MODULES_JSON) + if (NOT CMAKE_CXX_STDLIB_MODULES_JSON) execute_process( COMMAND "${CMAKE_CXX_COMPILER}"
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index 87a4cdd..a6412e9 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/Modules/Compiler/Clang-CXX.cmake
@@ -18,11 +18,6 @@ if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl") set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE_DRIVER_MODE "cl") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles" - AND CMAKE_DEPFILE_FLAGS_CXX) - set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE) - endif() endif() if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
diff --git a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake index 08d6273..c8bd960 100644 --- a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake +++ b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
@@ -4,7 +4,7 @@ return () endif () - if (NOT DEFINED CMAKE_CXX_STDLIB_MODULES_JSON) + if (NOT CMAKE_CXX_STDLIB_MODULES_JSON) execute_process( COMMAND "${CMAKE_CXX_COMPILER}"
diff --git a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake index 733b31b..b7bd525 100644 --- a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake +++ b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
@@ -1,5 +1,5 @@ function (_cmake_cxx_find_modules_json) - if (DEFINED CMAKE_CXX_STDLIB_MODULES_JSON) + if (CMAKE_CXX_STDLIB_MODULES_JSON) return () endif ()
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake index 4a39d2c..95d2692 100644 --- a/Modules/FindLibLZMA.cmake +++ b/Modules/FindLibLZMA.cmake
@@ -6,7 +6,7 @@ ----------- Finds the liblzma, a data compression library that implements the LZMA -(Lempel–Ziv–Markov chain algorithm): +(Lempel-Ziv-Markov chain algorithm): .. code-block:: cmake
diff --git a/Modules/Platform/Windows-Clang-C.cmake b/Modules/Platform/Windows-Clang-C.cmake index a90e4b7..a1c52d9 100644 --- a/Modules/Platform/Windows-Clang-C.cmake +++ b/Modules/Platform/Windows-Clang-C.cmake
@@ -1,18 +1,10 @@ include(Platform/Windows-Clang) __windows_compiler_clang(C) -if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_C) - set(CMAKE_C_DEPENDS_USE_COMPILER TRUE) - endif() -elseif("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_C) - # dependencies are computed by the compiler itself - set(CMAKE_C_DEPFILE_FORMAT gcc) - set(CMAKE_C_DEPENDS_USE_COMPILER TRUE) - endif() +if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" + AND CMAKE_DEPFILE_FLAGS_C) + # dependencies are computed by the compiler itself + set(CMAKE_C_DEPFILE_FORMAT gcc) + set(CMAKE_C_DEPENDS_USE_COMPILER TRUE) endif()
diff --git a/Modules/Platform/Windows-Clang-CXX.cmake b/Modules/Platform/Windows-Clang-CXX.cmake index af2a48f..6624088 100644 --- a/Modules/Platform/Windows-Clang-CXX.cmake +++ b/Modules/Platform/Windows-Clang-CXX.cmake
@@ -2,18 +2,10 @@ set(_COMPILE_CXX_MSVC " -TP") __windows_compiler_clang(CXX) -if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_CXX) - set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE) - endif() -elseif("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_CXX) - # dependencies are computed by the compiler itself - set(CMAKE_CXX_DEPFILE_FORMAT gcc) - set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE) - endif() +if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" + AND CMAKE_DEPFILE_FLAGS_CXX) + # dependencies are computed by the compiler itself + set(CMAKE_CXX_DEPFILE_FORMAT gcc) + set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE) endif()
diff --git a/Modules/Platform/Windows-Clang-HIP.cmake b/Modules/Platform/Windows-Clang-HIP.cmake index 75b38e2..bb80e59 100644 --- a/Modules/Platform/Windows-Clang-HIP.cmake +++ b/Modules/Platform/Windows-Clang-HIP.cmake
@@ -2,18 +2,10 @@ set(_COMPILE_HIP_MSVC " -x hip") __windows_compiler_clang(HIP) -if("x${CMAKE_HIP_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_HIP) - set(CMAKE_HIP_DEPENDS_USE_COMPILER TRUE) - endif() -elseif("x${CMAKE_HIP_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_HIP) - # dependencies are computed by the compiler itself - set(CMAKE_HIP_DEPFILE_FORMAT gcc) - set(CMAKE_HIP_DEPENDS_USE_COMPILER TRUE) - endif() +if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" + AND CMAKE_DEPFILE_FLAGS_HIP) + # dependencies are computed by the compiler itself + set(CMAKE_HIP_DEPFILE_FORMAT gcc) + set(CMAKE_HIP_DEPENDS_USE_COMPILER TRUE) endif()
diff --git a/Modules/Platform/Windows-Clang-OBJC.cmake b/Modules/Platform/Windows-Clang-OBJC.cmake index 7babb98..7e9a164 100644 --- a/Modules/Platform/Windows-Clang-OBJC.cmake +++ b/Modules/Platform/Windows-Clang-OBJC.cmake
@@ -1,18 +1,10 @@ include(Platform/Windows-Clang) __windows_compiler_clang(OBJC) -if("x${CMAKE_OBJC_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_OBJC) - set(CMAKE_OBJC_DEPENDS_USE_COMPILER TRUE) - endif() -elseif("x${CMAKE_OBJC_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_OBJC) - # dependencies are computed by the compiler itself - set(CMAKE_OBJC_DEPFILE_FORMAT gcc) - set(CMAKE_OBJC_DEPENDS_USE_COMPILER TRUE) - endif() +if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" + AND CMAKE_DEPFILE_FLAGS_OBJC) + # dependencies are computed by the compiler itself + set(CMAKE_OBJC_DEPFILE_FORMAT gcc) + set(CMAKE_OBJC_DEPENDS_USE_COMPILER TRUE) endif()
diff --git a/Modules/Platform/Windows-Clang-OBJCXX.cmake b/Modules/Platform/Windows-Clang-OBJCXX.cmake index 3bc1673..55b9070 100644 --- a/Modules/Platform/Windows-Clang-OBJCXX.cmake +++ b/Modules/Platform/Windows-Clang-OBJCXX.cmake
@@ -1,18 +1,10 @@ include(Platform/Windows-Clang) __windows_compiler_clang(OBJCXX) -if("x${CMAKE_OBJCXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_OBJCXX) - set(CMAKE_OBJCXX_DEPENDS_USE_COMPILER TRUE) - endif() -elseif("x${CMAKE_OBJCXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") - if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" - AND CMAKE_DEPFILE_FLAGS_OBJCXX) - # dependencies are computed by the compiler itself - set(CMAKE_OBJCXX_DEPFILE_FORMAT gcc) - set(CMAKE_OBJCXX_DEPENDS_USE_COMPILER TRUE) - endif() +if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" + AND CMAKE_DEPFILE_FLAGS_OBJCXX) + # dependencies are computed by the compiler itself + set(CMAKE_OBJCXX_DEPFILE_FORMAT gcc) + set(CMAKE_OBJCXX_DEPENDS_USE_COMPILER TRUE) endif()
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index 82e9d82..0c002dd 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake
@@ -233,6 +233,11 @@ macro(__windows_compiler_clang_base lang) set(_COMPILE_${lang} "${_COMPILE_${lang}_MSVC}") __windows_compiler_msvc(${lang}) + + # Prefer clang-cl's gcc-style depfile over cl-style /showIncludes + set(CMAKE_DEPFILE_FLAGS_${lang} "-clang:-MD -clang:-MT<DEP_TARGET> -clang:-MF<DEP_FILE>") + unset(CMAKE_${lang}_DEPFILE_FORMAT) + unset(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue) # -ZI not supported by Clang set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-WX") set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-imsvc")
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ef4985a..ff49eef 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt
@@ -401,7 +401,6 @@ cmRulePlaceholderExpander.cxx cmRulePlaceholderExpander.h cmLocalUnixMakefileGenerator3.cxx - cmLocale.h cmMakefile.cxx cmMakefile.h cmMakefileTargetGenerator.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 7e9b346..0a5745b 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 4) set(CMake_VERSION_MINOR 2) -set(CMake_VERSION_PATCH 20260210) +set(CMake_VERSION_PATCH 20260216) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 8b955aa..e440b84 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -27,6 +27,7 @@ #include "cmWIXDirectoriesSourceWriter.h" #include "cmWIXFeaturesSourceWriter.h" #include "cmWIXFilesSourceWriter.h" +#include "cmWIXInstallScope.h" #include "cmWIXRichTextFormatWriter.h" #include "cmWIXSourceWriter.h" @@ -545,9 +546,20 @@ this->WixSources.push_back(directoryDefinitionsFilename); + cmWIXInstallScope installScope = GetInstallScope(); + + std::string componentKeysRegistryPath = + GetOption("CPACK_WIX_COMPONENT_KEYS_REGISTRY_PATH"); + if (componentKeysRegistryPath.empty()) { + componentKeysRegistryPath = + cmStrCat("Software\\", GetOption("CPACK_PACKAGE_VENDOR"), "\\", + GetOption("CPACK_PACKAGE_NAME"), "\\Components"); + } + cmSystemTools::ReplaceString(componentKeysRegistryPath, "/", "\\"); + cmWIXDirectoriesSourceWriter directoryDefinitions( this->WixVersion, this->Logger, directoryDefinitionsFilename, - this->ComponentGuidType); + this->ComponentGuidType, installScope, componentKeysRegistryPath); InjectXmlNamespaces(directoryDefinitions); directoryDefinitions.BeginElement("Fragment"); @@ -565,15 +577,18 @@ auto installationPrefixDirectory = directoryDefinitions.BeginInstallationPrefixDirectory(GetRootFolderId(), installRoot); + cm::optional<std::string> removeFolderComponentId = + directoryDefinitions.EmitRemoveFolderComponentOnUserInstall( + "INSTALL_ROOT"); std::string fileDefinitionsFilename = cmStrCat(this->CPackTopLevel, "/files.wxs"); this->WixSources.push_back(fileDefinitionsFilename); - cmWIXFilesSourceWriter fileDefinitions(this->WixVersion, this->Logger, - fileDefinitionsFilename, - this->ComponentGuidType); + cmWIXFilesSourceWriter fileDefinitions( + this->WixVersion, this->Logger, fileDefinitionsFilename, + this->ComponentGuidType, installScope, componentKeysRegistryPath); InjectXmlNamespaces(fileDefinitions); fileDefinitions.BeginElement("Fragment"); @@ -622,6 +637,10 @@ *package, GetOption("CPACK_WIX_UPGRADE_GUID")); } + if (removeFolderComponentId.has_value()) { + featureDefinitions.EmitComponentRef(*removeFolderComponentId); + } + if (!CreateFeatureHierarchy(featureDefinitions)) { return false; } @@ -728,6 +747,8 @@ cmValue rootFolderId = GetOption("CPACK_WIX_ROOT_FOLDER_ID"); if (rootFolderId) { result = *rootFolderId; + } else if (GetInstallScope() == cmWIXInstallScope::PER_USER) { + result = "LocalAppDataFolder"; } else if (this->WixVersion >= 4) { result = "ProgramFiles6432Folder"; } else { @@ -1083,6 +1104,13 @@ directoryDefinitions.AddAttribute("Name", fileName); this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions); + cm::optional<std::string> removeFolderComponentId = + directoryDefinitions.EmitRemoveFolderComponentOnUserInstall( + subDirectoryId); + if (removeFolderComponentId.has_value()) { + featureDefinitions.EmitComponentRef(*removeFolderComponentId); + } + AddDirectoryAndFileDefinitions(fullPath, subDirectoryId, directoryDefinitions, fileDefinitions, featureDefinitions, packageExecutables, @@ -1374,3 +1402,24 @@ ns.second); } } + +cmWIXInstallScope cmCPackWIXGenerator::GetInstallScope() const +{ + cmValue value = this->GetOption("CPACK_WIX_INSTALL_SCOPE"); + + if (value == "perUser"_s) { + return cmWIXInstallScope::PER_USER; + } + if (value == "perMachine"_s) { + return cmWIXInstallScope::PER_MACHINE; + } + if (value == "NONE"_s) { + return cmWIXInstallScope::NONE; + } + + cmCPackLogger( + cmCPackLog::LOG_ERROR, + "Invalid CPACK_WIX_INSTALL_SCOPE value, defaulting to perMachine: " + << (value ? *value : "") << std::endl); + return cmWIXInstallScope::PER_MACHINE; +}
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h index bfad0d4..0d59eeb 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.h +++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -7,6 +7,7 @@ #include <string> #include "cmCPackGenerator.h" +#include "cmWIXInstallScope.h" #include "cmWIXPatch.h" #include "cmWIXShortcut.h" @@ -159,6 +160,8 @@ void InjectXmlNamespaces(cmWIXSourceWriter& sourceWriter); + cmWIXInstallScope GetInstallScope() const; + std::vector<std::string> WixSources; id_map_t PathToIdMap; ambiguity_map_t IdAmbiguityCounter;
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx index b6e3cd2..4cee0f1 100644 --- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
@@ -6,9 +6,24 @@ cmWIXDirectoriesSourceWriter::cmWIXDirectoriesSourceWriter( unsigned long wixVersion, cmCPackLog* logger, std::string const& filename, - GuidType componentGuidType) + GuidType componentGuidType, cmWIXInstallScope installScope, + std::string componentKeysRegistryPath) : cmWIXSourceWriter(wixVersion, logger, filename, componentGuidType) + , ComponentKeysRegistryPath(std::move(componentKeysRegistryPath)) { + switch (installScope) { + case cmWIXInstallScope::PER_USER: + this->PerUserInstall = true; + break; + case cmWIXInstallScope::PER_MACHINE: + case cmWIXInstallScope::NONE: + this->PerUserInstall = false; + break; + default: + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Unhandled install scope value, this is a CPack Bug."); + break; + } } void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder( @@ -47,6 +62,43 @@ EndElement_StandardDirectory(); } +cm::optional<std::string> +cmWIXDirectoriesSourceWriter::EmitRemoveFolderComponentOnUserInstall( + std::string const& directoryId) +{ + if (!this->PerUserInstall) { + return {}; + } + + BeginElement("Component"); + + std::string componentId = directoryId + "_RemoveFolderComponent"; + AddAttribute("Id", componentId); + AddAttribute("Guid", CreateGuidFromComponentId(componentId)); + + BeginElement("RemoveFolder"); + AddAttribute("Id", directoryId + "_RemoveFolder"); + AddAttribute("Directory", directoryId); + AddAttribute("On", "uninstall"); + EndElement("RemoveFolder"); + + // Need a keyPath for the component + BeginElement("RegistryValue"); + + AddAttribute("Root", "HKCU"); + AddAttribute("Key", this->ComponentKeysRegistryPath); + AddAttribute("Name", componentId); + AddAttribute("Type", "string"); + AddAttribute("Value", "1"); + AddAttribute("KeyPath", "yes"); + + EndElement("RegistryValue"); + + EndElement("Component"); + + return componentId; +} + cmWIXDirectoriesSourceWriter::InstallationPrefixDirectory cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory( std::string const& programFilesFolderId,
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h index 5aa194d..8ec5810 100644 --- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h +++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
@@ -4,7 +4,10 @@ #include <string> +#include <cm/optional> + #include "cmCPackGenerator.h" +#include "cmWIXInstallScope.h" #include "cmWIXSourceWriter.h" /** \class cmWIXDirectoriesSourceWriter @@ -15,7 +18,9 @@ public: cmWIXDirectoriesSourceWriter(unsigned long wixVersion, cmCPackLog* logger, std::string const& filename, - GuidType componentGuidType); + GuidType componentGuidType, + cmWIXInstallScope installScope, + std::string componentKeysRegistryPath); void EmitStartMenuFolder(std::string const& startMenuFolder); @@ -23,6 +28,9 @@ void EmitStartupFolder(); + cm::optional<std::string> EmitRemoveFolderComponentOnUserInstall( + std::string const& directoryId); + struct InstallationPrefixDirectory { bool HasStandardDirectory = false; @@ -35,4 +43,8 @@ void EndInstallationPrefixDirectory( InstallationPrefixDirectory installationPrefixDirectory); + +private: + bool PerUserInstall = false; + std::string ComponentKeysRegistryPath; };
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx index 550e029..9581d9f 100644 --- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -19,12 +19,26 @@ # include "cmsys/Encoding.hxx" #endif -cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(unsigned long wixVersion, - cmCPackLog* logger, - std::string const& filename, - GuidType componentGuidType) +cmWIXFilesSourceWriter::cmWIXFilesSourceWriter( + unsigned long wixVersion, cmCPackLog* logger, std::string const& filename, + GuidType componentGuidType, cmWIXInstallScope installScope, + std::string componentKeysRegistryPath) : cmWIXSourceWriter(wixVersion, logger, filename, componentGuidType) + , ComponentKeysRegistryPath(std::move(componentKeysRegistryPath)) { + switch (installScope) { + case cmWIXInstallScope::PER_USER: + this->PerUserInstall = true; + break; + case cmWIXInstallScope::PER_MACHINE: + case cmWIXInstallScope::NONE: + this->PerUserInstall = false; + break; + default: + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Unhandled install scope value, this is a CPack Bug."); + break; + } } void cmWIXFilesSourceWriter::EmitShortcut(std::string const& id, @@ -127,7 +141,11 @@ std::string componentId = std::string("CM_C") + id; std::string fileId = std::string("CM_F") + id; - std::string guid = CreateGuidFromComponentId(componentId); + // Wix doesn't support automatic GUIDs for components which have both + // registry entries and files. + std::string guid = this->PerUserInstall + ? CreateCmakeGeneratedGuidFromComponentId(componentId) + : CreateGuidFromComponentId(componentId); BeginElement("DirectoryRef"); AddAttribute("Id", directoryId); @@ -150,6 +168,22 @@ } patch.ApplyFragment(componentId, *this); + + if (this->PerUserInstall) { + // For perUser installs, MSI requires using a registry entry as the key + // path for components. + BeginElement("RegistryValue"); + + AddAttribute("Root", "HKCU"); + AddAttribute("Key", this->ComponentKeysRegistryPath); + AddAttribute("Name", fileId); + AddAttribute("Type", "string"); + AddAttribute("Value", "1"); + AddAttribute("KeyPath", "yes"); + + EndElement("RegistryValue"); + } + BeginElement("File"); AddAttribute("Id", fileId); @@ -164,7 +198,9 @@ #endif AddAttribute("Source", sourcePath); - AddAttribute("KeyPath", "yes"); + if (!this->PerUserInstall) { + AddAttribute("KeyPath", "yes"); + } mode_t fileMode = 0; cmSystemTools::GetPermissions(filePath.c_str(), fileMode);
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.h b/Source/CPack/WiX/cmWIXFilesSourceWriter.h index fff7c4f..1d55067 100644 --- a/Source/CPack/WiX/cmWIXFilesSourceWriter.h +++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
@@ -2,7 +2,10 @@ file LICENSE.rst or https://cmake.org/licensing for details. */ #pragma once +#include <string> + #include "cmCPackGenerator.h" +#include "cmWIXInstallScope.h" #include "cmWIXPatch.h" #include "cmWIXShortcut.h" #include "cmWIXSourceWriter.h" @@ -15,7 +18,9 @@ public: cmWIXFilesSourceWriter(unsigned long wixVersion, cmCPackLog* logger, std::string const& filename, - GuidType componentGuidType); + GuidType componentGuidType, + cmWIXInstallScope installScope, + std::string componentKeysRegistryPath); void EmitShortcut(std::string const& id, cmWIXShortcut const& shortcut, std::string const& shortcutPrefix, size_t shortcutIndex); @@ -37,4 +42,8 @@ std::string const& filePath, cmWIXPatch& patch, cmInstalledFile const* installedFile, int diskId); + +private: + bool PerUserInstall = false; + std::string ComponentKeysRegistryPath; };
diff --git a/Source/CPack/WiX/cmWIXInstallScope.h b/Source/CPack/WiX/cmWIXInstallScope.h new file mode 100644 index 0000000..6b69457 --- /dev/null +++ b/Source/CPack/WiX/cmWIXInstallScope.h
@@ -0,0 +1,10 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file LICENSE.rst or https://cmake.org/licensing for details. */ +#pragma once + +enum class cmWIXInstallScope +{ + NONE, + PER_MACHINE, + PER_USER +};
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx index ed3cbe0..f2cb8b4 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -159,15 +159,21 @@ { std::string guid = "*"; if (this->ComponentGuidType == CMAKE_GENERATED_GUID) { - cmCryptoHash hasher(cmCryptoHash::AlgoMD5); - std::string md5 = hasher.HashString(componentId); - cmUuid uuid; - std::vector<unsigned char> ns; - guid = uuid.FromMd5(ns, md5); + guid = CreateCmakeGeneratedGuidFromComponentId(componentId); } return guid; } +std::string cmWIXSourceWriter::CreateCmakeGeneratedGuidFromComponentId( + std::string const& componentId) +{ + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); + std::string md5 = hasher.HashString(componentId); + cmUuid uuid; + std::vector<unsigned char> ns; + return uuid.FromMd5(ns, md5); +} + void cmWIXSourceWriter::WriteXMLDeclaration() { File << R"(<?xml version="1.0" encoding="UTF-8"?>)" << std::endl;
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h index 5e1150d..8243275 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.h +++ b/Source/CPack/WiX/cmWIXSourceWriter.h
@@ -5,6 +5,8 @@ #include <string> #include <vector> +#include <cm/optional> + #include "cmsys/FStream.hxx" #include "cmCPackLog.h" @@ -52,6 +54,12 @@ std::string CreateGuidFromComponentId(std::string const& componentId); + // In most cases CreateGuidFromComponentId should be used instead, since it + // takes ComponentGuidType into consideration. This function always generates + // an explicit GUID. + static std::string CreateCmakeGeneratedGuidFromComponentId( + std::string const& componentId); + static std::string EscapeAttributeValue(std::string const& value); protected:
diff --git a/Source/CPack/cmCPackAppImageGenerator.cxx b/Source/CPack/cmCPackAppImageGenerator.cxx index c6d4d8a..03dffab 100644 --- a/Source/CPack/cmCPackAppImageGenerator.cxx +++ b/Source/CPack/cmCPackAppImageGenerator.cxx
@@ -4,7 +4,6 @@ #include "cmCPackAppImageGenerator.h" #include <algorithm> -#include <cctype> #include <cstddef> #include <utility> #include <vector> @@ -14,6 +13,7 @@ #include <sys/types.h> #include "cmsys/FStream.hxx" +#include "cmsys/String.h" #include "cmCPackLog.h" #include "cmELF.h" @@ -340,11 +340,9 @@ // Trim leading and trailing whitespace from a string std::string trim(std::string const& str) { - auto start = std::find_if_not( - str.begin(), str.end(), [](unsigned char c) { return std::isspace(c); }); - auto end = std::find_if_not(str.rbegin(), str.rend(), [](unsigned char c) { - return std::isspace(c); - }).base(); + auto start = std::find_if_not(str.begin(), str.end(), cmsysString_isspace); + auto end = + std::find_if_not(str.rbegin(), str.rend(), cmsysString_isspace).base(); return (start < end) ? std::string(start, end) : std::string(); } } // namespace
diff --git a/Source/CPack/cmCPackInnoSetupGenerator.cxx b/Source/CPack/cmCPackInnoSetupGenerator.cxx index 9522e86..4b8533b 100644 --- a/Source/CPack/cmCPackInnoSetupGenerator.cxx +++ b/Source/CPack/cmCPackInnoSetupGenerator.cxx
@@ -4,12 +4,12 @@ #include "cmCPackInnoSetupGenerator.h" #include <algorithm> -#include <cctype> #include <cstdlib> #include <ostream> #include <utility> #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #include "cmCPackComponentGroup.h" #include "cmCPackLog.h" @@ -116,7 +116,7 @@ if (cmSystemTools::LowerCase(i) == "english") { params["MessagesFile"] = "\"compiler:Default.isl\""; } else { - i[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(i[0]))); + i[0] = static_cast<char>(cmsysString_toupper(i[0])); params["MessagesFile"] = cmStrCat("\"compiler:Languages\\", i, ".isl\""); }
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index 19cbee1..2bc60c2 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -3,12 +3,13 @@ #include "cmCPackRPMGenerator.h" #include <algorithm> -#include <cctype> #include <map> #include <ostream> #include <utility> #include <vector> +#include "cmsys/String.h" + #include "cmCPackComponentGroup.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" @@ -143,7 +144,7 @@ ++compIt) { std::string component(compIt->first); std::transform(component.begin(), component.end(), component.begin(), - [](unsigned char c) { return std::toupper(c); }); + cmsysString_toupper); if (this->IsOn("CPACK_RPM_" + compIt->first + "_DEBUGINFO_PACKAGE") || this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) { @@ -157,7 +158,7 @@ compGIt != this->ComponentGroups.end(); ++compGIt) { std::string component(compGIt->first); std::transform(component.begin(), component.end(), component.begin(), - [](unsigned char c) { return std::toupper(c); }); + cmsysString_toupper); if (this->IsOn("CPACK_RPM_" + compGIt->first + "_DEBUGINFO_PACKAGE") || this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) { @@ -174,8 +175,7 @@ if (!compIt->second.Group) { std::string component(compIt->first); std::transform(component.begin(), component.end(), - component.begin(), - [](unsigned char c) { return std::toupper(c); }); + component.begin(), cmsysString_toupper); if (this->IsOn("CPACK_RPM_" + compIt->first + "_DEBUGINFO_PACKAGE") || @@ -207,8 +207,7 @@ std::string mainComponentUpper(mainComponent); std::transform(mainComponentUpper.begin(), mainComponentUpper.end(), - mainComponentUpper.begin(), - [](unsigned char c) { return std::toupper(c); }); + mainComponentUpper.begin(), cmsysString_toupper); // The default behavior is to have one package by component group // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. @@ -220,7 +219,7 @@ compGIt != this->ComponentGroups.end(); ++compGIt) { std::string component(compGIt->first); std::transform(component.begin(), component.end(), component.begin(), - [](unsigned char c) { return std::toupper(c); }); + cmsysString_toupper); if (mainComponentUpper == component) { // main component will be handled last @@ -242,7 +241,7 @@ if (!compIt->second.Group) { std::string component(compIt->first); std::transform(component.begin(), component.end(), component.begin(), - [](unsigned char c) { return std::toupper(c); }); + cmsysString_toupper); if (mainComponentUpper == component) { // main component will be handled last @@ -285,7 +284,7 @@ ++compIt) { std::string component(compIt->first); std::transform(component.begin(), component.end(), component.begin(), - [](unsigned char c) { return std::toupper(c); }); + cmsysString_toupper); if (mainComponentUpper == component) { // main component will be handled last
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 52adedd..fdb0bb7 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx
@@ -11,6 +11,7 @@ #include <cmext/algorithm> #include "cmsys/FStream.hxx" +#include "cmsys/String.h" #include "cmCTest.h" #include "cmCTestVC.h" @@ -412,14 +413,14 @@ char const* ConsumeSpace(char const* c) { - while (*c && cmIsSpace(*c)) { + while (*c && cmsysString_isspace(*c)) { ++c; } return c; } char const* ConsumeField(char const* c) { - while (*c && !cmIsSpace(*c)) { + while (*c && !cmsysString_isspace(*c)) { ++c; } return c; @@ -479,7 +480,7 @@ { // Person Name <person@domain.com> 1234567890 +0000 char const* c = str; - while (*c && cmIsSpace(*c)) { + while (*c && cmsysString_isspace(*c)) { ++c; } @@ -488,7 +489,7 @@ ++c; } char const* name_last = c; - while (name_last != name_first && cmIsSpace(*(name_last - 1))) { + while (name_last != name_first && cmsysString_isspace(*(name_last - 1))) { --name_last; } person.Name.assign(name_first, name_last - name_first);
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index de8651c..40db404 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx
@@ -365,6 +365,9 @@ if (!skipped) { this->TestResult.CompletionStatus = "Completed"; } + this->TestResult.StartTestTime = + std::chrono::duration_cast<std::chrono::milliseconds>( + this->TestProcess->GetSystemStartTime().time_since_epoch()); this->TestResult.ExecutionTime = this->TestProcess->GetTotalTime(); this->MemCheckPostProcess(); this->ComputeWeightedCost();
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index d8b90e3..5f442cb 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1525,6 +1525,7 @@ xml.Element("Path", this->CTest->GetShortPathToFile(result.Path)); xml.Element("FullName", this->CTest->GetShortPathToFile(testPath)); xml.Element("FullCommandLine", result.FullCommandLine); + xml.Element("StartTestTime", result.StartTestTime); } void cmCTestTestHandler::WriteTestResultFooter(cmXMLWriter& xml,
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index e57bc10..f2c8e79 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h
@@ -194,6 +194,7 @@ std::string TestMeasurementsOutput; std::string InstrumentationFile; int TestCount = 0; + std::chrono::milliseconds StartTestTime; cmCTestTestProperties* Properties = nullptr; };
diff --git a/Source/CursesDialog/cmCursesColor.cxx b/Source/CursesDialog/cmCursesColor.cxx index c9add4f..a9e5ff6 100644 --- a/Source/CursesDialog/cmCursesColor.cxx +++ b/Source/CursesDialog/cmCursesColor.cxx
@@ -2,12 +2,13 @@ file LICENSE.rst or https://cmake.org/licensing for details. */ #include "cmCursesColor.h" -#include <cctype> #include <cstdlib> #include <cstring> #include <unordered_map> #include <utility> +#include "cmsys/String.h" + #include "cmCursesStandardIncludes.h" bool cmCursesColor::HasColors() @@ -42,7 +43,7 @@ if (!initialized) { if (auto* v = getenv("CCMAKE_COLORS")) { while (v[0] && v[1] && v[1] == '=') { - auto const n = std::toupper(static_cast<unsigned char>(*v)); + char const n = cmsysString_toupper(*v); char buffer[12]; memset(buffer, 0, sizeof(buffer));
diff --git a/Source/QtDialog/RegexExplorer.cxx b/Source/QtDialog/RegexExplorer.cxx index 9065f66..b0333cf 100644 --- a/Source/QtDialog/RegexExplorer.cxx +++ b/Source/QtDialog/RegexExplorer.cxx
@@ -2,6 +2,8 @@ file LICENSE.rst or https://cmake.org/licensing for details. */ #include "RegexExplorer.h" +#include "cmsys/String.h" + RegexExplorer::RegexExplorer(QWidget* p) : QDialog(p) , m_matched(false) @@ -147,7 +149,7 @@ } else if (nextc == 'n') { result.append(1, '\n'); in++; - } else if (isalnum(nextc) || nextc == '\0') { + } else if (cmsysString_isalnum(nextc) || nextc == '\0') { return false; } else { result.append(1, nextc);
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index bbcb0bc..59680aa 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx
@@ -72,6 +72,7 @@ # include <windows.h> # include "cmsys/Encoding.hxx" +# include "cmsys/String.h" #endif #include "cmsys/FStream.hxx" @@ -261,7 +262,7 @@ } // clear out any leading spaces - while (isspace(symbol[0])) + while (cmsysString_isspace(symbol[0])) symbol.erase(0, 1); // if it starts with _ and has an @ then it is a __cdecl // so remove the @ stuff for the export
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index ab7e624..0adcefd 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx
@@ -24,7 +24,6 @@ #include "cm_parse_date.h" -#include "cmLocale.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -449,9 +448,6 @@ } char const* out = file + skip; - cmLocaleRAII localeRAII; - static_cast<void>(localeRAII); - // Meta-data. std::string dest = cmStrCat(prefix ? prefix : "", out); if (this->Verbose) {
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index 9674c52..55e93ee 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -4,7 +4,6 @@ #include <algorithm> #include <cassert> -#include <cctype> #include <cstddef> #include <initializer_list> #include <map> @@ -16,8 +15,13 @@ #include <cm/type_traits> #include <cmext/string_view> +#if !defined(_WIN32) +# include <langinfo.h> +#endif + #include "cmsys/FStream.hxx" #include "cmsys/Glob.hxx" +#include "cmsys/String.h" #include "cmsys/SystemInformation.hxx" #include "cmArgumentParser.h" @@ -74,6 +78,22 @@ if (key == "FQDN"_s) { return ValueToString(info.GetFullyQualifiedDomainName()); } + if (key == "LOCALE_CHARSET"_s) { +#if defined(_WIN32) + // On Windows we always use UTF-8. + return ValueToString("UTF-8"); +#else + // On non-Windows platforms we use the locale's encoding. + if (char const* charset = nl_langinfo(CODESET)) { + if (cmsysString_strcasecmp(charset, "utf-8") == 0 || + cmsysString_strcasecmp(charset, "utf8") == 0) { + charset = "UTF-8"; + } + return ValueToString(charset); + } + return ValueToString(""); +#endif + } if (key == "TOTAL_VIRTUAL_MEMORY"_s) { return ValueToString(info.GetTotalVirtualMemory()); } @@ -218,10 +238,10 @@ for (auto ch : line) { switch (state) { case PARSE_KEY_1ST: - if (std::isalpha(ch) || ch == '_') { + if (cmsysString_isalpha(ch) || ch == '_') { key += ch; state = PARSE_KEY; - } else if (!cmIsSpace(ch)) { + } else if (!cmsysString_isspace(ch)) { state = IGNORE_REST; } break; @@ -229,7 +249,7 @@ case PARSE_KEY: if (ch == '=') { state = FOUND_EQ; - } else if (std::isalnum(ch) || ch == '_') { + } else if (cmsysString_isalnum(ch) || ch == '_') { key += ch; } else { state = IGNORE_REST; @@ -281,7 +301,7 @@ break; case PARSE_VALUE: - if (ch == '#' || cmIsSpace(ch)) { + if (ch == '#' || cmsysString_isspace(ch)) { state = IGNORE_REST; } else { value += ch; @@ -355,8 +375,8 @@ auto const& filename = cmSystemTools::GetFilenameName(filepath); // NOTE Minimum filename length expected: // NNN-<at-least-one-char-name>.cmake --> 11 - return (filename.size() < 11) || !std::isdigit(filename[0]) || - !std::isdigit(filename[1]) || !std::isdigit(filename[2]) || + return (filename.size() < 11) || !cmsysString_isdigit(filename[0]) || + !cmsysString_isdigit(filename[1]) || !cmsysString_isdigit(filename[2]) || filename[3] != '-'; }; scripts.erase(std::remove_if(scripts.begin(), scripts.end(), checkName),
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index f503e93..ed1516f 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx
@@ -3,7 +3,6 @@ #include "cmCTest.h" #include <algorithm> -#include <cctype> #include <chrono> #include <cstdint> #include <cstdio> @@ -34,6 +33,7 @@ #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #include "cmsys/SystemInformation.hxx" #ifndef _WIN32 # include <unistd.h> // IWYU pragma: keep @@ -299,7 +299,8 @@ { std::string out; for (char const* c = in.c_str(); *c; ++c) { - if (*c == '%' && isxdigit(*(c + 1)) && isxdigit(*(c + 2))) { + if (*c == '%' && cmsysString_isxdigit(*(c + 1)) && + cmsysString_isxdigit(*(c + 2))) { char buf[3] = { *(c + 1), *(c + 2), 0 }; out.append(1, static_cast<char>(strtoul(buf, nullptr, 16))); c += 2; @@ -3702,8 +3703,7 @@ bool generating_test_xml = root["role"] == "test"; if (!generating_test_xml) { std::string element_name = root["role"].asString(); - element_name[0] = static_cast<char>( - std::toupper(static_cast<unsigned char>(element_name[0]))); + element_name[0] = static_cast<char>(cmsysString_toupper(element_name[0])); xml.StartElement(element_name); std::vector<std::string> keys = root.getMemberNames(); for (auto const& key : keys) { @@ -3735,8 +3735,8 @@ std::vector<std::string> keys = dynamic_information.getMemberNames(); for (auto const& key : keys) { std::string measurement_name = key; - measurement_name[0] = static_cast<char>( - std::toupper(static_cast<unsigned char>(measurement_name[0]))); + measurement_name[0] = + static_cast<char>(cmsysString_toupper(measurement_name[0])); xml.StartElement("NamedMeasurement"); xml.Attribute("type", "numeric/double");
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h index f11d1fb..4c88f23 100644 --- a/Source/cmCommandLineArgument.h +++ b/Source/cmCommandLineArgument.h
@@ -2,11 +2,11 @@ file LICENSE.rst or https://cmake.org/licensing for details. */ #pragma once -#include <cctype> - #include <cm/optional> #include <cm/string_view> +#include "cmsys/String.h" + #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -288,6 +288,6 @@ static bool IsFlag(cm::string_view arg) { return !arg.empty() && arg[0] == '-' && - !(arg.size() >= 2 && std::isdigit(arg[1])); + !(arg.size() >= 2 && cmsysString_isdigit(arg[1])); } };
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index baa1198..6db6767 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx
@@ -180,35 +180,90 @@ if (cmComputeLinkInformation* cli = this->GeneratorTarget->GetLinkInformation(config)) { - auto addLinkedTarget = - [this, &lang, &config, &dirs, &direct_emitted, &forward_emitted, - gg](cmGeneratorTarget const* linkee, Forwarding forward) { - if (linkee && - !linkee->IsImported() - // Skip targets that build after this one in a static lib cycle. - && gg->TargetOrderIndexLess(linkee, this->GeneratorTarget) - // We can ignore the INTERFACE_LIBRARY items because - // Target->GetLinkInformation already processed their - // link interface and they don't have any output themselves. - && (linkee->GetType() != cmStateEnums::INTERFACE_LIBRARY - // Synthesized targets may have relevant rules. - || linkee->IsSynthetic()) && - ((lang == "CXX"_s && linkee->HaveCxx20ModuleSources()) || - (lang == "Fortran"_s && linkee->HaveFortranSources(config)))) { - cmLocalGenerator* lg = linkee->GetLocalGenerator(); - std::string di = linkee->GetSupportDirectory(); - if (lg->GetGlobalGenerator()->IsMultiConfig()) { - di = cmStrCat(di, '/', config); - } - if (forward == Forwarding::Yes && - forward_emitted.insert(linkee).second) { - dirs.Forward.push_back(di); - } - if (direct_emitted.insert(linkee).second) { - dirs.Direct.emplace_back(di); + + auto findSyntheticTarget = + [this, + &config](cmGeneratorTarget const* linkee) -> cmGeneratorTarget const* { + if (!linkee) { + return nullptr; + } + + // Check the map of direct synthetic dependencies for a substitute + auto const& synthDeps = this->GeneratorTarget->GetSyntheticDeps(config); + auto it = synthDeps.find(linkee); + if (it != synthDeps.end() && !it->second.empty()) { + return it->second.front(); + } + + // Check linked targets to finding synthetic targets for transitive deps + std::vector<cmGeneratorTarget const*> pending; + std::set<cmGeneratorTarget const*> visited; + for (auto const& dep : synthDeps) { + for (auto const* synth : dep.second) { + if (synth && visited.insert(synth).second) { + pending.push_back(synth); } } - }; + } + + while (!pending.empty()) { + auto const* current = pending.back(); + pending.pop_back(); + auto const& transitiveSynthDeps = current->GetSyntheticDeps(config); + auto itLinkeeSynth = transitiveSynthDeps.find(linkee); + if (itLinkeeSynth != transitiveSynthDeps.end() && + !itLinkeeSynth->second.empty()) { + return itLinkeeSynth->second.front(); + } + for (auto const& entry : transitiveSynthDeps) { + for (auto const* synth : entry.second) { + if (synth && visited.insert(synth).second) { + pending.push_back(synth); + } + } + } + } + + return nullptr; + }; + + auto addLinkedTarget = [this, &lang, &config, &dirs, &direct_emitted, + &forward_emitted, &findSyntheticTarget, + gg](cmGeneratorTarget const* linkee, + Forwarding forward) { + // Check if the linkee has a synthetic target to use for importing + cmGeneratorTarget const* mappedLinkee = linkee; + if (auto const* synth = findSyntheticTarget(linkee)) { + mappedLinkee = synth; + } + + if (mappedLinkee && + !mappedLinkee->IsImported() + // Skip targets that build after this one in a static lib cycle. + && gg->TargetOrderIndexLess(mappedLinkee, this->GeneratorTarget) + // We can ignore the INTERFACE_LIBRARY items because + // Target->GetLinkInformation already processed their + // link interface and they don't have any output themselves. + && (mappedLinkee->GetType() != cmStateEnums::INTERFACE_LIBRARY + // Synthesized targets may have relevant rules. + || mappedLinkee->IsSynthetic()) && + ((lang == "CXX"_s && mappedLinkee->HaveCxx20ModuleSources()) || + (lang == "Fortran"_s && + mappedLinkee->HaveFortranSources(config)))) { + cmLocalGenerator* lg = mappedLinkee->GetLocalGenerator(); + std::string di = mappedLinkee->GetSupportDirectory(); + if (lg->GetGlobalGenerator()->IsMultiConfig()) { + di = cmStrCat(di, '/', config); + } + if (forward == Forwarding::Yes && + forward_emitted.insert(mappedLinkee).second) { + dirs.Forward.push_back(di); + } + if (direct_emitted.insert(mappedLinkee).second) { + dirs.Direct.emplace_back(di); + } + } + }; for (auto const& item : cli->GetItems()) { if (item.Target) { addLinkedTarget(item.Target, Forwarding::No);
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 324ff30..5ff8784 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx
@@ -3,7 +3,6 @@ #include "cmComputeLinkInformation.h" #include <algorithm> -#include <cctype> #include <sstream> #include <utility> @@ -13,6 +12,8 @@ #include <cmext/algorithm> #include <cmext/string_view> +#include "cmsys/String.h" + #include "cmComputeLinkDepends.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -1556,8 +1557,8 @@ ret += c; } else { ret += '['; - ret += static_cast<char>(tolower(static_cast<unsigned char>(c))); - ret += static_cast<char>(toupper(static_cast<unsigned char>(c))); + ret += static_cast<char>(cmsysString_tolower(c)); + ret += static_cast<char>(cmsysString_toupper(c)); ret += ']'; } }
diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx index 484ac1f..ab30dc6 100644 --- a/Source/cmCurl.cxx +++ b/Source/cmCurl.cxx
@@ -227,38 +227,6 @@ return e; } -std::string cmCurlFixFileURL(std::string url) -{ - if (!cmHasLiteralPrefix(url, "file://")) { - return url; - } - - // libcurl 7.77 and below accidentally allowed spaces in URLs in some cases. - // One such case was file:// URLs, which CMake has long accepted as a result. - // Explicitly encode spaces for a URL. - cmSystemTools::ReplaceString(url, " ", "%20"); - -#if defined(_WIN32) - // libcurl doesn't support file:// urls for unicode filenames on Windows. - // Convert string from UTF-8 to ACP if this is a file:// URL. - std::wstring wurl = cmsys::Encoding::ToWide(url); - if (!wurl.empty()) { - int mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, nullptr, 0, - nullptr, nullptr); - if (mblen > 0) { - std::vector<char> chars(mblen); - mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, &chars[0], - mblen, nullptr, nullptr); - if (mblen > 0) { - url = &chars[0]; - } - } - } -#endif - - return url; -} - ::CURL* cm_curl_easy_init() { ::CURL* curl = curl_easy_init();
diff --git a/Source/cmCurl.h b/Source/cmCurl.h index 3d60671..321ef5a 100644 --- a/Source/cmCurl.h +++ b/Source/cmCurl.h
@@ -21,7 +21,6 @@ std::string cmCurlSetCAInfo(::CURL* curl, std::string const& cafile = {}); std::string cmCurlSetNETRCOption(::CURL* curl, std::string const& netrc_level, std::string const& netrc_file); -std::string cmCurlFixFileURL(std::string url); ::CURLcode cm_curl_global_init(long flags); ::CURL* cm_curl_easy_init();
diff --git a/Source/cmCxxModuleUsageEffects.cxx b/Source/cmCxxModuleUsageEffects.cxx index aa1a13f..8985a58 100644 --- a/Source/cmCxxModuleUsageEffects.cxx +++ b/Source/cmCxxModuleUsageEffects.cxx
@@ -2,17 +2,28 @@ file LICENSE.rst or https://cmake.org/licensing for details. */ #include "cmCxxModuleUsageEffects.h" -cmCxxModuleUsageEffects::cmCxxModuleUsageEffects( - cmGeneratorTarget const* /*gt*/) - : Hash("0000000000000000000000000000000000000000") +#include <cm/optional> + +#include "cmCryptoHash.h" +#include "cmGeneratorTarget.h" +#include "cmTarget.h" + +cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(cmGeneratorTarget const* gt) { - // TODO: collect information from the generator target as to what might - // affect module consumption. + cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512); + this->Hash = hasher.HashString(gt->GetName()); + + // Collect compile features from the consuming target. + for (auto const& feature : gt->Target->GetCompileFeaturesEntries()) { + this->CompileFeatures.emplace_back(feature); + } } -void cmCxxModuleUsageEffects::ApplyToTarget(cmTarget* /*tgt*/) +void cmCxxModuleUsageEffects::ApplyToTarget(cmTarget* tgt) { - // TODO: apply the information collected in the constructor + for (auto const& feature : this->CompileFeatures) { + tgt->AppendProperty("COMPILE_FEATURES", feature.Value, feature.Backtrace); + } } std::string const& cmCxxModuleUsageEffects::GetHash() const
diff --git a/Source/cmCxxModuleUsageEffects.h b/Source/cmCxxModuleUsageEffects.h index 1c3933c..56a85b9 100644 --- a/Source/cmCxxModuleUsageEffects.h +++ b/Source/cmCxxModuleUsageEffects.h
@@ -5,6 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> +#include <vector> + +#include "cmListFileCache.h" class cmGeneratorTarget; class cmTarget; @@ -19,4 +22,5 @@ private: std::string Hash; + std::vector<BT<std::string>> CompileFeatures; };
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 35cf9e4..66e3730 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx
@@ -3,13 +3,13 @@ #include "cmDocumentation.h" #include <algorithm> -#include <cctype> #include <cstring> #include <utility> #include "cmsys/FStream.hxx" #include "cmsys/Glob.hxx" #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #if !defined(CMAKE_BOOTSTRAP) # include <memory> @@ -516,7 +516,7 @@ std::string line; cmsys::ifstream fin(f.c_str()); while (fin && cmSystemTools::GetLineFromStream(fin, line)) { - if (!line.empty() && (isalnum(line[0]) || line[0] == '<')) { + if (!line.empty() && (cmsysString_isalnum(line[0]) || line[0] == '<')) { names.push_back(line); break; }
diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx index 2a17925..3122722 100644 --- a/Source/cmDyndepCollation.cxx +++ b/Source/cmDyndepCollation.cxx
@@ -108,6 +108,11 @@ if (fs_type != "CXX_MODULES"_s) { continue; } + // Synthetic (BMI-only) targets do not build private C++ modules. + if (tgt->IsSynthetic() && + file_set->GetVisibility() == cmFileSetVisibility::Private) { + continue; + } auto fileEntries = file_set->CompileFileEntries(); auto directoryEntries = file_set->CompileDirectoryEntries();
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 7050f0d..63dcb60 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx
@@ -24,6 +24,8 @@ # include "cm_fileno.hxx" #endif +#include "cmsys/String.h" + #include "cmArgumentParser.h" #include "cmExecutionStatus.h" #include "cmList.h" @@ -40,7 +42,7 @@ namespace { bool cmExecuteProcessCommandIsWhitespace(char c) { - return (cmIsSpace(c) || c == '\n' || c == '\r'); + return (cmsysString_isspace(c) || c == '\n' || c == '\r'); } FILE* FopenCLOEXEC(std::string const& path, char const* mode)
diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx index 60e3aea..3d022d7 100644 --- a/Source/cmExperimental.cxx +++ b/Source/cmExperimental.cxx
@@ -29,24 +29,6 @@ "only for experimentation and feedback to CMake developers.", {}, cmExperimental::TryCompileCondition::Always }, - // ImportPackageInfo - { "ImportPackageInfo", - "e82e467b-f997-4464-8ace-b00808fff261", - "CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES", - "CMake's support for importing package information in the Common Package " - "Specification format (via find_package) is experimental. It is meant " - "only for experimentation and feedback to CMake developers.", - {}, - cmExperimental::TryCompileCondition::Always }, - // ExportPackageInfo - { "ExportPackageInfo", - "7fa7d13b-8308-4dc7-af39-9e450456d68f", - "CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO", - "CMake's support for exporting package information in the Common Package " - "Specification format is experimental. It is meant only for " - "experimentation and feedback to CMake developers.", - {}, - cmExperimental::TryCompileCondition::Always }, // MappedPackageInfo { "MappedPackageInfo", "ababa1b5-7099-495f-a9cd-e22d38f274f2",
diff --git a/Source/cmExperimental.h b/Source/cmExperimental.h index 2b465a0..79dbd5f 100644 --- a/Source/cmExperimental.h +++ b/Source/cmExperimental.h
@@ -18,8 +18,6 @@ enum class Feature { ExportPackageDependencies, - ImportPackageInfo, - ExportPackageInfo, MappedPackageInfo, ExportBuildDatabase, GenerateSbom,
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index 65f1b12..38c2458 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx
@@ -401,12 +401,6 @@ static bool HandlePackageInfoMode(std::vector<std::string> const& args, cmExecutionStatus& status) { - if (!cmExperimental::HasSupportEnabled( - status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo)) { - status.SetError("does not recognize sub-command PACKAGE_INFO"); - return false; - } - using arg_t = cmPackageInfoArguments; using gen_t = cmExportBuildPackageInfoGenerator; return HandleSpecialExportMode<arg_t, gen_t>(args, status);
diff --git a/Source/cmExportPackageInfoGenerator.cxx b/Source/cmExportPackageInfoGenerator.cxx index 20c1978..a30b0b0 100644 --- a/Source/cmExportPackageInfoGenerator.cxx +++ b/Source/cmExportPackageInfoGenerator.cxx
@@ -30,7 +30,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" -static std::string const kCPS_VERSION_STR = "0.14.0"; +static std::string const kCPS_VERSION_STR = "0.14.1"; cmExportPackageInfoGenerator::cmExportPackageInfoGenerator( cmPackageInfoArguments arguments) @@ -386,6 +386,28 @@ return false; } +std::vector<std::string> cmExportPackageInfoGenerator::ExtractRequirements( + std::vector<std::string> const& names, bool& result, + std::vector<std::string>& libraryPaths) const +{ + std::vector<std::string> output; + + for (auto const& name : names) { + auto const& ti = this->LinkTargets.find(name); + if (ti != this->LinkTargets.end()) { + if (ti->second.empty()) { + result = false; + } else { + output.emplace_back(ti->second); + } + } else { + libraryPaths.emplace_back(name); + } + } + + return output; +} + void cmExportPackageInfoGenerator::GenerateInterfaceLinkProperties( bool& result, Json::Value& component, cmGeneratorTarget const* target, ImportPropertyMap const& properties) const @@ -397,43 +419,26 @@ // Extract any $<LINK_ONLY:...> from the link libraries, and assert that no // other generator expressions are present. - std::map<std::string, std::vector<std::string>> allowList = { - { "COMPILE_ONLY", {} }, - { "LINK_ONLY", {} }, - }; + std::map<std::string, std::vector<std::string>> + allowedGeneratorExpressions = { + { "COMPILE_ONLY", {} }, + { "LINK_ONLY", {} }, + }; std::string interfaceLinkLibraries; if (!cmGeneratorExpression::ForbidGeneratorExpressions( target, iter->first, iter->second, interfaceLinkLibraries, - allowList)) { + allowedGeneratorExpressions)) { result = false; return; } - std::vector<std::string> buildRequires; - std::vector<std::string> compileRequires; - std::vector<std::string> linkRequires; std::vector<std::string> linkLibraries; - - auto addLibraries = [this, &linkLibraries, - &result](std::vector<std::string> const& names, - std::vector<std::string>& output) -> void { - for (auto const& name : names) { - auto const& ti = this->LinkTargets.find(name); - if (ti != this->LinkTargets.end()) { - if (ti->second.empty()) { - result = false; - } else { - output.emplace_back(ti->second); - } - } else { - linkLibraries.emplace_back(name); - } - } - }; - - addLibraries(allowList["COMPILE_ONLY"], compileRequires); - addLibraries(allowList["LINK_ONLY"], linkRequires); - addLibraries(cmList{ interfaceLinkLibraries }, buildRequires); + std::vector<std::string> buildRequires = this->ExtractRequirements( + cmList{ interfaceLinkLibraries }, result, linkLibraries); + std::vector<std::string> compileRequires = this->ExtractRequirements( + allowedGeneratorExpressions["COMPILE_ONLY"], result, linkLibraries); + std::vector<std::string> linkRequires = this->ExtractRequirements( + allowedGeneratorExpressions["LINK_ONLY"], result, linkLibraries); BuildArray(component, "requires", buildRequires); BuildArray(component, "link_requires", linkRequires); @@ -560,6 +565,22 @@ component["location"] = p.second; } else if (prop == "IMPLIB") { component["link_location"] = p.second; + } else if (prop == "LINK_DEPENDENT_LIBRARIES") { + bool result; + std::vector<std::string> libraries; + std::vector<std::string> components = + this->ExtractRequirements(cmList{ p.second }, result, libraries); + BuildArray(component, "dyld_requires", components); + if (!libraries.empty()) { + // In theory this can never happen? + this->IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat("Package \""_s, this->GetPackageName(), + "\" has IMPORTED_LINK_DEPENDENT_LIBRARIES \""_s, + cmJoin(libraries, ";"_s), this->PackageVersionSchema, + "\". These cannot be exported. " + "Consumers may encounter link errors."_s)); + } } else if (prop == "LINK_INTERFACE_LANGUAGES") { std::vector<std::string> languages; for (auto const& lang : cmList{ p.second }) {
diff --git a/Source/cmExportPackageInfoGenerator.h b/Source/cmExportPackageInfoGenerator.h index c5d1f75..d7eeba2 100644 --- a/Source/cmExportPackageInfoGenerator.h +++ b/Source/cmExportPackageInfoGenerator.h
@@ -94,6 +94,10 @@ bool CheckVersion() const; bool CheckDefaultTargets() const; + std::vector<std::string> ExtractRequirements( + std::vector<std::string> const& names, bool& result, + std::vector<std::string>& libraryPaths) const; + void GenerateInterfaceLinkProperties( bool& result, Json::Value& component, cmGeneratorTarget const* target, ImportPropertyMap const& properties) const;
diff --git a/Source/cmFastbuildNormalTargetGenerator.cxx b/Source/cmFastbuildNormalTargetGenerator.cxx index cc21591..f9acd33 100644 --- a/Source/cmFastbuildNormalTargetGenerator.cxx +++ b/Source/cmFastbuildNormalTargetGenerator.cxx
@@ -1399,9 +1399,11 @@ cmSourceFile const& srcFile = *source; std::string const pathToFile = srcFile.GetFullPath(); + bool fileUsesUnity = useUnity; if (useUnity) { // Check if the source should be added to "UnityInputIsolatedFiles". if (srcFile.GetPropertyAsBool(SKIP_UNITY_BUILD_INCLUSION)) { + fileUsesUnity = false; isolatedFromUnity.emplace(pathToFile); } std::string const perFileUnityGroup = @@ -1441,11 +1443,17 @@ // If object should be placed in some subdir in the output // path. Tested in "SourceGroups" test. - auto const subdir = cmSystemTools::GetFilenamePath( - this->GeneratorTarget->GetObjectName(source)); - if (!subdir.empty()) { - objOutDirWithPossibleSubdir += "/"; - objOutDirWithPossibleSubdir += subdir; + // Not necessary for files in unity buckets because they are + // built into a single unity object file. Executing this logic + // for unity bucketed files prevents buckets from containing + // source files in different subdirectories. + if (!fileUsesUnity) { + auto const subdir = cmSystemTools::GetFilenamePath( + this->GeneratorTarget->GetObjectName(source)); + if (!subdir.empty()) { + objOutDirWithPossibleSubdir += "/"; + objOutDirWithPossibleSubdir += subdir; + } } std::string const objectListHash = hash.HashString(cmStrCat(
diff --git a/Source/cmFileAPICommand.cxx b/Source/cmFileAPICommand.cxx index dbd8f05..091fbc8 100644 --- a/Source/cmFileAPICommand.cxx +++ b/Source/cmFileAPICommand.cxx
@@ -4,13 +4,14 @@ #include <algorithm> #include <array> -#include <cctype> #include <cstdlib> #include <utility> #include <cm/string_view> #include <cmext/string_view> +#include "cmsys/String.h" + #include "cmArgumentParser.h" #include "cmArgumentParserTypes.h" #include "cmExecutionStatus.h" @@ -23,11 +24,6 @@ namespace { -bool isCharDigit(char ch) -{ - return std::isdigit(static_cast<unsigned char>(ch)); -} - std::string processObjectKindVersions(cmFileAPI& fileApi, cmFileAPI::ObjectKind objectKind, cm::string_view keyword, @@ -103,7 +99,7 @@ } if (!std::all_of(arguments.ApiVersion.begin(), arguments.ApiVersion.end(), - isCharDigit)) { + cmsysString_isdigit)) { status.SetError("QUERY given non-integer API_VERSION."); return false; }
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index f964367..16cd19b 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx
@@ -4,7 +4,6 @@ #include <algorithm> #include <cassert> -#include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> @@ -26,6 +25,7 @@ #include "cmsys/FStream.hxx" #include "cmsys/Glob.hxx" #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #include "cm_sys_stat.h" @@ -519,7 +519,8 @@ } if (c >= 0 && c <= 0xFF && - (isprint(c) || c == '\t' || (c == '\n' && newline_consume))) { + (cmsysString_isprint(static_cast<char>(c)) || c == '\t' || + (c == '\n' && newline_consume))) { // This is an ASCII character that may be part of a string. // Cast added to avoid compiler warning. Cast is ok because // c is guaranteed to fit in char by the above if... @@ -1698,6 +1699,16 @@ // Stuff for curl download/upload using cmFileCommandVectorOfChar = std::vector<char>; +std::string CurlCompatFileURL(std::string url) +{ + if (cmHasLiteralPrefix(url, "file://")) { + // libcurl 7.77 and below accidentally allowed spaces in file:// URLs, + // which CMake has long accepted as a result. Explicitly encode spaces. + cmSystemTools::ReplaceString(url, " ", "%20"); + } + return url; +} + size_t cmWriteToFileCallback(void* ptr, size_t size, size_t nmemb, void* data) { int realsize = static_cast<int>(size * nmemb); @@ -2139,7 +2150,7 @@ } } - url = cmCurlFixFileURL(url); + url = CurlCompatFileURL(url); ::CURL* curl; cm_curl_global_init(CURL_GLOBAL_DEFAULT); @@ -2541,7 +2552,7 @@ unsigned long file_size = cmsys::SystemTools::FileLength(filename); - url = cmCurlFixFileURL(url); + url = CurlCompatFileURL(url); ::CURL* curl; cm_curl_global_init(CURL_GLOBAL_DEFAULT); @@ -3757,7 +3768,7 @@ if (!parsedArgs.CompressionLevel.empty()) { if (parsedArgs.CompressionLevel.size() != 1 && - !std::isdigit(parsedArgs.CompressionLevel[0])) { + !cmsysString_isdigit(parsedArgs.CompressionLevel[0])) { status.SetError( cmStrCat("compression level ", parsedArgs.CompressionLevel, " for ", parsedArgs.Compression, " should be in range ", @@ -3790,7 +3801,7 @@ constexpr int minThreads = 0; if (!parsedArgs.Threads.empty()) { if (parsedArgs.Threads.size() != 1 && - !std::isdigit(parsedArgs.Threads[0])) { + !cmsysString_isdigit(parsedArgs.Threads[0])) { status.SetError(cmStrCat("number of threads ", parsedArgs.Threads, " should be at least ", minThreads)); cmSystemTools::SetFatalErrorOccurred();
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index ad36c4a..57d2a41 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx
@@ -3,7 +3,6 @@ #include "cmFindLibraryCommand.h" #include <algorithm> -#include <cctype> #include <cstdio> #include <cstring> #include <set> @@ -13,6 +12,7 @@ #include <cm/optional> #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #include "cmFindCommon.h" #include "cmGlobalGenerator.h" @@ -349,7 +349,7 @@ out += "\\"; } if (dirCase == cmSystemTools::DirCase::Insensitive) { - out += static_cast<char>(tolower(static_cast<unsigned char>(ch))); + out += static_cast<char>(cmsysString_tolower(ch)); } else { out += ch; }
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index dd8c580..cf6184b 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx
@@ -27,7 +27,6 @@ #include "cmConfigureLog.h" #include "cmDependencyProvider.h" #include "cmExecutionStatus.h" -#include "cmExperimental.h" #include "cmFindPackageStack.h" #include "cmList.h" #include "cmListFileCache.h" @@ -926,9 +925,7 @@ // Check and eliminate search modes not allowed by the args provided this->UseFindModules = configArgs.empty(); this->UseConfigFiles = moduleArgs.empty(); - if (this->UseConfigFiles && - cmExperimental::HasSupportEnabled( - *this->Makefile, cmExperimental::Feature::ImportPackageInfo)) { + if (this->UseConfigFiles) { this->UseCpsFiles = this->Configs.empty(); } else { this->UseCpsFiles = false;
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx index 3136f69..478a93d 100644 --- a/Source/cmGccDepfileLexerHelper.cxx +++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -12,9 +12,8 @@ #include "LexerParser/cmGccDepfileLexer.h" #ifdef _WIN32 -# include <cctype> - # include "cmsys/Encoding.h" +# include "cmsys/String.h" #endif bool cmGccDepfileLexerHelper::readFile(char const* filePath) @@ -128,8 +127,7 @@ // Some versions of GNU compilers can escape this character. // c\:\path must be transformed to c:\path if (pit->size() >= 3) { - auto pit0 = static_cast<char>( - std::toupper(static_cast<unsigned char>((*pit)[0]))); + auto pit0 = static_cast<char>(cmsysString_toupper((*pit)[0])); if (pit0 >= 'A' && pit0 <= 'Z' && (*pit)[1] == '\\' && (*pit)[2] == ':') { pit->erase(1, 1);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index c5f4e35..4799c78 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx
@@ -5,7 +5,6 @@ #include <algorithm> #include <array> #include <cassert> -#include <cctype> #include <cstddef> #include <cstdio> #include <cstring> @@ -20,6 +19,8 @@ #include <cmext/algorithm> #include <cmext/string_view> +#include "cmsys/String.h" + #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" // IWYU pragma: keep #include "cmCryptoHash.h" @@ -3953,8 +3954,7 @@ if (linkerType != "DEFAULT"_s) { auto isCMakeLinkerType = [](std::string const& type) -> bool { - return std::all_of(type.cbegin(), type.cend(), - [](char c) { return std::isupper(c); }); + return std::all_of(type.cbegin(), type.cend(), cmsysString_isupper); }; if (isCMakeLinkerType(linkerType)) { this->LocalGenerator->IssueMessage( @@ -5309,118 +5309,135 @@ return true; } -bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache, - std::string const& config) +bool cmGeneratorTarget::DiscoverSyntheticTargets( + cmSyntheticTargetCache& cache, std::string const& config, + cmGeneratorTarget const* bmiConsumer) { std::vector<std::string> allConfigs = this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); cmOptionalLinkImplementation impl; this->ComputeLinkImplementationLibraries(config, impl, UseTo::Link); - cmCxxModuleUsageEffects usage(this); + if (!bmiConsumer) { + bmiConsumer = this; + } + + cmCxxModuleUsageEffects usage(bmiConsumer); auto& SyntheticDeps = this->Configs[config].SyntheticDeps; for (auto const& entry : impl.Libraries) { auto const* gt = entry.Target; - if (!gt || !gt->IsImported()) { + if (!gt || !gt->HaveCxx20ModuleSources()) { continue; } - if (gt->HaveCxx20ModuleSources()) { - cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512); - constexpr size_t HASH_TRUNCATION = 12; - auto dirhash = hasher.HashString( - gt->GetLocalGenerator()->GetCurrentBinaryDirectory()); - std::string safeName = gt->GetName(); - cmSystemTools::ReplaceString(safeName, ":", "_"); - auto targetIdent = - hasher.HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash())); - std::string targetName = - cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION)); + // Visual Studio generators do not currently support BMI-only compilation, + // so they can't generate synthetic targets. For consuming native modules, + // skip so that the native target is used directly. For imported modules, + // create the synth target anyway and diagnose later, in the VS generator. + if (!gt->IsImported() && this->GlobalGenerator->IsVisualStudio()) { + continue; + } - // Check the cache to see if this instance of the imported target has - // already been created. - auto cached = cache.CxxModuleTargets.find(targetName); - cmGeneratorTarget const* synthDep = nullptr; - if (cached == cache.CxxModuleTargets.end()) { - auto const* model = gt->Target; - auto* mf = gt->Makefile; - auto* lg = gt->GetLocalGenerator(); - auto* tgt = mf->AddSynthesizedTarget(cmStateEnums::INTERFACE_LIBRARY, - targetName); + cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512); + constexpr size_t HASH_TRUNCATION = 12; + auto dirhash = + hasher.HashString(gt->GetLocalGenerator()->GetCurrentBinaryDirectory()); + std::string safeName = gt->GetName(); + cmSystemTools::ReplaceString(safeName, ":", "_"); + auto targetIdent = + hasher.HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash())); + std::string targetName = + cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION)); - // Copy relevant information from the existing IMPORTED target. + // Check the cache to see if this instance of the target has + // already been created. + auto cached = cache.CxxModuleTargets.find(targetName); + cmGeneratorTarget const* synthDep = nullptr; + if (cached == cache.CxxModuleTargets.end()) { + auto const* model = gt->Target; + auto* mf = gt->Makefile; + auto* lg = gt->GetLocalGenerator(); + auto* tgt = + mf->AddSynthesizedTarget(cmStateEnums::INTERFACE_LIBRARY, targetName); - // Copy policies to the target. - tgt->CopyPolicyStatuses(model); + // Copy relevant information from the existing target. - // Copy file sets. - { - auto fsNames = model->GetAllFileSetNames(); - for (auto const& fsName : fsNames) { - auto const* fs = model->GetFileSet(fsName); - if (!fs) { - mf->IssueMessage(MessageType::INTERNAL_ERROR, - cmStrCat("Failed to find file set named '", - fsName, "' on target '", - tgt->GetName(), '\'')); - continue; - } - auto* newFs = tgt - ->GetOrCreateFileSet(fs->GetName(), fs->GetType(), - fs->GetVisibility()) - .first; - newFs->CopyEntries(fs); + // Copy policies to the target. + tgt->CopyPolicyStatuses(model); + + // Copy file sets. + { + auto fsNames = model->GetAllFileSetNames(); + for (auto const& fsName : fsNames) { + auto const* fs = model->GetFileSet(fsName); + if (!fs) { + mf->IssueMessage(MessageType::INTERNAL_ERROR, + cmStrCat("Failed to find file set named '", + fsName, "' on target '", tgt->GetName(), + '\'')); + continue; } + auto* newFs = tgt + ->GetOrCreateFileSet(fs->GetName(), fs->GetType(), + fs->GetVisibility()) + .first; + newFs->CopyEntries(fs); } - - // Copy imported C++ module properties. - tgt->CopyImportedCxxModulesEntries(model); - - // Copy other properties which may affect the C++ module BMI - // generation. - tgt->CopyImportedCxxModulesProperties(model); - - tgt->AddLinkLibrary(*mf, - cmStrCat("$<COMPILE_ONLY:", model->GetName(), '>'), - GENERAL_LibraryType); - - // Apply usage requirements to the target. - usage.ApplyToTarget(tgt); - - // Create the generator target and attach it to the local generator. - auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg); - - synthDep = gtp.get(); - cache.CxxModuleTargets[targetName] = synthDep; - - // See `localGen->ComputeTargetCompileFeatures()` call in - // `cmGlobalGenerator::Compute` for where non-synthetic targets resolve - // this. - for (auto const& innerConfig : allConfigs) { - gtp->ComputeCompileFeatures(innerConfig); - } - // See `cmGlobalGenerator::ApplyCXXStdTargets` in - // `cmGlobalGenerator::Compute` for non-synthetic target resolutions. - if (!gtp->ApplyCXXStdTargets()) { - return false; - } - - gtp->DiscoverSyntheticTargets(cache, config); - - lg->AddGeneratorTarget(std::move(gtp)); - } else { - synthDep = cached->second; } - SyntheticDeps[gt].push_back(synthDep); + // Copy C++ module properties. + tgt->CopyCxxModulesEntries(model); + + // Copy other properties which may affect the C++ module BMI + // generation. + tgt->CopyCxxModulesProperties(model); + + tgt->AddLinkLibrary(*mf, + cmStrCat("$<COMPILE_ONLY:", model->GetName(), '>'), + GENERAL_LibraryType); + + // Apply usage requirements to the target. + usage.ApplyToTarget(tgt); + + // Create the generator target and attach it to the local generator. + auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg); + + synthDep = gtp.get(); + cache.CxxModuleTargets[targetName] = synthDep; + + // See `localGen->ComputeTargetCompileFeatures()` call in + // `cmGlobalGenerator::Compute` for where non-synthetic targets resolve + // this. + for (auto const& innerConfig : allConfigs) { + gtp->ComputeCompileFeatures(innerConfig); + } + // See `cmGlobalGenerator::ApplyCXXStdTargets` in + // `cmGlobalGenerator::Compute` for non-synthetic target resolutions. + if (!gtp->ApplyCXXStdTargets()) { + return false; + } + + gtp->DiscoverSyntheticTargets(cache, config, bmiConsumer); + + lg->AddGeneratorTarget(std::move(gtp)); + } else { + synthDep = cached->second; } + + SyntheticDeps[gt].push_back(synthDep); } return true; } +cmGeneratorTarget::SyntheticDepsMap const& cmGeneratorTarget::GetSyntheticDeps( + std::string const& config) const +{ + return this->Configs[config].SyntheticDeps; +} + bool cmGeneratorTarget::HasPackageReferences() const { return this->IsInBuildSystem() &&
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index a32ecba..8c56a9b 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h
@@ -1118,8 +1118,13 @@ std::string GetImportedXcFrameworkPath(std::string const& config) const; bool ApplyCXXStdTargets(); - bool DiscoverSyntheticTargets(cmSyntheticTargetCache& cache, - std::string const& config); + bool DiscoverSyntheticTargets( + cmSyntheticTargetCache& cache, std::string const& config, + cmGeneratorTarget const* bmiConsumer = nullptr); + + using SyntheticDepsMap = + std::map<cmGeneratorTarget const*, std::vector<cmGeneratorTarget const*>>; + SyntheticDepsMap const& GetSyntheticDeps(std::string const& config) const; class CustomTransitiveProperty : public TransitiveProperty {
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 46bb45e..f603fe2 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -4,7 +4,6 @@ #include <algorithm> #include <cassert> -#include <cctype> #include <cstdio> #include <functional> #include <iterator> @@ -23,6 +22,7 @@ #include <cm3p/json/writer.h> #include "cmsys/FStream.hxx" +#include "cmsys/String.h" #include "cmCustomCommand.h" #include "cmCxxModuleMapper.h" @@ -172,7 +172,7 @@ // "." and all invalid characters as hexadecimal. std::string encoded; for (char i : name) { - if (isalnum(i) || i == '_' || i == '-') { + if (cmsysString_isalnum(i) || i == '_' || i == '-') { encoded += i; } else { char buf[16]; @@ -2587,8 +2587,8 @@ std::string const& module_dir, std::vector<std::string> const& linked_target_dirs, std::vector<std::string> const& forward_modules_from_target_dirs, - std::string const& arg_lang, std::string const& arg_modmapfmt, - cmCxxModuleExportInfo const& export_info) + std::string const& native_target_dir, std::string const& arg_lang, + std::string const& arg_modmapfmt, cmCxxModuleExportInfo const& export_info) { // Setup path conversions. { @@ -2748,6 +2748,47 @@ } } + // If this is a synthetic target for a non-imported target, read PRIVATE + // module info from the native target + if (!native_target_dir.empty()) { + std::string const modules_info_path = + cmStrCat(native_target_dir, '/', arg_lang, "Modules.json"); + Json::Value native_modules_info; + cmsys::ifstream modules_file(modules_info_path.c_str(), + std::ios::in | std::ios::binary); + if (!modules_file) { + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to open ", + modules_info_path, + " for module information")); + return false; + } + Json::Reader reader; + if (!reader.parse(modules_file, native_modules_info, false)) { + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", + modules_info_path, + reader.getFormattedErrorMessages())); + return false; + } + if (native_modules_info.isObject()) { + Json::Value const& native_target_modules = + native_modules_info["modules"]; + if (native_target_modules.isObject()) { + for (auto i = native_target_modules.begin(); + i != native_target_modules.end(); ++i) { + Json::Value const& visible_module = *i; + if (visible_module.isObject()) { + auto is_private = visible_module["is-private"].asBool(); + // Only add private modules since others are discovered by the + // synthetic target's own scan rules + if (is_private) { + target_modules[i.key().asString()] = visible_module; + } + } + } + } + } + } + cmGeneratedFileStream ddf(arg_dd); ddf << "ninja_dyndep_version = 1.0\n"; @@ -3041,6 +3082,7 @@ tdi_forward_modules_from_target_dir.asString()); } } + std::string const native_target_dir = tdi["native-target-dir"].asString(); std::string const compilerId = tdi["compiler-id"].asString(); std::string const simulateId = tdi["compiler-simulate-id"].asString(); std::string const compilerFrontendVariant = @@ -3064,8 +3106,9 @@ # endif return gg.WriteDyndepFile(dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld, arg_dd, arg_ddis, module_dir, linked_target_dirs, - forward_modules_from_target_dirs, arg_lang, - arg_modmapfmt, *export_info) + forward_modules_from_target_dirs, + native_target_dir, arg_lang, arg_modmapfmt, + *export_info) ? 0 : 1; }
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 152c45c..059dea8 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h
@@ -433,7 +433,8 @@ std::string const& module_dir, std::vector<std::string> const& linked_target_dirs, std::vector<std::string> const& forward_modules_from_target_dirs, - std::string const& arg_lang, std::string const& arg_modmapfmt, + std::string const& native_target_dir, std::string const& arg_lang, + std::string const& arg_modmapfmt, cmCxxModuleExportInfo const& export_info); virtual std::string BuildAlias(std::string const& alias,
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 53c9659..baba225 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx
@@ -3,7 +3,6 @@ #include "cmGraphVizWriter.h" #include <algorithm> -#include <cctype> #include <iostream> #include <memory> #include <set> @@ -13,6 +12,7 @@ #include <cm/memory> #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" @@ -602,7 +602,7 @@ auto const extra_chars = std::set<char>{ '.', '-', '_' }; for (char c : str) { - if (std::isalnum(c) || extra_chars.find(c) != extra_chars.cend()) { + if (cmsysString_isalnum(c) || extra_chars.find(c) != extra_chars.cend()) { pathSafeStr += c; } }
diff --git a/Source/cmHexFileConverter.cxx b/Source/cmHexFileConverter.cxx index a028bb4..3036473 100644 --- a/Source/cmHexFileConverter.cxx +++ b/Source/cmHexFileConverter.cxx
@@ -2,10 +2,11 @@ file LICENSE.rst or https://cmake.org/licensing for details. */ #include "cmHexFileConverter.h" -#include <cctype> #include <cstdio> #include <cstring> +#include "cmsys/String.h" + #include "cmSystemTools.h" #define INTEL_HEX_MIN_LINE_LENGTH (1 + 8 + 2) @@ -163,7 +164,7 @@ } for (unsigned int i = 1; i < slen; i++) { - if (!isxdigit(buf[i])) { + if (!cmsysString_isxdigit(buf[i])) { return Binary; } }
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 9ee87b1..1d37546 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx
@@ -2286,8 +2286,6 @@ #ifndef CMAKE_BOOTSTRAP // Check if PACKAGE_INFO export has been requested for this export set. if (cmExperimental::HasSupportEnabled( - status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo) && - cmExperimental::HasSupportEnabled( status.GetMakefile(), cmExperimental::Feature::MappedPackageInfo)) { if (cmValue const& piExports = helper.Makefile->GetDefinition( "CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO")) { @@ -2321,12 +2319,6 @@ cmExecutionStatus& status) { #ifndef CMAKE_BOOTSTRAP - if (!cmExperimental::HasSupportEnabled( - status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo)) { - status.SetError("does not recognize sub-command PACKAGE_INFO"); - return false; - } - Helper helper(status); // This is the PACKAGE_INFO mode.
diff --git a/Source/cmInstrumentationCommand.cxx b/Source/cmInstrumentationCommand.cxx index 182deca..0b0d0f8 100644 --- a/Source/cmInstrumentationCommand.cxx +++ b/Source/cmInstrumentationCommand.cxx
@@ -3,7 +3,6 @@ #include "cmInstrumentationCommand.h" #include <algorithm> -#include <cctype> #include <cstdlib> #include <functional> #include <set> @@ -14,6 +13,8 @@ #include <cm3p/json/reader.h> #include <cm3p/json/value.h> +#include "cmsys/String.h" + #include "cmArgumentParser.h" #include "cmArgumentParserTypes.h" #include "cmExecutionStatus.h" @@ -27,14 +28,11 @@ namespace { -bool isCharDigit(char ch) -{ - return std::isdigit(static_cast<unsigned char>(ch)); -} bool validateVersion(std::string const& key, std::string const& versionString, int& version, cmExecutionStatus& status) { - if (!std::all_of(versionString.begin(), versionString.end(), isCharDigit)) { + if (!std::all_of(versionString.begin(), versionString.end(), + cmsysString_isdigit)) { status.SetError(cmStrCat("given a non-integer ", key, '.')); return false; }
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 5ce0851..4a8c3d2 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx
@@ -5,7 +5,6 @@ #include <algorithm> #include <array> #include <cassert> -#include <cctype> #include <cstdio> #include <cstdlib> #include <initializer_list> @@ -23,6 +22,7 @@ #include <cmext/string_view> #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #include "cmAlgorithms.h" #include "cmCMakePath.h" @@ -2556,7 +2556,8 @@ void cmLocalGenerator::AppendFlags(std::string& flags, std::string const& newFlags) const { - bool allSpaces = std::all_of(newFlags.begin(), newFlags.end(), cmIsSpace); + bool allSpaces = + std::all_of(newFlags.begin(), newFlags.end(), cmsysString_isspace); if (!newFlags.empty() && !allSpaces) { if (!flags.empty()) { @@ -3489,8 +3490,7 @@ } } else if (linkerType != "DEFAULT"_s) { auto isCMakeLinkerType = [](std::string const& type) -> bool { - return std::all_of(type.cbegin(), type.cend(), - [](char c) { return std::isupper(c); }); + return std::all_of(type.cbegin(), type.cend(), cmsysString_isupper); }; if (isCMakeLinkerType(linkerType)) { this->IssueMessage(
diff --git a/Source/cmLocale.h b/Source/cmLocale.h deleted file mode 100644 index b0d1065..0000000 --- a/Source/cmLocale.h +++ /dev/null
@@ -1,26 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file LICENSE.rst or https://cmake.org/licensing for details. */ -#pragma once - -#include "cmConfigure.h" // IWYU pragma: keep - -#include <clocale> -#include <string> - -class cmLocaleRAII -{ -public: - cmLocaleRAII() - : OldLocale(setlocale(LC_CTYPE, nullptr)) - { - setlocale(LC_CTYPE, ""); - } - - ~cmLocaleRAII() { setlocale(LC_CTYPE, this->OldLocale.c_str()); } - - cmLocaleRAII(cmLocaleRAII const&) = delete; - cmLocaleRAII& operator=(cmLocaleRAII const&) = delete; - -private: - std::string OldLocale; -};
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index a78fc1e..6ff3489 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx
@@ -6,7 +6,6 @@ #include <algorithm> #include <cassert> -#include <cctype> #include <cstdio> #include <cstdlib> #include <cstring> @@ -28,6 +27,7 @@ #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" @@ -1299,8 +1299,8 @@ for (std::string::size_type lpos = dflags.find(flag, 0); lpos != std::string::npos; lpos = dflags.find(flag, lpos)) { std::string::size_type rpos = lpos + len; - if ((lpos <= 0 || cmIsSpace(dflags[lpos - 1])) && - (rpos >= dflags.size() || cmIsSpace(dflags[rpos]))) { + if ((lpos <= 0 || cmsysString_isspace(dflags[lpos - 1])) && + (rpos >= dflags.size() || cmsysString_isspace(dflags[rpos]))) { dflags.erase(lpos, len); } else { ++lpos; @@ -2705,7 +2705,7 @@ last = next + 1; } else if (nextc == ';' && openstack.empty()) { // Handled in ExpandListArgument; pass the backslash literally. - } else if (isalnum(nextc) || nextc == '\0') { + } else if (cmsysString_isalnum(nextc) || nextc == '\0') { errorstr += "Invalid character escape '\\"; if (nextc) { errorstr += nextc; @@ -2773,8 +2773,8 @@ CM_FALLTHROUGH; default: { if (!openstack.empty() && - !(isalnum(inc) || inc == '_' || inc == '/' || inc == '.' || - inc == '+' || inc == '-')) { + !(cmsysString_isalnum(inc) || inc == '_' || inc == '/' || + inc == '.' || inc == '+' || inc == '-')) { errorstr += cmStrCat("Invalid character ('", inc); result.append(last, in - last); errorstr += cmStrCat("') in a variable name: '",
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index d833bbb..653466b 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1228,6 +1228,23 @@ this->WriteTargetDependInfo(language, config); + // Non-imported synthetic targets read module info from their native target + // Add as implicit dependency. + if (this->GeneratorTarget->IsSynthetic()) { + if (cmGeneratorTarget const* native_gt = + this->LocalGenerator->FindGeneratorTargetToUse( + this->GeneratorTarget->Target->GetTemplateName())) { + if (!native_gt->IsImported()) { + std::string native_dir = native_gt->GetSupportDirectory(); + if (this->GetGlobalGenerator()->IsMultiConfig()) { + native_dir = cmStrCat(native_dir, '/', config); + } + build.ImplicitDeps.emplace_back(this->ConvertToNinjaPath( + cmStrCat(native_dir, '/', language, "Modules.json"))); + } + } + } + auto const linked_directories = this->GetLinkedTargetDirectories(language, config); for (std::string const& l : linked_directories.Direct) { @@ -2155,6 +2172,22 @@ tdi_forward_modules_from_target_dirs.append(l); } + // Record the native target support directory for non-imported synthetic + // targets + if (this->GeneratorTarget->IsSynthetic()) { + if (cmGeneratorTarget* nativeGT = + this->LocalGenerator->FindGeneratorTargetToUse( + this->GeneratorTarget->Target->GetTemplateName())) { + if (!nativeGT->IsImported()) { + std::string nativeDir = nativeGT->GetSupportDirectory(); + if (this->GetGlobalGenerator()->IsMultiConfig()) { + nativeDir = cmStrCat(nativeDir, '/', config); + } + tdi["native-target-dir"] = nativeDir; + } + } + } + cmDyndepGeneratorCallbacks cb; cb.ObjectFilePath = [this](cmSourceFile const* sf, std::string const& cnf) { return this->GetObjectFilePath(sf, cnf);
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index ddae68c..c72dbe4 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx
@@ -4,7 +4,6 @@ #include <algorithm> #include <cassert> -#include <cctype> #include <set> #include <vector> @@ -13,6 +12,8 @@ # include <utility> #endif +#include "cmsys/String.h" + #include "cmList.h" #include "cmState.h" #include "cmStateDirectory.h" @@ -425,7 +426,7 @@ static bool Shell_CharIsMakeVariableName(char c) { - return c && (c == '_' || isalpha((static_cast<int>(c)))); + return c && (c == '_' || cmsysString_isalpha((static_cast<int>(c)))); } bool cmOutputConverter::Shell_CharNeedsQuotes(char c, int flags)
diff --git a/Source/cmPackageInfoReader.cxx b/Source/cmPackageInfoReader.cxx index 6817938..9bab7a7 100644 --- a/Source/cmPackageInfoReader.cxx +++ b/Source/cmPackageInfoReader.cxx
@@ -250,6 +250,21 @@ } } +void AppendImportProperty(cmMakefile* makefile, cmTarget* target, + cm::string_view property, + cm::string_view configuration, + std::string const& value) +{ + if (!configuration.empty()) { + std::string const fullprop = cmStrCat( + "IMPORTED_", property, '_', cmSystemTools::UpperCase(configuration)); + target->AppendProperty(fullprop, value, makefile->GetBacktrace()); + } else { + std::string const fullprop = cmStrCat("IMPORTED_", property); + target->AppendProperty(fullprop, value, makefile->GetBacktrace()); + } +} + template <typename Transform> void AppendLanguageProperties(cmMakefile* makefile, cmTarget* target, cm::string_view property, @@ -781,6 +796,15 @@ AppendProperty(makefile, target, "LINK_LIBRARIES"_s, configuration, lib); } + for (std::string const& dep : ReadList(data, "dyld_requires")) { + AppendImportProperty(makefile, target, "LINK_DEPENDENT_LIBRARIES"_s, + configuration, NormalizeTargetName(dep, package)); + } + + for (std::string const& lib : ReadList(data, "link_libraries")) { + AppendProperty(makefile, target, "LINK_LIBRARIES"_s, configuration, lib); + } + // TODO: Handle non-configuration modules // once IMPORTED_CXX_MODULES supports it if (!configuration.empty()) {
diff --git a/Source/cmPathResolver.cxx b/Source/cmPathResolver.cxx index 67d63b9..f384dbf 100644 --- a/Source/cmPathResolver.cxx +++ b/Source/cmPathResolver.cxx
@@ -13,9 +13,9 @@ #include <cmext/string_view> #ifdef _WIN32 -# include <cctype> - # include <windows.h> + +# include <cmsys/String.h> #endif #define MAX_SYMBOLIC_LINKS 32 @@ -95,7 +95,7 @@ Root ClassifyRoot(cm::string_view p) { #ifdef _WIN32 - if (p.size() >= 2 && std::isalpha(p[0]) && p[1] == ':') { + if (p.size() >= 2 && cmsysString_isalpha(p[0]) && p[1] == ':') { return Root::Drive; } if (p.size() >= 3 && p[0] == '/' && p[1] == '/' && p[2] != '/') { @@ -171,8 +171,7 @@ std::string d = this->OS.GetWorkingDirectoryOnDrive(letter); std::replace(d.begin(), d.end(), '\\', '/'); if (d.size() >= 3 && - std::toupper(static_cast<unsigned char>(d[0])) == - std::toupper(static_cast<unsigned char>(letter)) && + cmsysString_toupper(d[0]) == cmsysString_toupper(letter) && d[1] == ':' && d[2] == '/') { d[0] = letter; d.push_back('/'); @@ -182,8 +181,7 @@ // Use the current working directory if the drive matches. d = this->OS.GetWorkingDirectory(); if (d.size() >= 3 && - std::toupper(static_cast<unsigned char>(d[0])) == - std::toupper(static_cast<unsigned char>(letter)) && + cmsysString_toupper(d[0]) == cmsysString_toupper(letter) && d[1] == ':' && d[2] == '/') { d[0] = letter; d.push_back('/'); @@ -284,7 +282,7 @@ if (Policy::ActualCase == Options::ActualCase::Yes) { // Normalize the drive letter to upper-case. - P[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(P[0]))); + P[0] = static_cast<char>(cmsysString_toupper(P[0])); } // The root is a drive letter. The root '/' immediately follows.
diff --git a/Source/cmPkgConfigResolver.cxx b/Source/cmPkgConfigResolver.cxx index 8be5f34..54598c8 100644 --- a/Source/cmPkgConfigResolver.cxx +++ b/Source/cmPkgConfigResolver.cxx
@@ -4,7 +4,6 @@ #include "cmPkgConfigResolver.h" #include <algorithm> -#include <cctype> #include <cstring> #include <iterator> #include <string> @@ -15,6 +14,8 @@ #include <cm/optional> #include <cm/string_view> +#include "cmsys/String.h" + #include "cmPkgConfigParser.h" #include "cmStringAlgorithms.h" @@ -24,7 +25,7 @@ { if (!str.empty()) { auto it = str.end() - 1; - for (; std::isspace(*it); --it) { + for (; cmsysString_isspace(*it); --it) { if (it == str.begin()) { str.clear(); return; @@ -45,11 +46,11 @@ auto begin = str.begin() + size; auto cur = str.end() - 1; - while (cur != begin && std::isspace(*cur)) { + while (cur != begin && cmsysString_isspace(*cur)) { --cur; } - if (std::isspace(*cur)) { + if (cmsysString_isspace(*cur)) { return {}; } @@ -59,7 +60,8 @@ cm::string_view TrimFlag(cm::string_view flag) { std::size_t trim_size = 2; - for (auto c = flag.rbegin(); c != flag.rend() && std::isspace(*c); ++c) { + for (auto c = flag.rbegin(); c != flag.rend() && cmsysString_isspace(*c); + ++c) { ++trim_size; } return { flag.data() + 2, flag.size() - trim_size }; @@ -406,7 +408,7 @@ std::vector<cm::string_view> result; auto it = flagline.begin(); - while (it != flagline.end() && std::isspace(*it)) { + while (it != flagline.end() && cmsysString_isspace(*it)) { ++it; } @@ -414,11 +416,11 @@ char const* start = &(*it); std::size_t len = 0; - for (; it != flagline.end() && !std::isspace(*it); ++it) { + for (; it != flagline.end() && !cmsysString_isspace(*it); ++it) { ++len; } - for (; it != flagline.end() && std::isspace(*it); ++it) { + for (; it != flagline.end() && cmsysString_isspace(*it); ++it) { ++len; } @@ -665,12 +667,12 @@ return result; } - if (!std::isspace(*cur)) { + if (!cmsysString_isspace(*cur)) { break; } } - for (; cur != end && !std::isspace(*cur) && *cur != ','; ++cur) { + for (; cur != end && !cmsysString_isspace(*cur) && *cur != ','; ++cur) { result.Version += *cur; } @@ -687,7 +689,7 @@ auto end = deps.end(); while (cur != end) { - while ((std::isspace(*cur) || *cur == ',')) { + while ((cmsysString_isspace(*cur) || *cur == ',')) { if (++cur == end) { return result; } @@ -696,7 +698,7 @@ result.emplace_back(); auto& dep = result.back(); - while (!std::isspace(*cur) && *cur != ',') { + while (!cmsysString_isspace(*cur) && *cur != ',') { dep.Name += *cur; if (++cur == end) { return result; @@ -713,7 +715,7 @@ return true; } - if (!std::isspace(*cur)) { + if (!cmsysString_isspace(*cur)) { return false; } } @@ -769,11 +771,11 @@ auto b_end = provided.end(); while (a_cur != a_end && b_cur != b_end) { - while (a_cur != a_end && !std::isalnum(*a_cur) && *a_cur != '~') { + while (a_cur != a_end && !cmsysString_isalnum(*a_cur) && *a_cur != '~') { ++a_cur; } - while (b_cur != b_end && !std::isalnum(*b_cur) && *b_cur != '~') { + while (b_cur != b_end && !cmsysString_isalnum(*b_cur) && *b_cur != '~') { ++b_cur; } @@ -799,23 +801,23 @@ auto b_seg = b_cur; bool is_num; - if (std::isdigit(*a_cur)) { + if (cmsysString_isdigit(*a_cur)) { is_num = true; - while (a_cur != a_end && std::isdigit(*a_cur)) { + while (a_cur != a_end && cmsysString_isdigit(*a_cur)) { ++a_cur; } - while (b_cur != b_end && std::isdigit(*b_cur)) { + while (b_cur != b_end && cmsysString_isdigit(*b_cur)) { ++b_cur; } } else { is_num = false; - while (a_cur != a_end && std::isalpha(*a_cur)) { + while (a_cur != a_end && cmsysString_isalpha(*a_cur)) { ++a_cur; } - while (b_cur != b_end && std::isalpha(*b_cur)) { + while (b_cur != b_end && cmsysString_isalpha(*b_cur)) { ++b_cur; } }
diff --git a/Source/cmPlaceholderExpander.cxx b/Source/cmPlaceholderExpander.cxx index f5dc544..aea427b 100644 --- a/Source/cmPlaceholderExpander.cxx +++ b/Source/cmPlaceholderExpander.cxx
@@ -2,7 +2,7 @@ file LICENSE.rst or https://cmake.org/licensing for details. */ #include "cmPlaceholderExpander.h" -#include <cctype> +#include "cmsys/String.h" std::string& cmPlaceholderExpander::ExpandVariables(std::string& s) { @@ -23,7 +23,7 @@ char c = s[start + 1]; // if the next char after the < is not A-Za-z then // skip it and try to find the next < in the string - if (!isalpha(c)) { + if (!cmsysString_isalpha(c)) { start = s.find('<', start + 1); } else { // extract the var
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 4583863..337f220 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx
@@ -3,12 +3,13 @@ #include "cmPolicies.h" #include <cassert> -#include <cctype> #include <cstdio> #include <cstring> #include <sstream> #include <vector> +#include "cmsys/String.h" + #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -32,7 +33,7 @@ return true; } for (int i = 3; i < 7; ++i) { - if (!isdigit(*(input + i))) { + if (!cmsysString_isdigit(*(input + i))) { return false; } }
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index d00cae1..8551132 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx
@@ -17,7 +17,6 @@ #include "cmArgumentParser.h" #include "cmArgumentParserTypes.h" #include "cmExecutionStatus.h" -#include "cmExperimental.h" #include "cmList.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -68,24 +67,18 @@ parser.BindKeywordMissingValue(missingValueKeywords) .BindParsedKeywords(parsedKeywords) .Bind("VERSION"_s, prArgs.Version) + .Bind("COMPAT_VERSION"_s, prArgs.CompatVersion) + .Bind("SPDX_LICENSE"_s, prArgs.License) .Bind("DESCRIPTION"_s, prArgs.Description) .Bind("HOMEPAGE_URL"_s, prArgs.HomepageURL) .Bind("LANGUAGES"_s, prArgs.Languages); - cmMakefile& mf = status.GetMakefile(); - bool enablePackageInfo = cmExperimental::HasSupportEnabled( - mf, cmExperimental::Feature::ExportPackageInfo); - - if (enablePackageInfo) { - parser.Bind("COMPAT_VERSION"_s, prArgs.CompatVersion); - parser.Bind("SPDX_LICENSE"_s, prArgs.License); - } - if (args.empty()) { status.SetError("PROJECT called with incorrect number of arguments"); return false; } + cmMakefile& mf = status.GetMakefile(); std::string const& projectName = args[0]; if (parser.HasKeyword(projectName)) { mf.IssueMessage(
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index 51245d6..e490370 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx
@@ -8,6 +8,7 @@ #include <utility> #include "cmsys/FStream.hxx" +#include "cmsys/String.h" #include "cmAlgorithms.h" #include "cmRange.h" @@ -158,7 +159,7 @@ // A line starting in .. is an explicit markup start. if (line == ".." || (line.size() >= 3 && line[0] == '.' && line[1] == '.' && - cmIsSpace(line[2]))) { + cmsysString_isspace(line[2]))) { this->Reset(); this->MarkupType = (line.find_first_not_of(" \t", 2) == std::string::npos ? Markup::Empty @@ -218,7 +219,7 @@ } // Indented lines following an explicit markup start are explicit markup. else if (this->MarkupType != Markup::None && - (line.empty() || cmIsSpace(line[0]))) { + (line.empty() || cmsysString_isspace(line[0]))) { this->MarkupType = Markup::Normal; // Record markup lines if the start line was recorded. if (!this->MarkupLines.empty()) {
diff --git a/Source/cmSbomArguments.cxx b/Source/cmSbomArguments.cxx index b939448..76322ab 100644 --- a/Source/cmSbomArguments.cxx +++ b/Source/cmSbomArguments.cxx
@@ -3,10 +3,11 @@ #include "cmSbomArguments.h" #include <algorithm> -#include <cctype> #include <cm/string_view> +#include "cmsys/String.h" + #include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmStringAlgorithms.h" @@ -99,6 +100,6 @@ std::string const pkgNameOnDisk = this->GetPackageDirName(); std::string format = GetSbomFileExtension(this->GetFormat()); std::transform(format.begin(), format.end(), format.begin(), - [](unsigned char c) { return std::tolower(c); }); + cmsysString_tolower); return cmStrCat(pkgNameOnDisk, format); }
diff --git a/Source/cmScanDepFormat.cxx b/Source/cmScanDepFormat.cxx index bd38273..0016544 100644 --- a/Source/cmScanDepFormat.cxx +++ b/Source/cmScanDepFormat.cxx
@@ -3,7 +3,6 @@ #include "cmScanDepFormat.h" -#include <cctype> #include <cstdio> #include <utility> @@ -16,6 +15,7 @@ #include <cm3p/json/writer.h> #include "cmsys/FStream.hxx" +#include "cmsys/String.h" #include "cmGeneratedFileStream.h" #include "cmStringAlgorithms.h" @@ -38,7 +38,7 @@ data.reserve(path.size()); for (auto const& byte : path) { - if (std::iscntrl(byte)) { + if (cmsysString_iscntrl(byte)) { // Control characters. data.append("\\u"); char buf[5];
diff --git a/Source/cmStdIoInit.cxx b/Source/cmStdIoInit.cxx index 49f3187..0d7a3d0 100644 --- a/Source/cmStdIoInit.cxx +++ b/Source/cmStdIoInit.cxx
@@ -3,6 +3,7 @@ #include "cmStdIoInit.h" #include <cerrno> +#include <clocale> #include <cstdio> #include <cstdlib> #include <iostream> @@ -106,14 +107,19 @@ static Globals& Get(); }; -#ifdef _WIN32 Globals::Globals() { +#ifdef _WIN32 + // On Windows, setlocale offers a ".<code-page>" syntax to select the + // user's locale with a specific character set. We always use UTF-8. + std::setlocale(LC_CTYPE, ".UTF-8"); + SetConsoleCtrlHandler(CtrlHandler, TRUE); -} #else -Globals::Globals() = default; + // On non-Windows platforms, we select the user's locale. + std::setlocale(LC_CTYPE, ""); #endif +} Globals& Globals::Get() {
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx index d46019b..e13c226 100644 --- a/Source/cmStringAlgorithms.cxx +++ b/Source/cmStringAlgorithms.cxx
@@ -8,15 +8,17 @@ #include <cstdio> #include <cstdlib> +#include "cmsys/String.h" + bool cmStrCaseEq(cm::string_view s1, cm::string_view s2) { if (s1.size() != s2.size()) { return false; } - return std::equal( - s1.begin(), s1.end(), s2.begin(), - [](unsigned char a, unsigned char b) { return tolower(a) == tolower(b); }); + return std::equal(s1.begin(), s1.end(), s2.begin(), [](char a, char b) { + return cmsysString_tolower(a) == cmsysString_tolower(b); + }); } std::string cmTrimWhitespace(cm::string_view str) @@ -25,7 +27,7 @@ // because the qualification of `auto` is platform-dependent. // NOLINTNEXTLINE(readability-qualified-auto) auto start = str.begin(); - while (start != str.end() && cmIsSpace(*start)) { + while (start != str.end() && cmsysString_isspace(*start)) { ++start; } if (start == str.end()) { @@ -33,7 +35,7 @@ } // NOLINTNEXTLINE(readability-qualified-auto) auto stop = str.end() - 1; - while (cmIsSpace(*stop)) { + while (cmsysString_isspace(*stop)) { --stop; } return std::string(start, stop + 1); @@ -44,14 +46,14 @@ std::string::size_type const l = str.size(); std::string::size_type s = 0; - while (s < l && cmIsSpace(str[s])) { + while (s < l && cmsysString_isspace(str[s])) { ++s; } if (s == l) { return cm::string_view{}; } std::string::size_type e = l - 1; - while (cmIsSpace(str[e])) { + while (cmsysString_isspace(str[e])) { --e; } return str.substr(s, e + 1 - s); @@ -196,7 +198,7 @@ { errno = 0; char* endp; - while (cmIsSpace(*str)) { + while (cmsysString_isspace(*str)) { ++str; } if (*str == '-') { @@ -228,7 +230,7 @@ { errno = 0; char* endp; - while (cmIsSpace(*str)) { + while (cmsysString_isspace(*str)) { ++str; } if (*str == '-') {
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h index d847ece..966091a 100644 --- a/Source/cmStringAlgorithms.h +++ b/Source/cmStringAlgorithms.h
@@ -4,7 +4,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <cctype> #include <cstring> #include <initializer_list> #include <iterator> @@ -50,15 +49,6 @@ */ bool cmStrCaseEq(cm::string_view a, cm::string_view b); -/** Returns true if the character @a ch is a whitespace character. **/ -inline bool cmIsSpace(char ch) -{ - // isspace takes 'int' but documents that the value must be representable - // by 'unsigned char', or be EOF. Cast to 'unsigned char' to avoid sign - // extension while converting to 'int'. - return std::isspace(static_cast<unsigned char>(ch)); -} - /** Returns a string that has whitespace removed from the start and the end. */ std::string cmTrimWhitespace(cm::string_view str);
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 1d15b55..2329449 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx
@@ -58,7 +58,6 @@ # include <cm3p/archive_entry.h> # include "cmArchiveWrite.h" -# include "cmLocale.h" # ifndef __LA_INT64_T # define __LA_INT64_T la_int64_t # endif @@ -77,7 +76,6 @@ #include <algorithm> #include <cassert> -#include <cctype> #include <cerrno> #include <cstdint> #include <cstdio> @@ -104,6 +102,7 @@ #endif #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #include "cmsys/System.h" #if defined(_WIN32) @@ -574,7 +573,7 @@ } else { arg.append(backslashes, '\\'); backslashes = 0; - if (cmIsSpace(*c)) { + if (cmsysString_isspace(*c)) { if (in_quotes) { arg.append(1, *c); } else if (in_argument) { @@ -733,7 +732,7 @@ char const* c = command.c_str(); // Skip leading whitespace. - while (cmIsSpace(*c)) { + while (cmsysString_isspace(*c)) { ++c; } @@ -763,7 +762,7 @@ in_double = true; } else if (*c == '\'') { in_single = true; - } else if (cmIsSpace(*c)) { + } else if (cmsysString_isspace(*c)) { break; } else { program += *c; @@ -1340,7 +1339,7 @@ } // Normalize to upper-case drive letter as cm::PathResolver does. if (resolved_path.size() > 1 && resolved_path[1] == ':') { - resolved_path[0] = toupper(static_cast<unsigned char>(resolved_path[0])); + resolved_path[0] = cmsysString_toupper(resolved_path[0]); } return resolved_path; #else @@ -1362,12 +1361,10 @@ // limitation to otherwise preserve susbt drives. if (resolved_path.size() >= 2 && resolved_path[1] == ':' && path.size() >= 2 && path[1] == ':' && - toupper(static_cast<unsigned char>(resolved_path[0])) != - toupper(static_cast<unsigned char>(path[0]))) { + cmsysString_toupper(resolved_path[0]) != cmsysString_toupper(path[0])) { // FIXME: Add thread_local or mutex if we use threads. static std::map<char, std::string> substMap; - char const drive = - static_cast<char>(toupper(static_cast<unsigned char>(path[0]))); + char const drive = static_cast<char>(cmsysString_toupper(path[0])); std::string maybe_subst = cmStrCat(drive, ":/"); auto smi = substMap.find(drive); if (smi == substMap.end()) { @@ -2626,8 +2623,6 @@ cmSystemTools::cmTarExtractTimestamps extractTimestamps, bool extract) { - cmLocaleRAII localeRAII; - static_cast<void>(localeRAII); struct archive* a = archive_read_new(); struct archive* ext = archive_write_disk_new(); if (extract) { @@ -3866,7 +3861,7 @@ static size_t cm_strverscmp_find_digits_begin(char const* s, size_t i) { /* Step back until we are not preceded by a digit. */ - while (i > 0 && isdigit(s[i - 1])) { + while (i > 0 && cmsysString_isdigit(s[i - 1])) { --i; } return i; @@ -3875,7 +3870,7 @@ static size_t cm_strverscmp_find_digits_end(char const* s, size_t i) { /* Step forward over digits. */ - while (isdigit(s[i])) { + while (cmsysString_isdigit(s[i])) { ++i; } return i; @@ -3885,7 +3880,7 @@ { size_t i = b; /* Step forward over zeros that are followed by another digit. */ - while (s[i] == '0' && isdigit(s[i + 1])) { + while (s[i] == '0' && cmsysString_isdigit(s[i + 1])) { ++i; } return i - b; @@ -3897,7 +3892,8 @@ if (lhs[i] != rhs[i]) { /* The strings differ starting at 'i'. Check for a digit sequence. */ size_t const b = cm_strverscmp_find_digits_begin(lhs, i); - if (b != i || (isdigit(lhs[i]) && isdigit(rhs[i]))) { + if (b != i || + (cmsysString_isdigit(lhs[i]) && cmsysString_isdigit(rhs[i]))) { /* A digit sequence starts at 'b', preceding or at 'i'. */ /* Look for leading zeros, implying a leading decimal point. */
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 296adf5..fe713a2 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx
@@ -1721,37 +1721,52 @@ assert(!this->IsNormal()); // Imported targets cannot be the target of a copy. assert(!this->IsImported()); - // Only imported targets can be the source of a copy. - assert(tgt->IsImported()); + + // Only imported or normal targets can be the source of a copy. + assert(tgt->IsImported() || tgt->IsNormal()); this->impl->PolicyMap = tgt->impl->PolicyMap; this->impl->TemplateTarget = tgt; } -void cmTarget::CopyImportedCxxModulesEntries(cmTarget const* tgt) +void cmTarget::CopyCxxModulesEntries(cmTarget const* tgt) { // Normal targets cannot be the target of a copy. assert(!this->IsNormal()); // Imported targets cannot be the target of a copy. assert(!this->IsImported()); - // Only imported targets can be the source of a copy. - assert(tgt->IsImported()); + // Only imported or normal targets can be the source of a copy. + assert(tgt->IsImported() || tgt->IsNormal()); this->impl->IncludeDirectories.Entries.clear(); - this->impl->IncludeDirectories.CopyFromEntries( - cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries)); this->impl->CompileDefinitions.Entries.clear(); - this->impl->CompileDefinitions.CopyFromEntries( - cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries)); this->impl->CompileFeatures.Entries.clear(); - this->impl->CompileFeatures.CopyFromEntries( - cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries)); this->impl->CompileOptions.Entries.clear(); - this->impl->CompileOptions.CopyFromEntries( - cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries)); this->impl->LinkLibraries.Entries.clear(); - this->impl->LinkLibraries.CopyFromEntries( - cmMakeRange(tgt->impl->ImportedCxxModulesLinkLibraries.Entries)); + + if (tgt->IsImported()) { + this->impl->IncludeDirectories.CopyFromEntries( + cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries)); + this->impl->CompileDefinitions.CopyFromEntries( + cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries)); + this->impl->CompileFeatures.CopyFromEntries( + cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries)); + this->impl->CompileOptions.CopyFromEntries( + cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries)); + this->impl->LinkLibraries.CopyFromEntries( + cmMakeRange(tgt->impl->ImportedCxxModulesLinkLibraries.Entries)); + } else { + this->impl->IncludeDirectories.CopyFromEntries( + cmMakeRange(tgt->impl->IncludeDirectories.Entries)); + this->impl->CompileDefinitions.CopyFromEntries( + cmMakeRange(tgt->impl->CompileDefinitions.Entries)); + this->impl->CompileFeatures.CopyFromEntries( + cmMakeRange(tgt->impl->CompileFeatures.Entries)); + this->impl->CompileOptions.CopyFromEntries( + cmMakeRange(tgt->impl->CompileOptions.Entries)); + this->impl->LinkLibraries.CopyFromEntries( + cmMakeRange(tgt->impl->LinkLibraries.Entries)); + } // Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this // target's `PRIVATE`. @@ -1760,14 +1775,14 @@ tgt->impl->CxxModulesFileSets.InterfaceEntries.Entries; } -void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt) +void cmTarget::CopyCxxModulesProperties(cmTarget const* tgt) { // Normal targets cannot be the target of a copy. assert(!this->IsNormal()); // Imported targets cannot be the target of a copy. assert(!this->IsImported()); - // Only imported targets can be the source of a copy. - assert(tgt->IsImported()); + // Only imported or normal targets can be the source of a copy. + assert(tgt->IsImported() || tgt->IsNormal()); // The list of properties that are relevant here include: // - compilation-specific properties for any language or platform
diff --git a/Source/cmTarget.h b/Source/cmTarget.h index b275e47..ad3a9c0 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h
@@ -321,8 +321,8 @@ cmBTStringRange GetLinkInterfaceDirectExcludeEntries() const; void CopyPolicyStatuses(cmTarget const* tgt); - void CopyImportedCxxModulesEntries(cmTarget const* tgt); - void CopyImportedCxxModulesProperties(cmTarget const* tgt); + void CopyCxxModulesEntries(cmTarget const* tgt); + void CopyCxxModulesProperties(cmTarget const* tgt); cmBTStringRange GetHeaderSetsEntries() const; cmBTStringRange GetCxxModuleSetsEntries() const;
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx index 54b301b..342b4f7 100644 --- a/Source/cmVSSetupHelper.cxx +++ b/Source/cmVSSetupHelper.cxx
@@ -54,6 +54,8 @@ #endif namespace { +const WCHAR* Win11SDKComponent = + L"Microsoft.VisualStudio.Component.Windows11SDK"; const WCHAR* Win10SDKComponent = L"Microsoft.VisualStudio.Component.Windows10SDK"; const WCHAR* Win81SDKComponent = @@ -156,10 +158,9 @@ std::wstring id = std::wstring(bstrId); std::wstring type = std::wstring(bstrType); - // Checks for any version of Win10 SDK. The version is appended at the end of - // the - // component name ex: Microsoft.VisualStudio.Component.Windows10SDK.10240 - if (id.find(Win10SDKComponent) != std::wstring::npos && + // Check for any version of Win10 or Win11 SDK. + // The component name may have a `.<version>` suffix. Accept any. + if ((id.find(Win11SDKComponent) == 0 || id.find(Win10SDKComponent) == 0) && type == ComponentType) { bWin10SDK = true; ret = true; @@ -526,25 +527,25 @@ unsigned int chosenIndex = 0; for (unsigned int i = 1; i < vecVSInstances.size(); i++) { - // If the current has Win10 SDK but not the chosen one, then choose the - // current VS instance + // If the current instance has Win10 SDK, but the chosen one does not, + // then choose the current VS instance. if (!vecVSInstances[chosenIndex].IsWin10SDKInstalled && vecVSInstances[i].IsWin10SDKInstalled) { chosenIndex = i; continue; } - // If the chosen one has Win10 SDK but the current one is not, then look at - // the next VS instance even the current - // instance version may be higher + // If the chosen instance has Win10 SDK, but the current one does not, + // then look at the next VS instance even if the current instance version + // may be higher. if (vecVSInstances[chosenIndex].IsWin10SDKInstalled && !vecVSInstances[i].IsWin10SDKInstalled) { continue; } - // If both chosen one and current one doesn't have Win10 SDK but the - // current one has Win8.1 SDK installed, - // then choose the current one + // If both chosen instance and current instance do not have Win10 SDK, + // but the current one has Win8.1 SDK installed, then choose the current + // one. if (!vecVSInstances[chosenIndex].IsWin10SDKInstalled && !vecVSInstances[i].IsWin10SDKInstalled && !vecVSInstances[chosenIndex].IsWin81SDKInstalled &&
diff --git a/Source/cmWindowsRegistry.cxx b/Source/cmWindowsRegistry.cxx index 9d9de8c..ecce2f5 100644 --- a/Source/cmWindowsRegistry.cxx +++ b/Source/cmWindowsRegistry.cxx
@@ -4,7 +4,6 @@ #include "cmWindowsRegistry.h" -#include <cctype> #include <cstddef> #include <type_traits> #include <unordered_map> @@ -13,6 +12,7 @@ #include <cmext/string_view> #include "cmsys/RegularExpression.hxx" +#include "cmsys/String.h" #if defined(_WIN32) && !defined(__CYGWIN__) # include <algorithm> @@ -47,8 +47,8 @@ cm::string_view::size_type ri = 0; do { - lc = std::tolower(static_cast<unsigned char>(l[li++])); - rc = std::tolower(static_cast<unsigned char>(r[ri++])); + lc = cmsysString_tolower(l[li++]); + rc = cmsysString_tolower(r[ri++]); } while (lc == rc && li < l.size() && ri < r.size()); return lc == rc ? static_cast<int>(l.size() - r.size()) : lc - rc;
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h index e15542d..bad1bc1 100644 --- a/Source/cmXMLWriter.h +++ b/Source/cmXMLWriter.h
@@ -113,6 +113,11 @@ return std::chrono::system_clock::to_time_t(value); } + static long long SafeContent(std::chrono::milliseconds value) + { + return value.count(); + } + template <typename T> static T SafeContent(T value) {
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 42fe88a..35346af 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx
@@ -5,7 +5,6 @@ #include <algorithm> #include <cassert> -#include <cctype> #include <climits> #include <cstring> #include <functional> @@ -20,6 +19,8 @@ #include <cm3p/uv.h> +#include "cmsys/String.h" + #include "cmBuildArgs.h" #include "cmBuildOptions.h" #include "cmCommandLineArgument.h" @@ -500,8 +501,7 @@ }; auto resolvePackagesLambda = [&](std::string const& value) -> bool { std::string v = value; - std::transform(v.begin(), v.end(), v.begin(), - [](unsigned char c) { return std::tolower(c); }); + std::transform(v.begin(), v.end(), v.begin(), cmsysString_tolower); if (v == "on") { resolveMode = PackageResolveMode::Force; } else if (v == "only") {
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 08494b9..68e122e 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt
@@ -159,6 +159,7 @@ set(KWSYS_USE_FStream 1) set(KWSYS_USE_Encoding 1) set(KWSYS_USE_Status 1) + set(KWSYS_USE_String 1) endif() if(KWSYS_USE_Glob) set(KWSYS_USE_Directory 1) @@ -166,6 +167,7 @@ set(KWSYS_USE_RegularExpression 1) set(KWSYS_USE_FStream 1) set(KWSYS_USE_Encoding 1) + set(KWSYS_USE_String 1) endif() if(KWSYS_USE_Process) set(KWSYS_USE_System 1) @@ -179,6 +181,7 @@ endif() if(KWSYS_USE_System) set(KWSYS_USE_Encoding 1) + set(KWSYS_USE_String 1) endif() if(KWSYS_USE_Directory) set(KWSYS_USE_Encoding 1) @@ -913,6 +916,7 @@ # C tests set(KWSYS_C_TESTS testEncode.c + testString.c ) if(KWSYS_STANDALONE) set(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c)
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx index 7bf4681..885a1f7 100644 --- a/Source/kwsys/EncodingCXX.cxx +++ b/Source/kwsys/EncodingCXX.cxx
@@ -9,12 +9,14 @@ #include "kwsysPrivate.h" #include KWSYS_HEADER(Encoding.hxx) #include KWSYS_HEADER(Encoding.h) +#include KWSYS_HEADER(String.h) // Work-around CMake dependency scanning limitation. This must // duplicate the above list of headers. #if 0 # include "Encoding.h.in" # include "Encoding.hxx.in" +# include "String.h" #endif #include <cstdlib> @@ -29,7 +31,6 @@ #if defined(_WIN32) # include <windows.h> -# include <ctype.h> # include <shellapi.h> #endif @@ -248,7 +249,7 @@ * previous size workaround. */ wfull_len = static_cast<DWORD>(wcslen(&wfull[0])); - if (wfull_len >= 2 && isalpha(wfull[0]) && + if (wfull_len >= 2 && kwsysString_isalpha(wfull[0]) && wfull[1] == L':') { /* C:\Foo\bar\FooBar.txt */ return L"\\\\?\\" + std::wstring(&wfull[0]); } else if (wfull_len >= 2 && wfull[0] == L'\\' && @@ -259,7 +260,7 @@ wfull[6] == L'C' && wfull[7] == L'\\') { /* \\?\UNC\Foo\bar\FooBar.txt */ return std::wstring(&wfull[0]); - } else if (wfull_len >= 6 && isalpha(wfull[4]) && + } else if (wfull_len >= 6 && kwsysString_isalpha(wfull[4]) && wfull[5] == L':') { /* \\?\C:\Foo\bar\FooBar.txt */ return std::wstring(&wfull[0]); } else if (wfull_len >= 5) { /* \\?\Foo\bar\FooBar.txt */ @@ -267,7 +268,7 @@ } } else if (wfull_len >= 4 && wfull[2] == L'.' && wfull[3] == L'\\') { /* Starts with \\.\ a device name */ - if (wfull_len >= 6 && isalpha(wfull[4]) && + if (wfull_len >= 6 && kwsysString_isalpha(wfull[4]) && wfull[5] == L':') { /* \\.\C:\Foo\bar\FooBar.txt */ return L"\\\\?\\" + std::wstring(&wfull[4]); } else if (wfull_len >=
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index 90970ea..3ac75f6 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx
@@ -8,6 +8,7 @@ #include KWSYS_HEADER(RegularExpression.hxx) #include KWSYS_HEADER(SystemTools.hxx) #include KWSYS_HEADER(Directory.hxx) +#include KWSYS_HEADER(String.h) // Work-around CMake dependency scanning limitation. This must // duplicate the above list of headers. @@ -16,6 +17,7 @@ # include "Directory.hxx.in" # include "Glob.hxx.in" # include "RegularExpression.hxx.in" +# include "String.h.in" # include "SystemTools.hxx.in" #endif @@ -23,7 +25,6 @@ #include <string> #include <vector> -#include <cctype> #include <cstdio> #include <cstring> namespace KWSYS_NAMESPACE { @@ -162,7 +163,7 @@ // On case-insensitive systems file names are converted to lower // case before matching. if (!preserve_case) { - ch = tolower(static_cast<unsigned char>(ch)); + ch = kwsysString_tolower(ch); } } #endif
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c index 01dc039..8c22b4e 100644 --- a/Source/kwsys/ProcessUNIX.c +++ b/Source/kwsys/ProcessUNIX.c
@@ -54,7 +54,6 @@ #endif #include <assert.h> /* assert */ -#include <ctype.h> /* isspace */ #include <dirent.h> /* DIR, dirent */ #include <errno.h> /* errno */ #include <fcntl.h> /* fcntl */
diff --git a/Source/kwsys/String.c b/Source/kwsys/String.c index 7fd159b..0ccf38d 100644 --- a/Source/kwsys/String.c +++ b/Source/kwsys/String.c
@@ -17,84 +17,130 @@ # include "String.h.in" # endif -/* Select an implementation for strcasecmp. */ -# if defined(_MSC_VER) -# define KWSYS_STRING_USE_STRICMP -# include <string.h> -# elif defined(__GNUC__) -# define KWSYS_STRING_USE_STRCASECMP -# include <strings.h> -# else -/* Table to convert upper case letters to lower case and leave all - other characters alone. */ -static char kwsysString_strcasecmp_tolower[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\010', - '\011', '\012', '\013', '\014', '\015', '\016', '\017', '\020', '\021', - '\022', '\023', '\024', '\025', '\026', '\027', '\030', '\031', '\032', - '\033', '\034', '\035', '\036', '\037', '\040', '\041', '\042', '\043', - '\044', '\045', '\046', '\047', '\050', '\051', '\052', '\053', '\054', - '\055', '\056', '\057', '\060', '\061', '\062', '\063', '\064', '\065', - '\066', '\067', '\070', '\071', '\072', '\073', '\074', '\075', '\076', - '\077', '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\160', - '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\171', - '\172', '\133', '\134', '\135', '\136', '\137', '\140', '\141', '\142', - '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\152', '\153', - '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\163', '\164', - '\165', '\166', '\167', '\170', '\171', '\172', '\173', '\174', '\175', - '\176', '\177', '\200', '\201', '\202', '\203', '\204', '\205', '\206', - '\207', '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230', - '\231', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\241', - '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\252', - '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263', - '\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274', - '\275', '\276', '\277', '\300', '\301', '\302', '\303', '\304', '\305', - '\306', '\307', '\310', '\311', '\312', '\313', '\314', '\315', '\316', - '\317', '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', - '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', '\340', - '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', - '\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362', - '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\373', - '\374', '\375', '\376', '\377' -}; -# endif +# include <ctype.h> -/*--------------------------------------------------------------------------*/ -int kwsysString_strcasecmp(char const* lhs, char const* rhs) +int kwsysString_isalnum(char c) { -# if defined(KWSYS_STRING_USE_STRICMP) - return _stricmp(lhs, rhs); -# elif defined(KWSYS_STRING_USE_STRCASECMP) - return strcasecmp(lhs, rhs); -# else - char const* const lower = kwsysString_strcasecmp_tolower; - unsigned char const* us1 = (unsigned char const*)lhs; - unsigned char const* us2 = (unsigned char const*)rhs; - int result; - while ((result = lower[*us1] - lower[*us2++], result == 0) && *us1++) { - } - return result; -# endif + return (kwsysString_isalpha(c) | /* bitwise-or to avoid branching. */ + kwsysString_isdigit(c)); } -/*--------------------------------------------------------------------------*/ +int kwsysString_isalpha(char c) +{ + return (kwsysString_islower(c) | /* bitwise-or to avoid branching. */ + kwsysString_isupper(c)); +} + +int kwsysString_isascii(char c) +{ + unsigned char const uc = (unsigned char)c; + return (uc & 0x80) ^ 0x80; +} + +int kwsysString_isblank(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && isblank(uc); +} + +int kwsysString_iscntrl(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && iscntrl(uc); +} + +int kwsysString_isdigit(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push '0-9' to 246-255 so integer division by 246 is 1 only for them. */ + return ((uc + 246 - '0') & 0xFF) / 246; +} + +int kwsysString_isgraph(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && isgraph(uc); +} + +int kwsysString_islower(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 'a-z' to 230-255 so integer division by 230 is 1 only for them. */ + return ((uc + 230 - 'a') & 0xFF) / 230; +} + +int kwsysString_isprint(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 32-126 to 161-255 so integer division by 161 is 1 only for them. */ + return ((uc + 161 - ' ') & 0xFF) / 161; +} + +int kwsysString_ispunct(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && ispunct(uc); +} + +int kwsysString_isspace(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && isspace(uc); +} + +int kwsysString_isupper(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 'A-Z' to 230-255 so integer division by 230 is 1 only for them. */ + return ((uc + 230 - 'A') & 0xFF) / 230; +} + +int kwsysString_isxdigit(char c) +{ + unsigned char const uc = (unsigned char)c; + return ( + /* Push '0-9' to 246-255 so integer division by 246 is 1 only for them. */ + (((uc + 246 - '0') & 0xFF) / 246) | /* bitwise-or to avoid branching. */ + /* Push 'A-F' to 250-255 so integer division by 250 is 1 only for them. */ + (((uc + 250 - 'A') & 0xFF) / 250) | /* bitwise-or to avoid branching. */ + /* Push 'a-f' to 250-255 so integer division by 250 is 1 only for them. */ + (((uc + 250 - 'a') & 0xFF) / 250)); +} + +unsigned char kwsysString_tolower(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 'A-Z' to 230-255 so integer division by 230 is 1 only for them. */ + return (unsigned char)(uc ^ ((((uc + 230 - 'A') & 0xFF) / 230) << 5)); +} + +unsigned char kwsysString_toupper(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 'a-z' to 230-255 so integer division by 230 is 1 only for them. */ + return (unsigned char)(uc ^ ((((uc + 230 - 'a') & 0xFF) / 230) << 5)); +} + +int kwsysString_strcasecmp(char const* lhs, char const* rhs) +{ + int result; + while ((result = kwsysString_tolower(*lhs) - kwsysString_tolower(*rhs++)) == + 0 && + *lhs++) { + } + return result; +} + int kwsysString_strncasecmp(char const* lhs, char const* rhs, size_t n) { -# if defined(KWSYS_STRING_USE_STRICMP) - return _strnicmp(lhs, rhs, n); -# elif defined(KWSYS_STRING_USE_STRCASECMP) - return strncasecmp(lhs, rhs, n); -# else - char const* const lower = kwsysString_strcasecmp_tolower; - unsigned char const* us1 = (unsigned char const*)lhs; - unsigned char const* us2 = (unsigned char const*)rhs; int result = 0; - while (n && (result = lower[*us1] - lower[*us2++], result == 0) && *us1++) { + while (n && + (result = kwsysString_tolower(*lhs) - kwsysString_tolower(*rhs++)) == + 0 && + *lhs++) { --n; } return result; -# endif } #endif /* KWSYS_STRING_C */
diff --git a/Source/kwsys/String.h.in b/Source/kwsys/String.h.in index 6931051..abc74a6 100644 --- a/Source/kwsys/String.h.in +++ b/Source/kwsys/String.h.in
@@ -16,6 +16,21 @@ # define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT #endif #if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# define kwsysString_isalnum kwsys_ns(String_isalnum) +# define kwsysString_isalpha kwsys_ns(String_isalpha) +# define kwsysString_isascii kwsys_ns(String_isascii) +# define kwsysString_isblank kwsys_ns(String_isblank) +# define kwsysString_iscntrl kwsys_ns(String_iscntrl) +# define kwsysString_isdigit kwsys_ns(String_isdigit) +# define kwsysString_isgraph kwsys_ns(String_isgraph) +# define kwsysString_islower kwsys_ns(String_islower) +# define kwsysString_isprint kwsys_ns(String_isprint) +# define kwsysString_ispunct kwsys_ns(String_ispunct) +# define kwsysString_isspace kwsys_ns(String_isspace) +# define kwsysString_isupper kwsys_ns(String_isupper) +# define kwsysString_isxdigit kwsys_ns(String_isxdigit) +# define kwsysString_tolower kwsys_ns(String_tolower) +# define kwsysString_toupper kwsys_ns(String_toupper) # define kwsysString_strcasecmp kwsys_ns(String_strcasecmp) # define kwsysString_strncasecmp kwsys_ns(String_strncasecmp) #endif @@ -24,6 +39,51 @@ extern "C" { #endif +/** Locale-independent ASCII isalnum. */ +kwsysEXPORT int kwsysString_isalnum(char c); + +/** Locale-independent ASCII isalpha. */ +kwsysEXPORT int kwsysString_isalpha(char c); + +/** Locale-independent ASCII isascii. */ +kwsysEXPORT int kwsysString_isascii(char c); + +/** Locale-independent ASCII isblank. */ +kwsysEXPORT int kwsysString_isblank(char c); + +/** Locale-independent ASCII iscntrl. */ +kwsysEXPORT int kwsysString_iscntrl(char c); + +/** Locale-independent ASCII isdigit. */ +kwsysEXPORT int kwsysString_isdigit(char c); + +/** Locale-independent ASCII isgraph. */ +kwsysEXPORT int kwsysString_isgraph(char c); + +/** Locale-independent ASCII islower. */ +kwsysEXPORT int kwsysString_islower(char c); + +/** Locale-independent ASCII isprint. */ +kwsysEXPORT int kwsysString_isprint(char c); + +/** Locale-independent ASCII ispunct. */ +kwsysEXPORT int kwsysString_ispunct(char c); + +/** Locale-independent ASCII isspace. */ +kwsysEXPORT int kwsysString_isspace(char c); + +/** Locale-independent ASCII isupper. */ +kwsysEXPORT int kwsysString_isupper(char c); + +/** Locale-independent ASCII isxdigit. */ +kwsysEXPORT int kwsysString_isxdigit(char c); + +/** Locale-independent ASCII tolower. */ +kwsysEXPORT unsigned char kwsysString_tolower(char c); + +/** Locale-independent ASCII toupper. */ +kwsysEXPORT unsigned char kwsysString_toupper(char c); + /** * Compare two strings ignoring the case of the characters. The * integer returned is negative, zero, or positive if the first string @@ -49,6 +109,21 @@ # undef kwsys_ns # undef kwsysEXPORT # if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# undef kwsysString_isalnum +# undef kwsysString_isalpha +# undef kwsysString_isascii +# undef kwsysString_isblank +# undef kwsysString_iscntrl +# undef kwsysString_isdigit +# undef kwsysString_isgraph +# undef kwsysString_islower +# undef kwsysString_isprint +# undef kwsysString_ispunct +# undef kwsysString_isspace +# undef kwsysString_isupper +# undef kwsysString_isxdigit +# undef kwsysString_tolower +# undef kwsysString_toupper # undef kwsysString_strcasecmp # undef kwsysString_strncasecmp # endif
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c index 11257cd..cb7fc2d 100644 --- a/Source/kwsys/System.c +++ b/Source/kwsys/System.c
@@ -1,15 +1,16 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ #include "kwsysPrivate.h" +#include KWSYS_HEADER(String.h) #include KWSYS_HEADER(System.h) /* Work-around CMake dependency scanning limitation. This must duplicate the above list of headers. */ #if 0 +# include "String.h.in" # include "System.h.in" #endif -#include <ctype.h> /* isspace */ #include <stddef.h> /* ptrdiff_t */ #include <stdlib.h> /* malloc, free */ #include <string.h> /* memcpy */ @@ -148,7 +149,7 @@ in_argument = 1; } } - } else if (isspace((unsigned char)*c)) { + } else if (kwsysString_isspace(*c)) { if (in_argument) { if (in_single || in_double) { /* This space belongs to a quoted argument. */
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 5f67f16..0a472d3 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx
@@ -28,6 +28,7 @@ // https://msdn.microsoft.com/en-us/library/ms683219(VS.85).aspx #include "kwsysPrivate.h" +#include KWSYS_HEADER(String.h) #include KWSYS_HEADER(SystemInformation.hxx) #include KWSYS_HEADER(Process.h) @@ -35,6 +36,7 @@ // duplicate the above list of headers. #if 0 # include "Process.h.in" +# include "String.h.in" # include "SystemInformation.hxx.in" #endif @@ -165,7 +167,6 @@ # undef KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP #endif -#include <cctype> // int isdigit(int c); #include <cstdio> #include <cstdlib> #include <cstring> @@ -4167,11 +4168,11 @@ char majorChar = unameInfo.release[0]; char minorChar = unameInfo.release[2]; - if (isdigit(majorChar)) { + if (kwsysString_isdigit(majorChar)) { linuxMajor = majorChar - '0'; } - if (isdigit(minorChar)) { + if (kwsysString_isdigit(minorChar)) { linuxMinor = minorChar - '0'; } }
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 2bedcbd..7e23c16 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx
@@ -25,9 +25,9 @@ #include KWSYS_HEADER(FStream.hxx) #include KWSYS_HEADER(Encoding.h) #include KWSYS_HEADER(Encoding.hxx) +#include KWSYS_HEADER(String.h) #include <algorithm> -#include <cctype> #include <fstream> #include <iostream> #include <set> @@ -44,9 +44,11 @@ // duplicate the above list of headers. #if 0 # include "Directory.hxx.in" +# include "Encoding.h.in" # include "Encoding.hxx.in" # include "FStream.hxx.in" # include "RegularExpression.hxx.in" +# include "String.h.in" # include "SystemTools.hxx.in" #endif @@ -58,7 +60,6 @@ # pragma set woff 1375 /* base class destructor not virtual */ #endif -#include <cctype> #include <cerrno> #include <cstdio> #include <cstdlib> @@ -321,8 +322,7 @@ if (nlen < len) { // make sure the drive letter is capital if (nlen > 1 && buf[1] == ':') { - buf[0] = - static_cast<char>(toupper(static_cast<unsigned char>(buf[0]))); + buf[0] = kwsysString_toupper(buf[0]); } return buf; } @@ -554,8 +554,7 @@ casePath = path_components[idx++]; // make sure drive letter is always upper case if (casePath.size() > 1 && casePath[1] == ':') { - casePath[0] = static_cast<std::string::value_type>( - toupper(static_cast<unsigned char>(casePath[0]))); + casePath[0] = kwsysString_toupper(casePath[0]); } char const* sep = ""; @@ -1659,11 +1658,9 @@ return n; } n.resize(s.size()); - n[0] = static_cast<std::string::value_type>( - toupper(static_cast<unsigned char>(s[0]))); + n[0] = static_cast<std::string::value_type>(kwsysString_toupper(s[0])); for (size_t i = 1; i < s.size(); i++) { - n[i] = static_cast<std::string::value_type>( - tolower(static_cast<unsigned char>(s[i]))); + n[i] = static_cast<std::string::value_type>(kwsysString_tolower(s[i])); } return n; } @@ -1673,17 +1670,9 @@ { std::string n(s); for (size_t i = 0; i < s.size(); i++) { -#if defined(_MSC_VER) && defined(_MT) && defined(_DEBUG) - // MS has an assert that will fail if s[i] < 0; setting - // LC_CTYPE using setlocale() does *not* help. Painful. - if ((int)s[i] >= 0 && isalpha(s[i]) && - (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1])))) -#else - if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1]))) -#endif - { - n[i] = static_cast<std::string::value_type>( - toupper(static_cast<unsigned char>(s[i]))); + if (kwsysString_isalpha(s[i]) && + (i == 0 || kwsysString_isspace(s[i - 1]))) { + n[i] = static_cast<std::string::value_type>(kwsysString_toupper(s[i])); } } return n; @@ -1694,17 +1683,9 @@ { std::string n(s); for (size_t i = 0; i < s.size(); i++) { -#if defined(_MSC_VER) && defined(_MT) && defined(_DEBUG) - // MS has an assert that will fail if s[i] < 0; setting - // LC_CTYPE using setlocale() does *not* help. Painful. - if ((int)s[i] >= 0 && isalpha(s[i]) && - (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1])))) -#else - if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1]))) -#endif - { - n[i] = static_cast<std::string::value_type>( - tolower(static_cast<unsigned char>(s[i]))); + if (kwsysString_isalpha(s[i]) && + (i == 0 || kwsysString_isspace(s[i - 1]))) { + n[i] = static_cast<std::string::value_type>(kwsysString_tolower(s[i])); } } return n; @@ -1718,7 +1699,8 @@ n.reserve(s.size()); n += s[0]; for (size_t i = 1; i < s.size(); i++) { - if (isupper(s[i]) && !isspace(s[i - 1]) && !isupper(s[i - 1])) { + if (kwsysString_isupper(s[i]) && !kwsysString_isspace(s[i - 1]) && + !kwsysString_isupper(s[i - 1])) { n += ' '; } n += s[i]; @@ -1771,15 +1753,13 @@ std::string SystemTools::LowerCase(std::string s) { - std::transform(s.begin(), s.end(), s.begin(), - [](unsigned char c) { return std::tolower(c); }); + std::transform(s.begin(), s.end(), s.begin(), kwsysString_tolower); return s; } std::string SystemTools::UpperCase(std::string s) { - std::transform(s.begin(), s.end(), s.begin(), - [](unsigned char c) { return std::toupper(c); }); + std::transform(s.begin(), s.end(), s.begin(), kwsysString_toupper); return s; } @@ -2004,7 +1984,7 @@ if (*cur++ == '%') { // Skip "%%" since it doesn't correspond to a va_arg. if (*cur != '%') { - while (!int(isalpha(*cur))) { + while (!kwsysString_isalpha(*cur)) { ++cur; } switch (*cur) { @@ -2742,8 +2722,8 @@ int lc; int rc; do { - lc = tolower(static_cast<unsigned char>(*l++)); - rc = tolower(static_cast<unsigned char>(*r++)); + lc = kwsysString_tolower(*l++); + rc = kwsysString_tolower(*r++); } while (lc == rc && lc); return lc - rc; }
diff --git a/Source/kwsys/testString.c b/Source/kwsys/testString.c new file mode 100644 index 0000000..b6a1e84 --- /dev/null +++ b/Source/kwsys/testString.c
@@ -0,0 +1,134 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ +#include "kwsysPrivate.h" +#include KWSYS_HEADER(String.h) + +/* Work-around CMake dependency scanning limitation. This must + duplicate the above list of headers. */ +#if 0 +# include "String.h.in" +#endif + +#include <ctype.h> +#include <locale.h> +#include <stdio.h> + +#ifdef _WIN32 +static int isprint_posix(int c) +{ + return isprint(c) && c != '\t'; +} +# define isprint isprint_posix +#endif + +#define MAKE_testString_(isXXXXX) \ + static int testString_##isXXXXX(void) \ + { \ + int i = 0; \ + for (; i < 128; ++i) { \ + if (!!isXXXXX(i) != !!kwsysString_##isXXXXX((char)i)) { \ + printf(#isXXXXX "(%d) failed: %d\n", i, \ + kwsysString_##isXXXXX((char)i)); \ + return 1; \ + } \ + } \ + for (; i < 256; ++i) { \ + if (kwsysString_##isXXXXX((char)i)) { \ + printf(#isXXXXX "(%d) failed: %d\n", i, \ + kwsysString_##isXXXXX((char)i)); \ + return 1; \ + } \ + } \ + return 0; \ + } \ + static int testString_##isXXXXX(void) + +MAKE_testString_(isalnum); +MAKE_testString_(isalpha); +MAKE_testString_(isascii); +MAKE_testString_(isblank); +MAKE_testString_(iscntrl); +MAKE_testString_(isdigit); +MAKE_testString_(isgraph); +MAKE_testString_(islower); +MAKE_testString_(isprint); +MAKE_testString_(ispunct); +MAKE_testString_(isspace); +MAKE_testString_(isupper); +MAKE_testString_(isxdigit); + +static int testString_tolower(void) +{ + int i = 0; + int j; + for (; i < 'A'; ++i) { + if ((j = kwsysString_tolower((char)i)) != i) { + printf("tolower(%d) failed: %d\n", i, j); + return 1; + } + } + for (; i <= 'Z'; ++i) { + if ((j = kwsysString_tolower((char)i)) != i + 32) { + printf("tolower(%d) failed: %d\n", i, j); + return 1; + } + } + for (; i < 256; ++i) { + if ((j = kwsysString_tolower((char)i)) != i) { + printf("tolower(%d) failed: %d\n", i, j); + return 1; + } + } + return 0; +} + +static int testString_toupper(void) +{ + int i = 0; + int j; + for (; i < 'a'; ++i) { + if ((j = kwsysString_toupper((char)i)) != i) { + printf("toupper(%d) failed: %d\n", i, j); + return 1; + } + } + for (; i <= 'z'; ++i) { + if ((j = kwsysString_toupper((char)i)) != i - 32) { + printf("toupper(%d) failed: %d\n", i, j); + return 1; + } + } + for (; i < 256; ++i) { + if ((j = kwsysString_toupper((char)i)) != i) { + printf("toupper(%d) failed: %d\n", i, j); + return 1; + } + } + return 0; +} + +int testString(int argc, char* argv[]) +{ + int result = 0; + (void)argc; + (void)argv; + setlocale(LC_CTYPE, ""); + + result |= testString_isalnum(); + result |= testString_isalpha(); + result |= testString_isascii(); + result |= testString_isblank(); + result |= testString_iscntrl(); + result |= testString_isdigit(); + result |= testString_isgraph(); + result |= testString_islower(); + result |= testString_isprint(); + result |= testString_ispunct(); + result |= testString_isspace(); + result |= testString_isupper(); + result |= testString_isxdigit(); + result |= testString_tolower(); + result |= testString_toupper(); + + return result; +}
diff --git a/Tests/CMakeLib/testPathResolver.cxx b/Tests/CMakeLib/testPathResolver.cxx index 6a38c31..ce759e5 100644 --- a/Tests/CMakeLib/testPathResolver.cxx +++ b/Tests/CMakeLib/testPathResolver.cxx
@@ -9,7 +9,7 @@ #include <utility> #ifdef _WIN32 -# include <cctype> +# include <cmsys/String.h> #endif #include <cmsys/Status.hxx> @@ -92,8 +92,7 @@ std::string GetWorkingDirectoryOnDrive(char letter) override { std::string result; - auto i = this->WorkDirOnDrive.find( - std::tolower(static_cast<unsigned char>(letter))); + auto i = this->WorkDirOnDrive.find(cmsysString_tolower(letter)); if (i != this->WorkDirOnDrive.end()) { result = i->second; }
diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx index ea843d9..50ad761 100644 --- a/Tests/CMakeLib/testUVProcessChainHelper.cxx +++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx
@@ -1,4 +1,3 @@ -#include <cctype> #include <chrono> #include <cstdlib> #include <iostream> @@ -7,6 +6,7 @@ #include <string> #include <thread> +#include "cmsys/String.h" #include "cmsys/SystemTools.hxx" #ifdef _WIN32 @@ -41,7 +41,7 @@ std::this_thread::sleep_for(std::chrono::milliseconds(12000)); std::string input = getStdin(); for (auto& c : input) { - c = static_cast<char>(std::toupper(static_cast<unsigned char>(c))); + c = static_cast<char>(cmsysString_toupper(c)); } std::cout << input << std::flush; std::cerr << "2" << std::flush;
diff --git a/Tests/FindPackageCpsTest/CMakeLists.txt b/Tests/FindPackageCpsTest/CMakeLists.txt index 3c762fd..232c7d8 100644 --- a/Tests/FindPackageCpsTest/CMakeLists.txt +++ b/Tests/FindPackageCpsTest/CMakeLists.txt
@@ -1,8 +1,6 @@ cmake_minimum_required(VERSION 3.31) project(FindPackageCpsTest) -set(CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES "e82e467b-f997-4464-8ace-b00808fff261") - # Protect tests from running inside the default install prefix. set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix") @@ -29,6 +27,13 @@ endif() endfunction() +function(expect_property TARGET PROPERTY DESCRIPTION EXPECTED) + get_target_property(actual ${TARGET} ${PROPERTY}) + if(NOT "${actual}" STREQUAL "${EXPECTED}") + message(SEND_ERROR "${TARGET} has wrong ${DESCRIPTION} '${actual}' !") + endif() +endfunction() + function(test_version PACKAGE LITERAL COUNT MAJOR MINOR PATCH TWEAK) if(NOT ${PACKAGE}_FOUND) message(SEND_ERROR "${PACKAGE} not found !") @@ -47,7 +52,7 @@ test_version(${PACKAGE} "${VERSION}" 0 0 0 0 0) endfunction() -function(test_global TARGET VALUE) +function(expect_global TARGET VALUE) get_target_property(global "${TARGET}" IMPORTED_GLOBAL) if((VALUE AND NOT global) OR (NOT VALUE AND global)) message(SEND_ERROR "${TARGET} has wrong IMPORTED_GLOBAL '${global}' !") @@ -78,6 +83,7 @@ ############################################################################### # Test finding a package whose CPS file is in the package prefix root. + set(RootTest_DIR "${CMAKE_CURRENT_SOURCE_DIR}/RootTest") find_package(RootTest) if(NOT RootTest_FOUND) @@ -166,21 +172,15 @@ elseif(NOT TARGET Foo::Empty) message(SEND_ERROR "Foo::Empty missing !") else() - get_property(pt_includes - TARGET Foo::PrefixTest PROPERTY INTERFACE_INCLUDE_DIRECTORIES) - if(NOT "${pt_includes}" STREQUAL "$<$<CONFIG:default>:${CMAKE_CURRENT_SOURCE_DIR}/include>" ) - message(SEND_ERROR "Foo::PrefixTest has wrong includes '${pt_includes}' !") - endif() - set(pt_includes) + expect_property( + Foo::PrefixTest INTERFACE_INCLUDE_DIRECTORIES "includes" + "$<$<CONFIG:default>:${CMAKE_CURRENT_SOURCE_DIR}/include>") - get_property(rt_includes - TARGET Foo::RelativeTest PROPERTY INTERFACE_INCLUDE_DIRECTORIES) - if(NOT "${rt_includes}" STREQUAL "$<$<CONFIG:default>:${CMAKE_CURRENT_SOURCE_DIR}/cps/../include>") - message(SEND_ERROR "Foo::RelativeTest has wrong includes '${rt_includes}' !") - endif() - set(rt_includes) + expect_property( + Foo::RelativeTest INTERFACE_INCLUDE_DIRECTORIES "includes" + "$<$<CONFIG:default>:${CMAKE_CURRENT_SOURCE_DIR}/cps/../include>") - test_global(Foo::Empty FALSE) + expect_global(Foo::Empty FALSE) endif() ############################################################################### @@ -192,7 +192,7 @@ elseif(NOT TARGET Global::Target) message(SEND_ERROR "Global::Target missing !") else() - test_global(Foo::Empty FALSE) + expect_global(Foo::Empty FALSE) endif() ############################################################################### @@ -223,6 +223,18 @@ add_executable(requires-test-compile_only requires-test.cxx) target_link_libraries(requires-test-compile_only RequiresTest::CompileOnly) +expect_property( + RequiresTest::Other INTERFACE_LINK_LIBRARIES + "link libraries" "every-config;$<$<CONFIG:test>:test-config>") + +expect_property( + RequiresTest::Other IMPORTED_LINK_DEPENDENT_LIBRARIES + "dyld requirements (any config)" "RequiresTest::Private1") + +expect_property( + RequiresTest::Other IMPORTED_LINK_DEPENDENT_LIBRARIES_TEST + "dyld requirements ('TEST' config)" "RequiresTest::Private2") + ############################################################################### # Test importing of (language-specific) include paths. @@ -343,16 +355,10 @@ elseif(NOT TARGET DefaultConfigurationsTest::Target2) message(SEND_ERROR "DefaultConfigurationsTest::Target2 missing !") else() - get_property(dct1_configs - TARGET DefaultConfigurationsTest::Target1 PROPERTY IMPORTED_CONFIGURATIONS) - if(NOT "${dct1_configs}" STREQUAL "DEFAULT;TEST") - message(SEND_ERROR "DefaultConfigurationsTest::Target1 has wrong configurations '${dct1_configs}' !") - endif() - get_property(dct2_configs - TARGET DefaultConfigurationsTest::Target2 PROPERTY IMPORTED_CONFIGURATIONS) - if(NOT "${dct2_configs}" STREQUAL "TEST") - message(SEND_ERROR "DefaultConfigurationsTest::Target2 has wrong configurations '${dct2_configs}' !") - endif() - set(dct1_configs) - set(dct2_configs) + expect_property( + DefaultConfigurationsTest::Target1 IMPORTED_CONFIGURATIONS + "configurations" "DEFAULT;TEST") + expect_property( + DefaultConfigurationsTest::Target2 IMPORTED_CONFIGURATIONS + "configurations" "TEST") endif()
diff --git a/Tests/FindPackageCpsTest/cps/RequiresTest.cps b/Tests/FindPackageCpsTest/cps/RequiresTest.cps index cf2c522..3a6affb 100644 --- a/Tests/FindPackageCpsTest/cps/RequiresTest.cps +++ b/Tests/FindPackageCpsTest/cps/RequiresTest.cps
@@ -27,6 +27,23 @@ "ANSWER": 42 } } + }, + "Private1": { + "type": "dylib" + }, + "Private2": { + "type": "dylib" + }, + "Other": { + "type": "dylib", + "link_libraries": [ "every-config" ], + "dyld_requires": [ ":Private1" ], + "configurations": { + "test": { + "link_libraries": [ "test-config" ], + "dyld_requires": [ ":Private2" ] + } + } } } }
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 2fc19c7..6d23fc8 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt
@@ -685,6 +685,9 @@ endif() add_RunCMake_test(execute_process) add_RunCMake_test(export) +if(DEFINED CMake_TEST_LOCALE_CHARSET) + list(APPEND cmake_host_system_information_ARGS -DCMake_TEST_LOCALE_CHARSET=${CMake_TEST_LOCALE_CHARSET}) +endif() if(CMake_TEST_MSYSTEM_PREFIX) list(APPEND cmake_host_system_information_ARGS -DCMake_TEST_MSYSTEM_PREFIX=${CMake_TEST_MSYSTEM_PREFIX}) endif()
diff --git a/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-cpack-WIX-check.cmake b/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-cpack-WIX-check.cmake new file mode 100644 index 0000000..a7a28ae --- /dev/null +++ b/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-cpack-WIX-check.cmake
@@ -0,0 +1 @@ +include(${RunCMake_SOURCE_DIR}/cpack-check-common.cmake)
diff --git a/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-verify-stdout.txt b/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-verify-stdout.txt new file mode 100644 index 0000000..2c625fb --- /dev/null +++ b/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-verify-stdout.txt
@@ -0,0 +1,40 @@ +-- MyLib-1\.0\.0-(win64|windows-arm64)\.msi +Component: 'INSTALL_ROOT_RemoveFolderComponent' 'INSTALL_ROOT' +Component: 'CM_DP_applications\.bin_RemoveFolderComponent' 'CM_DP_applications\.bin' +Component: 'CM_DP_applications2\.bin_RemoveFolderComponent' 'CM_DP_applications2\.bin' +Component: 'CM_DP_extras\.extras_RemoveFolderComponent' 'CM_DP_extras\.extras' +Component: 'CM_DP_extras\.extras\.empty_RemoveFolderComponent' 'CM_DP_extras\.extras\.empty' +Component: 'CM_DP_headers\.include_RemoveFolderComponent' 'CM_DP_headers\.include' +Component: 'CM_DP_libraries\.lib_RemoveFolderComponent' 'CM_DP_libraries\.lib' +Component: 'CM_CP_applications\.bin\.my_libapp\.exe' 'CM_DP_applications\.bin' +Component: 'CM_SHORTCUT_applications' 'PROGRAM_MENU_FOLDER' +Component: 'CM_SHORTCUT_DESKTOP_applications' 'DesktopFolder' +Component: 'CM_CP_applications2\.bin\.my_other_app\.exe' 'CM_DP_applications2\.bin' +Component: 'CM_SHORTCUT_applications2' 'PROGRAM_MENU_FOLDER' +Component: 'CM_SHORTCUT_DESKTOP_applications2' 'DesktopFolder' +Component: 'CM_C_EMPTY_CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras\.empty' +Component: 'CM_CP_headers\.include\.file_with_spaces\.h' 'CM_DP_headers\.include' +Component: 'CM_CP_headers\.include\.mylib\.h' 'CM_DP_headers\.include' +Component: 'CM_CP_libraries\.lib\.mylib\.lib' 'CM_DP_libraries\.lib' +Directory: 'INSTALL_ROOT' 'LocalAppDataFolder' '[^']*\|CPack Component Example' +Directory: 'CM_DP_applications\.bin' 'INSTALL_ROOT' 'bin' +Directory: 'CM_DP_applications2\.bin' 'INSTALL_ROOT' 'bin' +Directory: 'CM_DP_extras\.extras' 'INSTALL_ROOT' 'extras' +Directory: 'CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras' 'empty' +Directory: 'CM_DP_headers\.include' 'INSTALL_ROOT' 'include' +Directory: 'CM_DP_libraries\.lib' 'INSTALL_ROOT' 'lib' +Directory: 'PROGRAM_MENU_FOLDER' 'ProgramMenuFolder' 'MyLib' +Directory: 'DesktopFolder' 'TARGETDIR' 'Desktop' +Directory: 'LocalAppDataFolder' 'TARGETDIR' '\.' +Directory: 'TARGETDIR' '' 'SourceDir' +Directory: 'ProgramMenuFolder' 'TARGETDIR' '\.' +File: 'CM_FP_applications\.bin\.my_libapp\.exe' 'CM_CP_applications\.bin\.my_libapp\.exe' '[^']*\|my-libapp\.exe' +File: 'CM_FP_applications2\.bin\.my_other_app\.exe' 'CM_CP_applications2\.bin\.my_other_app\.exe' '[^']*\|my-other-app\.exe' +File: 'CM_FP_headers\.include\.file_with_spaces\.h' 'CM_CP_headers\.include\.file_with_spaces\.h' '[^']*\|file with spaces\.h' +File: 'CM_FP_headers\.include\.mylib\.h' 'CM_CP_headers\.include\.mylib\.h' 'mylib\.h' +File: 'CM_FP_libraries\.lib\.mylib\.lib' 'CM_CP_libraries\.lib\.mylib\.lib' 'mylib\.lib' +Shortcut: 'CM_SP_applications\.bin\.my_libapp\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_applications' +Shortcut: 'CM_DSP_applications\.bin\.my_libapp\.exe' 'DesktopFolder' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications' +Shortcut: 'CM_SP_applications2\.bin\.my_other_app\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_applications2' +Shortcut: 'CM_DSP_applications2\.bin\.my_other_app\.exe' 'DesktopFolder' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications2' +--
diff --git a/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-check.cmake b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-check.cmake new file mode 100644 index 0000000..a7a28ae --- /dev/null +++ b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-check.cmake
@@ -0,0 +1 @@ +include(${RunCMake_SOURCE_DIR}/cpack-check-common.cmake)
diff --git a/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-stdout.txt b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-stdout.txt new file mode 100644 index 0000000..80e0e3a --- /dev/null +++ b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-stdout.txt
@@ -0,0 +1,13 @@ +CPack: Create package using WIX +CPack: Install projects +CPack: - Install project: CPackWiXGenerator \[Release\] +CPack: - Install component: applications +CPack: - Install component: applications2 +CPack: - Install component: empty1 +CPack: - Install component: empty2 +CPack: - Install component: extras +CPack: - Install component: headers +CPack: - Install component: libraries +CPack: Create package +CPack: - package: [^ +]*/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-build/MyLib-1\.0\.0-(win64|windows-arm64)\.msi generated\.
diff --git a/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-verify-stdout.txt b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-verify-stdout.txt new file mode 100644 index 0000000..bbd9fbe --- /dev/null +++ b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-verify-stdout.txt
@@ -0,0 +1,40 @@ +-- MyLib-1\.0\.0-(win64|windows-arm64)\.msi +Component: 'INSTALL_ROOT_RemoveFolderComponent' 'INSTALL_ROOT' +Component: 'CM_DP_applications\.bin_RemoveFolderComponent' 'CM_DP_applications\.bin' +Component: 'CM_CP_applications\.bin\.my_libapp\.exe' 'CM_DP_applications\.bin' +Component: 'CM_SHORTCUT_applications' 'PROGRAM_MENU_FOLDER' +Component: 'CM_SHORTCUT_DESKTOP_applications' 'DesktopFolder' +Component: 'CM_DP_applications2\.bin_RemoveFolderComponent' 'CM_DP_applications2\.bin' +Component: 'CM_CP_applications2\.bin\.my_other_app\.exe' 'CM_DP_applications2\.bin' +Component: 'CM_SHORTCUT_applications2' 'PROGRAM_MENU_FOLDER' +Component: 'CM_SHORTCUT_DESKTOP_applications2' 'DesktopFolder' +Component: 'CM_DP_extras\.extras_RemoveFolderComponent' 'CM_DP_extras\.extras' +Component: 'CM_DP_extras\.extras\.empty_RemoveFolderComponent' 'CM_DP_extras\.extras\.empty' +Component: 'CM_C_EMPTY_CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras\.empty' +Component: 'CM_DP_headers\.include_RemoveFolderComponent' 'CM_DP_headers\.include' +Component: 'CM_CP_headers\.include\.file_with_spaces\.h' 'CM_DP_headers\.include' +Component: 'CM_CP_headers\.include\.mylib\.h' 'CM_DP_headers\.include' +Component: 'CM_DP_libraries\.lib_RemoveFolderComponent' 'CM_DP_libraries\.lib' +Component: 'CM_CP_libraries\.lib\.mylib\.lib' 'CM_DP_libraries\.lib' +Directory: 'INSTALL_ROOT' 'LocalAppDataFolder' '[^']*\|CPack Component Example' +Directory: 'CM_DP_applications\.bin' 'INSTALL_ROOT' 'bin' +Directory: 'CM_DP_applications2\.bin' 'INSTALL_ROOT' 'bin' +Directory: 'CM_DP_extras\.extras' 'INSTALL_ROOT' 'extras' +Directory: 'CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras' 'empty' +Directory: 'CM_DP_headers\.include' 'INSTALL_ROOT' 'include' +Directory: 'CM_DP_libraries\.lib' 'INSTALL_ROOT' 'lib' +Directory: 'PROGRAM_MENU_FOLDER' 'ProgramMenuFolder' 'MyLib' +Directory: 'DesktopFolder' 'TARGETDIR' 'Desktop' +Directory: 'LocalAppDataFolder' 'TARGETDIR' 'LocalApp' +Directory: 'ProgramMenuFolder' 'TARGETDIR' 'PMenu' +Directory: 'TARGETDIR' '' 'SourceDir' +File: 'CM_FP_applications\.bin\.my_libapp\.exe' 'CM_CP_applications\.bin\.my_libapp\.exe' '[^']*\|my-libapp\.exe' +File: 'CM_FP_applications2\.bin\.my_other_app\.exe' 'CM_CP_applications2\.bin\.my_other_app\.exe' '[^']*\|my-other-app\.exe' +File: 'CM_FP_headers\.include\.file_with_spaces\.h' 'CM_CP_headers\.include\.file_with_spaces\.h' '[^']*\|file with spaces\.h' +File: 'CM_FP_headers\.include\.mylib\.h' 'CM_CP_headers\.include\.mylib\.h' 'mylib\.h' +File: 'CM_FP_libraries\.lib\.mylib\.lib' 'CM_CP_libraries\.lib\.mylib\.lib' 'mylib\.lib' +Shortcut: 'CM_SP_applications\.bin\.my_libapp\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_applications' +Shortcut: 'CM_DSP_applications\.bin\.my_libapp\.exe' 'DesktopFolder' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications' +Shortcut: 'CM_SP_applications2\.bin\.my_other_app\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_applications2' +Shortcut: 'CM_DSP_applications2\.bin\.my_other_app\.exe' 'DesktopFolder' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications2' +--
diff --git a/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake b/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake index bb34321..486271b 100644 --- a/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake
@@ -11,14 +11,21 @@ run_cpack(${v}-AppWiX SAMPLE AppWiX BUILD) endfunction() +function(run_cpack_wix_peruser v) + set(RunCMake_TEST_OPTIONS -DCPACK_WIX_VERSION=${v} -DCPACK_WIX_INSTALL_SCOPE=perUser) + run_cpack(${v}-AppWiX-perUser SAMPLE AppWiX BUILD) +endfunction() + if(CMake_TEST_CPACK_WIX3) set(ENV{PATH} "${CMake_TEST_CPACK_WIX3};${env_PATH}") run_cpack_wix(3) + run_cpack_wix_peruser(3) endif() if(CMake_TEST_CPACK_WIX4) set(ENV{PATH} "${CMake_TEST_CPACK_WIX4};${env_PATH}") set(ENV{WIX_EXTENSIONS} "${CMake_TEST_CPACK_WIX4}") run_cpack_wix(4) + run_cpack_wix_peruser(4) unset(ENV{WIX_EXTENSIONS}) endif()
diff --git a/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake b/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake index 8f6a656..be9c632 100644 --- a/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake +++ b/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake
@@ -3,7 +3,7 @@ # TODO(cxxmodules): Add instances of this test which test the policy # of the property's unset behavior. -# set(CMAKE_CXX_MODULE_STD …) +# set(CMAKE_CXX_MODULE_STD ...) add_library(nocxx23target) target_sources(nocxx23target
diff --git a/Tests/RunCMake/CXXModules/NoCXX26TargetUnset.cmake b/Tests/RunCMake/CXXModules/NoCXX26TargetUnset.cmake index 85108ff..c725490 100644 --- a/Tests/RunCMake/CXXModules/NoCXX26TargetUnset.cmake +++ b/Tests/RunCMake/CXXModules/NoCXX26TargetUnset.cmake
@@ -3,7 +3,7 @@ # TODO(cxxmodules): Add instances of this test which test the policy # of the property's unset behavior. -# set(CMAKE_CXX_MODULE_STD …) +# set(CMAKE_CXX_MODULE_STD ...) add_library(nocxx26target) target_sources(nocxx26target
diff --git a/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake index de3f027..663f9ca 100644 --- a/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake +++ b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake
@@ -177,6 +177,13 @@ run_cxx_module_test(scan_props) run_cxx_module_test(target-objects) + # mixed-bmi-compatibility requires a generator that implements per-importer + # BMI generation + if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND + RunCMake_GENERATOR MATCHES "Ninja") + run_cxx_module_test(mixed-bmi-compatibility) + endif() + if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND "import_std23" IN_LIST CMake_TEST_MODULE_COMPILATION) run_cxx_module_test(imp-std) @@ -251,6 +258,7 @@ # Tests which use named modules in shared libraries. if ("shared" IN_LIST CMake_TEST_MODULE_COMPILATION) run_cxx_module_test(library library-shared -DBUILD_SHARED_LIBS=ON) + run_cxx_module_test(shared-library-symbol-visibility) endif () # Tests which use partitions. @@ -274,22 +282,19 @@ run_cxx_module_test(imp-mods "imp-mods-${name}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/${name}-${type}" ${ARGN}) endfunction () -set(export_cps "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO=7fa7d13b-8308-4dc7-af39-9e450456d68f") -set(import_cps "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261") - # Tests which install BMIs if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION) run_cxx_module_test(exp-iface-no-props-build) - run_cxx_module_test(exp-iface-build exp-iface-build ${export_cps}) - run_cxx_module_test(exp-incdirs-build exp-incdirs-build ${export_cps}) + run_cxx_module_test(exp-iface-build) + run_cxx_module_test(exp-incdirs-build) run_cxx_module_test(exp-incdirs-old-cmake-build) run_cxx_module_test(exp-usage-build) run_cxx_module_test(exp-bmi-and-iface-build) - run_cxx_module_test(exp-command-sepdir-build exp-command-sepdir-build ${export_cps}) + run_cxx_module_test(exp-command-sepdir-build) run_cxx_module_test(exp-trans-targets-build) - run_cxx_module_test(exp-trans-mods1-build exp-trans-mods1-build ${export_cps}) - run_cxx_module_test(exp-trans-mods-build exp-trans-mods-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" ${export_cps} ${import_cps}) - run_cxx_module_test(exp-with-headers-build exp-with-headers-build ${export_cps}) + run_cxx_module_test(exp-trans-mods1-build) + run_cxx_module_test(exp-trans-mods-build exp-trans-mods-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build") + run_cxx_module_test(exp-with-headers-build) if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION) @@ -322,16 +327,16 @@ if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION) run_cxx_module_test(exp-iface-no-props-install) - run_cxx_module_test(exp-iface-install exp-iface-install ${export_cps}) - run_cxx_module_test(exp-incdirs-install exp-incdirs-install ${export_cps}) + run_cxx_module_test(exp-iface-install) + run_cxx_module_test(exp-incdirs-install) run_cxx_module_test(exp-incdirs-old-cmake-install) run_cxx_module_test(exp-usage-install) run_cxx_module_test(exp-bmi-and-iface-install) - run_cxx_module_test(exp-command-sepdir-install exp-command-sepdir-install ${export_cps}) + run_cxx_module_test(exp-command-sepdir-install) run_cxx_module_test(exp-trans-targets-install) - run_cxx_module_test(exp-trans-mods1-install exp-trans-mods1-install ${export_cps}) - run_cxx_module_test(exp-trans-mods-install exp-trans-mods-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install/lib/cmake/export_transitive_modules1_cps" ${export_cps} ${import_cps}) - run_cxx_module_test(exp-with-headers-install exp-with-headers-install ${export_cps}) + run_cxx_module_test(exp-trans-mods1-install) + run_cxx_module_test(exp-trans-mods-install exp-trans-mods-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install/lib/cmake/export_transitive_modules1_cps") + run_cxx_module_test(exp-with-headers-install) if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
diff --git a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake index 94e833a..4568873 100644 --- a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake +++ b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake
@@ -1,12 +1,27 @@ -if (RunCMake_GENERATOR_IS_MULTI_CONFIG) - set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/Debug/CXX.dd") - set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/Debug/CXXModules.json") -else () - set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/CXX.dd") - set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/CXXModules.json") +file(GLOB synth_dirs + "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/depchain_with_modules_json_file@synth_*.dir") + +list(LENGTH synth_dirs synth_dirs_len) +if (NOT synth_dirs_len EQUAL 1) + list(APPEND RunCMake_TEST_FAILED + "Expected exactly one synthetic target for consuming 'depchain_with_modules_json_file' but found ${synth_dirs_len}: ${synth_dirs}") endif () -if ("${RunCMake_TEST_BINARY_DIR}/${modules_json_path}" IS_NEWER_THAN "${RunCMake_TEST_BINARY_DIR}/${dep_modules_json_path}") +list(GET synth_dirs 0 synth_dir) + +if (RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/Debug/CXX.dd") + set(modules_json_path "${synth_dir}/Debug/CXXModules.json") +else () + set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/CXX.dd") + set(modules_json_path "${synth_dir}/CXXModules.json") +endif () + + +if ("${modules_json_path}" IS_NEWER_THAN "${RunCMake_TEST_BINARY_DIR}/${dep_modules_json_path}") + cmake_path(RELATIVE_PATH modules_json_path + BASE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + list(APPEND RunCMake_TEST_FAILED "Object '${dep_modules_json_path}' should have recompiled if '${modules_json_path}' changed.") endif ()
diff --git a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake index 9c3f2ff..2b2ce92 100644 --- a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake +++ b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake
@@ -1,7 +1,17 @@ +file(GLOB synth_dirs + "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/depchain_with_modules_json_file@synth_*.dir") + +list(LENGTH synth_dirs synth_dirs_len) +if (NOT synth_dirs_len EQUAL 1) + return() +endif() + +list(GET synth_dirs 0 synth_dir) + if (RunCMake_GENERATOR_IS_MULTI_CONFIG) - set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/Debug/CXXModules.json") + set(modules_json_path "${synth_dir}/Debug/CXXModules.json") else () - set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/CXXModules.json") + set(modules_json_path "${synth_dir}/CXXModules.json") endif () -file(TOUCH_NOCREATE "${RunCMake_TEST_BINARY_DIR}/${modules_json_path}") +file(TOUCH_NOCREATE "${modules_json_path}")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt index 6a7a48b..2fe8960 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt
@@ -36,7 +36,6 @@ "-Dexpected_dir=${CMAKE_CURRENT_SOURCE_DIR}" "-Dexport_sepdir_DIR=${CMAKE_CURRENT_BINARY_DIR}" "-Dexport_sepdir_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt index f41720e..928be0b 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt
@@ -40,7 +40,6 @@ "-Dexpected_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu" "-Dexport_sepdir_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_sepdir" "-Dexport_sepdir_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_sepdir_cps" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-iface-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-build-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-iface-build-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt index 3d21eff..80db2e9 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt
@@ -58,7 +58,6 @@ "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}" "-Dexport_interfaces_DIR=${CMAKE_CURRENT_BINARY_DIR}" "-Dexport_interfaces_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-iface-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-install-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-iface-install-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt index a48ce85..b31033b 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt
@@ -62,7 +62,6 @@ "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi" "-Dexport_interfaces_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_interfaces" "-Dexport_interfaces_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_interfaces_cps" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt index 5caee96..a1607e4 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt
@@ -64,7 +64,6 @@ "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}" "-Dexport_include_directories_DIR=${CMAKE_CURRENT_BINARY_DIR}" "-Dexport_include_directories_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt index 7ce17c0..afda611 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt
@@ -74,7 +74,6 @@ "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi" "-Dexport_include_directories_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_include_directories" "-Dexport_include_directories_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_include_directories_cps" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt index 99fecc8..8a87e7a 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt
@@ -71,7 +71,6 @@ "-Dexport_transitive_modules_DIR=${CMAKE_CURRENT_BINARY_DIR}" "-Dexport_transitive_modules1_cps_DIR=${CMAKE_PREFIX_PATH}" "-Dexport_transitive_modules_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt index d909125..bed56a0 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt
@@ -75,7 +75,6 @@ "-Dexport_transitive_modules_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules" "-Dexport_transitive_modules1_cps_DIR=${CMAKE_PREFIX_PATH}/lib/cmake/export_transitive_modules1_cps" "-Dexport_transitive_modules_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules_cps" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt index bba1a4f..530c61e 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt
@@ -47,7 +47,6 @@ "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}" "-Dexport_transitive_modules1_DIR=${CMAKE_CURRENT_BINARY_DIR}" "-Dexport_transitive_modules1_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt index 2c44f7b..dd37577 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt
@@ -51,7 +51,6 @@ "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi" "-Dexport_transitive_modules1_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules1" "-Dexport_transitive_modules1_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules1_cps" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt index e189c0b..8672cb8 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt
@@ -48,7 +48,6 @@ "${CMAKE_COMMAND}" "-Dexport_with_headers_DIR=${CMAKE_CURRENT_BINARY_DIR}" "-Dexport_with_headers_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install-stderr.txt deleted file mode 100644 index 4397b15..0000000 --- a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install-stderr.txt +++ /dev/null
@@ -1,5 +0,0 @@ -CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -This warning is for project developers\. Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt index a3ded85..2932501 100644 --- a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt
@@ -51,7 +51,6 @@ "${CMAKE_COMMAND}" "-Dexport_with_headers_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_with_headers" "-Dexport_with_headers_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_with_headers_cps" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261" ${generator} -S "${CMAKE_CURRENT_SOURCE_DIR}/test" -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt index 97d2325..d611029 100644 --- a/Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt +++ b/Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt
@@ -18,7 +18,9 @@ BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" FILES - importable.cxx) + importable.ixx + PRIVATE + importable.cxx) target_compile_features(library PUBLIC cxx_std_20) add_executable(exe)
diff --git a/Tests/RunCMake/CXXModulesCompile/library/importable.cxx b/Tests/RunCMake/CXXModulesCompile/library/importable.cxx index 72ed0df..859fa3d 100644 --- a/Tests/RunCMake/CXXModulesCompile/library/importable.cxx +++ b/Tests/RunCMake/CXXModulesCompile/library/importable.cxx
@@ -1,8 +1,6 @@ -export module importable; +module importable; -#include "library_export.h" - -export LIBRARY_EXPORT int from_import() +int from_import() { return 0; }
diff --git a/Tests/RunCMake/CXXModulesCompile/library/importable.ixx b/Tests/RunCMake/CXXModulesCompile/library/importable.ixx new file mode 100644 index 0000000..d3fb7f6 --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/library/importable.ixx
@@ -0,0 +1,5 @@ +export module importable; + +#include "library_export.h" + +export LIBRARY_EXPORT int from_import();
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility-build-check.cmake b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility-build-check.cmake new file mode 100644 index 0000000..a53b3ca --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility-build-check.cmake
@@ -0,0 +1,111 @@ +# Verify the build system generated a synthetic target/BMI for each unique importer +set(expected_consumers consumer20 consumer23) +set(linked_dir_keys "") +set(linked_dir_names "") + +if (DEFINED RunCMake_TEST_CONFIG) + set(config_dir "${RunCMake_TEST_CONFIG}") +else () + set(config_dir "Debug") +endif () + +# Get and check linked-target-dirs for each consumer +foreach (consumer IN LISTS expected_consumers) + + if (RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(output_dir "${consumer}.dir/${config_dir}") + else () + set(output_dir "${consumer}.dir") + endif () + + set(depend_info_file "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${output_dir}/CXXDependInfo.json") + if (NOT EXISTS "${depend_info_file}") + list(APPEND RunCMake_TEST_FAILED + "Could not find CXXDependInfo.json for consumer ${consumer}: checked ${depend_info_file}") + continue() + endif () + + file(READ "${depend_info_file}" depend_info_json) + + # Extract linked-target-dirs array length and first element + string(JSON linked_dirs_len LENGTH "${depend_info_json}" "linked-target-dirs") + string(JSON linked_dirs GET "${depend_info_json}" "linked-target-dirs") + + if (NOT linked_dirs_len GREATER 0) + list(APPEND RunCMake_TEST_FAILED + "Consumer '${consumer}' has no linked-target-dirs but expected synthetic target for 'importable'") + continue() + endif () + + # For this test, expect exactly one linked target dir per consumer + if (NOT linked_dirs_len EQUAL 1) + list(APPEND RunCMake_TEST_FAILED + "Expected 1 linked-target-dir for '${consumer}' but found ${linked_dirs_len}: ${linked_dirs}") + continue() + endif () + + string(JSON linked_dir GET "${depend_info_json}" "linked-target-dirs" 0) + + if (RunCMake_GENERATOR_IS_MULTI_CONFIG) + cmake_path(GET linked_dir PARENT_PATH linked_tgt_root) + else () + set(linked_tgt_root "${linked_dir}") + endif () + + cmake_path(GET linked_tgt_root FILENAME linked_tgt_name) + + # Verify it is a synthetic target for the 'importable' library + if (NOT linked_tgt_name MATCHES "^importable@synth_[A-Za-z0-9_]+\.dir$") + list(APPEND RunCMake_TEST_FAILED + "Consumer '${consumer}' should link to synthetic target dir for 'importable' but found ${linked_dir}") + continue() + endif () + + if (RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(linked_output_dir "${linked_dir}/${config_dir}") + else () + set(linked_output_dir "${linked_dir}") + endif () + + # Verify the synthetic target dir exists and contains a BMI + if (NOT EXISTS "${linked_dir}") + list(APPEND RunCMake_TEST_FAILED + "Consumer '${consumer}' links to synthetic target directory that does not exist: ${linked_dir}") + continue() + endif () + + file(GLOB_RECURSE bmi_files "${linked_dir}/*.bmi") + if (NOT bmi_files) + list(APPEND RunCMake_TEST_FAILED + "No BMI files found in synthetic target directory: ${linked_dir}") + continue() + endif () + + # Record the consumers of each linked dir to verify uniqueness + string(REGEX REPLACE "[^A-Za-z0-9_]" "_" linked_dir_key "${linked_tgt_name}") + set(linked_dir_consumers_var "linked_dir_consumers_${linked_dir_key}") + if (NOT DEFINED ${linked_dir_consumers_var}) + list(APPEND linked_dir_keys "${linked_dir_key}") + list(APPEND linked_dir_names "${linked_tgt_name}") + endif () + + list(APPEND ${linked_dir_consumers_var} ${consumer}) + +endforeach () + +# Verify each synthetic target is consumed exactly once +foreach (linked_dir_key IN LISTS linked_dir_keys) + set(consumers "${linked_dir_consumers_${linked_dir_key}}") + list(LENGTH consumers linked_dir_consumer_count) + + if (linked_dir_consumer_count GREATER 1) + list(FIND linked_dir_keys ${linked_dir_key} linked_dir_index) + list(GET linked_dir_names ${linked_dir_index} linked_tgt_name) + + string(JOIN ", " linked_dir_consumers_joined ${consumers}) + list(APPEND RunCMake_TEST_FAILED + "Expected per-importer BMI generation, but '${linked_tgt_name}' is linked to by multiple targets: ${linked_dir_consumers_joined}") + endif () +endforeach () + +string(REPLACE ";" "\n " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/CMakeLists.txt new file mode 100644 index 0000000..4af50c8 --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/CMakeLists.txt
@@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.24...3.28) +project(cxx_modules_mixed_bmi_compatibility CXX) + +include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") + +add_library(importable) +target_sources(importable + PUBLIC FILE_SET CXX_MODULES FILES importable.cxx) + +target_compile_features(importable PUBLIC cxx_std_20) + +add_executable(consumer20 consumer20.cxx) +target_compile_features(consumer20 PRIVATE cxx_std_20) +target_link_libraries(consumer20 PRIVATE importable) + +add_executable(consumer23 consumer23.cxx) +target_compile_features(consumer23 PRIVATE cxx_std_23) +target_link_libraries(consumer23 PRIVATE importable) + +add_test(NAME consumer20 COMMAND consumer20) +add_test(NAME consumer23 COMMAND consumer23)
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer20.cxx b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer20.cxx new file mode 100644 index 0000000..5f0bbbc --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer20.cxx
@@ -0,0 +1,9 @@ +#include <iostream> + +import importable; + +int main() +{ + std::cout << "from_import() = " << from_import() << '\n'; + return 0; +}
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer23.cxx b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer23.cxx new file mode 100644 index 0000000..e36852b --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer23.cxx
@@ -0,0 +1,9 @@ +#include <print> + +import importable; + +int main() +{ + std::println("from_import() = {}", from_import()); + return 0; +}
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/importable.cxx b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/importable.cxx new file mode 100644 index 0000000..607680a --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/importable.cxx
@@ -0,0 +1,6 @@ +export module importable; + +export int from_import() +{ + return 0; +}
diff --git a/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/CMakeLists.txt new file mode 100644 index 0000000..7f3d290 --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/CMakeLists.txt
@@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.24...3.28) +project(cxx_modules_library CXX) + +include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") + +include(GenerateExportHeader) + +add_library(library SHARED) +generate_export_header(library) +target_sources(library + PUBLIC + FILE_SET HEADERS + BASE_DIRS + "${CMAKE_CURRENT_BINARY_DIR}" + FILES + "${CMAKE_CURRENT_BINARY_DIR}/library_export.h" + FILE_SET CXX_MODULES + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + importable.ixx + PRIVATE + importable.cxx) +target_compile_features(library PUBLIC cxx_std_20) +target_compile_definitions(library INTERFACE CHECK_IMPORT_INTERFACE) + +add_executable(exe) +target_link_libraries(exe PRIVATE library) +target_sources(exe + PRIVATE + main.cxx) + +add_test(NAME exe COMMAND exe)
diff --git a/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.cxx b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.cxx new file mode 100644 index 0000000..859fa3d --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.cxx
@@ -0,0 +1,6 @@ +module importable; + +int from_import() +{ + return 0; +}
diff --git a/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.ixx b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.ixx new file mode 100644 index 0000000..dd5fa68 --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.ixx
@@ -0,0 +1,15 @@ +export module importable; + +#include "library_export.h" + +#ifdef CHECK_IMPORT_INTERFACE +# ifdef library_EXPORTS +# error "library_EXPORTS defined but should NOT be defined when importing module" +# endif +#else +# ifndef library_EXPORTS +# error "library_EXPORTS NOT defined but should be defined when building module" +# endif +#endif + +export LIBRARY_EXPORT int from_import();
diff --git a/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/main.cxx b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/main.cxx new file mode 100644 index 0000000..feb38d2 --- /dev/null +++ b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/main.cxx
@@ -0,0 +1,6 @@ +import importable; + +int main(int argc, char* argv[]) +{ + return from_import(); +}
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index f42709c..b54a01a 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -837,7 +837,7 @@ file(WRITE "${out}/first_file.txt" "first file to append\n") file(WRITE "${out}/second_file.txt" "second file to append\n") file(WRITE "${out}/empty_file.txt" "") -file(WRITE "${out}/unicode_file.txt" "àéùç - 한국어") # Korean in Korean +file(WRITE "${out}/unicode_file.txt" "àéùç - 한국어") # UTF-8: Korean in Korean run_cmake_command(E_cat_good_cat ${CMAKE_COMMAND} -E cat "${out}/first_file.txt" "${out}/second_file.txt" "${out}/empty_file.txt" "${out}/unicode_file.txt")
diff --git a/Tests/RunCMake/CpsExportImportBuild/RunCMakeTest.cmake b/Tests/RunCMake/CpsExportImportBuild/RunCMakeTest.cmake index c69ebbd..d0c460d 100644 --- a/Tests/RunCMake/CpsExportImportBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/CpsExportImportBuild/RunCMakeTest.cmake
@@ -1,11 +1,5 @@ include(RunCMake) -set(RunCMake_TEST_OPTIONS - -Wno-dev - "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" - ) - function(build_project test) set(RunCMake_TEST_NO_CLEAN FALSE) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
diff --git a/Tests/RunCMake/CpsExportImportInstall/RunCMakeTest.cmake b/Tests/RunCMake/CpsExportImportInstall/RunCMakeTest.cmake index 31d503b..bdc5e34 100644 --- a/Tests/RunCMake/CpsExportImportInstall/RunCMakeTest.cmake +++ b/Tests/RunCMake/CpsExportImportInstall/RunCMakeTest.cmake
@@ -1,11 +1,5 @@ include(RunCMake) -set(RunCMake_TEST_OPTIONS - -Wno-dev - "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" - ) - function(build_project test) set(RunCMake_TEST_NO_CLEAN FALSE) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
diff --git a/Tests/RunCMake/CpsMapConfig/RunCMakeTest.cmake b/Tests/RunCMake/CpsMapConfig/RunCMakeTest.cmake index cd0cd2d..0a381d6 100644 --- a/Tests/RunCMake/CpsMapConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/CpsMapConfig/RunCMakeTest.cmake
@@ -1,10 +1,5 @@ include(RunCMake) -set(RunCMake_TEST_OPTIONS - -Wno-dev - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" - ) - function(build_project test) set(RunCMake_TEST_NO_CLEAN FALSE) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
diff --git a/Tests/RunCMake/DependencyProviders/RedirectFetchContentSerial-stderr.txt b/Tests/RunCMake/DependencyProviders/RedirectFetchContentSerial-stderr.txt index 047a64b..c168e07 100644 --- a/Tests/RunCMake/DependencyProviders/RedirectFetchContentSerial-stderr.txt +++ b/Tests/RunCMake/DependencyProviders/RedirectFetchContentSerial-stderr.txt
@@ -2,6 +2,8 @@ Could not find a package configuration file provided by "SomeDep" with any of the following names: + SomeDep\.cps + somedep\.cps SomeDepConfig\.cmake somedep-config\.cmake
diff --git a/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake b/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake index f350661..f72942d 100644 --- a/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake +++ b/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake
@@ -3,8 +3,6 @@ set(common_test_options -Wno-dev "-DCMAKE_EXPERIMENTAL_GENERATE_SBOM:STRING=ca494ed3-b261-4205-a01f-603c95e4cae0" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" - "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f" "-DCMAKE_INSTALL_SBOM_FORMATS:STRING=JSON" "-DCMAKE_INSTALL_LIBDIR=lib" )
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-result.txt b/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-result.txt +++ /dev/null
@@ -1 +0,0 @@ -1
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-stderr.txt b/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-stderr.txt deleted file mode 100644 index b0d7bc9..0000000 --- a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-stderr.txt +++ /dev/null
@@ -1,2 +0,0 @@ -CMake Error at ExperimentalGate\.cmake:5 \(export\): - export does not recognize sub-command PACKAGE_INFO
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate.cmake b/Tests/RunCMake/ExportPackageInfo/ExperimentalGate.cmake deleted file mode 100644 index 96b19cd..0000000 --- a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate.cmake +++ /dev/null
@@ -1,5 +0,0 @@ -unset(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO) - -add_library(foo INTERFACE) -install(TARGETS foo EXPORT foo DESTINATION .) -export(PACKAGE_INFO foo EXPORT foo)
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning-stderr.txt b/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning-stderr.txt deleted file mode 100644 index d81b375..0000000 --- a/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning-stderr.txt +++ /dev/null
@@ -1,7 +0,0 @@ -CMake Warning \(dev\) at ExperimentalWarning\.cmake:8 \(export\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -Call Stack \(most recent call first\): - CMakeLists\.txt:3 \(include\) -This warning is for project developers\. Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning.cmake b/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning.cmake deleted file mode 100644 index f994893..0000000 --- a/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning.cmake +++ /dev/null
@@ -1,8 +0,0 @@ -set( - CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO - "7fa7d13b-8308-4dc7-af39-9e450456d68f" - ) - -add_library(foo INTERFACE) -install(TARGETS foo EXPORT foo DESTINATION .) -export(PACKAGE_INFO foo EXPORT foo)
diff --git a/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries-check.cmake b/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries-check.cmake new file mode 100644 index 0000000..19eb3f1 --- /dev/null +++ b/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries-check.cmake
@@ -0,0 +1,15 @@ +include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake) + +set(out_dir "${RunCMake_BINARY_DIR}/LinkDependentLibraries-build") + +file(READ "${out_dir}/dyld.cps" content) +expect_value("${content}" "dyld" "name") +expect_value("${content}" "dylib" "components" "private" "type") +expect_value("${content}" "dylib" "components" "public" "type") + +expect_array( + "${content}" 1 + "components" "public" "configurations" "generic" "dyld_requires") +expect_value( + "${content}" ":private" + "components" "public" "configurations" "generic" "dyld_requires" 0)
diff --git a/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries.cmake b/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries.cmake new file mode 100644 index 0000000..1867ae6 --- /dev/null +++ b/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries.cmake
@@ -0,0 +1,16 @@ +project(dyld CXX) + +get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(_isMultiConfig) + set(CMAKE_CONFIGURATION_TYPES "generic" CACHE STRING "" FORCE) +else() + set(CMAKE_BUILD_TYPE "generic" CACHE STRING "" FORCE) +endif() + +add_library(private SHARED foo.cxx) +add_library(public SHARED foo.cxx) + +target_link_libraries(public PRIVATE private) + +install(TARGETS private public EXPORT dyld DESTINATION .) +export(PACKAGE_INFO dyld EXPORT dyld)
diff --git a/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake b/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake index 3454a69..e2582cf 100644 --- a/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake
@@ -1,20 +1,5 @@ include(RunCMake) -# Test experimental gate -run_cmake(ExperimentalGate) -run_cmake(ExperimentalWarning) - -# Test version check author warning -# TODO Move to be with other tests when experimental gate is removed. -run_cmake(VersionCheckWarning) - -# Enable experimental feature and suppress warnings -set(RunCMake_TEST_OPTIONS - -Wno-dev - "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" - ) - # Test incorrect usage run_cmake(BadArgs0) run_cmake(BadArgs1) @@ -43,6 +28,7 @@ run_cmake(MinimalVersion) run_cmake(LowerCaseFile) run_cmake(Requirements) +run_cmake(LinkDependentLibraries) run_cmake(ExportSymbolicComponent) run_cmake(TargetTypes) run_cmake(DependsMultiple) @@ -55,5 +41,5 @@ run_cmake(DependencyVersionCps) run_cmake(TransitiveSymbolicComponent) run_cmake(VersionCheck) -# run_cmake(VersionCheckWarning) +run_cmake(VersionCheckWarning) run_cmake(VersionCheckError)
diff --git a/Tests/RunCMake/ExportPackageInfo/VersionCheckWarning.cmake b/Tests/RunCMake/ExportPackageInfo/VersionCheckWarning.cmake index 4bb2d11..b87f282 100644 --- a/Tests/RunCMake/ExportPackageInfo/VersionCheckWarning.cmake +++ b/Tests/RunCMake/ExportPackageInfo/VersionCheckWarning.cmake
@@ -1,8 +1,3 @@ -set( - CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO - "7fa7d13b-8308-4dc7-af39-9e450456d68f" -) - add_library(foo INTERFACE) install(TARGETS foo EXPORT foo DESTINATION .)
diff --git a/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake b/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake index 1d81ee6..5e09f91 100644 --- a/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake
@@ -3,8 +3,6 @@ set(common_test_options -Wno-dev "-DCMAKE_EXPERIMENTAL_GENERATE_SBOM:STRING=ca494ed3-b261-4205-a01f-603c95e4cae0" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" - "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f" ) function(run_cmake_install test)
diff --git a/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake b/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake index 57f74a2..87b9048 100644 --- a/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake
@@ -6,6 +6,8 @@ run_cmake(UnityBatchSize) run_cmake(UnityGroup) run_cmake(UnityIsolate) +run_cmake(UnitySubdirs) +run_cmake(UnitySubdirsIsolate) run_cmake(DisableCaching) run_cmake(DisableDistribution) run_cmake(SetCompilerProps)
diff --git a/Tests/RunCMake/FASTBuild/UnitySubdirs-check.cmake b/Tests/RunCMake/FASTBuild/UnitySubdirs-check.cmake new file mode 100644 index 0000000..a249da3 --- /dev/null +++ b/Tests/RunCMake/FASTBuild/UnitySubdirs-check.cmake
@@ -0,0 +1,23 @@ +# Verify that files from different subdirectories are combined into a single Unity node. + +set(REGEX_TO_MATCH " + Unity\\('main_Unity_1'\\) + { + \\.UnityOutputPath = 'CMakeFiles/main.dir' + \\.UnityOutputPattern = 'main_Unity_1.cpp' + \\.UnityInputFiles = + { + .*main.cpp', + .*subdir1/file1.cpp', + .*subdir2/file2.cpp' + } + } +.*ObjectList.* +.* + .CompilerInputUnity = + { + 'main_Unity_1' + } +") + +include(${RunCMake_SOURCE_DIR}/check.cmake)
diff --git a/Tests/RunCMake/FASTBuild/UnitySubdirs.cmake b/Tests/RunCMake/FASTBuild/UnitySubdirs.cmake new file mode 100644 index 0000000..a2d50fa --- /dev/null +++ b/Tests/RunCMake/FASTBuild/UnitySubdirs.cmake
@@ -0,0 +1,16 @@ +# Test that unity build combines files from different subdirectories into the same unity bucket. + +set(CMAKE_UNITY_BUILD ON) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/subdir1) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/subdir2) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp "int main() { return 0; }\n") +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/subdir1/file1.cpp "int file1() { return 1; }\n") +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/subdir2/file2.cpp "int file2() { return 2; }\n") + +add_executable(main + ${CMAKE_CURRENT_BINARY_DIR}/main.cpp + ${CMAKE_CURRENT_BINARY_DIR}/subdir1/file1.cpp + ${CMAKE_CURRENT_BINARY_DIR}/subdir2/file2.cpp +)
diff --git a/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate-check.cmake b/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate-check.cmake new file mode 100644 index 0000000..2431660 --- /dev/null +++ b/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate-check.cmake
@@ -0,0 +1,26 @@ +# Verify that: +# 1. Non-isolated files from different subdirs are combined in one Unity node +# 2. Isolated files from subdirs are in separate ObjectLists with proper subdir paths + +# Check that Unity node contains the non-isolated files (main.cpp and unity_file.cpp) +# but not the isolated file. The isolated file should be compiled separately with +# its subdirectory in the output path. +set(REGEX_TO_MATCH " + Unity\\('main_Unity_1'\\) + { + \\.UnityOutputPath = 'CMakeFiles/main.dir' + \\.UnityOutputPattern = 'main_Unity_1.cpp' + \\.UnityInputFiles = + { + .*main.cpp', + .*subdir1/unity_file.cpp' + } + } +.*ObjectList.* +.* + \\.CompilerOutputPath = 'CMakeFiles/main.dir/subdir2' +.* + .*isolated_file.cpp' +") + +include(${RunCMake_SOURCE_DIR}/check.cmake)
diff --git a/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate.cmake b/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate.cmake new file mode 100644 index 0000000..8d37f93 --- /dev/null +++ b/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate.cmake
@@ -0,0 +1,23 @@ +# Test that isolated files from subdirectories get proper subdirectory-based object paths, +# while non-isolated files are combined in unity buckets regardless of subdirectory. + +set(CMAKE_UNITY_BUILD ON) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/subdir1) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/subdir2) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp "int main() { return 0; }\n") +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/subdir1/unity_file.cpp "int unity_file() { return 1; }\n") +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/subdir2/isolated_file.cpp "int isolated_file() { return 2; }\n") + +add_executable(main + ${CMAKE_CURRENT_BINARY_DIR}/main.cpp + ${CMAKE_CURRENT_BINARY_DIR}/subdir1/unity_file.cpp + ${CMAKE_CURRENT_BINARY_DIR}/subdir2/isolated_file.cpp +) + +set_source_files_properties( + ${CMAKE_CURRENT_BINARY_DIR}/subdir2/isolated_file.cpp + TARGET_DIRECTORY main + PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON +)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt index b761f9c..1b2c7d8 100644 --- a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt +++ b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt
@@ -1,4 +1,4 @@ -CMake Warning \(dev\) at ExperimentalWarning\.cmake:13 \(install\): +CMake Warning \(dev\) at ExperimentalWarning\.cmake:[0-9]+ \(install\): CMake's support for generating package information in the Common Package Specification format from CMake script exports is experimental\. It is meant only for experimentation and feedback to CMake developers\.
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake index e2740a8..941fe54 100644 --- a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake +++ b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake
@@ -1,8 +1,4 @@ set( - CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO - "7fa7d13b-8308-4dc7-af39-9e450456d68f" - ) -set( CMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO "ababa1b5-7099-495f-a9cd-e22d38f274f2" )
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake index f77161b..54f3e37 100644 --- a/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake +++ b/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake
@@ -7,7 +7,6 @@ # Enable experimental feature and suppress warnings set(RunCMake_TEST_OPTIONS -Wno-dev - "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f" "-DCMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO:STRING=ababa1b5-7099-495f-a9cd-e22d38f274f2" )
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-result.txt b/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-result.txt +++ /dev/null
@@ -1 +0,0 @@ -1
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-stderr.txt b/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-stderr.txt deleted file mode 100644 index d7ad6ff..0000000 --- a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-stderr.txt +++ /dev/null
@@ -1,2 +0,0 @@ -CMake Error at ExperimentalGate\.cmake:5 \(install\): - install does not recognize sub-command PACKAGE_INFO
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate.cmake b/Tests/RunCMake/InstallPackageInfo/ExperimentalGate.cmake deleted file mode 100644 index 327d3bb..0000000 --- a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate.cmake +++ /dev/null
@@ -1,5 +0,0 @@ -unset(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO) - -add_library(foo INTERFACE) -install(TARGETS foo EXPORT foo DESTINATION .) -install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning-stderr.txt b/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning-stderr.txt deleted file mode 100644 index acac23b..0000000 --- a/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning-stderr.txt +++ /dev/null
@@ -1,7 +0,0 @@ -CMake Warning \(dev\) at ExperimentalWarning\.cmake:8 \(install\): - CMake's support for exporting package information in the Common Package - Specification format is experimental\. It is meant only for experimentation - and feedback to CMake developers\. -Call Stack \(most recent call first\): - CMakeLists\.txt:3 \(include\) -This warning is for project developers\. Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning.cmake b/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning.cmake deleted file mode 100644 index 3c6b90d..0000000 --- a/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning.cmake +++ /dev/null
@@ -1,8 +0,0 @@ -set( - CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO - "7fa7d13b-8308-4dc7-af39-9e450456d68f" - ) - -add_library(foo INTERFACE) -install(TARGETS foo EXPORT foo DESTINATION .) -install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)
diff --git a/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake b/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake index 2f3be0c..56ee883 100644 --- a/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake +++ b/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake
@@ -1,20 +1,5 @@ include(RunCMake) -# Test experimental gate -run_cmake(ExperimentalGate) -run_cmake(ExperimentalWarning) - -# Test version check author warning -# TODO Move to be with other tests when experimental gate is removed. -run_cmake(VersionCheckWarning) - -# Enable experimental feature and suppress warnings -set(RunCMake_TEST_OPTIONS - -Wno-dev - "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" - ) - function(run_cmake_install test) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build) if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG) @@ -64,6 +49,6 @@ run_cmake(TransitiveSymbolicComponent) run_cmake(InstallSymbolicComponent) run_cmake(VersionCheck) -# run_cmake(VersionCheckWarning) +run_cmake(VersionCheckWarning) run_cmake(VersionCheckError) run_cmake_install(Destination)
diff --git a/Tests/RunCMake/InstallPackageInfo/VersionCheckWarning.cmake b/Tests/RunCMake/InstallPackageInfo/VersionCheckWarning.cmake index 833fbbf..62ee7d0 100644 --- a/Tests/RunCMake/InstallPackageInfo/VersionCheckWarning.cmake +++ b/Tests/RunCMake/InstallPackageInfo/VersionCheckWarning.cmake
@@ -1,8 +1,3 @@ -set( - CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO - "7fa7d13b-8308-4dc7-af39-9e450456d68f" -) - add_library(foo INTERFACE) install(TARGETS foo EXPORT foo DESTINATION .)
diff --git a/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake b/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake index 525a371..ef6b864 100644 --- a/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake +++ b/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake
@@ -3,8 +3,6 @@ set(common_test_options -Wno-dev "-DCMAKE_EXPERIMENTAL_GENERATE_SBOM:STRING=ca494ed3-b261-4205-a01f-603c95e4cae0" - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" - "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f" ) function(run_cmake_install test)
diff --git a/Tests/RunCMake/Ninja/Intl-common.cmake b/Tests/RunCMake/Ninja/Intl-common.cmake index 7703976..a26e517 100644 --- a/Tests/RunCMake/Ninja/Intl-common.cmake +++ b/Tests/RunCMake/Ninja/Intl-common.cmake
@@ -1 +1 @@ -set(intl "intl-ë®") +set(intl "intl-ë®") # UTF-8
diff --git a/Tests/RunCMake/add_test/CMP0110-Common-OtherSpecialChars.cmake b/Tests/RunCMake/add_test/CMP0110-Common-OtherSpecialChars.cmake index f74c3b5..2a53a3c 100644 --- a/Tests/RunCMake/add_test/CMP0110-Common-OtherSpecialChars.cmake +++ b/Tests/RunCMake/add_test/CMP0110-Common-OtherSpecialChars.cmake
@@ -1,2 +1,2 @@ -set(TEST_NAME "!§%&/ü:*😤~") +set(TEST_NAME "!§%&/ü:*😤~") # UTF-8 include(CMP0110-Common.cmake)
diff --git a/Tests/RunCMake/cmake_host_system_information/Locale-stdout-iso-8859-1.txt b/Tests/RunCMake/cmake_host_system_information/Locale-stdout-iso-8859-1.txt new file mode 100644 index 0000000..2307984 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Locale-stdout-iso-8859-1.txt
@@ -0,0 +1 @@ +^-- LOCALE_CHARSET='ISO-8859-1'$
diff --git a/Tests/RunCMake/cmake_host_system_information/Locale-stdout-utf-8.txt b/Tests/RunCMake/cmake_host_system_information/Locale-stdout-utf-8.txt new file mode 100644 index 0000000..f15d5c9 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Locale-stdout-utf-8.txt
@@ -0,0 +1 @@ +^-- LOCALE_CHARSET='UTF-8'$
diff --git a/Tests/RunCMake/cmake_host_system_information/Locale-stdout.txt b/Tests/RunCMake/cmake_host_system_information/Locale-stdout.txt new file mode 100644 index 0000000..3cb5e72 --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Locale-stdout.txt
@@ -0,0 +1 @@ +^-- LOCALE_CHARSET='[^']+'$
diff --git a/Tests/RunCMake/cmake_host_system_information/Locale.cmake b/Tests/RunCMake/cmake_host_system_information/Locale.cmake new file mode 100644 index 0000000..32b31be --- /dev/null +++ b/Tests/RunCMake/cmake_host_system_information/Locale.cmake
@@ -0,0 +1,2 @@ +cmake_host_system_information(RESULT charset QUERY LOCALE_CHARSET) +message(STATUS "LOCALE_CHARSET='${charset}'")
diff --git a/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt b/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt index 1a43221..3575c84 100644 --- a/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt +++ b/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt
@@ -23,6 +23,7 @@ -- PROCESSOR_SERIAL_NUMBER=`.*` -- PROCESSOR_NAME=`.*` -- PROCESSOR_DESCRIPTION=`.*` +-- LOCALE_CHARSET=`[^`]+` -- OS_NAME=`.*` -- OS_RELEASE=`.*` -- OS_VERSION=`.*`
diff --git a/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake b/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake index 2b497fb..408dd0d 100644 --- a/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake +++ b/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake
@@ -28,6 +28,7 @@ try_and_print(PROCESSOR_SERIAL_NUMBER) try_and_print(PROCESSOR_NAME) try_and_print(PROCESSOR_DESCRIPTION) +try_and_print(LOCALE_CHARSET) try_and_print(OS_NAME) try_and_print(OS_RELEASE) try_and_print(OS_VERSION)
diff --git a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake index 3917913..803518a 100644 --- a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake +++ b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
@@ -7,6 +7,14 @@ run_cmake(QueryList) run_cmake(QueryKeys) +if(CMake_TEST_LOCALE_CHARSET STREQUAL "UTF-8" OR CMAKE_HOST_WIN32) + set(RunCMake-stdout-file Locale-stdout-utf-8.txt) +elseif(CMake_TEST_LOCALE_CHARSET STREQUAL "ISO-8859-1") + set(RunCMake-stdout-file Locale-stdout-iso-8859-1.txt) +endif() +run_cmake_script(Locale) +unset(RunCMake-stdout-file) + run_cmake(UnitTest) run_cmake(Exherbo) run_cmake(Ubuntu)
diff --git a/Tests/RunCMake/file/REAL_PATH.cmake b/Tests/RunCMake/file/REAL_PATH.cmake index 0485655..a8a3d0e 100644 --- a/Tests/RunCMake/file/REAL_PATH.cmake +++ b/Tests/RunCMake/file/REAL_PATH.cmake
@@ -88,6 +88,10 @@ file(REAL_PATH "${low}" out) if(NOT "${out}" PATH_EQUAL "${in}") - message(SEND_ERROR "real path is \"${out}\", should be \"${in}\"") + message(SEND_ERROR + "real path is:\n" + " \"${out}\"\n" + "but should be:\n" + " \"${in}\"") endif() endif()
diff --git a/Tests/RunCMake/find_package-CPS/ExperimentalWarning-stderr.txt b/Tests/RunCMake/find_package-CPS/ExperimentalWarning-stderr.txt deleted file mode 100644 index d23e7d5..0000000 --- a/Tests/RunCMake/find_package-CPS/ExperimentalWarning-stderr.txt +++ /dev/null
@@ -1,27 +0,0 @@ -CMake Warning \(dev\) at ExperimentalWarning\.cmake:[0-9]+ \(find_package\): - CMake's support for importing package information in the Common Package - Specification format \(via find_package\) is experimental\. It is meant only - for experimentation and feedback to CMake developers\. -Call Stack \(most recent call first\): - CMakeLists\.txt:3 \(include\) -This warning is for project developers\. Use -Wno-dev to suppress it\. - -CMake Warning at ExperimentalWarning\.cmake:[0-9]+ \(find_package\): - By not providing "FindDoesNotExist\.cmake" in CMAKE_MODULE_PATH this project - has asked CMake to find a package configuration file provided by - "DoesNotExist", but CMake did not find one\. - - Could not find a package configuration file provided by "DoesNotExist" with - any of the following names: - - DoesNotExist\.cps - doesnotexist\.cps - DoesNotExistConfig\.cmake - doesnotexist-config\.cmake - - Add the installation prefix of "DoesNotExist" to CMAKE_PREFIX_PATH or set - "DoesNotExist_DIR" to a directory containing one of the above files\. If - "DoesNotExist" provides a separate development package or SDK, be sure it - has been installed\. -Call Stack \(most recent call first\): - CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package-CPS/ExperimentalWarning.cmake b/Tests/RunCMake/find_package-CPS/ExperimentalWarning.cmake deleted file mode 100644 index 3837352..0000000 --- a/Tests/RunCMake/find_package-CPS/ExperimentalWarning.cmake +++ /dev/null
@@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 4.0) - -set( - CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES - "e82e467b-f997-4464-8ace-b00808fff261" - ) - -include(Setup.cmake) - -find_package(DoesNotExist)
diff --git a/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake b/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake index 944b80b..698a0bf 100644 --- a/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake
@@ -1,13 +1,5 @@ include(RunCMake) -run_cmake(ExperimentalWarning) - -# Enable experimental feature and suppress warnings -set(RunCMake_TEST_OPTIONS - -Wno-dev - "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" - ) - function(run_cmake_build test) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build) if(${ARGC} EQUAL 2)
diff --git a/Tests/RunCMake/find_package/ConfigureLog-config.txt b/Tests/RunCMake/find_package/ConfigureLog-config.txt index 4c39756..d55c2fe 100644 --- a/Tests/RunCMake/find_package/ConfigureLog-config.txt +++ b/Tests/RunCMake/find_package/ConfigureLog-config.txt
@@ -19,10 +19,16 @@ name: "ViaConfig" configs: - - filename: "ViaConfigConfig.cmake" + filename: "ViaConfig\.cps" + kind: "cps" + - + filename: "viaconfig\.cps" + kind: "cps" + - + filename: "ViaConfigConfig\.cmake" kind: "cmake" - - filename: "viaconfig-config.cmake" + filename: "viaconfig-config\.cmake" kind: "cmake" version_request: exact: false @@ -48,31 +54,63 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/ViaConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/ViaConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/viaconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/viaconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ViaConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/ViaConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/viaconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/ViaConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/viaconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ViaConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/viaconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/viaconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ViaConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ViaConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/viaconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/viaconfig-config\.cmake" mode: "config" reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ViaConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/viaconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ViaConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/viaconfig\.cps" + mode: "cps" + reason: "no_exist" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ViaConfig/ViaConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ViaConfig/ViaConfigConfig\.cmake" mode: "config" version: "1\.0" search_context:( @@ -104,9 +142,9 @@ CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY: true CMAKE_FIND_ROOT_PATH_MODE: "BOTH" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/FindViaModule.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/FindViaModule\.cmake" mode: "module" - version: "1.0" + version: "1\.0" search_context:( [^ ]*)+ @@ -117,10 +155,16 @@ name: "Inner" configs: - - filename: "InnerConfig.cmake" + filename: "Inner\.cps" + kind: "cps" + - + filename: "inner\.cps" + kind: "cps" + - + filename: "InnerConfig\.cmake" kind: "cmake" - - filename: "inner-config.cmake" + filename: "inner-config\.cmake" kind: "cmake" version_request: exact: false @@ -146,33 +190,65 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/CMakeFiles/pkgRedirects/InnerConfig.cmake" + path: "[^"]*/CMakeFiles/pkgRedirects/InnerConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/inner-config.cmake" + path: "[^"]*/CMakeFiles/pkgRedirects/inner-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/InnerConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/Inner\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/inner\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/Inner\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/inner\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/InnerConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/inner-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/inner-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/InnerConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/InnerConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/inner-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/inner-config\.cmake" mode: "config" reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/Inner\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/inner\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/Inner\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/inner\.cps" + mode: "cps" + reason: "no_exist" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/Inner/InnerConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/Inner/InnerConfig\.cmake" mode: "config" - version: "1.1" + version: "1\.1" search_context:( [^ ]*)+ @@ -202,9 +278,9 @@ CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY: true CMAKE_FIND_ROOT_PATH_MODE: "BOTH" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/FindWithInner.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/FindWithInner\.cmake" mode: "module" - version: "1.1" + version: "1\.1" search_context:( [^ ]*)+ @@ -215,14 +291,20 @@ name: "VersionCheck" configs: - - filename: "VersionCheckConfig.cmake" + filename: "VersionCheck\.cps" + kind: "cps" + - + filename: "versioncheck\.cps" + kind: "cps" + - + filename: "VersionCheckConfig\.cmake" kind: "cmake" - - filename: "versioncheck-config.cmake" + filename: "versioncheck-config\.cmake" kind: "cmake" version_request: - version: "2.0" - version_complete: "2.0" + version: "2\.0" + version_complete: "2\.0" exact: false settings: required: "optional" @@ -246,42 +328,74 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/CMakeFiles/pkgRedirects/VersionCheckConfig.cmake" + path: "[^"]*/CMakeFiles/pkgRedirects/VersionCheckConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/versioncheck-config.cmake" + path: "[^"]*/CMakeFiles/pkgRedirects/versioncheck-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/VersionCheckConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/VersionCheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/versioncheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/VersionCheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/versioncheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/VersionCheckConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/versioncheck-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/versioncheck-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/VersionCheckConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/VersionCheckConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/versioncheck-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/versioncheck-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1.5/VersionCheckConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/VersionCheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/versioncheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/VersionCheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/versioncheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1\.5/VersionCheckConfig\.cmake" mode: "config" reason: "insufficient_version" - message: "The version found is not compatible with the version requested." + message: "The version found is not compatible with the version requested\." - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1.5/versioncheck-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1\.5/versioncheck-config\.cmake" mode: "config" reason: "no_exist" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-2.5/VersionCheckConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-2\.5/VersionCheckConfig\.cmake" mode: "config" - version: "2.5" + version: "2\.5" search_context:( [^ ]*)+
diff --git a/Tests/RunCMake/find_package/ConfigureLog-stderr.txt b/Tests/RunCMake/find_package/ConfigureLog-stderr.txt index e01e46e..87e3419 100644 --- a/Tests/RunCMake/find_package/ConfigureLog-stderr.txt +++ b/Tests/RunCMake/find_package/ConfigureLog-stderr.txt
@@ -69,10 +69,18 @@ .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/ViaConfigConfig\.cmake .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/viaconfig-config\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/ViaConfig\.cps + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/viaconfig\.cps + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/ViaConfig\.cps + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/viaconfig\.cps .*/Tests/RunCMake/find_package/ConfigureLog/ViaConfigConfig\.cmake .*/Tests/RunCMake/find_package/ConfigureLog/viaconfig-config\.cmake .*/Tests/RunCMake/find_package/ConfigureLog/cmake/ViaConfigConfig\.cmake .*/Tests/RunCMake/find_package/ConfigureLog/cmake/viaconfig-config\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ViaConfig\.cps + .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/viaconfig\.cps + .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ViaConfig\.cps + .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/viaconfig\.cps .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ViaConfig/ViaConfigConfig\.cmake The file was found at @@ -165,12 +173,20 @@ find_package considered the following locations for Inner's Config module: - .*/CMakeFiles/pkgRedirects/InnerConfig\.cmake - .*/CMakeFiles/pkgRedirects/inner-config\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/InnerConfig\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/inner-config\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/Inner\.cps + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/inner\.cps + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/Inner\.cps + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/inner\.cps .*/Tests/RunCMake/find_package/ConfigureLog/InnerConfig\.cmake .*/Tests/RunCMake/find_package/ConfigureLog/inner-config\.cmake .*/Tests/RunCMake/find_package/ConfigureLog/cmake/InnerConfig\.cmake .*/Tests/RunCMake/find_package/ConfigureLog/cmake/inner-config\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/Inner\.cps + .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/inner\.cps + .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/Inner\.cps + .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/inner\.cps .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/Inner/InnerConfig\.cmake The file was found at @@ -266,12 +282,20 @@ find_package considered the following locations for VersionCheck's Config module: - .*/CMakeFiles/pkgRedirects/VersionCheckConfig\.cmake - .*/CMakeFiles/pkgRedirects/versioncheck-config\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/VersionCheckConfig\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/versioncheck-config\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/VersionCheck\.cps + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/versioncheck\.cps + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/VersionCheck\.cps + .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/versioncheck\.cps .*/Tests/RunCMake/find_package/ConfigureLog/VersionCheckConfig\.cmake .*/Tests/RunCMake/find_package/ConfigureLog/versioncheck-config\.cmake .*/Tests/RunCMake/find_package/ConfigureLog/cmake/VersionCheckConfig\.cmake - .*/Tests/RunCMake/find_package/ConfigureLog/cmake/versioncheck-config\.cmake( + .*/Tests/RunCMake/find_package/ConfigureLog/cmake/versioncheck-config\.cmake + .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/VersionCheck\.cps + .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/versioncheck\.cps + .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/VersionCheck\.cps + .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/versioncheck\.cps( .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1\.5/VersionCheckConfig\.cmake .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1\.5/versioncheck-config\.cmake)? .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-2\.5/VersionCheckConfig\.cmake
diff --git a/Tests/RunCMake/find_package/ConfigureLogParameters2-config.txt b/Tests/RunCMake/find_package/ConfigureLogParameters2-config.txt index 362a080..07b5384 100644 --- a/Tests/RunCMake/find_package/ConfigureLogParameters2-config.txt +++ b/Tests/RunCMake/find_package/ConfigureLogParameters2-config.txt
@@ -19,10 +19,16 @@ name: "ParameterCheckConfig" configs: - - filename: "ParameterCheckConfigConfig.cmake" + filename: "ParameterCheckConfig\.cps" + kind: "cps" + - + filename: "parametercheckconfig\.cps" + kind: "cps" + - + filename: "ParameterCheckConfigConfig\.cmake" kind: "cmake" - - filename: "parametercheckconfig-config.cmake" + filename: "parametercheckconfig-config\.cmake" kind: "cmake" version_request: exact: false @@ -50,33 +56,65 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake" mode: "config" - version: "1.6" + version: "1\.6" search_context:( [^ ]*)+ @@ -87,10 +125,16 @@ name: "ParameterCheckConfig" configs: - - filename: "ParameterCheckConfigConfig.cmake" + filename: "ParameterCheckConfig\.cps" + kind: "cps" + - + filename: "parametercheckconfig\.cps" + kind: "cps" + - + filename: "ParameterCheckConfigConfig\.cmake" kind: "cmake" - - filename: "parametercheckconfig-config.cmake" + filename: "parametercheckconfig-config\.cmake" kind: "cmake" version_request: exact: false @@ -118,81 +162,177 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/suffix1/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix1/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/suffix1/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix1/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/suffix2/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix2/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/suffix2/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix2/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix1/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix1/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix2/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix2/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix1/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix1/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix2/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix2/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix1/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix1/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix1/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix1/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix2/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix2/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix2/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix2/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix1/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix1/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix1/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix1/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix1/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix1/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix2/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix2/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix1/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix1/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix2/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix2/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake" mode: "config" - version: "1.6" + version: "1\.6" search_context:( [^ ]*)+ @@ -203,10 +343,16 @@ name: "ParameterCheckConfig" configs: - - filename: "ParameterCheckConfigConfig.cmake" + filename: "ParameterCheckConfig\.cps" + kind: "cps" + - + filename: "parametercheckconfig\.cps" + kind: "cps" + - + filename: "ParameterCheckConfigConfig\.cmake" kind: "cmake" - - filename: "parametercheckconfig-config.cmake" + filename: "parametercheckconfig-config\.cmake" kind: "cmake" version_request: exact: false @@ -232,13 +378,29 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" found: null search_context:( [^ @@ -250,10 +412,16 @@ name: "ParameterCheckConfig" configs: - - filename: "ParameterCheckConfigConfig.cmake" + filename: "ParameterCheckConfig\.cps" + kind: "cps" + - + filename: "parametercheckconfig\.cps" + kind: "cps" + - + filename: "ParameterCheckConfigConfig\.cmake" kind: "cmake" - - filename: "parametercheckconfig-config.cmake" + filename: "parametercheckconfig-config\.cmake" kind: "cmake" version_request: exact: false @@ -279,33 +447,65 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake" mode: "config" - version: "1.6" + version: "1\.6" search_context:( [^ ]*)+ @@ -316,10 +516,16 @@ name: "ParameterCheckConfig" configs: - - filename: "ParameterCheckConfigConfig.cmake" + filename: "ParameterCheckConfig\.cps" + kind: "cps" + - + filename: "parametercheckconfig\.cps" + kind: "cps" + - + filename: "ParameterCheckConfigConfig\.cmake" kind: "cmake" - - filename: "parametercheckconfig-config.cmake" + filename: "parametercheckconfig-config\.cmake" kind: "cmake" version_request: exact: false @@ -345,33 +551,65 @@ CMAKE_FIND_ROOT_PATH_MODE: "ONLY" candidates: - - path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake" mode: "config" - version: "1.6" + version: "1\.6" search_context:( [^ ]*)+ @@ -382,10 +620,16 @@ name: "ParameterCheckConfig" configs: - - filename: "ParameterCheckConfigConfig.cmake" + filename: "ParameterCheckConfig\.cps" + kind: "cps" + - + filename: "parametercheckconfig\.cps" + kind: "cps" + - + filename: "ParameterCheckConfigConfig\.cmake" kind: "cmake" - - filename: "parametercheckconfig-config.cmake" + filename: "parametercheckconfig-config\.cmake" kind: "cmake" version_request: exact: false @@ -411,33 +655,65 @@ CMAKE_FIND_ROOT_PATH_MODE: "NEVER" candidates: - - path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake" mode: "config" - version: "1.6" + version: "1\.6" search_context:( [^ ]*)+ @@ -448,16 +724,28 @@ name: "OtherParameterCheck" configs: - - filename: "BogusParameterCheckConfig.cmake" + filename: "BogusParameterCheck\.cps" + kind: "cps" + - + filename: "bogusparametercheck\.cps" + kind: "cps" + - + filename: "BogusParameterCheckConfig\.cmake" kind: "cmake" - - filename: "bogusparametercheck-config.cmake" + filename: "bogusparametercheck-config\.cmake" kind: "cmake" - - filename: "ParameterCheckConfigConfig.cmake" + filename: "ParameterCheckConfig\.cps" + kind: "cps" + - + filename: "parametercheckconfig\.cps" + kind: "cps" + - + filename: "ParameterCheckConfigConfig\.cmake" kind: "cmake" - - filename: "parametercheckconfig-config.cmake" + filename: "parametercheckconfig-config\.cmake" kind: "cmake" version_request: exact: false @@ -484,65 +772,129 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/CMakeFiles/pkgRedirects/BogusParameterCheckConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/BogusParameterCheckConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/bogusparametercheck-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/bogusparametercheck-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/BogusParameterCheckConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/BogusParameterCheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/bogusparametercheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/BogusParameterCheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/bogusparametercheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/BogusParameterCheckConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/bogusparametercheck-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/bogusparametercheck-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/BogusParameterCheckConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/BogusParameterCheckConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/bogusparametercheck-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/bogusparametercheck-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/BogusParameterCheckConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/BogusParameterCheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/bogusparametercheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/BogusParameterCheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/bogusparametercheck\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/BogusParameterCheckConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/bogusparametercheck-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/bogusparametercheck-config\.cmake" mode: "config" reason: "no_exist" found: - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake" mode: "config" - version: "1.6" + version: "1\.6" search_context:( [^ ]*)+
diff --git a/Tests/RunCMake/find_package/ConfigureLogParameters2-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogParameters2-stderr.txt index 1fbf938..2d7d3ef 100644 --- a/Tests/RunCMake/find_package/ConfigureLogParameters2-stderr.txt +++ b/Tests/RunCMake/find_package/ConfigureLogParameters2-stderr.txt
@@ -68,6 +68,14 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake [^ ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake @@ -76,6 +84,14 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake The file was found at @@ -164,6 +180,30 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix2/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix1/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix1/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix2/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix2/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix1/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix1/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix2/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix2/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake [^ ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake @@ -188,6 +228,30 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix1/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix1/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix2/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix2/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix1/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix1/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix2/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix2/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake The file was found at @@ -220,6 +284,14 @@ ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake [^ ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps The file was not found\. @@ -296,6 +368,14 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake [^ ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake @@ -304,6 +384,14 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake The file was found at @@ -384,6 +472,14 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake [^ ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake @@ -392,6 +488,14 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake The file was found at @@ -472,6 +576,14 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake [^ ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake @@ -480,6 +592,14 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake The file was found at @@ -564,6 +684,22 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/BogusParameterCheck.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/bogusparametercheck.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/BogusParameterCheck.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/bogusparametercheck.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/BogusParameterCheckConfig\.cmake [^ ]*/Tests/RunCMake/find_package/ConfigureLog/bogusparametercheck-config\.cmake @@ -580,6 +716,22 @@ [^ ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/BogusParameterCheck.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/bogusparametercheck.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/BogusParameterCheck.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/bogusparametercheck.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps + [^ +]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps + [^ ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/BogusParameterCheckConfig\.cmake [^ ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/bogusparametercheck-config\.cmake
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2-stderr.txt index 6f8f9f1..7691f6d 100644 --- a/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2-stderr.txt +++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2-stderr.txt
@@ -7,6 +7,8 @@ Could not find a package configuration file provided by "ViaConfig" with any of the following names: + ViaConfig\.cps + viaconfig\.cps ViaConfigConfig\.cmake viaconfig-config\.cmake @@ -27,6 +29,8 @@ Could not find a package configuration file provided by "ViaConfig" with any of the following names: + ViaConfig\.cps + viaconfig\.cps ViaConfigConfig\.cmake viaconfig-config\.cmake @@ -49,6 +53,8 @@ Could not find a package configuration file provided by "ViaConfig" with any of the following names: + ViaConfig\.cps + viaconfig\.cps ViaConfigConfig\.cmake viaconfig-config\.cmake
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2Suppressed-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2Suppressed-stderr.txt index 88574e3..343e48c 100644 --- a/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2Suppressed-stderr.txt +++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2Suppressed-stderr.txt
@@ -7,6 +7,8 @@ Could not find a package configuration file provided by "ViaConfig" with any of the following names: + ViaConfig\.cps + viaconfig\.cps ViaConfigConfig\.cmake viaconfig-config\.cmake @@ -27,6 +29,8 @@ Could not find a package configuration file provided by "ViaConfig" with any of the following names: + ViaConfig\.cps + viaconfig\.cps ViaConfigConfig\.cmake viaconfig-config\.cmake @@ -49,6 +53,8 @@ Could not find a package configuration file provided by "ViaConfig" with any of the following names: + ViaConfig\.cps + viaconfig\.cps ViaConfigConfig\.cmake viaconfig-config\.cmake
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-config.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-config.txt index b7cd63a..bd1de84 100644 --- a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-config.txt +++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-config.txt
@@ -27,10 +27,16 @@ name: "ViaModule" configs: - - filename: "ViaModuleConfig.cmake" + filename: "ViaModule\.cps" + kind: "cps" + - + filename: "viamodule\.cps" + kind: "cps" + - + filename: "ViaModuleConfig\.cmake" kind: "cmake" - - filename: "viamodule-config.cmake" + filename: "viamodule-config\.cmake" kind: "cmake" version_request: exact: false @@ -56,16 +62,32 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/ViaModuleConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/ViaModuleConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/viamodule-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/viamodule-config\.cmake" mode: "config" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/lib/cps/ViaModule\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/lib/cps/viamodule\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/share/cps/ViaModule\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/share/cps/viamodule\.cps" + mode: "cps" reason: "no_exist"( - - path: "[^"]*/(viamodule-config|ViaModuleConfig).cmake" - mode: "config" + path: "[^"]*/((viamodule|ViaModule)\.cps|(viamodule-config|ViaModuleConfig)\.cmake)" + mode: "(cps|config)" reason: "no_exist")* found: null search_context:( @@ -107,10 +129,16 @@ name: "ViaModule" configs: - - filename: "ViaModuleConfig.cmake" + filename: "ViaModule\.cps" + kind: "cps" + - + filename: "viamodule\.cps" + kind: "cps" + - + filename: "ViaModuleConfig\.cmake" kind: "cmake" - - filename: "viamodule-config.cmake" + filename: "viamodule-config\.cmake" kind: "cmake" version_request: exact: false @@ -136,16 +164,32 @@ CMAKE_FIND_ROOT_PATH_MODE: "BOTH" candidates: - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/ViaModuleConfig.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/ViaModuleConfig\.cmake" mode: "config" reason: "no_exist" - - path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/viamodule-config.cmake" + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/viamodule-config\.cmake" mode: "config" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/lib/cps/ViaModule\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/lib/cps/viamodule\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/share/cps/ViaModule\.cps" + mode: "cps" + reason: "no_exist" + - + path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/share/cps/viamodule\.cps" + mode: "cps" reason: "no_exist"( - - path: "[^"]*/(viamodule-config|ViaModuleConfig).cmake" - mode: "config" + path: "[^"]*/((viamodule|ViaModule)\.cps|(viamodule-config|ViaModuleConfig)\.cmake)" + mode: "(cps|config)" reason: "no_exist")* found: null search_context:(
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-stderr.txt index de0168b..aa642c4 100644 --- a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-stderr.txt +++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-stderr.txt
@@ -7,6 +7,8 @@ Could not find a package configuration file provided by "ViaModule" with any of the following names: + ViaModule\.cps + viamodule\.cps ViaModuleConfig\.cmake viamodule-config\.cmake @@ -27,6 +29,8 @@ Could not find a package configuration file provided by "ViaModule" with any of the following names: + ViaModule\.cps + viamodule\.cps ViaModuleConfig\.cmake viamodule-config\.cmake @@ -49,6 +53,8 @@ Could not find a package configuration file provided by "ViaModule" with any of the following names: + ViaModule\.cps + viamodule\.cps ViaModuleConfig\.cmake viamodule-config\.cmake
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2Suppressed-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2Suppressed-stderr.txt index a41ea03..4895471 100644 --- a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2Suppressed-stderr.txt +++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2Suppressed-stderr.txt
@@ -7,6 +7,8 @@ Could not find a package configuration file provided by "ViaModule" with any of the following names: + ViaModule\.cps + viamodule\.cps ViaModuleConfig\.cmake viamodule-config\.cmake @@ -27,6 +29,8 @@ Could not find a package configuration file provided by "ViaModule" with any of the following names: + ViaModule\.cps + viamodule\.cps ViaModuleConfig\.cmake viamodule-config\.cmake @@ -49,6 +53,8 @@ Could not find a package configuration file provided by "ViaModule" with any of the following names: + ViaModule\.cps + viamodule\.cps ViaModuleConfig\.cmake viamodule-config\.cmake
diff --git a/Tests/RunCMake/find_package/DebugRoot-stderr.txt b/Tests/RunCMake/find_package/DebugRoot-stderr.txt index c27c314..512f9ed 100644 --- a/Tests/RunCMake/find_package/DebugRoot-stderr.txt +++ b/Tests/RunCMake/find_package/DebugRoot-stderr.txt
@@ -41,6 +41,14 @@ [^ ]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/debugroot-config\.cmake [^ +]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/lib/cps/DebugRoot\.cps + [^ +]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/lib/cps/debugroot\.cps + [^ +]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/share/cps/DebugRoot\.cps + [^ +]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/share/cps/debugroot\.cps + [^ ]*/Tests/RunCMake/find_package/DebugRoot/Exist/DebugRoot/DebugRootConfig\.cmake The file was found at
diff --git a/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt b/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt index 19449f1..0df8659 100644 --- a/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt +++ b/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt
@@ -78,6 +78,14 @@ [^ ]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/resolved-config\.cmake [^ +]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/lib/cps/Resolved\.cps + [^ +]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/lib/cps/resolved\.cps + [^ +]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/share/cps/Resolved\.cps + [^ +]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/share/cps/resolved\.cps + [^ ]*/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig\.cmake The file was found at
diff --git a/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-stderr.txt b/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-stderr.txt index f0f8e32..368f40c 100644 --- a/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-stderr.txt +++ b/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-stderr.txt
@@ -78,6 +78,14 @@ [^ ]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/resolved-config\.cmake [^ +]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/lib/cps/Resolved\.cps + [^ +]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/lib/cps/resolved\.cps + [^ +]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/share/cps/Resolved\.cps + [^ +]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/share/cps/resolved\.cps + [^ ]*/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig\.cmake The file was found at
diff --git a/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt b/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt index 363f5de..da58d29 100644 --- a/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt +++ b/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt
@@ -2,6 +2,8 @@ Could not find a package configuration file provided by "NotHere" with any of the following names: + NotHere\.cps + nothere\.cps NotHereConfig\.cmake nothere-config\.cmake
diff --git a/Tests/RunCMake/find_package/MissingNormal-stderr.txt b/Tests/RunCMake/find_package/MissingNormal-stderr.txt index 9e79ea6..005854c 100644 --- a/Tests/RunCMake/find_package/MissingNormal-stderr.txt +++ b/Tests/RunCMake/find_package/MissingNormal-stderr.txt
@@ -6,6 +6,8 @@ Could not find a package configuration file provided by "NotHere" with any of the following names: + NotHere\.cps + nothere\.cps NotHereConfig\.cmake nothere-config\.cmake
diff --git a/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt b/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt index e455b2d..6d517d2 100644 --- a/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt +++ b/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt
@@ -6,6 +6,8 @@ Could not find a package configuration file provided by "NotHere" with any of the following names: + NotHere\.cps + nothere\.cps NotHereConfig\.cmake nothere-config\.cmake
diff --git a/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt b/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt index 258cff7..11dc7f1 100644 --- a/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt +++ b/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt
@@ -6,6 +6,8 @@ Could not find a package configuration file provided by "NotHere" \(requested version 1\.2\) with any of the following names: + NotHere\.cps + nothere\.cps NotHereConfig\.cmake nothere-config\.cmake
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt index ee0b337..0d3b5fb 100644 --- a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt +++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt
@@ -19,6 +19,8 @@ Could not find a package configuration file provided by "NotHere" with any of the following names: + NotHere\.cps + nothere\.cps NotHereConfig\.cmake nothere-config\.cmake
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt index 288730a..5f45a51 100644 --- a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt +++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
@@ -19,6 +19,8 @@ Could not find a package configuration file provided by "NotHere" with any of the following names: + NotHere\.cps + nothere\.cps NotHereConfig\.cmake nothere-config\.cmake
diff --git a/Tests/RunCMake/find_package/ModuleModeDebugPkg-stderr.txt b/Tests/RunCMake/find_package/ModuleModeDebugPkg-stderr.txt index cd0fc78..ced6175 100644 --- a/Tests/RunCMake/find_package/ModuleModeDebugPkg-stderr.txt +++ b/Tests/RunCMake/find_package/ModuleModeDebugPkg-stderr.txt
@@ -116,6 +116,14 @@ ]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/ZotConfig\.cmake [^ ]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/zot-config\.cmake + [^ +]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/lib/cps/Zot\.cps + [^ +]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/lib/cps/zot\.cps + [^ +]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/share/cps/Zot\.cps + [^ +]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/share/cps/zot\.cps The file was not found\.
diff --git a/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt b/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt index bec4fba..ca1830f 100644 --- a/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt +++ b/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt
@@ -6,6 +6,8 @@ Could not find a package configuration file provided by "Foo" with any of the following names: + Foo\.cps + foo\.cps FooConfig\.cmake foo-config\.cmake
diff --git a/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt b/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt index dad7bf6..79354d1 100644 --- a/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt +++ b/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt
@@ -6,6 +6,8 @@ Could not find a package configuration file provided by "DoesNotExist" with any of the following names: + DoesNotExist\.cps + doesnotexist\.cps DoesNotExistConfig\.cmake doesnotexist-config\.cmake
diff --git a/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt b/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt index 0bb5dd0..a69a2a6 100644 --- a/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt +++ b/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt
@@ -6,6 +6,8 @@ Could not find a package configuration file provided by "DoesNotExist" with any of the following names: + DoesNotExist\.cps + doesnotexist\.cps DoesNotExistConfig\.cmake doesnotexist-config\.cmake
diff --git a/Tests/RunCMake/find_package/UnwindIncludeBlock-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeBlock-stderr.txt index 5a80e75..3b48bbf 100644 --- a/Tests/RunCMake/find_package/UnwindIncludeBlock-stderr.txt +++ b/Tests/RunCMake/find_package/UnwindIncludeBlock-stderr.txt
@@ -6,6 +6,7 @@ Could not find a package configuration file provided by "foo" with any of the following names: + foo\.cps fooConfig\.cmake foo-config\.cmake
diff --git a/Tests/RunCMake/find_package/UnwindIncludeFunction-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeFunction-stderr.txt index 209143b..bd475ee 100644 --- a/Tests/RunCMake/find_package/UnwindIncludeFunction-stderr.txt +++ b/Tests/RunCMake/find_package/UnwindIncludeFunction-stderr.txt
@@ -6,6 +6,7 @@ Could not find a package configuration file provided by "foo" with any of the following names: + foo\.cps fooConfig\.cmake foo-config\.cmake
diff --git a/Tests/RunCMake/find_package/UnwindIncludeInvalidFindPackage-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeInvalidFindPackage-stderr.txt index 7a33a52..af68586 100644 --- a/Tests/RunCMake/find_package/UnwindIncludeInvalidFindPackage-stderr.txt +++ b/Tests/RunCMake/find_package/UnwindIncludeInvalidFindPackage-stderr.txt
@@ -6,6 +6,7 @@ Could not find a package configuration file provided by "foo" with any of the following names: + foo\.cps fooConfig\.cmake foo-config\.cmake
diff --git a/Tests/RunCMake/find_package/UnwindIncludeInvalidInclude-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeInvalidInclude-stderr.txt index 6306519..48286aa 100644 --- a/Tests/RunCMake/find_package/UnwindIncludeInvalidInclude-stderr.txt +++ b/Tests/RunCMake/find_package/UnwindIncludeInvalidInclude-stderr.txt
@@ -6,6 +6,7 @@ Could not find a package configuration file provided by "foo" with any of the following names: + foo\.cps fooConfig\.cmake foo-config\.cmake
diff --git a/Tests/RunCMake/find_package/UnwindIncludeOnly-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeOnly-stderr.txt index 7ca9976..cea39ed 100644 --- a/Tests/RunCMake/find_package/UnwindIncludeOnly-stderr.txt +++ b/Tests/RunCMake/find_package/UnwindIncludeOnly-stderr.txt
@@ -6,6 +6,7 @@ Could not find a package configuration file provided by "foo" with any of the following names: + foo\.cps fooConfig\.cmake foo-config\.cmake
diff --git a/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt b/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt index 038dac2..dedabfe 100644 --- a/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt +++ b/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt
@@ -6,6 +6,8 @@ Could not find a package configuration file provided by "NoPrefix" with any of the following names: + NoPrefix\.cps + noprefix\.cps NoPrefixConfig\.cmake noprefix-config\.cmake
diff --git a/Tests/RunCMake/project/KeywordProjectName-stderr.txt b/Tests/RunCMake/project/KeywordProjectName-stderr.txt index a96ac32..73ca463 100644 --- a/Tests/RunCMake/project/KeywordProjectName-stderr.txt +++ b/Tests/RunCMake/project/KeywordProjectName-stderr.txt
@@ -15,6 +15,22 @@ This warning is for project developers\. Use -Wno-dev to suppress it\. CMake Warning \(dev\) at KeywordProjectName\.cmake:[0-9]+ \(project\): + project\(\) called with 'COMPAT_VERSION' as first argument\. The first + parameter should be the project name, not a keyword argument\. See the + cmake-commands\(7\) manual for correct usage of the project\(\) command\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\. + +CMake Warning \(dev\) at KeywordProjectName\.cmake:[0-9]+ \(project\): + project\(\) called with 'SPDX_LICENSE' as first argument\. The first + parameter should be the project name, not a keyword argument\. See the + cmake-commands\(7\) manual for correct usage of the project\(\) command\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\. + +CMake Warning \(dev\) at KeywordProjectName\.cmake:[0-9]+ \(project\): project\(\) called with 'DESCRIPTION' as first argument\. The first parameter should be the project name, not a keyword argument\. See the cmake-commands\(7\) manual for correct usage of the project\(\) command\.
diff --git a/Tests/RunCMake/project/KeywordProjectName.cmake b/Tests/RunCMake/project/KeywordProjectName.cmake index a8215bc..6e27dd5 100644 --- a/Tests/RunCMake/project/KeywordProjectName.cmake +++ b/Tests/RunCMake/project/KeywordProjectName.cmake
@@ -1,9 +1,6 @@ project(LANGUAGES) project(VERSION) +project(COMPAT_VERSION) +project(SPDX_LICENSE) project(DESCRIPTION) project(HOMEPAGE_URL) - -# CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO=7fa7d13b-8308-4dc7-af39-9e450456d68f -# Enable these when Package Info is no longer experimental -# project(COMPAT_VERSION) -# project(SPDX_LICENSE)
diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake index 9ad4504..e98ce74 100644 --- a/Tests/RunCMake/project/RunCMakeTest.cmake +++ b/Tests/RunCMake/project/RunCMakeTest.cmake
@@ -36,6 +36,13 @@ run_cmake(LanguagesUsedButNotEnabled) endif() run_cmake(ProjectCMP0126) +run_cmake(ProjectCompatVersion) +run_cmake(ProjectCompatVersion2) +run_cmake(ProjectCompatVersionEqual) +run_cmake(ProjectCompatVersionInvalid) +run_cmake(ProjectCompatVersionMissingVersion) +run_cmake(ProjectCompatVersionNewer) +run_cmake(ProjectCompatVersionNoArg) run_cmake(ProjectDescription) run_cmake(ProjectDescription2) run_cmake(ProjectDescriptionNoArg) @@ -46,6 +53,10 @@ run_cmake(ProjectIsTopLevel) run_cmake(ProjectIsTopLevelMultiple) run_cmake(ProjectIsTopLevelSubdirectory) +run_cmake(ProjectLicense) +run_cmake(ProjectLicense2) +run_cmake(ProjectLicenseNoArg) +run_cmake(ProjectLicenseNoArg2) run_cmake(ProjectTwice) run_cmake(Omissions) run_cmake(VersionAbsent) @@ -57,23 +68,6 @@ run_cmake(VersionTwice) run_cmake(VersionMax) -set(opts - "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO=7fa7d13b-8308-4dc7-af39-9e450456d68f" - "-Wno-dev" -) - -run_cmake_with_options(ProjectCompatVersion ${opts}) -run_cmake_with_options(ProjectCompatVersion2 ${opts}) -run_cmake_with_options(ProjectCompatVersionEqual ${opts}) -run_cmake_with_options(ProjectCompatVersionInvalid ${opts}) -run_cmake_with_options(ProjectCompatVersionMissingVersion ${opts}) -run_cmake_with_options(ProjectCompatVersionNewer ${opts}) -run_cmake_with_options(ProjectCompatVersionNoArg ${opts}) -run_cmake_with_options(ProjectLicense ${opts}) -run_cmake_with_options(ProjectLicense2 ${opts}) -run_cmake_with_options(ProjectLicenseNoArg ${opts}) -run_cmake_with_options(ProjectLicenseNoArg2 ${opts}) - run_cmake(CMP0048-NEW) run_cmake(CMP0096-WARN)
diff --git a/Tests/RunCMake/string/CaseUTF-8.cmake b/Tests/RunCMake/string/CaseUTF-8.cmake new file mode 100644 index 0000000..f44e47c --- /dev/null +++ b/Tests/RunCMake/string/CaseUTF-8.cmake
@@ -0,0 +1,11 @@ +# Chinese Hindi Greek English Russian +set(string_mixed "注意 यूनिकोड είναι VeRy здорово!") # UTF-8 +set(string_upper "注意 यूनिकोड είναι VERY здорово!") # UTF-8 +set(string_lower "注意 यूनिकोड είναι very здорово!") # UTF-8 +string(TOLOWER "${string_mixed}" output_lower) +string(TOUPPER "${string_mixed}" output_upper) +foreach(case lower upper) + if(NOT "${output_${case}}" STREQUAL "${string_${case}}") + message(SEND_ERROR "to${case} failed:\n \"${output_${case}}\"") + endif() +endforeach()
diff --git a/Tests/RunCMake/string/Hex.cmake b/Tests/RunCMake/string/Hex.cmake index 1c5aaa1..c314156 100644 --- a/Tests/RunCMake/string/Hex.cmake +++ b/Tests/RunCMake/string/Hex.cmake
@@ -12,7 +12,7 @@ string(HEX "${_input2}" _result2) assert_strequal("${_input2}" "${_result2}" "48656c6c6f20776f726c6421") -set(_input3 "Ash nazg durbatulûk\nAsh nazg gimbatul\nAsh nazg thrakatulûk\nAgh burzum-ishi krimpatul") +set(_input3 "Ash nazg durbatulûk\nAsh nazg gimbatul\nAsh nazg thrakatulûk\nAgh burzum-ishi krimpatul") # UTF-8 string(HEX "${_input3}" _result3) assert_strequal("${_input3}" "${_result3}" "417368206e617a6720647572626174756cc3bb6b0a417368206e617a672067696d626174756c0a417368206e617a6720746872616b6174756cc3bb6b0a416768206275727a756d2d69736869206b72696d706174756c")
diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake index f4a6ff8..3da258e 100644 --- a/Tests/RunCMake/string/RunCMakeTest.cmake +++ b/Tests/RunCMake/string/RunCMakeTest.cmake
@@ -14,6 +14,8 @@ run_cmake(Prepend) run_cmake(PrependNoArgs) +run_cmake_script(CaseUTF-8) + run_cmake(Concat) run_cmake(ConcatNoArgs)
diff --git a/Utilities/Scripts/update-nghttp2.bash b/Utilities/Scripts/update-nghttp2.bash index ad7e79b..551044b 100755 --- a/Utilities/Scripts/update-nghttp2.bash +++ b/Utilities/Scripts/update-nghttp2.bash
@@ -8,7 +8,7 @@ readonly ownership="nghttp2 upstream <kwrobot@kitware.com>" readonly subtree="Utilities/cmnghttp2" readonly repo="https://github.com/nghttp2/nghttp2.git" -readonly tag="v1.52.0" # When updating, sync PACKAGE_VERSION below! +readonly tag="v1.68.0" # When updating, sync PACKAGE_VERSION below! readonly shortlog=false readonly exact_tree_match=false readonly paths=" @@ -24,7 +24,7 @@ pushd "${extractdir}/${name}-reduced" echo "* -whitespace" > .gitattributes mv lib/includes/nghttp2/nghttp2ver.h.in lib/includes/nghttp2/nghttp2ver.h - sed -i 's/@PACKAGE_VERSION@/1.52.0/;s/@PACKAGE_VERSION_NUM@/0x013400/' lib/includes/nghttp2/nghttp2ver.h + sed -i 's/@PACKAGE_VERSION@/1.68.0/;s/@PACKAGE_VERSION_NUM@/0x014400/' lib/includes/nghttp2/nghttp2ver.h popd }
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index 0b4b558..2c6a6e6 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt
@@ -82,7 +82,7 @@ set(ENABLE_DEBUG OFF CACHE INTERNAL "No curl debug features") set(ENABLE_IPV6 ON CACHE INTERNAL "Enable curl IPv6 support detection") set(ENABLE_THREADED_RESOLVER OFF CACHE INTERNAL "No curl POSIX threaded DNS lookup") -set(ENABLE_UNICODE OFF) +set(ENABLE_UNICODE ON) set(ENABLE_UNIX_SOCKETS OFF CACHE INTERNAL "No curl Unix domain sockets support") set(HAVE_ATOMIC 0) set(HAVE_BORINGSSL 0) # we do not need this info
diff --git a/Utilities/cmnghttp2/CMakeLists.txt b/Utilities/cmnghttp2/CMakeLists.txt index d49693a..ff8de47 100644 --- a/Utilities/cmnghttp2/CMakeLists.txt +++ b/Utilities/cmnghttp2/CMakeLists.txt
@@ -16,6 +16,7 @@ configure_file(cmakeconfig.h.in config.h) add_library(cmnghttp2 STATIC + lib/nghttp2_alpn.c lib/nghttp2_buf.c lib/nghttp2_callbacks.c lib/nghttp2_debug.c @@ -28,17 +29,19 @@ lib/nghttp2_http.c lib/nghttp2_map.c lib/nghttp2_mem.c - lib/nghttp2_npn.c lib/nghttp2_option.c lib/nghttp2_outbound_item.c lib/nghttp2_pq.c lib/nghttp2_priority_spec.c lib/nghttp2_queue.c + lib/nghttp2_ratelim.c lib/nghttp2_rcbuf.c lib/nghttp2_session.c lib/nghttp2_stream.c lib/nghttp2_submit.c + lib/nghttp2_time.c lib/nghttp2_version.c + lib/sfparse.c ) target_compile_definitions(cmnghttp2
diff --git a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h index 3f31b89..ff1e576 100644 --- a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h +++ b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h
@@ -51,13 +51,14 @@ #endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ #include <sys/types.h> #include <stdarg.h> +#include <stddef.h> #include "nghttp2ver.h" #ifdef NGHTTP2_STATICLIB # define NGHTTP2_EXTERN -#elif defined(WIN32) || (__has_declspec_attribute(dllexport) && \ - __has_declspec_attribute(dllimport)) +#elif defined(WIN32) || \ + (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport)) # ifdef BUILDING_NGHTTP2 # define NGHTTP2_EXTERN __declspec(dllexport) # else /* !BUILDING_NGHTTP2 */ @@ -71,6 +72,17 @@ # endif /* !BUILDING_NGHTTP2 */ #endif /* !defined(WIN32) */ +#ifdef BUILDING_NGHTTP2 +# undef NGHTTP2_NO_SSIZE_T +#endif /* BUILDING_NGHTTP2 */ + +/** + * @typedef + * + * :type:`nghttp2_ssize` is a signed counterpart of size_t. + */ +typedef ptrdiff_t nghttp2_ssize; + /** * @macro * @@ -168,6 +180,12 @@ /** * @macro * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * The default weight of stream dependency. */ #define NGHTTP2_DEFAULT_WEIGHT 16 @@ -175,6 +193,12 @@ /** * @macro * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * The maximum weight of stream dependency. */ #define NGHTTP2_MAX_WEIGHT 256 @@ -182,6 +206,12 @@ /** * @macro * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * The minimum weight of stream dependency. */ #define NGHTTP2_MIN_WEIGHT 1 @@ -255,7 +285,7 @@ */ NGHTTP2_ERR_UNSUPPORTED_VERSION = -503, /** - * Used as a return value from :type:`nghttp2_send_callback`, + * Used as a return value from :type:`nghttp2_send_callback2`, * :type:`nghttp2_recv_callback` and * :type:`nghttp2_send_data_callback` to indicate that the operation * would block. @@ -275,9 +305,9 @@ NGHTTP2_ERR_EOF = -507, /** * Used as a return value from - * :func:`nghttp2_data_source_read_callback` to indicate that data + * :func:`nghttp2_data_source_read_callback2` to indicate that data * transfer is postponed. See - * :func:`nghttp2_data_source_read_callback` for details. + * :func:`nghttp2_data_source_read_callback2` for details. */ NGHTTP2_ERR_DEFERRED = -508, /** @@ -440,7 +470,12 @@ * exhaustion on server side to send these frames forever and does * not read network. */ - NGHTTP2_ERR_FLOODED = -904 + NGHTTP2_ERR_FLOODED = -904, + /** + * When a local endpoint receives too many CONTINUATION frames + * following a HEADER frame. + */ + NGHTTP2_ERR_TOO_MANY_CONTINUATIONS = -905, } nghttp2_error; /** @@ -830,7 +865,7 @@ * @union * * This union represents the some kind of data source passed to - * :type:`nghttp2_data_source_read_callback`. + * :type:`nghttp2_data_source_read_callback2`. */ typedef union { /** @@ -847,7 +882,7 @@ * @enum * * The flags used to set in |data_flags| output parameter in - * :type:`nghttp2_data_source_read_callback`. + * :type:`nghttp2_data_source_read_callback2`. */ typedef enum { /** @@ -861,8 +896,8 @@ /** * Indicates that END_STREAM flag must not be set even if * NGHTTP2_DATA_FLAG_EOF is set. Usually this flag is used to send - * trailer fields with `nghttp2_submit_request()` or - * `nghttp2_submit_response()`. + * trailer fields with `nghttp2_submit_request2()` or + * `nghttp2_submit_response2()`. */ NGHTTP2_DATA_FLAG_NO_END_STREAM = 0x02, /** @@ -872,9 +907,15 @@ NGHTTP2_DATA_FLAG_NO_COPY = 0x04 } nghttp2_data_flag; +#ifndef NGHTTP2_NO_SSIZE_T /** * @functypedef * + * .. warning:: + * + * Deprecated. Use :type:`nghttp2_data_source_read_callback2` + * instead. + * * Callback function invoked when the library wants to read data from * the |source|. The read data is sent in the stream |stream_id|. * The implementation of this function must read at most |length| @@ -936,8 +977,101 @@ * signal the entire session failure. */ typedef ssize_t (*nghttp2_data_source_read_callback)( - nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, - uint32_t *data_flags, nghttp2_data_source *source, void *user_data); + nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, + uint32_t *data_flags, nghttp2_data_source *source, void *user_data); + +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @functypedef + * + * Callback function invoked when the library wants to read data from + * the |source|. The read data is sent in the stream |stream_id|. + * The implementation of this function must read at most |length| + * bytes of data from |source| (or possibly other places) and store + * them in |buf| and return number of data stored in |buf|. If EOF is + * reached, set :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag + * in |*data_flags|. + * + * Sometime it is desirable to avoid copying data into |buf| and let + * application to send data directly. To achieve this, set + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` to + * |*data_flags| (and possibly other flags, just like when we do + * copy), and return the number of bytes to send without copying data + * into |buf|. The library, seeing + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY`, will invoke + * :type:`nghttp2_send_data_callback`. The application must send + * complete DATA frame in that callback. + * + * If this callback is set by `nghttp2_submit_request2()`, + * `nghttp2_submit_response2()` or `nghttp2_submit_headers()` and + * `nghttp2_submit_data2()` with flag parameter + * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` set, and + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag is set to + * |*data_flags|, DATA frame will have END_STREAM flag set. Usually, + * this is expected behaviour and all are fine. One exception is send + * trailer fields. You cannot send trailer fields after sending frame + * with END_STREAM set. To avoid this problem, one can set + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM` along + * with :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` to signal the + * library not to set END_STREAM in DATA frame. Then application can + * use `nghttp2_submit_trailer()` to send trailer fields. + * `nghttp2_submit_trailer()` can be called inside this callback. + * + * If the application wants to postpone DATA frames (e.g., + * asynchronous I/O, or reading data blocks for long time), it is + * achieved by returning :enum:`nghttp2_error.NGHTTP2_ERR_DEFERRED` + * without reading any data in this invocation. The library removes + * DATA frame from the outgoing queue temporarily. To move back + * deferred DATA frame to outgoing queue, call + * `nghttp2_session_resume_data()`. + * + * By default, |length| is limited to 16KiB at maximum. If peer + * allows larger frames, application can enlarge transmission buffer + * size. See :type:`nghttp2_data_source_read_length_callback` for + * more details. + * + * If the application just wants to return from + * `nghttp2_session_send()` or `nghttp2_session_mem_send2()` without + * sending anything, return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`. + * + * In case of error, there are 2 choices. Returning + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will + * close the stream by issuing RST_STREAM with + * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. If a different + * error code is desirable, use `nghttp2_submit_rst_stream()` with a + * desired error code and then return + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. + * Returning :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will + * signal the entire session failure. + */ +typedef nghttp2_ssize (*nghttp2_data_source_read_callback2)( + nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, + uint32_t *data_flags, nghttp2_data_source *source, void *user_data); + +#ifndef NGHTTP2_NO_SSIZE_T +/** + * @struct + * + * .. warning:: + * + * Deprecated. Use :type:`nghttp2_data_provider2` instead. + * + * This struct represents the data source and the way to read a chunk + * of data from it. + */ +typedef struct { + /** + * The data source. + */ + nghttp2_data_source source; + /** + * The callback function to read a chunk of data from the |source|. + */ + nghttp2_data_source_read_callback read_callback; +} nghttp2_data_provider; + +#endif /* NGHTTP2_NO_SSIZE_T */ /** * @struct @@ -953,8 +1087,8 @@ /** * The callback function to read a chunk of data from the |source|. */ - nghttp2_data_source_read_callback read_callback; -} nghttp2_data_provider; + nghttp2_data_source_read_callback2 read_callback; +} nghttp2_data_provider2; /** * @struct @@ -1008,6 +1142,12 @@ /** * @struct * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * The structure to specify stream dependency. */ typedef struct { @@ -1042,6 +1182,12 @@ */ size_t padlen; /** + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * The priority specification */ nghttp2_priority_spec pri_spec; @@ -1062,6 +1208,12 @@ /** * @struct * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * The PRIORITY frame. It has the following members: */ typedef struct { @@ -1305,9 +1457,14 @@ nghttp2_extension ext; } nghttp2_frame; +#ifndef NGHTTP2_NO_SSIZE_T /** * @functypedef * + * .. warning:: + * + * Deprecated. Use :type:`nghttp2_send_callback2` instead. + * * Callback function invoked when |session| wants to send data to the * remote peer. The implementation of this function must send at most * |length| bytes of data stored in |data|. The |flags| is currently @@ -1340,6 +1497,44 @@ const uint8_t *data, size_t length, int flags, void *user_data); +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @functypedef + * + * Callback function invoked when |session| wants to send data to the + * remote peer. The implementation of this function must send at most + * |length| bytes of data stored in |data|. The |flags| is currently + * not used and always 0. It must return the number of bytes sent if + * it succeeds. If it cannot send any single byte without blocking, + * it must return :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. For + * other errors, it must return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The + * |user_data| pointer is the third argument passed in to the call to + * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. + * + * This callback is required if the application uses + * `nghttp2_session_send()` to send data to the remote endpoint. If + * the application uses solely `nghttp2_session_mem_send2()` instead, + * this callback function is unnecessary. + * + * To set this callback to :type:`nghttp2_session_callbacks`, use + * `nghttp2_session_callbacks_set_send_callback2()`. + * + * .. note:: + * + * The |length| may be very small. If that is the case, and + * application disables Nagle algorithm (``TCP_NODELAY``), then just + * writing |data| to the network stack leads to very small packet, + * and it is very inefficient. An application should be responsible + * to buffer up small chunks of data as necessary to avoid this + * situation. + */ +typedef nghttp2_ssize (*nghttp2_send_callback2)(nghttp2_session *session, + const uint8_t *data, + size_t length, int flags, + void *user_data); + /** * @functypedef * @@ -1370,7 +1565,7 @@ * error; if partial frame data has already sent, it is impossible to * send another data in that state, and all we can do is tear down * connection). When data is fully processed, but application wants - * to make `nghttp2_session_mem_send()` or `nghttp2_session_send()` + * to make `nghttp2_session_mem_send2()` or `nghttp2_session_send()` * return immediately without processing next frames, return * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`. If application decided to * reset this stream, return @@ -1387,9 +1582,14 @@ nghttp2_data_source *source, void *user_data); +#ifndef NGHTTP2_NO_SSIZE_T /** * @functypedef * + * .. warning:: + * + * Deprecated. Use :type:`nghttp2_recv_callback2` instead. + * * Callback function invoked when |session| wants to receive data from * the remote peer. The implementation of this function must read at * most |length| bytes of data and store it in |buf|. The |flags| is @@ -1417,11 +1617,43 @@ size_t length, int flags, void *user_data); +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @functypedef + * + * Callback function invoked when |session| wants to receive data from + * the remote peer. The implementation of this function must read at + * most |length| bytes of data and store it in |buf|. The |flags| is + * currently not used and always 0. It must return the number of + * bytes written in |buf| if it succeeds. If it cannot read any + * single byte without blocking, it must return + * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. If it gets EOF + * before it reads any single byte, it must return + * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`. For other errors, it must + * return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. + * Returning 0 is treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. The |user_data| + * pointer is the third argument passed in to the call to + * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. + * + * This callback is required if the application uses + * `nghttp2_session_recv()` to receive data from the remote endpoint. + * If the application uses solely `nghttp2_session_mem_recv2()` + * instead, this callback function is unnecessary. + * + * To set this callback to :type:`nghttp2_session_callbacks`, use + * `nghttp2_session_callbacks_set_recv_callback2()`. + */ +typedef nghttp2_ssize (*nghttp2_recv_callback2)(nghttp2_session *session, + uint8_t *buf, size_t length, + int flags, void *user_data); + /** * @functypedef * * Callback function invoked by `nghttp2_session_recv()` and - * `nghttp2_session_mem_recv()` when a frame is received. The + * `nghttp2_session_mem_recv2()` when a frame is received. The * |user_data| pointer is the third argument passed in to the call to * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. * @@ -1439,8 +1671,8 @@ * * The implementation of this function must return 0 if it succeeds. * If nonzero value is returned, it is treated as fatal error and - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return + * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use @@ -1454,7 +1686,7 @@ * @functypedef * * Callback function invoked by `nghttp2_session_recv()` and - * `nghttp2_session_mem_recv()` when an invalid non-DATA frame is + * `nghttp2_session_mem_recv2()` when an invalid non-DATA frame is * received. The error is indicated by the |lib_error_code|, which is * one of the values defined in :type:`nghttp2_error`. When this * callback function is invoked, the library automatically submits @@ -1468,16 +1700,16 @@ * * The implementation of this function must return 0 if it succeeds. * If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return + * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_on_invalid_frame_recv_callback()`. */ typedef int (*nghttp2_on_invalid_frame_recv_callback)( - nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, - void *user_data); + nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, + void *user_data); /** * @functypedef @@ -1492,19 +1724,19 @@ * argument passed in to the call to `nghttp2_session_client_new()` or * `nghttp2_session_server_new()`. * - * If the application uses `nghttp2_session_mem_recv()`, it can return - * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make - * `nghttp2_session_mem_recv()` return without processing further + * If the application uses `nghttp2_session_mem_recv2()`, it can + * return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make + * `nghttp2_session_mem_recv2()` return without processing further * input bytes. The memory by pointed by the |data| is retained until - * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called. - * The application must retain the input bytes which was used to - * produce the |data| parameter, because it may refer to the memory + * `nghttp2_session_mem_recv2()` or `nghttp2_session_recv()` is + * called. The application must retain the input bytes which was used + * to produce the |data| parameter, because it may refer to the memory * region included in the input bytes. * * The implementation of this function must return 0 if it succeeds. * If nonzero is returned, it is treated as fatal error, and - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return + * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use @@ -1531,8 +1763,8 @@ * If there is a fatal error while executing this callback, the * implementation should return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which makes - * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions - * immediately return + * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * If the other value is returned, it is treated as if @@ -1556,8 +1788,8 @@ * * The implementation of this function must return 0 if it succeeds. * If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions - * immediately return + * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use @@ -1579,8 +1811,8 @@ * * The implementation of this function must return 0 if it succeeds. * If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions - * immediately return + * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * `nghttp2_session_get_stream_user_data()` can be used to get @@ -1601,7 +1833,7 @@ * The reason of closure is indicated by the |error_code|. The * |error_code| is usually one of :enum:`nghttp2_error_code`, but that * is not guaranteed. The stream_user_data, which was specified in - * `nghttp2_submit_request()` or `nghttp2_submit_headers()`, is still + * `nghttp2_submit_request2()` or `nghttp2_submit_headers()`, is still * available in this function. The |user_data| pointer is the third * argument passed in to the call to `nghttp2_session_client_new()` or * `nghttp2_session_server_new()`. @@ -1610,8 +1842,8 @@ * * The implementation of this function must return 0 if it succeeds. * If nonzero is returned, it is treated as fatal error and - * `nghttp2_session_recv()`, `nghttp2_session_mem_recv()`, - * `nghttp2_session_send()`, and `nghttp2_session_mem_send()` + * `nghttp2_session_recv()`, `nghttp2_session_mem_recv2()`, + * `nghttp2_session_send()`, and `nghttp2_session_mem_send2()` * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * @@ -1681,7 +1913,7 @@ * value is returned, it is treated as if * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned. If * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned, - * `nghttp2_session_mem_recv()` function will immediately return + * `nghttp2_session_mem_recv2()` function will immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use @@ -1726,11 +1958,11 @@ * performs validation based on HTTP Messaging rule, which is briefly * explained in :ref:`http-messaging` section. * - * If the application uses `nghttp2_session_mem_recv()`, it can return - * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make - * `nghttp2_session_mem_recv()` return without processing further + * If the application uses `nghttp2_session_mem_recv2()`, it can + * return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make + * `nghttp2_session_mem_recv2()` return without processing further * input bytes. The memory pointed by |frame|, |name| and |value| - * parameters are retained until `nghttp2_session_mem_recv()` or + * parameters are retained until `nghttp2_session_mem_recv2()` or * `nghttp2_session_recv()` is called. The application must retain * the input bytes which was used to produce these parameters, because * it may refer to the memory region included in the input bytes. @@ -1757,8 +1989,8 @@ * nonzero value is returned, it is treated as * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned, - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return + * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use @@ -1807,18 +2039,19 @@ /** * @functypedef * - * Callback function invoked when a invalid header name/value pair is + * Callback function invoked when an invalid header name/value pair is * received for the |frame|. * * The parameter and behaviour are similar to * :type:`nghttp2_on_header_callback`. The difference is that this - * callback is only invoked when a invalid header name/value pair is - * received which is treated as stream error if this callback is not - * set. Only invalid regular header field are passed to this - * callback. In other words, invalid pseudo header field is not - * passed to this callback. Also header fields which includes upper - * cased latter are also treated as error without passing them to this - * callback. + * callback is only invoked when an invalid header name/value pair is + * received which is treated as stream error if this callback returns + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` and + * :type:`nghttp2_on_invalid_header_callback2` is not set. Only + * invalid regular header field are passed to this callback. In other + * words, invalid pseudo header field is not passed to this callback. + * Also header fields which includes upper cased latter are also + * treated as error without passing them to this callback. * * This callback is only considered if HTTP messaging validation is * turned on (which is on by default, see @@ -1837,24 +2070,25 @@ * not reset. */ typedef int (*nghttp2_on_invalid_header_callback)( - nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, - size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, - void *user_data); + nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, + size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, + void *user_data); /** * @functypedef * - * Callback function invoked when a invalid header name/value pair is + * Callback function invoked when an invalid header name/value pair is * received for the |frame|. * * The parameter and behaviour are similar to * :type:`nghttp2_on_header_callback2`. The difference is that this - * callback is only invoked when a invalid header name/value pair is - * received which is silently ignored if this callback is not set. - * Only invalid regular header field are passed to this callback. In - * other words, invalid pseudo header field is not passed to this - * callback. Also header fields which includes upper cased latter are - * also treated as error without passing them to this callback. + * callback is only invoked when an invalid header name/value pair is + * received which is silently ignored if neither this callback nor + * :type:`nghttp2_on_invalid_header_callback` is set. Only invalid + * regular header field are passed to this callback. In other words, + * invalid pseudo header field is not passed to this callback. Also + * header fields which includes upper cased latter are also treated as + * error without passing them to this callback. * * This callback is only considered if HTTP messaging validation is * turned on (which is on by default, see @@ -1870,12 +2104,18 @@ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. */ typedef int (*nghttp2_on_invalid_header_callback2)( - nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, - nghttp2_rcbuf *value, uint8_t flags, void *user_data); + nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, + nghttp2_rcbuf *value, uint8_t flags, void *user_data); +#ifndef NGHTTP2_NO_SSIZE_T /** * @functypedef * + * .. warning:: + * + * Deprecated. Use :type:`nghttp2_select_padding_callback2` + * instead. + * * Callback function invoked when the library asks application how * many padding bytes are required for the transmission of the * |frame|. The application must choose the total length of payload @@ -1896,9 +2136,39 @@ size_t max_payloadlen, void *user_data); +#endif /* NGHTTP2_NO_SSIZE_T */ + /** * @functypedef * + * Callback function invoked when the library asks application how + * many padding bytes are required for the transmission of the + * |frame|. The application must choose the total length of payload + * including padded bytes in range [frame->hd.length, max_payloadlen], + * inclusive. Choosing number not in this range will be treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Returning + * ``frame->hd.length`` means no padding is added. Returning + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will make + * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` + * functions immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. + * + * To set this callback to :type:`nghttp2_session_callbacks`, use + * `nghttp2_session_callbacks_set_select_padding_callback2()`. + */ +typedef nghttp2_ssize (*nghttp2_select_padding_callback2)( + nghttp2_session *session, const nghttp2_frame *frame, size_t max_payloadlen, + void *user_data); + +#ifndef NGHTTP2_NO_SSIZE_T +/** + * @functypedef + * + * .. warning:: + * + * Deprecated. Use + * :type:`nghttp2_data_source_read_length_callback2` instead. + * * Callback function invoked when library wants to get max length of * data to send data to the remote peer. The implementation of this * function should return a value in the following range. [1, @@ -1922,9 +2192,41 @@ * `nghttp2_session_callbacks_set_data_source_read_length_callback()`. */ typedef ssize_t (*nghttp2_data_source_read_length_callback)( - nghttp2_session *session, uint8_t frame_type, int32_t stream_id, - int32_t session_remote_window_size, int32_t stream_remote_window_size, - uint32_t remote_max_frame_size, void *user_data); + nghttp2_session *session, uint8_t frame_type, int32_t stream_id, + int32_t session_remote_window_size, int32_t stream_remote_window_size, + uint32_t remote_max_frame_size, void *user_data); + +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @functypedef + * + * Callback function invoked when library wants to get max length of + * data to send data to the remote peer. The implementation of this + * function should return a value in the following range. [1, + * min(|session_remote_window_size|, |stream_remote_window_size|, + * |remote_max_frame_size|)]. If a value greater than this range is + * returned than the max allow value will be used. Returning a value + * smaller than this range is treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The + * |frame_type| is provided for future extensibility and identifies + * the type of frame (see :type:`nghttp2_frame_type`) for which to get + * the length for. Currently supported frame types are: + * :enum:`nghttp2_frame_type.NGHTTP2_DATA`. + * + * This callback can be used to control the length in bytes for which + * :type:`nghttp2_data_source_read_callback` is allowed to send to the + * remote endpoint. This callback is optional. Returning + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will signal the + * entire session failure. + * + * To set this callback to :type:`nghttp2_session_callbacks`, use + * `nghttp2_session_callbacks_set_data_source_read_length_callback2()`. + */ +typedef nghttp2_ssize (*nghttp2_data_source_read_length_callback2)( + nghttp2_session *session, uint8_t frame_type, int32_t stream_id, + int32_t session_remote_window_size, int32_t stream_remote_window_size, + uint32_t remote_max_frame_size, void *user_data); /** * @functypedef @@ -1942,8 +2244,8 @@ * * The implementation of this function must return 0 if it succeeds. * If nonzero value is returned, it is treated as fatal error and - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return + * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use @@ -1967,15 +2269,15 @@ * * If fatal error occurred, application should return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return + * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other * values are returned, currently they are treated as * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. */ typedef int (*nghttp2_on_extension_chunk_recv_callback)( - nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data, - size_t len, void *user_data); + nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data, + size_t len, void *user_data); /** * @functypedef @@ -1997,7 +2299,7 @@ * ``NULL``. The |*payload| is available as ``frame->ext.payload`` in * :type:`nghttp2_on_frame_recv_callback`. Therefore if application * can free that memory inside :type:`nghttp2_on_frame_recv_callback` - * callback. Of course, application has a liberty not ot use + * callback. Of course, application has a liberty not to use * |*payload|, and do its own mechanism to process extension frames. * * To abort processing this extension frame, return @@ -2005,8 +2307,8 @@ * * If fatal error occurred, application should return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, - * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return + * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` + * functions immediately return * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other * values are returned, currently they are treated as * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. @@ -2016,9 +2318,15 @@ const nghttp2_frame_hd *hd, void *user_data); +#ifndef NGHTTP2_NO_SSIZE_T /** * @functypedef * + * .. warning:: + * + * Deprecated. Use :type:`nghttp2_pack_extension_callback2` + * instead. + * * Callback function invoked when library asks the application to pack * extension payload in its wire format. The frame header will be * packed by library. Application must pack payload only. @@ -2049,18 +2357,53 @@ const nghttp2_frame *frame, void *user_data); +#endif /* NGHTTP2_NO_SSIZE_T */ + /** * @functypedef * + * Callback function invoked when library asks the application to pack + * extension payload in its wire format. The frame header will be + * packed by library. Application must pack payload only. + * ``frame->ext.payload`` is the object passed to + * `nghttp2_submit_extension()` as payload parameter. Application + * must pack extension payload to the |buf| of its capacity |len| + * bytes. The |len| is at least 16KiB. + * + * The implementation of this function should return the number of + * bytes written into |buf| when it succeeds. + * + * To abort processing this extension frame, return + * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`, and + * :type:`nghttp2_on_frame_not_send_callback` will be invoked. + * + * If fatal error occurred, application should return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, + * `nghttp2_session_send()` and `nghttp2_session_mem_send2()` + * functions immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other + * values are returned, currently they are treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the return + * value is strictly larger than |len|, it is treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. + */ +typedef nghttp2_ssize (*nghttp2_pack_extension_callback2)( + nghttp2_session *session, uint8_t *buf, size_t len, + const nghttp2_frame *frame, void *user_data); + +/** + * @functypedef + * + * .. warning:: + * + * Deprecated. Use :type:`nghttp2_error_callback2` instead. + * * Callback function invoked when library provides the error message * intended for human consumption. This callback is solely for * debugging purpose. The |msg| is typically NULL-terminated string * of length |len|. |len| does not include the sentinel NULL * character. * - * This function is deprecated. The new application should use - * :type:`nghttp2_error_callback2`. - * * The format of error message may change between nghttp2 library * versions. The application should not depend on the particular * format. @@ -2104,6 +2447,15 @@ int lib_error_code, const char *msg, size_t len, void *user_data); +/** + * @functypedef + * + * Callback function invoked when unpredictable data of |destlen| + * bytes are needed. The implementation must write unpredictable data + * of |destlen| bytes into the buffer pointed by |dest|. + */ +typedef void (*nghttp2_rand_callback)(uint8_t *dest, size_t destlen); + struct nghttp2_session_callbacks; /** @@ -2143,49 +2495,87 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks); +#ifndef NGHTTP2_NO_SSIZE_T /** * @function * + * .. warning:: + * + * Deprecated. Use `nghttp2_session_callbacks_set_send_callback2()` + * with :type:`nghttp2_send_callback2` instead. + * * Sets callback function invoked when a session wants to send data to * the remote peer. This callback is not necessary if the application * uses solely `nghttp2_session_mem_send()` to serialize data to * transmit. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback( - nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback); + nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback); + +#endif /* NGHTTP2_NO_SSIZE_T */ /** * @function * + * Sets callback function invoked when a session wants to send data to + * the remote peer. This callback is not necessary if the application + * uses solely `nghttp2_session_mem_send2()` to serialize data to + * transmit. + */ +NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback2( + nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback); + +#ifndef NGHTTP2_NO_SSIZE_T +/** + * @function + * + * .. warning:: + * + * Deprecated. Use `nghttp2_session_callbacks_set_recv_callback2()` + * with :type:`nghttp2_recv_callback2` instead. + * * Sets callback function invoked when the a session wants to receive * data from the remote peer. This callback is not necessary if the * application uses solely `nghttp2_session_mem_recv()` to process * received data. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback); + nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback); + +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @function + * + * Sets callback function invoked when the a session wants to receive + * data from the remote peer. This callback is not necessary if the + * application uses solely `nghttp2_session_mem_recv2()` to process + * received data. + */ +NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback2( + nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback); /** * @function * * Sets callback function invoked by `nghttp2_session_recv()` and - * `nghttp2_session_mem_recv()` when a frame is received. + * `nghttp2_session_mem_recv2()` when a frame is received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_recv_callback on_frame_recv_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_recv_callback on_frame_recv_callback); /** * @function * * Sets callback function invoked by `nghttp2_session_recv()` and - * `nghttp2_session_mem_recv()` when an invalid non-DATA frame is + * `nghttp2_session_mem_recv2()` when an invalid non-DATA frame is * received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback); /** * @function @@ -2194,8 +2584,8 @@ * is received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback); /** * @function @@ -2203,8 +2593,8 @@ * Sets callback function invoked before a non-DATA frame is sent. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_before_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_before_frame_send_callback before_frame_send_callback); + nghttp2_session_callbacks *cbs, + nghttp2_before_frame_send_callback before_frame_send_callback); /** * @function @@ -2212,8 +2602,8 @@ * Sets callback function invoked after a frame is sent. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_send_callback on_frame_send_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_send_callback on_frame_send_callback); /** * @function @@ -2222,8 +2612,8 @@ * because of an error. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_not_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_not_send_callback on_frame_not_send_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_not_send_callback on_frame_not_send_callback); /** * @function @@ -2231,8 +2621,8 @@ * Sets callback function invoked when the stream is closed. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_stream_close_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_stream_close_callback on_stream_close_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_stream_close_callback on_stream_close_callback); /** * @function @@ -2241,8 +2631,8 @@ * in HEADERS or PUSH_PROMISE is started. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_headers_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_headers_callback on_begin_headers_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_begin_headers_callback on_begin_headers_callback); /** * @function @@ -2254,8 +2644,8 @@ * set callbacks, the latter has the precedence. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback on_header_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_header_callback on_header_callback); /** * @function @@ -2264,31 +2654,51 @@ * received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback2 on_header_callback2); + nghttp2_session_callbacks *cbs, + nghttp2_on_header_callback2 on_header_callback2); /** * @function * - * Sets callback function invoked when a invalid header name/value + * Sets callback function invoked when an invalid header name/value * pair is received. If both * `nghttp2_session_callbacks_set_on_invalid_header_callback()` and * `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are * used to set callbacks, the latter takes the precedence. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback on_invalid_header_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_header_callback on_invalid_header_callback); /** * @function * - * Sets callback function invoked when a invalid header name/value + * Sets callback function invoked when an invalid header name/value * pair is received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback2 on_invalid_header_callback2); + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_header_callback2 on_invalid_header_callback2); + +#ifndef NGHTTP2_NO_SSIZE_T +/** + * @function + * + * .. warning:: + * + * Deprecated. Use + * `nghttp2_session_callbacks_set_select_padding_callback2()` with + * :type:`nghttp2_select_padding_callback2` instead. + * + * Sets callback function invoked when the library asks application + * how many padding bytes are required for the transmission of the + * given frame. + */ +NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback( + nghttp2_session_callbacks *cbs, + nghttp2_select_padding_callback select_padding_callback); + +#endif /* NGHTTP2_NO_SSIZE_T */ /** * @function @@ -2297,20 +2707,40 @@ * how many padding bytes are required for the transmission of the * given frame. */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback select_padding_callback); +NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback2( + nghttp2_session_callbacks *cbs, + nghttp2_select_padding_callback2 select_padding_callback); +#ifndef NGHTTP2_NO_SSIZE_T /** * @function * + * .. warning:: + * + * Deprecated. Use + * `nghttp2_session_callbacks_set_data_source_read_length_callback2()` + * with :type:`nghttp2_data_source_read_length_callback2` instead. + * * Sets callback function determine the length allowed in * :type:`nghttp2_data_source_read_callback`. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_data_source_read_length_callback( - nghttp2_session_callbacks *cbs, - nghttp2_data_source_read_length_callback data_source_read_length_callback); + nghttp2_session_callbacks *cbs, + nghttp2_data_source_read_length_callback data_source_read_length_callback); + +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @function + * + * Sets callback function determine the length allowed in + * :type:`nghttp2_data_source_read_callback2`. + */ +NGHTTP2_EXTERN void +nghttp2_session_callbacks_set_data_source_read_length_callback2( + nghttp2_session_callbacks *cbs, + nghttp2_data_source_read_length_callback2 data_source_read_length_callback); /** * @function @@ -2318,19 +2748,38 @@ * Sets callback function invoked when a frame header is received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_frame_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_frame_callback on_begin_frame_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_begin_frame_callback on_begin_frame_callback); /** * @function * * Sets callback function invoked when * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in - * :type:`nghttp2_data_source_read_callback` to avoid data copy. + * :type:`nghttp2_data_source_read_callback2` to avoid data copy. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback( - nghttp2_session_callbacks *cbs, - nghttp2_send_data_callback send_data_callback); + nghttp2_session_callbacks *cbs, + nghttp2_send_data_callback send_data_callback); + +#ifndef NGHTTP2_NO_SSIZE_T +/** + * @function + * + * .. warning:: + * + * Deprecated. Use + * `nghttp2_session_callbacks_set_pack_extension_callback2()` with + * :type:`nghttp2_pack_extension_callback2` instead. + * + * Sets callback function invoked when the library asks the + * application to pack extension frame payload in wire format. + */ +NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback( + nghttp2_session_callbacks *cbs, + nghttp2_pack_extension_callback pack_extension_callback); + +#endif /* NGHTTP2_NO_SSIZE_T */ /** * @function @@ -2338,9 +2787,9 @@ * Sets callback function invoked when the library asks the * application to pack extension frame payload in wire format. */ -NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback pack_extension_callback); +NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback2( + nghttp2_session_callbacks *cbs, + nghttp2_pack_extension_callback2 pack_extension_callback); /** * @function @@ -2349,8 +2798,8 @@ * application to unpack extension frame payload from wire format. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_unpack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_unpack_extension_callback unpack_extension_callback); + nghttp2_session_callbacks *cbs, + nghttp2_unpack_extension_callback unpack_extension_callback); /** * @function @@ -2360,24 +2809,27 @@ */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback); /** * @function * + * .. warning:: + * + * Deprecated. Use + * `nghttp2_session_callbacks_set_error_callback2()` with + * :type:`nghttp2_error_callback2` instead. + * * Sets callback function invoked when library tells error message to * the application. * - * This function is deprecated. The new application should use - * `nghttp2_session_callbacks_set_error_callback2()`. - * * If both :type:`nghttp2_error_callback` and * :type:`nghttp2_error_callback2` are set, the latter takes * precedence. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback( - nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback); + nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback); /** * @function @@ -2390,7 +2842,19 @@ * precedence. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2( - nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2); + nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2); + +/** + * @function + * + * Sets callback function invoked when unpredictable data is needed. + * Although this callback is optional due to the backward + * compatibility, it is recommended to specify it to harden the + * runtime behavior against suspicious activities of a remote + * endpoint. + */ +NGHTTP2_EXTERN void nghttp2_session_callbacks_set_rand_callback( + nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback); /** * @functypedef @@ -2568,7 +3032,7 @@ * * If this option is not used or used with zero value, if MAGIC does * not match :macro:`NGHTTP2_CLIENT_MAGIC`, `nghttp2_session_recv()` - * and `nghttp2_session_mem_recv()` will return error + * and `nghttp2_session_mem_recv2()` will return error * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal * error. */ @@ -2692,14 +3156,12 @@ /** * @function * - * This option prevents the library from retaining closed streams to - * maintain the priority tree. If this option is set to nonzero, - * applications can discard closed stream completely to save memory. + * .. warning:: * - * If - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * of value of 1 is submitted via `nghttp2_submit_settings()`, any - * closed streams are not retained regardless of this option. + * Deprecated. Closed streams are not retained anymore. + * + * This function works as before, but it does not take any effect + * against :type:`nghttp2_session`. */ NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option, int val); @@ -2729,16 +3191,11 @@ /** * @function * - * This option, if set to nonzero, allows server to fallback to - * :rfc:`7540` priorities if SETTINGS_NO_RFC7540_PRIORITIES was not - * received from client, and server submitted - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * = 1 via `nghttp2_submit_settings()`. Most of the advanced - * functionality for RFC 7540 priorities are still disabled. This - * fallback only enables the minimal feature set of RFC 7540 - * priorities to deal with priority signaling from client. + * .. warning:: + * Deprecated. :rfc:`7540` priorities have been removed. * - * Client session ignores this option. + * This function works as before, but it does not take any effect + * against :type:`nghttp2_session`. */ NGHTTP2_EXTERN void nghttp2_option_set_server_fallback_rfc7540_priorities(nghttp2_option *option, @@ -2754,7 +3211,52 @@ */ NGHTTP2_EXTERN void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation( - nghttp2_option *option, int val); + nghttp2_option *option, int val); + +/** + * @function + * + * This function sets the rate limit for the incoming stream reset + * (RST_STREAM frame). It is server use only. It is a token-bucket + * based rate limiter. |burst| specifies the number of tokens that is + * initially available. The maximum number of tokens is capped to + * this value. |rate| specifies the number of tokens that are + * regenerated per second. An incoming RST_STREAM consumes one token. + * If there is no token available, GOAWAY is sent to tear down the + * connection. |burst| and |rate| default to 1000 and 33 + * respectively. + */ +NGHTTP2_EXTERN void +nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, + uint64_t burst, uint64_t rate); + +/** + * @function + * + * This function sets the maximum number of CONTINUATION frames + * following an incoming HEADER frame. If more than those frames are + * received, the remote endpoint is considered to be misbehaving and + * session will be closed. The default value is 8. + */ +NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option, + size_t val); + +/** + * @function + * + * This function sets the rate limit for the "glitches", the + * suspicious activities from a remote endpoint. It is a token-bucket + * based rate limiter. |burst| specifies the number of tokens that is + * initially available. The maximum number of tokens is capped to + * this value. |rate| specifies the number of tokens that are + * regenerated per second. When a suspicious activity is detected, + * some amount of tokens are consumed. If there is no token + * available, GOAWAY is sent to tear down the connection. |burst| and + * |rate| default to 1000 and 33 respectively. + */ +NGHTTP2_EXTERN void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option, + uint64_t burst, + uint64_t rate); /** * @function @@ -2764,7 +3266,7 @@ * does not store |callbacks|. The |user_data| is an arbitrary user * supplied data, which will be passed to the callback functions. * - * The :type:`nghttp2_send_callback` must be specified. If the + * The :type:`nghttp2_send_callback2` must be specified. If the * application code uses `nghttp2_session_recv()`, the * :type:`nghttp2_recv_callback` must be specified. The other members * of |callbacks| can be ``NULL``. @@ -2790,7 +3292,7 @@ * does not store |callbacks|. The |user_data| is an arbitrary user * supplied data, which will be passed to the callback functions. * - * The :type:`nghttp2_send_callback` must be specified. If the + * The :type:`nghttp2_send_callback2` must be specified. If the * application code uses `nghttp2_session_recv()`, the * :type:`nghttp2_recv_callback` must be specified. The other members * of |callbacks| can be ``NULL``. @@ -2882,8 +3384,8 @@ * Out of memory. */ NGHTTP2_EXTERN int nghttp2_session_client_new3( - nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option, nghttp2_mem *mem); + nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, + void *user_data, const nghttp2_option *option, nghttp2_mem *mem); /** * @function @@ -2907,8 +3409,8 @@ * Out of memory. */ NGHTTP2_EXTERN int nghttp2_session_server_new3( - nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option, nghttp2_mem *mem); + nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, + void *user_data, const nghttp2_option *option, nghttp2_mem *mem); /** * @function @@ -2926,7 +3428,7 @@ * This function retrieves the highest prioritized frame from the * outbound queue and sends it to the remote peer. It does this as * many times as possible until the user callback - * :type:`nghttp2_send_callback` returns + * :type:`nghttp2_send_callback2` returns * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`, the outbound queue * becomes empty or flow control is triggered (remote window size * becomes depleted or maximum number of concurrent streams is @@ -2956,7 +3458,7 @@ * :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort * the following steps. * - * 8. :type:`nghttp2_send_callback` is invoked one or more times to + * 8. :type:`nghttp2_send_callback2` is invoked one or more times to * send the frame. * * 9. :type:`nghttp2_on_frame_send_callback` is invoked. @@ -2975,9 +3477,14 @@ */ NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session); +#ifndef NGHTTP2_NO_SSIZE_T /** * @function * + * .. warning:: + * + * Deprecated. Use `nghttp2_session_mem_send2()` instead. + * * Returns the serialized data to send. * * This function behaves like `nghttp2_session_send()` except that it @@ -3017,6 +3524,50 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session, const uint8_t **data_ptr); +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @function + * + * Returns the serialized data to send. + * + * This function behaves like `nghttp2_session_send()` except that it + * does not use :type:`nghttp2_send_callback2` to transmit data. + * Instead, it assigns the pointer to the serialized data to the + * |*data_ptr| and returns its length. The other callbacks are called + * in the same way as they are in `nghttp2_session_send()`. + * + * If no data is available to send, this function returns 0. + * + * This function may not return all serialized data in one invocation. + * To get all data, call this function repeatedly until it returns 0 + * or one of negative error codes. + * + * The assigned |*data_ptr| is valid until the next call of + * `nghttp2_session_mem_send2()` or `nghttp2_session_send()`. + * + * The caller must send all data before sending the next chunk of + * data. + * + * This function returns the length of the data pointed by the + * |*data_ptr| if it succeeds, or one of the following negative error + * codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` + * Out of memory. + * + * .. note:: + * + * This function may produce very small byte string. If that is the + * case, and application disables Nagle algorithm (``TCP_NODELAY``), + * then writing this small chunk leads to very small packet, and it + * is very inefficient. An application should be responsible to + * buffer up small chunks of data as necessary to avoid this + * situation. + */ +NGHTTP2_EXTERN nghttp2_ssize +nghttp2_session_mem_send2(nghttp2_session *session, const uint8_t **data_ptr); + /** * @function * @@ -3087,9 +3638,14 @@ */ NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session); +#ifndef NGHTTP2_NO_SSIZE_T /** * @function * + * .. warning:: + * + * Deprecated. Use `nghttp2_session_mem_recv2()` instead. + * * Processes data |in| as an input from the remote endpoint. The * |inlen| indicates the number of bytes to receive in the |in|. * @@ -3128,6 +3684,49 @@ const uint8_t *in, size_t inlen); +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @function + * + * Processes data |in| as an input from the remote endpoint. The + * |inlen| indicates the number of bytes to receive in the |in|. + * + * This function behaves like `nghttp2_session_recv()` except that it + * does not use :type:`nghttp2_recv_callback` to receive data; the + * |in| is the only data for the invocation of this function. If all + * bytes are processed, this function returns. The other callbacks + * are called in the same way as they are in `nghttp2_session_recv()`. + * + * In the current implementation, this function always tries to + * processes |inlen| bytes of input data unless either an error occurs or + * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is returned from + * :type:`nghttp2_on_header_callback` or + * :type:`nghttp2_on_data_chunk_recv_callback`. If + * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is used, the return value + * includes the number of bytes which was used to produce the data or + * frame for the callback. + * + * This function returns the number of processed bytes, or one of the + * following negative error codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` + * Out of memory. + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` + * The callback function failed. + * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC` + * Invalid client magic was detected. This error only returns + * when |session| was configured as server and + * `nghttp2_option_set_no_recv_client_magic()` is not used with + * nonzero value. + * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED` + * Flooding was detected in this HTTP/2 session, and it must be + * closed. This is most likely caused by misbehaviour of peer. + */ +NGHTTP2_EXTERN nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + const uint8_t *in, + size_t inlen); + /** * @function * @@ -3173,7 +3772,7 @@ * @function * * Returns stream_user_data for the stream |stream_id|. The - * stream_user_data is provided by `nghttp2_submit_request()`, + * stream_user_data is provided by `nghttp2_submit_request2()`, * `nghttp2_submit_headers()` or * `nghttp2_session_set_stream_user_data()`. Unless it is set using * `nghttp2_session_set_stream_user_data()`, if the stream is @@ -3241,7 +3840,7 @@ * This function returns -1 if it fails. */ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_recv_data_length( - nghttp2_session *session, int32_t stream_id); + nghttp2_session *session, int32_t stream_id); /** * @function @@ -3261,7 +3860,7 @@ * This function returns -1 if it fails. */ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_local_window_size( - nghttp2_session *session, int32_t stream_id); + nghttp2_session *session, int32_t stream_id); /** * @function @@ -3276,7 +3875,7 @@ * This function returns -1 if it fails. */ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_local_window_size( - nghttp2_session *session, int32_t stream_id); + nghttp2_session *session, int32_t stream_id); /** * @function @@ -3344,7 +3943,7 @@ * This function returns -1 if it fails. */ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_remote_window_size( - nghttp2_session *session, int32_t stream_id); + nghttp2_session *session, int32_t stream_id); /** * @function @@ -3498,7 +4097,7 @@ * :enum:`nghttp2_settings_id`. */ NGHTTP2_EXTERN uint32_t nghttp2_session_get_remote_settings( - nghttp2_session *session, nghttp2_settings_id id); + nghttp2_session *session, nghttp2_settings_id id); /** * @function @@ -3508,7 +4107,7 @@ * in :enum:`nghttp2_settings_id`. */ NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings( - nghttp2_session *session, nghttp2_settings_id id); + nghttp2_session *session, nghttp2_settings_id id); /** * @function @@ -3609,36 +4208,13 @@ /** * @function * - * Changes priority of existing stream denoted by |stream_id|. The - * new priority specification is |pri_spec|. + * .. warning:: * - * The priority is changed silently and instantly, and no PRIORITY - * frame will be sent to notify the peer of this change. This - * function may be useful for server to change the priority of pushed - * stream. + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. * - * If |session| is initialized as server, and ``pri_spec->stream_id`` - * points to the idle stream, the idle stream is created if it does - * not exist. The created idle stream will depend on root stream - * (stream 0) with weight 16. - * - * Otherwise, if stream denoted by ``pri_spec->stream_id`` is not - * found, we use default priority instead of given |pri_spec|. That - * is make stream depend on root stream with weight 16. - * - * If - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * of value of 1 is submitted via `nghttp2_submit_settings()`, this - * function does nothing and returns 0. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * Attempted to depend on itself; or no stream exist for the given - * |stream_id|; or |stream_id| is 0 + * This function is noop. It always returns 0. */ NGHTTP2_EXTERN int nghttp2_session_change_stream_priority(nghttp2_session *session, @@ -3648,48 +4224,13 @@ /** * @function * - * Creates idle stream with the given |stream_id|, and priority - * |pri_spec|. + * .. warning:: * - * The stream creation is done without sending PRIORITY frame, which - * means that peer does not know about the existence of this idle - * stream in the local endpoint. + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. * - * RFC 7540 does not disallow the use of creation of idle stream with - * odd or even stream ID regardless of client or server. So this - * function can create odd or even stream ID regardless of client or - * server. But probably it is a bit safer to use the stream ID the - * local endpoint can initiate (in other words, use odd stream ID for - * client, and even stream ID for server), to avoid potential - * collision from peer's instruction. Also we can use - * `nghttp2_session_set_next_stream_id()` to avoid to open created - * idle streams accidentally if we follow this recommendation. - * - * If |session| is initialized as server, and ``pri_spec->stream_id`` - * points to the idle stream, the idle stream is created if it does - * not exist. The created idle stream will depend on root stream - * (stream 0) with weight 16. - * - * Otherwise, if stream denoted by ``pri_spec->stream_id`` is not - * found, we use default priority instead of given |pri_spec|. That - * is make stream depend on root stream with weight 16. - * - * If - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * of value of 1 is submitted via `nghttp2_submit_settings()`, this - * function does nothing and returns 0. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` - * Out of memory. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * Attempted to depend on itself; or stream denoted by |stream_id| - * already exists; or |stream_id| cannot be used to create idle - * stream (in other words, local endpoint has already opened - * stream ID greater than or equal to the given stream ID; or - * |stream_id| is 0 + * This function is noop. It always returns 0. */ NGHTTP2_EXTERN int nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id, @@ -3698,10 +4239,6 @@ /** * @function * - * Performs post-process of HTTP Upgrade request. This function can - * be called from both client and server, but the behavior is very - * different in each other. - * * .. warning:: * * This function is deprecated in favor of @@ -3713,6 +4250,10 @@ * HEAD is used in request, the length of response body must be 0 * regardless of value included in content-length header field. * + * Performs post-process of HTTP Upgrade request. This function can + * be called from both client and server, but the behavior is very + * different in each other. + * * If called from client side, the |settings_payload| must be the * value sent in ``HTTP2-Settings`` header field and must be decoded * by base64url decoder. The |settings_payloadlen| is the length of @@ -3792,6 +4333,37 @@ int head_request, void *stream_user_data); +#ifndef NGHTTP2_NO_SSIZE_T +/** + * @function + * + * .. warning:: + * + * Deprecated. Use `nghttp2_pack_settings_payload2()` instead. + * + * Serializes the SETTINGS values |iv| in the |buf|. The size of the + * |buf| is specified by |buflen|. The number of entries in the |iv| + * array is given by |niv|. The required space in |buf| for the |niv| + * entries is ``6*niv`` bytes and if the given buffer is too small, an + * error is returned. This function is used mainly for creating a + * SETTINGS payload to be sent with the ``HTTP2-Settings`` header + * field in an HTTP Upgrade request. The data written in |buf| is NOT + * base64url encoded and the application is responsible for encoding. + * + * This function returns the number of bytes written in |buf|, or one + * of the following negative error codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` + * The |iv| contains duplicate settings ID or invalid value. + * + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` + * The provided |buflen| size is too small to hold the output. + */ +NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload( + uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv); + +#endif /* NGHTTP2_NO_SSIZE_T */ + /** * @function * @@ -3813,8 +4385,8 @@ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` * The provided |buflen| size is too small to hold the output. */ -NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload( - uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv); +NGHTTP2_EXTERN nghttp2_ssize nghttp2_pack_settings_payload2( + uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv); /** * @function @@ -3837,6 +4409,12 @@ /** * @function * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * Initializes |pri_spec| with the |stream_id| of the stream to depend * on with |weight| and its exclusive flag. If |exclusive| is * nonzero, exclusive flag is set. @@ -3851,6 +4429,12 @@ /** * @function * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * Initializes |pri_spec| with the default values. The default values * are: stream_id = 0, weight = :macro:`NGHTTP2_DEFAULT_WEIGHT` and * exclusive = 0. @@ -3861,33 +4445,28 @@ /** * @function * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * Returns nonzero if the |pri_spec| is filled with default values. */ NGHTTP2_EXTERN int nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec); +#ifndef NGHTTP2_NO_SSIZE_T /** * @function * + * .. warning:: + * + * Deprecated. Use `nghttp2_submit_request2()` instead. + * * Submits HEADERS frame and optionally one or more DATA frames. * - * The |pri_spec| is priority specification of this request. ``NULL`` - * means the default priority (see - * `nghttp2_priority_spec_default_init()`). To specify the priority, - * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``, - * this function will copy its data members. - * - * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, - * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` - * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes - * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than - * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes - * :macro:`NGHTTP2_MAX_WEIGHT`. - * - * If - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * of value of 1 is received by a remote endpoint, |pri_spec| is - * ignored, and treated as if ``NULL`` is specified. + * The |pri_spec| is ignored. * * The |nva| is an array of name/value pair :type:`nghttp2_nv` with * |nvlen| elements. The application is responsible to include @@ -3930,9 +4509,6 @@ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` * No stream ID is available because maximum stream ID was * reached. - * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * Trying to depend on itself (new stream ID equals - * ``pri_spec->stream_id``). * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` * The |session| is server session. * @@ -3949,13 +4525,88 @@ * */ NGHTTP2_EXTERN int32_t nghttp2_submit_request( - nghttp2_session *session, const nghttp2_priority_spec *pri_spec, - const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd, - void *stream_user_data); + nghttp2_session *session, const nghttp2_priority_spec *pri_spec, + const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd, + void *stream_user_data); + +#endif /* NGHTTP2_NO_SSIZE_T */ /** * @function * + * Submits HEADERS frame and optionally one or more DATA frames. + * + * The |pri_spec| is ignored. + * + * The |nva| is an array of name/value pair :type:`nghttp2_nv` with + * |nvlen| elements. The application is responsible to include + * required pseudo-header fields (header field whose name starts with + * ":") in |nva| and must place pseudo-headers before regular header + * fields. + * + * This function creates copies of all name/value pairs in |nva|. It + * also lower-cases all names in |nva|. The order of elements in + * |nva| is preserved. For header fields with + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, + * header field name and value are not copied respectively. With + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application + * is responsible to pass header field name in lowercase. The + * application should maintain the references to them until + * :type:`nghttp2_on_frame_send_callback` or + * :type:`nghttp2_on_frame_not_send_callback` is called. + * + * HTTP/2 specification has requirement about header fields in the + * request HEADERS. See the specification for more details. + * + * If |data_prd| is not ``NULL``, it provides data which will be sent + * in subsequent DATA frames. In this case, a method that allows + * request message bodies + * (https://tools.ietf.org/html/rfc7231#section-4) must be specified + * with ``:method`` key in |nva| (e.g. ``POST``). This function does + * not take ownership of the |data_prd|. The function copies the + * members of the |data_prd|. If |data_prd| is ``NULL``, HEADERS have + * END_STREAM set. The |stream_user_data| is data associated to the + * stream opened by this request and can be an arbitrary pointer, + * which can be retrieved later by + * `nghttp2_session_get_stream_user_data()`. + * + * This function returns assigned stream ID if it succeeds, or one of + * the following negative error codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` + * Out of memory. + * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` + * No stream ID is available because maximum stream ID was + * reached. + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` + * The |session| is server session. + * + * .. warning:: + * + * This function returns assigned stream ID if it succeeds. But + * that stream is not created yet. The application must not submit + * frame to that stream ID before + * :type:`nghttp2_before_frame_send_callback` is called for this + * frame. This means `nghttp2_session_get_stream_user_data()` does + * not work before the callback. But + * `nghttp2_session_set_stream_user_data()` handles this situation + * specially, and it can set data to a stream during this period. + * + */ +NGHTTP2_EXTERN int32_t nghttp2_submit_request2( + nghttp2_session *session, const nghttp2_priority_spec *pri_spec, + const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider2 *data_prd, + void *stream_user_data); + +#ifndef NGHTTP2_NO_SSIZE_T +/** + * @function + * + * .. warning:: + * + * Deprecated. Use `nghttp2_submit_response2()` instead. + * * Submits response HEADERS frame and optionally one or more DATA * frames against the stream |stream_id|. * @@ -4022,6 +4673,77 @@ const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd); +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @function + * + * Submits response HEADERS frame and optionally one or more DATA + * frames against the stream |stream_id|. + * + * The |nva| is an array of name/value pair :type:`nghttp2_nv` with + * |nvlen| elements. The application is responsible to include + * required pseudo-header fields (header field whose name starts with + * ":") in |nva| and must place pseudo-headers before regular header + * fields. + * + * This function creates copies of all name/value pairs in |nva|. It + * also lower-cases all names in |nva|. The order of elements in + * |nva| is preserved. For header fields with + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, + * header field name and value are not copied respectively. With + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application + * is responsible to pass header field name in lowercase. The + * application should maintain the references to them until + * :type:`nghttp2_on_frame_send_callback` or + * :type:`nghttp2_on_frame_not_send_callback` is called. + * + * HTTP/2 specification has requirement about header fields in the + * response HEADERS. See the specification for more details. + * + * If |data_prd| is not ``NULL``, it provides data which will be sent + * in subsequent DATA frames. This function does not take ownership + * of the |data_prd|. The function copies the members of the + * |data_prd|. If |data_prd| is ``NULL``, HEADERS will have + * END_STREAM flag set. + * + * This method can be used as normal HTTP response and push response. + * When pushing a resource using this function, the |session| must be + * configured using `nghttp2_session_server_new()` or its variants and + * the target stream denoted by the |stream_id| must be reserved using + * `nghttp2_submit_push_promise()`. + * + * To send non-final response headers (e.g., HTTP status 101), don't + * use this function because this function half-closes the outbound + * stream. Instead, use `nghttp2_submit_headers()` for this purpose. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` + * Out of memory. + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` + * The |stream_id| is 0. + * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` + * DATA or HEADERS has been already submitted and not fully + * processed yet. Normally, this does not happen, but when + * application wrongly calls `nghttp2_submit_response2()` twice, + * this may happen. + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` + * The |session| is client session. + * + * .. warning:: + * + * Calling this function twice for the same stream ID may lead to + * program crash. It is generally considered to a programming error + * to commit response twice. + */ +NGHTTP2_EXTERN int +nghttp2_submit_response2(nghttp2_session *session, int32_t stream_id, + const nghttp2_nv *nva, size_t nvlen, + const nghttp2_data_provider2 *data_prd); + /** * @function * @@ -4047,22 +4769,23 @@ * DATA without END_STREAM flat set. The library does not enforce * this requirement, and applications should do this for themselves. * If `nghttp2_submit_trailer()` is called before any response HEADERS - * submission (usually by `nghttp2_submit_response()`), the content of - * |nva| will be sent as response headers, which will result in error. + * submission (usually by `nghttp2_submit_response2()`), the content + * of |nva| will be sent as response headers, which will result in + * error. * * This function has the same effect with `nghttp2_submit_headers()`, * with flags = :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` and both * pri_spec and stream_user_data to NULL. * - * To submit trailer fields after `nghttp2_submit_response()` is + * To submit trailer fields after `nghttp2_submit_response2()` is * called, the application has to specify - * :type:`nghttp2_data_provider` to `nghttp2_submit_response()`. - * Inside of :type:`nghttp2_data_source_read_callback`, when setting + * :type:`nghttp2_data_provider2` to `nghttp2_submit_response2()`. + * Inside of :type:`nghttp2_data_source_read_callback2`, when setting * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF`, also set * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM`. After * that, the application can send trailer fields using * `nghttp2_submit_trailer()`. `nghttp2_submit_trailer()` can be used - * inside :type:`nghttp2_data_source_read_callback`. + * inside :type:`nghttp2_data_source_read_callback2`. * * This function returns 0 if it succeeds and |stream_id| is -1. * Otherwise, this function returns 0 if it succeeds, or one of the @@ -4097,22 +4820,7 @@ * assigned stream ID will be returned. Otherwise, specify stream ID * in |stream_id|. * - * The |pri_spec| is priority specification of this request. ``NULL`` - * means the default priority (see - * `nghttp2_priority_spec_default_init()`). To specify the priority, - * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``, - * this function will copy its data members. - * - * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, - * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` - * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes - * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than - * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`. - * - * If - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * of value of 1 is received by a remote endpoint, |pri_spec| is - * ignored, and treated as if ``NULL`` is specified. + * The |pri_spec| is ignored. * * The |nva| is an array of name/value pair :type:`nghttp2_nv` with * |nvlen| elements. The application is responsible to include @@ -4139,8 +4847,8 @@ * * This function is low-level in a sense that the application code can * specify flags directly. For usual HTTP request, - * `nghttp2_submit_request()` is useful. Likewise, for HTTP response, - * prefer `nghttp2_submit_response()`. + * `nghttp2_submit_request2()` is useful. Likewise, for HTTP + * response, prefer `nghttp2_submit_response2()`. * * This function returns newly assigned stream ID if it succeeds and * |stream_id| is -1. Otherwise, this function returns 0 if it @@ -4152,8 +4860,7 @@ * No stream ID is available because maximum stream ID was * reached. * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0; or trying to depend on itself (stream ID - * equals ``pri_spec->stream_id``). + * The |stream_id| is 0. * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` * DATA or HEADERS has been already submitted and not fully * processed yet. This happens if stream denoted by |stream_id| @@ -4171,13 +4878,18 @@ * */ NGHTTP2_EXTERN int32_t nghttp2_submit_headers( - nghttp2_session *session, uint8_t flags, int32_t stream_id, - const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen, - void *stream_user_data); + nghttp2_session *session, uint8_t flags, int32_t stream_id, + const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen, + void *stream_user_data); +#ifndef NGHTTP2_NO_SSIZE_T /** * @function * + * .. warning:: + * + * Deprecated. Use `nghttp2_submit_data2()` instead. + * * Submits one or more DATA frames to the stream |stream_id|. The * data to be sent are provided by |data_prd|. If |flags| contains * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame @@ -4220,40 +4932,63 @@ int32_t stream_id, const nghttp2_data_provider *data_prd); +#endif /* NGHTTP2_NO_SSIZE_T */ + /** * @function * - * Submits PRIORITY frame to change the priority of stream |stream_id| - * to the priority specification |pri_spec|. + * Submits one or more DATA frames to the stream |stream_id|. The + * data to be sent are provided by |data_prd|. If |flags| contains + * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame + * has END_STREAM flag set. * - * The |flags| is currently ignored and should be - * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. - * - * The |pri_spec| is priority specification of this request. ``NULL`` - * is not allowed for this function. To specify the priority, use - * `nghttp2_priority_spec_init()`. This function will copy its data - * members. - * - * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, - * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` - * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes - * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than - * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes - * :macro:`NGHTTP2_MAX_WEIGHT`. - * - * If - * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` - * of value of 1 is received by a remote endpoint, this function does - * nothing and returns 0. + * This function does not take ownership of the |data_prd|. The + * function copies the members of the |data_prd|. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. + * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` + * DATA or HEADERS has been already submitted and not fully + * processed yet. * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` - * The |stream_id| is 0; or the |pri_spec| is NULL; or trying to - * depend on itself. + * The |stream_id| is 0. + * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED` + * The stream was already closed; or the |stream_id| is invalid. + * + * .. note:: + * + * Currently, only one DATA or HEADERS is allowed for a stream at a + * time. Submitting these frames more than once before first DATA + * or HEADERS is finished results in + * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` error code. The + * earliest callback which tells that previous frame is done is + * :type:`nghttp2_on_frame_send_callback`. In side that callback, + * new data can be submitted using `nghttp2_submit_data2()`. Of + * course, all data except for last one must not have + * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` flag set in |flags|. + * This sounds a bit complicated, and we recommend to use + * `nghttp2_submit_request2()` and `nghttp2_submit_response2()` to + * avoid this cascading issue. The experience shows that for HTTP + * use, these two functions are enough to implement both client and + * server. + */ +NGHTTP2_EXTERN int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags, + int32_t stream_id, + const nghttp2_data_provider2 *data_prd); + +/** + * @function + * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * + * This function is noop. It always returns 0. */ NGHTTP2_EXTERN int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags, @@ -4412,7 +5147,7 @@ * The client side is not allowed to use this function. * * To submit response headers and data, use - * `nghttp2_submit_response()`. + * `nghttp2_submit_response2()`. * * This function returns assigned promised stream ID if it succeeds, * or one of the following negative error codes: @@ -4445,8 +5180,8 @@ * */ NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise( - nghttp2_session *session, uint8_t flags, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data); + nghttp2_session *session, uint8_t flags, int32_t stream_id, + const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data); /** * @function @@ -4551,10 +5286,11 @@ * reasons are: session is server; stream ID has been spent; GOAWAY * has been sent or received. * - * The application can call `nghttp2_submit_request()` without - * consulting this function. In that case, `nghttp2_submit_request()` - * may return error. Or, request is failed to sent, and - * :type:`nghttp2_on_stream_close_callback` is called. + * The application can call `nghttp2_submit_request2()` without + * consulting this function. In that case, + * `nghttp2_submit_request2()` may return error. Or, request is + * failed to sent, and :type:`nghttp2_on_stream_close_callback` is + * called. */ NGHTTP2_EXTERN int nghttp2_session_check_request_allowed(nghttp2_session *session); @@ -4656,11 +5392,11 @@ * Application can pass arbitrary frame flags and stream ID in |flags| * and |stream_id| respectively. The |payload| is opaque pointer, and * it can be accessible though ``frame->ext.payload`` in - * :type:`nghttp2_pack_extension_callback`. The library will not own + * :type:`nghttp2_pack_extension_callback2`. The library will not own * passed |payload| pointer. * - * The application must set :type:`nghttp2_pack_extension_callback` - * using `nghttp2_session_callbacks_set_pack_extension_callback()`. + * The application must set :type:`nghttp2_pack_extension_callback2` + * using `nghttp2_session_callbacks_set_pack_extension_callback2()`. * * The application should retain the memory pointed by |payload| until * the transmission of extension frame is done (which is indicated by @@ -4668,7 +5404,7 @@ * (which is indicated by :type:`nghttp2_on_frame_not_send_callback`). * If application does not touch this memory region after packing it * into a wire format, application can free it inside - * :type:`nghttp2_pack_extension_callback`. + * :type:`nghttp2_pack_extension_callback2`. * * The standard HTTP/2 frame cannot be sent with this function, so * |type| must be strictly grater than 0x9. Otherwise, this function @@ -4679,7 +5415,7 @@ * negative error codes: * * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` - * If :type:`nghttp2_pack_extension_callback` is not set. + * If :type:`nghttp2_pack_extension_callback2` is not set. * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * If |type| specifies standard HTTP/2 frame type. The frame * types in the rage [0x0, 0x9], both inclusive, are standard @@ -4938,8 +5674,57 @@ * found. */ NGHTTP2_EXTERN int nghttp2_session_change_extpri_stream_priority( - nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri, - int ignore_client_signal); + nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri, + int ignore_client_signal); + +/** + * @function + * + * Stores the stream priority of the existing stream denoted by + * |stream_id| in the object pointed by |extpri|. This function is + * meant to be used by server for :rfc:`9218` extensible + * prioritization scheme. + * + * If |session| is initialized as client, this function returns + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. + * + * If + * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` + * of value of 1 is not submitted via `nghttp2_submit_settings()`, + * this function does nothing and returns 0. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` + * The |session| is initialized as client. + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` + * |stream_id| is zero; or a stream denoted by |stream_id| is not + * found. + */ +NGHTTP2_EXTERN int nghttp2_session_get_extpri_stream_priority( + nghttp2_session *session, nghttp2_extpri *extpri, int32_t stream_id); + +/** + * @function + * + * Parses Priority header field value pointed by |value| of length + * |len|, and stores the result in the object pointed by |extpri|. + * Priority header field is defined in :rfc:`9218`. + * + * This function does not initialize the object pointed by |extpri| + * before storing the result. It only assigns the values that the + * parser correctly extracted to fields. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` + * Failed to parse the header field value. + */ +NGHTTP2_EXTERN int nghttp2_extpri_parse_priority(nghttp2_extpri *extpri, + const uint8_t *value, + size_t len); /** * @function @@ -4956,11 +5741,14 @@ /** * @function * - * A helper function for dealing with NPN in client side or ALPN in - * server side. The |in| contains peer's protocol list in preferable - * order. The format of |in| is length-prefixed and not - * null-terminated. For example, ``h2`` and - * ``http/1.1`` stored in |in| like this:: + * .. warning:: + * + * Deprecated. Use `nghttp2_select_alpn` instead. + * + * A helper function for dealing with ALPN in server side. The |in| + * contains peer's protocol list in preferable order. The format of + * |in| is length-prefixed and not null-terminated. For example, + * ``h2`` and ``http/1.1`` stored in |in| like this:: * * in[0] = 2 * in[1..2] = "h2" @@ -4985,20 +5773,18 @@ * * For ALPN, refer to https://tools.ietf.org/html/rfc7301 * - * See http://technotes.googlecode.com/git/nextprotoneg.html for more - * details about NPN. + * To use this method you should do something like:: * - * For NPN, to use this method you should do something like:: - * - * static int select_next_proto_cb(SSL* ssl, - * unsigned char **out, + * static int alpn_select_proto_cb(SSL* ssl, + * const unsigned char **out, * unsigned char *outlen, * const unsigned char *in, * unsigned int inlen, * void *arg) * { * int rv; - * rv = nghttp2_select_next_protocol(out, outlen, in, inlen); + * rv = nghttp2_select_next_protocol((unsigned char**)out, outlen, + * in, inlen); * if (rv == -1) { * return SSL_TLSEXT_ERR_NOACK; * } @@ -5008,7 +5794,7 @@ * return SSL_TLSEXT_ERR_OK; * } * ... - * SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, my_obj); + * SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, my_obj); * */ NGHTTP2_EXTERN int nghttp2_select_next_protocol(unsigned char **out, @@ -5019,6 +5805,65 @@ /** * @function * + * A helper function for dealing with ALPN in server side. The |in| + * contains peer's protocol list in preferable order. The format of + * |in| is length-prefixed and not null-terminated. For example, + * ``h2`` and ``http/1.1`` stored in |in| like this:: + * + * in[0] = 2 + * in[1..2] = "h2" + * in[3] = 8 + * in[4..11] = "http/1.1" + * inlen = 12 + * + * The selection algorithm is as follows: + * + * 1. If peer's list contains HTTP/2 protocol the library supports, + * it is selected and returns 1. The following step is not taken. + * + * 2. If peer's list contains ``http/1.1``, this function selects + * ``http/1.1`` and returns 0. The following step is not taken. + * + * 3. This function selects nothing and returns -1 (So called + * non-overlap case). In this case, |out| and |outlen| are left + * untouched. + * + * Selecting ``h2`` means that ``h2`` is written into |*out| and its + * length (which is 2) is assigned to |*outlen|. + * + * For ALPN, refer to https://tools.ietf.org/html/rfc7301 + * + * To use this method you should do something like:: + * + * static int alpn_select_proto_cb(SSL* ssl, + * const unsigned char **out, + * unsigned char *outlen, + * const unsigned char *in, + * unsigned int inlen, + * void *arg) + * { + * int rv; + * rv = nghttp2_select_alpn(out, outlen, in, inlen); + * if (rv == -1) { + * return SSL_TLSEXT_ERR_NOACK; + * } + * if (rv == 1) { + * ((MyType*)arg)->http2_selected = 1; + * } + * return SSL_TLSEXT_ERR_OK; + * } + * ... + * SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, my_obj); + * + */ +NGHTTP2_EXTERN int nghttp2_select_alpn(const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen); + +/** + * @function + * * Returns a pointer to a nghttp2_info struct with version information * about the run-time library in use. The |least_version| argument * can be set to a 24 bit numerical value for the least accepted @@ -5100,6 +5945,12 @@ * :authority or host header field is valid according to * https://tools.ietf.org/html/rfc3986#section-3.2 * + * Note that :authority and host field values are not authority. They + * do not include userinfo in RFC 3986, see + * https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2, that + * is, it does not include '@'. This function treats '@' as a valid + * character. + * * |value| is valid if it merely consists of the allowed characters. * In particular, it does not check whether |value| follows the syntax * of authority. @@ -5191,9 +6042,14 @@ nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size); +#ifndef NGHTTP2_NO_SSIZE_T /** * @function * + * .. warning:: + * + * Deprecated. Use `nghttp2_hd_deflate_hd2()` instead. + * * Deflates the |nva|, which has the |nvlen| name/value pairs, into * the |buf| of length |buflen|. * @@ -5223,10 +6079,48 @@ const nghttp2_nv *nva, size_t nvlen); +#endif /* NGHTTP2_NO_SSIZE_T */ + /** * @function * * Deflates the |nva|, which has the |nvlen| name/value pairs, into + * the |buf| of length |buflen|. + * + * If |buf| is not large enough to store the deflated header block, + * this function fails with + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller + * should use `nghttp2_hd_deflate_bound()` to know the upper bound of + * buffer size required to deflate given header name/value pairs. + * + * Once this function fails, subsequent call of this function always + * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`. + * + * After this function returns, it is safe to delete the |nva|. + * + * This function returns the number of bytes written to |buf| if it + * succeeds, or one of the following negative error codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` + * Out of memory. + * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` + * Deflation process has failed. + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` + * The provided |buflen| size is too small to hold the output. + */ +NGHTTP2_EXTERN nghttp2_ssize +nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater, uint8_t *buf, + size_t buflen, const nghttp2_nv *nva, size_t nvlen); + +#ifndef NGHTTP2_NO_SSIZE_T +/** + * @function + * + * .. warning:: + * + * Deprecated. Use `nghttp2_hd_deflate_hd_vec2()` instead. + * + * Deflates the |nva|, which has the |nvlen| name/value pairs, into * the |veclen| size of buf vector |vec|. The each size of buffer * must be set in len field of :type:`nghttp2_vec`. If and only if * one chunk is filled up completely, next chunk will be used. If @@ -5257,6 +6151,40 @@ const nghttp2_nv *nva, size_t nvlen); +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @function + * + * Deflates the |nva|, which has the |nvlen| name/value pairs, into + * the |veclen| size of buf vector |vec|. The each size of buffer + * must be set in len field of :type:`nghttp2_vec`. If and only if + * one chunk is filled up completely, next chunk will be used. If + * |vec| is not large enough to store the deflated header block, this + * function fails with + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller + * should use `nghttp2_hd_deflate_bound()` to know the upper bound of + * buffer size required to deflate given header name/value pairs. + * + * Once this function fails, subsequent call of this function always + * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`. + * + * After this function returns, it is safe to delete the |nva|. + * + * This function returns the number of bytes written to |vec| if it + * succeeds, or one of the following negative error codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` + * Out of memory. + * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` + * Deflation process has failed. + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` + * The provided |buflen| size is too small to hold the output. + */ +NGHTTP2_EXTERN nghttp2_ssize nghttp2_hd_deflate_hd_vec2( + nghttp2_hd_deflater *deflater, const nghttp2_vec *vec, size_t veclen, + const nghttp2_nv *nva, size_t nvlen); + /** * @function * @@ -5370,7 +6298,7 @@ * This function must not be called while header block is being * inflated. In other words, this function must be called after * initialization of |inflater|, but before calling - * `nghttp2_hd_inflate_hd2()`, or after + * `nghttp2_hd_inflate_hd3()`, or after * `nghttp2_hd_inflate_end_headers()`. Otherwise, * `NGHTTP2_ERR_INVALID_STATE` was returned. * @@ -5408,6 +6336,7 @@ NGHTTP2_HD_INFLATE_EMIT = 0x02 } nghttp2_hd_inflate_flag; +#ifndef NGHTTP2_NO_SSIZE_T /** * @function * @@ -5495,9 +6424,16 @@ int *inflate_flags, uint8_t *in, size_t inlen, int in_final); +#endif /* NGHTTP2_NO_SSIZE_T */ + +#ifndef NGHTTP2_NO_SSIZE_T /** * @function * + * .. warning:: + * + * Deprecated. Use `nghttp2_hd_inflate_hd3()` instead. + * * Inflates name/value block stored in |in| with length |inlen|. This * function performs decompression. For each successful emission of * header name/value pair, @@ -5584,6 +6520,95 @@ const uint8_t *in, size_t inlen, int in_final); +#endif /* NGHTTP2_NO_SSIZE_T */ + +/** + * @function + * + * Inflates name/value block stored in |in| with length |inlen|. This + * function performs decompression. For each successful emission of + * header name/value pair, + * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in + * |*inflate_flags| and name/value pair is assigned to the |nv_out| + * and the function returns. The caller must not free the members of + * |nv_out|. + * + * The |nv_out| may include pointers to the memory region in the |in|. + * The caller must retain the |in| while the |nv_out| is used. + * + * The application should call this function repeatedly until the + * ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and + * return value is non-negative. If that happens, all given input + * data (|inlen| bytes) are processed successfully. Then the + * application must call `nghttp2_hd_inflate_end_headers()` to prepare + * for the next header block input. + * + * In other words, if |in_final| is nonzero, and this function returns + * |inlen|, you can assert that + * :enum:`nghttp2_hd_inflate_final.NGHTTP2_HD_INFLATE_FINAL` is set in + * |*inflate_flags|. + * + * The caller can feed complete compressed header block. It also can + * feed it in several chunks. The caller must set |in_final| to + * nonzero if the given input is the last block of the compressed + * header. + * + * This function returns the number of bytes processed if it succeeds, + * or one of the following negative error codes: + * + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` + * Out of memory. + * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` + * Inflation process has failed. + * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR` + * The header field name or value is too large. + * + * Example follows:: + * + * int inflate_header_block(nghttp2_hd_inflater *hd_inflater, + * uint8_t *in, size_t inlen, int final) + * { + * nghttp2_ssize rv; + * + * for(;;) { + * nghttp2_nv nv; + * int inflate_flags = 0; + * + * rv = nghttp2_hd_inflate_hd3(hd_inflater, &nv, &inflate_flags, + * in, inlen, final); + * + * if(rv < 0) { + * fprintf(stderr, "inflate failed with error code %td", rv); + * return -1; + * } + * + * in += rv; + * inlen -= rv; + * + * if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) { + * fwrite(nv.name, nv.namelen, 1, stderr); + * fprintf(stderr, ": "); + * fwrite(nv.value, nv.valuelen, 1, stderr); + * fprintf(stderr, "\n"); + * } + * if(inflate_flags & NGHTTP2_HD_INFLATE_FINAL) { + * nghttp2_hd_inflate_end_headers(hd_inflater); + * break; + * } + * if((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 && + * inlen == 0) { + * break; + * } + * } + * + * return 0; + * } + * + */ +NGHTTP2_EXTERN nghttp2_ssize nghttp2_hd_inflate_hd3( + nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out, int *inflate_flags, + const uint8_t *in, size_t inlen, int in_final); + /** * @function * @@ -5657,8 +6682,8 @@ * `nghttp2_session_get_root_stream()`) if 0 is given in |stream_id|. * * Unless |stream_id| == 0, the returned pointer is valid until next - * call of `nghttp2_session_send()`, `nghttp2_session_mem_send()`, - * `nghttp2_session_recv()`, and `nghttp2_session_mem_recv()`. + * call of `nghttp2_session_send()`, `nghttp2_session_mem_send2()`, + * `nghttp2_session_recv()`, and `nghttp2_session_mem_recv2()`. */ NGHTTP2_EXTERN nghttp2_stream * nghttp2_session_find_stream(nghttp2_session *session, int32_t stream_id); @@ -5712,6 +6737,12 @@ /** * @function * + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * * Returns root of dependency tree, which is imaginary stream with * stream ID 0. The returned pointer is valid until |session| is * freed by `nghttp2_session_del()`. @@ -5722,8 +6753,13 @@ /** * @function * - * Returns the parent stream of |stream| in dependency tree. Returns - * NULL if there is no such stream. + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * + * This function always returns NULL. */ NGHTTP2_EXTERN nghttp2_stream * nghttp2_stream_get_parent(nghttp2_stream *stream); @@ -5733,8 +6769,13 @@ /** * @function * - * Returns the next sibling stream of |stream| in dependency tree. - * Returns NULL if there is no such stream. + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * + * This function always returns NULL. */ NGHTTP2_EXTERN nghttp2_stream * nghttp2_stream_get_next_sibling(nghttp2_stream *stream); @@ -5742,8 +6783,13 @@ /** * @function * - * Returns the previous sibling stream of |stream| in dependency tree. - * Returns NULL if there is no such stream. + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * + * This function always returns NULL. */ NGHTTP2_EXTERN nghttp2_stream * nghttp2_stream_get_previous_sibling(nghttp2_stream *stream); @@ -5751,8 +6797,13 @@ /** * @function * - * Returns the first child stream of |stream| in dependency tree. - * Returns NULL if there is no such stream. + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * + * This function always returns NULL. */ NGHTTP2_EXTERN nghttp2_stream * nghttp2_stream_get_first_child(nghttp2_stream *stream); @@ -5760,14 +6811,26 @@ /** * @function * - * Returns dependency weight to the parent stream of |stream|. + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * + * This function always returns :macro:`NGHTTP2_DEFAULT_WEIGHT`. */ NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream); /** * @function * - * Returns the sum of the weight for |stream|'s children. + * .. warning:: + * + * Deprecated. :rfc:`7540` priorities are deprecated by + * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible + * prioritization scheme. + * + * This function always returns 0. */ NGHTTP2_EXTERN int32_t nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream); @@ -5806,7 +6869,7 @@ * this is important. */ NGHTTP2_EXTERN void nghttp2_set_debug_vprintf_callback( - nghttp2_debug_vprintf_callback debug_vprintf_callback); + nghttp2_debug_vprintf_callback debug_vprintf_callback); #ifdef __cplusplus }
diff --git a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h index 6ed0ac4..8dfe536 100644 --- a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h +++ b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h
@@ -29,7 +29,7 @@ * @macro * Version number of the nghttp2 library release */ -#define NGHTTP2_VERSION "1.52.0" +#define NGHTTP2_VERSION "1.68.0" /** * @macro @@ -37,6 +37,6 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define NGHTTP2_VERSION_NUM 0x013400 +#define NGHTTP2_VERSION_NUM 0x014400 #endif /* NGHTTP2VER_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_npn.c b/Utilities/cmnghttp2/lib/nghttp2_alpn.c similarity index 65% rename from Utilities/cmnghttp2/lib/nghttp2_npn.c rename to Utilities/cmnghttp2/lib/nghttp2_alpn.c index d1384c8..33c5885 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_npn.c +++ b/Utilities/cmnghttp2/lib/nghttp2_alpn.c
@@ -22,13 +22,13 @@ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "nghttp2_npn.h" +#include "nghttp2_alpn.h" #include <string.h> -static int select_next_protocol(unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, - const char *key, unsigned int keylen) { +static int select_alpn(const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const char *key, unsigned int keylen) { unsigned int i; for (i = 0; i + keylen <= inlen; i += (unsigned int)(in[i] + 1)) { if (memcmp(&in[i], key, keylen) == 0) { @@ -45,12 +45,25 @@ int nghttp2_select_next_protocol(unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen) { - if (select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_ALPN, - NGHTTP2_PROTO_ALPN_LEN) == 0) { + if (select_alpn((const unsigned char **)out, outlen, in, inlen, + NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN) == 0) { return 1; } - if (select_next_protocol(out, outlen, in, inlen, NGHTTP2_HTTP_1_1_ALPN, - NGHTTP2_HTTP_1_1_ALPN_LEN) == 0) { + if (select_alpn((const unsigned char **)out, outlen, in, inlen, + NGHTTP2_HTTP_1_1_ALPN, NGHTTP2_HTTP_1_1_ALPN_LEN) == 0) { + return 0; + } + return -1; +} + +int nghttp2_select_alpn(const unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen) { + if (select_alpn(out, outlen, in, inlen, NGHTTP2_PROTO_ALPN, + NGHTTP2_PROTO_ALPN_LEN) == 0) { + return 1; + } + if (select_alpn(out, outlen, in, inlen, NGHTTP2_HTTP_1_1_ALPN, + NGHTTP2_HTTP_1_1_ALPN_LEN) == 0) { return 0; } return -1;
diff --git a/Utilities/cmnghttp2/lib/nghttp2_npn.h b/Utilities/cmnghttp2/lib/nghttp2_alpn.h similarity index 90% rename from Utilities/cmnghttp2/lib/nghttp2_npn.h rename to Utilities/cmnghttp2/lib/nghttp2_alpn.h index c6f1c04..ecc9ed2 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_npn.h +++ b/Utilities/cmnghttp2/lib/nghttp2_alpn.h
@@ -22,13 +22,13 @@ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef NGHTTP2_NPN_H -#define NGHTTP2_NPN_H +#ifndef NGHTTP2_ALPN_H +#define NGHTTP2_ALPN_H #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> -#endif /* NGHTTP2_NPN_H */ +#endif /* !defined(NGHTTP2_ALPN_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_buf.c b/Utilities/cmnghttp2/lib/nghttp2_buf.c index ce51251..79de1dd 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_buf.c +++ b/Utilities/cmnghttp2/lib/nghttp2_buf.c
@@ -65,7 +65,7 @@ return 0; } - new_cap = nghttp2_max(new_cap, cap * 2); + new_cap = nghttp2_max_size(new_cap, cap * 2); ptr = nghttp2_mem_realloc(mem, buf->begin, new_cap); if (ptr == NULL) { @@ -347,7 +347,7 @@ while (len) { buf = &bufs->cur->buf; - nwrite = nghttp2_min(nghttp2_buf_avail(buf), len); + nwrite = nghttp2_min_size(nghttp2_buf_avail(buf), len); if (nwrite == 0) { rv = bufs_alloc_chain(bufs); if (rv != 0) { @@ -446,7 +446,7 @@ return 0; } -ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) { +nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) { size_t len; nghttp2_buf_chain *chain; nghttp2_buf *buf; @@ -478,7 +478,7 @@ *out = res; - return (ssize_t)len; + return (nghttp2_ssize)len; } size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out) {
diff --git a/Utilities/cmnghttp2/lib/nghttp2_buf.h b/Utilities/cmnghttp2/lib/nghttp2_buf.h index 45f62f1..636aa61 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_buf.h +++ b/Utilities/cmnghttp2/lib/nghttp2_buf.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -349,7 +349,7 @@ * NGHTTP2_ERR_NOMEM * Out of memory */ -ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out); +nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out); /* * Copies all data stored in |bufs| to |out|. This function assumes @@ -409,4 +409,4 @@ */ size_t nghttp2_bufs_len(nghttp2_bufs *bufs); -#endif /* NGHTTP2_BUF_H */ +#endif /* !defined(NGHTTP2_BUF_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_callbacks.c b/Utilities/cmnghttp2/lib/nghttp2_callbacks.c index 3c38214..162ca6b 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_callbacks.c +++ b/Utilities/cmnghttp2/lib/nghttp2_callbacks.c
@@ -41,135 +41,168 @@ } void nghttp2_session_callbacks_set_send_callback( - nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback) { + nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback) { cbs->send_callback = send_callback; } +void nghttp2_session_callbacks_set_send_callback2( + nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback) { + cbs->send_callback2 = send_callback; +} + void nghttp2_session_callbacks_set_recv_callback( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) { + nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) { cbs->recv_callback = recv_callback; } +void nghttp2_session_callbacks_set_recv_callback2( + nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback) { + cbs->recv_callback2 = recv_callback; +} + void nghttp2_session_callbacks_set_on_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_recv_callback on_frame_recv_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_recv_callback on_frame_recv_callback) { cbs->on_frame_recv_callback = on_frame_recv_callback; } void nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback) { cbs->on_invalid_frame_recv_callback = on_invalid_frame_recv_callback; } void nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback) { cbs->on_data_chunk_recv_callback = on_data_chunk_recv_callback; } void nghttp2_session_callbacks_set_before_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_before_frame_send_callback before_frame_send_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_before_frame_send_callback before_frame_send_callback) { cbs->before_frame_send_callback = before_frame_send_callback; } void nghttp2_session_callbacks_set_on_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_send_callback on_frame_send_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_send_callback on_frame_send_callback) { cbs->on_frame_send_callback = on_frame_send_callback; } void nghttp2_session_callbacks_set_on_frame_not_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_not_send_callback on_frame_not_send_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_not_send_callback on_frame_not_send_callback) { cbs->on_frame_not_send_callback = on_frame_not_send_callback; } void nghttp2_session_callbacks_set_on_stream_close_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_stream_close_callback on_stream_close_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_stream_close_callback on_stream_close_callback) { cbs->on_stream_close_callback = on_stream_close_callback; } void nghttp2_session_callbacks_set_on_begin_headers_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_headers_callback on_begin_headers_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_begin_headers_callback on_begin_headers_callback) { cbs->on_begin_headers_callback = on_begin_headers_callback; } void nghttp2_session_callbacks_set_on_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback on_header_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_header_callback on_header_callback) { cbs->on_header_callback = on_header_callback; } void nghttp2_session_callbacks_set_on_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback2 on_header_callback2) { + nghttp2_session_callbacks *cbs, + nghttp2_on_header_callback2 on_header_callback2) { cbs->on_header_callback2 = on_header_callback2; } void nghttp2_session_callbacks_set_on_invalid_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback on_invalid_header_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_header_callback on_invalid_header_callback) { cbs->on_invalid_header_callback = on_invalid_header_callback; } void nghttp2_session_callbacks_set_on_invalid_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) { + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) { cbs->on_invalid_header_callback2 = on_invalid_header_callback2; } void nghttp2_session_callbacks_set_select_padding_callback( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback select_padding_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_select_padding_callback select_padding_callback) { cbs->select_padding_callback = select_padding_callback; } +void nghttp2_session_callbacks_set_select_padding_callback2( + nghttp2_session_callbacks *cbs, + nghttp2_select_padding_callback2 select_padding_callback) { + cbs->select_padding_callback2 = select_padding_callback; +} + void nghttp2_session_callbacks_set_data_source_read_length_callback( - nghttp2_session_callbacks *cbs, - nghttp2_data_source_read_length_callback data_source_read_length_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_data_source_read_length_callback data_source_read_length_callback) { cbs->read_length_callback = data_source_read_length_callback; } +void nghttp2_session_callbacks_set_data_source_read_length_callback2( + nghttp2_session_callbacks *cbs, + nghttp2_data_source_read_length_callback2 data_source_read_length_callback) { + cbs->read_length_callback2 = data_source_read_length_callback; +} + void nghttp2_session_callbacks_set_on_begin_frame_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_frame_callback on_begin_frame_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_begin_frame_callback on_begin_frame_callback) { cbs->on_begin_frame_callback = on_begin_frame_callback; } void nghttp2_session_callbacks_set_send_data_callback( - nghttp2_session_callbacks *cbs, - nghttp2_send_data_callback send_data_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_send_data_callback send_data_callback) { cbs->send_data_callback = send_data_callback; } void nghttp2_session_callbacks_set_pack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback pack_extension_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_pack_extension_callback pack_extension_callback) { cbs->pack_extension_callback = pack_extension_callback; } +void nghttp2_session_callbacks_set_pack_extension_callback2( + nghttp2_session_callbacks *cbs, + nghttp2_pack_extension_callback2 pack_extension_callback) { + cbs->pack_extension_callback2 = pack_extension_callback; +} + void nghttp2_session_callbacks_set_unpack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_unpack_extension_callback unpack_extension_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_unpack_extension_callback unpack_extension_callback) { cbs->unpack_extension_callback = unpack_extension_callback; } void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) { cbs->on_extension_chunk_recv_callback = on_extension_chunk_recv_callback; } void nghttp2_session_callbacks_set_error_callback( - nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) { + nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) { cbs->error_callback = error_callback; } void nghttp2_session_callbacks_set_error_callback2( - nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) { + nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) { cbs->error_callback2 = error_callback2; } + +void nghttp2_session_callbacks_set_rand_callback( + nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback) { + cbs->rand_callback = rand_callback; +}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_callbacks.h b/Utilities/cmnghttp2/lib/nghttp2_callbacks.h index 61e51fa..4b45e57 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_callbacks.h +++ b/Utilities/cmnghttp2/lib/nghttp2_callbacks.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -36,20 +36,34 @@ */ struct nghttp2_session_callbacks { /** - * Callback function invoked when the session wants to send data to - * the remote peer. This callback is not necessary if the - * application uses solely `nghttp2_session_mem_send()` to serialize - * data to transmit. + * Deprecated. Use send_callback2 instead. Callback function + * invoked when the session wants to send data to the remote peer. + * This callback is not necessary if the application uses solely + * `nghttp2_session_mem_send()` to serialize data to transmit. */ nghttp2_send_callback send_callback; /** - * Callback function invoked when the session wants to receive data - * from the remote peer. This callback is not necessary if the - * application uses solely `nghttp2_session_mem_recv()` to process - * received data. + * Callback function invoked when the session wants to send data to + * the remote peer. This callback is not necessary if the + * application uses solely `nghttp2_session_mem_send2()` to + * serialize data to transmit. + */ + nghttp2_send_callback2 send_callback2; + /** + * Deprecated. Use recv_callback2 instead. Callback function + * invoked when the session wants to receive data from the remote + * peer. This callback is not necessary if the application uses + * solely `nghttp2_session_mem_recv()` to process received data. */ nghttp2_recv_callback recv_callback; /** + * Callback function invoked when the session wants to receive data + * from the remote peer. This callback is not necessary if the + * application uses solely `nghttp2_session_mem_recv2()` to process + * received data. + */ + nghttp2_recv_callback2 recv_callback2; + /** * Callback function invoked by `nghttp2_session_recv()` when a * frame is received. */ @@ -100,26 +114,44 @@ nghttp2_on_invalid_header_callback on_invalid_header_callback; nghttp2_on_invalid_header_callback2 on_invalid_header_callback2; /** - * Callback function invoked when the library asks application how - * many padding bytes are required for the transmission of the given + * Deprecated. Use select_padding_callback2 instead. Callback + * function invoked when the library asks application how many + * padding bytes are required for the transmission of the given * frame. */ nghttp2_select_padding_callback select_padding_callback; /** - * The callback function used to determine the length allowed in + * Callback function invoked when the library asks application how + * many padding bytes are required for the transmission of the given + * frame. + */ + nghttp2_select_padding_callback2 select_padding_callback2; + /** + * Deprecated. Use read_length_callback2 instead. The callback + * function used to determine the length allowed in * `nghttp2_data_source_read_callback()` */ nghttp2_data_source_read_length_callback read_length_callback; /** + * The callback function used to determine the length allowed in + * `nghttp2_data_source_read_callback2()` + */ + nghttp2_data_source_read_length_callback2 read_length_callback2; + /** * Sets callback function invoked when a frame header is received. */ nghttp2_on_begin_frame_callback on_begin_frame_callback; nghttp2_send_data_callback send_data_callback; + /** + * Deprecated. Use pack_extension_callback2 instead. + */ nghttp2_pack_extension_callback pack_extension_callback; + nghttp2_pack_extension_callback2 pack_extension_callback2; nghttp2_unpack_extension_callback unpack_extension_callback; nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback; nghttp2_error_callback error_callback; nghttp2_error_callback2 error_callback2; + nghttp2_rand_callback rand_callback; }; -#endif /* NGHTTP2_CALLBACKS_H */ +#endif /* !defined(NGHTTP2_CALLBACKS_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_debug.c b/Utilities/cmnghttp2/lib/nghttp2_debug.c index cb27797..b5f33ef 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_debug.c +++ b/Utilities/cmnghttp2/lib/nghttp2_debug.c
@@ -34,7 +34,7 @@ } static nghttp2_debug_vprintf_callback static_debug_vprintf_callback = - nghttp2_default_debug_vfprintf_callback; + nghttp2_default_debug_vfprintf_callback; void nghttp2_debug_vprintf(const char *format, ...) { if (static_debug_vprintf_callback) { @@ -46,15 +46,15 @@ } void nghttp2_set_debug_vprintf_callback( - nghttp2_debug_vprintf_callback debug_vprintf_callback) { + nghttp2_debug_vprintf_callback debug_vprintf_callback) { static_debug_vprintf_callback = debug_vprintf_callback; } -#else /* !DEBUGBUILD */ +#else /* !defined(DEBUGBUILD) */ void nghttp2_set_debug_vprintf_callback( - nghttp2_debug_vprintf_callback debug_vprintf_callback) { + nghttp2_debug_vprintf_callback debug_vprintf_callback) { (void)debug_vprintf_callback; } -#endif /* !DEBUGBUILD */ +#endif /* !defined(DEBUGBUILD) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_debug.h b/Utilities/cmnghttp2/lib/nghttp2_debug.h index cbb4dd5..26566a6 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_debug.h +++ b/Utilities/cmnghttp2/lib/nghttp2_debug.h
@@ -27,17 +27,17 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> #ifdef DEBUGBUILD # define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__) void nghttp2_debug_vprintf(const char *format, ...); -#else +#else /* !defined(DEBUGBUILD) */ # define DEBUGF(...) \ do { \ } while (0) -#endif +#endif /* !defined(DEBUGBUILD) */ -#endif /* NGHTTP2_DEBUG_H */ +#endif /* !defined(NGHTTP2_DEBUG_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_extpri.c b/Utilities/cmnghttp2/lib/nghttp2_extpri.c index 3fd9b78..ba0263e 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_extpri.c +++ b/Utilities/cmnghttp2/lib/nghttp2_extpri.c
@@ -24,6 +24,7 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "nghttp2_extpri.h" +#include "nghttp2_http.h" uint8_t nghttp2_extpri_to_uint8(const nghttp2_extpri *extpri) { return (uint8_t)((uint32_t)extpri->inc << 7 | extpri->urgency); @@ -33,3 +34,8 @@ extpri->urgency = nghttp2_extpri_uint8_urgency(u8extpri); extpri->inc = nghttp2_extpri_uint8_inc(u8extpri); } + +int nghttp2_extpri_parse_priority(nghttp2_extpri *extpri, const uint8_t *value, + size_t len) { + return nghttp2_http_parse_priority(extpri, value, len); +}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_extpri.h b/Utilities/cmnghttp2/lib/nghttp2_extpri.h index 23c6ddc..2e03916 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_extpri.h +++ b/Utilities/cmnghttp2/lib/nghttp2_extpri.h
@@ -28,7 +28,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -60,6 +60,6 @@ * nghttp2_extpri_uint8_inc extracts inc from |PRI| which is supposed to * be constructed by nghttp2_extpri_to_uint8. */ -#define nghttp2_extpri_uint8_inc(PRI) (((PRI)&NGHTTP2_EXTPRI_INC_MASK) != 0) +#define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0) -#endif /* NGHTTP2_EXTPRI_H */ +#endif /* !defined(NGHTTP2_EXTPRI_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_frame.c b/Utilities/cmnghttp2/lib/nghttp2_frame.c index 35072c1..edc2aaa 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_frame.c +++ b/Utilities/cmnghttp2/lib/nghttp2_frame.c
@@ -418,8 +418,8 @@ nghttp2_priority_spec_init(pri_spec, dep_stream_id, weight, exclusive); } -int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame, - const uint8_t *payload) { +void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame, + const uint8_t *payload) { if (frame->hd.flags & NGHTTP2_FLAG_PRIORITY) { nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload); } else { @@ -428,11 +428,9 @@ frame->nva = NULL; frame->nvlen = 0; - - return 0; } -int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) { +void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) { nghttp2_buf *buf; assert(bufs->head == bufs->cur); @@ -448,8 +446,6 @@ nghttp2_frame_pack_priority_spec(buf->last, &frame->pri_spec); buf->last += NGHTTP2_PRIORITY_SPECLEN; - - return 0; } void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame, @@ -457,8 +453,8 @@ nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload); } -int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs, - nghttp2_rst_stream *frame) { +void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs, + nghttp2_rst_stream *frame) { nghttp2_buf *buf; assert(bufs->head == bufs->cur); @@ -473,8 +469,6 @@ nghttp2_put_uint32be(buf->last, frame->error_code); buf->last += 4; - - return 0; } void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame, @@ -498,7 +492,7 @@ nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); buf->last += - nghttp2_frame_pack_settings_payload(buf->last, frame->iv, frame->niv); + nghttp2_frame_pack_settings_payload(buf->last, frame->iv, frame->niv); return 0; } @@ -543,7 +537,7 @@ } *iv_ptr = - nghttp2_mem_malloc(mem, (*niv_ptr) * sizeof(nghttp2_settings_entry)); + nghttp2_mem_malloc(mem, (*niv_ptr) * sizeof(nghttp2_settings_entry)); if (*iv_ptr == NULL) { return NGHTTP2_ERR_NOMEM; @@ -592,16 +586,15 @@ return frame_pack_headers_shared(bufs, &frame->hd); } -int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame, - const uint8_t *payload) { +void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame, + const uint8_t *payload) { frame->promised_stream_id = - nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; + nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; frame->nva = NULL; frame->nvlen = 0; - return 0; } -int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) { +void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) { nghttp2_buf *buf; assert(bufs->head == bufs->cur); @@ -615,9 +608,7 @@ nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); buf->last = - nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data)); - - return 0; + nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data)); } void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame, @@ -697,8 +688,8 @@ return 0; } -int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs, - nghttp2_window_update *frame) { +void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs, + nghttp2_window_update *frame) { nghttp2_buf *buf; assert(bufs->head == bufs->cur); @@ -713,17 +704,15 @@ nghttp2_put_uint32be(buf->last, (uint32_t)frame->window_size_increment); buf->last += 4; - - return 0; } void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame, const uint8_t *payload) { frame->window_size_increment = - nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK; + nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK; } -int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) { +void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) { int rv; nghttp2_buf *buf; nghttp2_ext_altsvc *altsvc; @@ -752,8 +741,6 @@ rv = nghttp2_bufs_add(bufs, altsvc->field_value, altsvc->field_value_len); assert(rv == 0); - - return 0; } void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame, @@ -901,8 +888,8 @@ return 0; } -int nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs, - nghttp2_extension *frame) { +void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs, + nghttp2_extension *frame) { int rv; nghttp2_buf *buf; nghttp2_ext_priority_update *priority_update; @@ -927,8 +914,6 @@ priority_update->field_value_len); assert(rv == 0); - - return 0; } void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame, @@ -941,7 +926,7 @@ priority_update = frame->payload; priority_update->stream_id = - nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; + nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; if (payloadlen > 4) { priority_update->field_value = payload + 4; @@ -1186,14 +1171,14 @@ buf->last += trail_padlen; } -int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd, - size_t padlen, int framehd_only) { +void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd, + size_t padlen, int framehd_only) { nghttp2_buf *buf; if (padlen == 0) { DEBUGF("send: padlen = 0, nothing to do\n"); - return 0; + return; } /* @@ -1226,6 +1211,4 @@ hd->flags |= NGHTTP2_FLAG_PADDED; DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen); - - return 0; }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_frame.h b/Utilities/cmnghttp2/lib/nghttp2_frame.h index 5f6152b..ed4ab2c 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_frame.h +++ b/Utilities/cmnghttp2/lib/nghttp2_frame.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> #include "nghttp2_hd.h" @@ -143,11 +143,9 @@ * Unpacks HEADERS frame byte sequence into |frame|. This function * only unapcks bytes that come before name/value header block and * after possible Pad Length field. - * - * This function always succeeds and returns 0. */ -int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame, - const uint8_t *payload); +void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame, + const uint8_t *payload); /* * Packs PRIORITY frame |frame| in wire format and store it in @@ -155,10 +153,8 @@ * * The caller must make sure that nghttp2_bufs_reset(bufs) is called * before calling this function. - * - * This function always succeeds and returns 0. */ -int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame); +void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame); /* * Unpacks PRIORITY wire format into |frame|. @@ -172,11 +168,9 @@ * * The caller must make sure that nghttp2_bufs_reset(bufs) is called * before calling this function. - * - * This function always succeeds and returns 0. */ -int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs, - nghttp2_rst_stream *frame); +void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs, + nghttp2_rst_stream *frame); /* * Unpacks RST_STREAM frame byte sequence into |frame|. @@ -265,15 +259,9 @@ * Unpacks PUSH_PROMISE frame byte sequence into |frame|. This * function only unapcks bytes that come before name/value header * block and after possible Pad Length field. - * - * This function returns 0 if it succeeds or one of the following - * negative error codes: - * - * NGHTTP2_ERR_PROTO - * TODO END_HEADERS flag is not set */ -int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame, - const uint8_t *payload); +void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame, + const uint8_t *payload); /* * Packs PING frame |frame| in wire format and store it in @@ -281,10 +269,8 @@ * * The caller must make sure that nghttp2_bufs_reset(bufs) is called * before calling this function. - * - * This function always succeeds and returns 0. */ -int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame); +void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame); /* * Unpacks PING wire format into |frame|. @@ -343,11 +329,9 @@ * * The caller must make sure that nghttp2_bufs_reset(bufs) is called * before calling this function. - * - * This function always succeeds and returns 0. */ -int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs, - nghttp2_window_update *frame); +void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs, + nghttp2_window_update *frame); /* * Unpacks WINDOW_UPDATE frame byte sequence into |frame|. @@ -361,17 +345,13 @@ * * The caller must make sure that nghttp2_bufs_reset(bufs) is called * before calling this function. - * - * This function always succeeds and returns 0. */ -int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext); +void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext); /* * Unpacks ALTSVC wire format into |frame|. The |payload| of * |payloadlen| bytes contains frame payload. This function assumes * that frame->payload points to the nghttp2_ext_altsvc object. - * - * This function always succeeds and returns 0. */ void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame, size_t origin_len, uint8_t *payload, @@ -431,19 +411,15 @@ * * The caller must make sure that nghttp2_bufs_reset(bufs) is called * before calling this function. - * - * This function always succeeds and returns 0. */ -int nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs, - nghttp2_extension *ext); +void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs, + nghttp2_extension *ext); /* * Unpacks PRIORITY_UPDATE wire format into |frame|. The |payload| of * |payloadlen| bytes contains frame payload. This function assumes * that frame->payload points to the nghttp2_ext_priority_update * object. - * - * This function always succeeds and returns 0. */ void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame, uint8_t *payload, @@ -654,16 +630,8 @@ * |padlen| including Pad Length field. The |hd| is the frame header * for the serialized data. This function fills zeros padding region * unless framehd_only is nonzero. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_FRAME_SIZE_ERROR - * The length of the resulting frame is too large. */ -int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd, - size_t padlen, int framehd_only); +void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd, + size_t padlen, int framehd_only); -#endif /* NGHTTP2_FRAME_H */ +#endif /* !defined(NGHTTP2_FRAME_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd.c b/Utilities/cmnghttp2/lib/nghttp2_hd.c index 8a2bda6..ad85eed 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_hd.c +++ b/Utilities/cmnghttp2/lib/nghttp2_hd.c
@@ -36,9 +36,10 @@ #define MAKE_STATIC_ENT(N, V, T, H) \ { \ {NULL, NULL, (uint8_t *)(N), sizeof((N)) - 1, -1}, \ - {NULL, NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \ - {(uint8_t *)(N), (uint8_t *)(V), sizeof((N)) - 1, sizeof((V)) - 1, 0}, \ - T, H \ + {NULL, NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \ + {(uint8_t *)(N), (uint8_t *)(V), sizeof((N)) - 1, sizeof((V)) - 1, 0}, \ + T, \ + H, \ } /* Generated by mkstatictbl.py */ @@ -46,67 +47,67 @@ first enum value if same header names are repeated (e.g., :status). */ static const nghttp2_hd_static_entry static_table[] = { - MAKE_STATIC_ENT(":authority", "", 0, 3153725150u), - MAKE_STATIC_ENT(":method", "GET", 1, 695666056u), - MAKE_STATIC_ENT(":method", "POST", 1, 695666056u), - MAKE_STATIC_ENT(":path", "/", 3, 3292848686u), - MAKE_STATIC_ENT(":path", "/index.html", 3, 3292848686u), - MAKE_STATIC_ENT(":scheme", "http", 5, 2510477674u), - MAKE_STATIC_ENT(":scheme", "https", 5, 2510477674u), - MAKE_STATIC_ENT(":status", "200", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "204", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "206", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "304", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "400", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "404", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "500", 7, 4000288983u), - MAKE_STATIC_ENT("accept-charset", "", 14, 3664010344u), - MAKE_STATIC_ENT("accept-encoding", "gzip, deflate", 15, 3379649177u), - MAKE_STATIC_ENT("accept-language", "", 16, 1979086614u), - MAKE_STATIC_ENT("accept-ranges", "", 17, 1713753958u), - MAKE_STATIC_ENT("accept", "", 18, 136609321u), - MAKE_STATIC_ENT("access-control-allow-origin", "", 19, 2710797292u), - MAKE_STATIC_ENT("age", "", 20, 742476188u), - MAKE_STATIC_ENT("allow", "", 21, 2930878514u), - MAKE_STATIC_ENT("authorization", "", 22, 2436257726u), - MAKE_STATIC_ENT("cache-control", "", 23, 1355326669u), - MAKE_STATIC_ENT("content-disposition", "", 24, 3889184348u), - MAKE_STATIC_ENT("content-encoding", "", 25, 65203592u), - MAKE_STATIC_ENT("content-language", "", 26, 24973587u), - MAKE_STATIC_ENT("content-length", "", 27, 1308181789u), - MAKE_STATIC_ENT("content-location", "", 28, 2302364718u), - MAKE_STATIC_ENT("content-range", "", 29, 3555523146u), - MAKE_STATIC_ENT("content-type", "", 30, 4244048277u), - MAKE_STATIC_ENT("cookie", "", 31, 2007449791u), - MAKE_STATIC_ENT("date", "", 32, 3564297305u), - MAKE_STATIC_ENT("etag", "", 33, 113792960u), - MAKE_STATIC_ENT("expect", "", 34, 2530896728u), - MAKE_STATIC_ENT("expires", "", 35, 1049544579u), - MAKE_STATIC_ENT("from", "", 36, 2513272949u), - MAKE_STATIC_ENT("host", "", 37, 2952701295u), - MAKE_STATIC_ENT("if-match", "", 38, 3597694698u), - MAKE_STATIC_ENT("if-modified-since", "", 39, 2213050793u), - MAKE_STATIC_ENT("if-none-match", "", 40, 2536202615u), - MAKE_STATIC_ENT("if-range", "", 41, 2340978238u), - MAKE_STATIC_ENT("if-unmodified-since", "", 42, 3794814858u), - MAKE_STATIC_ENT("last-modified", "", 43, 3226950251u), - MAKE_STATIC_ENT("link", "", 44, 232457833u), - MAKE_STATIC_ENT("location", "", 45, 200649126u), - MAKE_STATIC_ENT("max-forwards", "", 46, 1826162134u), - MAKE_STATIC_ENT("proxy-authenticate", "", 47, 2709445359u), - MAKE_STATIC_ENT("proxy-authorization", "", 48, 2686392507u), - MAKE_STATIC_ENT("range", "", 49, 4208725202u), - MAKE_STATIC_ENT("referer", "", 50, 3969579366u), - MAKE_STATIC_ENT("refresh", "", 51, 3572655668u), - MAKE_STATIC_ENT("retry-after", "", 52, 3336180598u), - MAKE_STATIC_ENT("server", "", 53, 1085029842u), - MAKE_STATIC_ENT("set-cookie", "", 54, 1848371000u), - MAKE_STATIC_ENT("strict-transport-security", "", 55, 4138147361u), - MAKE_STATIC_ENT("transfer-encoding", "", 56, 3719590988u), - MAKE_STATIC_ENT("user-agent", "", 57, 606444526u), - MAKE_STATIC_ENT("vary", "", 58, 1085005381u), - MAKE_STATIC_ENT("via", "", 59, 1762798611u), - MAKE_STATIC_ENT("www-authenticate", "", 60, 779865858u), + MAKE_STATIC_ENT(":authority", "", 0, 3153725150u), + MAKE_STATIC_ENT(":method", "GET", 1, 695666056u), + MAKE_STATIC_ENT(":method", "POST", 1, 695666056u), + MAKE_STATIC_ENT(":path", "/", 3, 3292848686u), + MAKE_STATIC_ENT(":path", "/index.html", 3, 3292848686u), + MAKE_STATIC_ENT(":scheme", "http", 5, 2510477674u), + MAKE_STATIC_ENT(":scheme", "https", 5, 2510477674u), + MAKE_STATIC_ENT(":status", "200", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "204", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "206", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "304", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "400", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "404", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "500", 7, 4000288983u), + MAKE_STATIC_ENT("accept-charset", "", 14, 3664010344u), + MAKE_STATIC_ENT("accept-encoding", "gzip, deflate", 15, 3379649177u), + MAKE_STATIC_ENT("accept-language", "", 16, 1979086614u), + MAKE_STATIC_ENT("accept-ranges", "", 17, 1713753958u), + MAKE_STATIC_ENT("accept", "", 18, 136609321u), + MAKE_STATIC_ENT("access-control-allow-origin", "", 19, 2710797292u), + MAKE_STATIC_ENT("age", "", 20, 742476188u), + MAKE_STATIC_ENT("allow", "", 21, 2930878514u), + MAKE_STATIC_ENT("authorization", "", 22, 2436257726u), + MAKE_STATIC_ENT("cache-control", "", 23, 1355326669u), + MAKE_STATIC_ENT("content-disposition", "", 24, 3889184348u), + MAKE_STATIC_ENT("content-encoding", "", 25, 65203592u), + MAKE_STATIC_ENT("content-language", "", 26, 24973587u), + MAKE_STATIC_ENT("content-length", "", 27, 1308181789u), + MAKE_STATIC_ENT("content-location", "", 28, 2302364718u), + MAKE_STATIC_ENT("content-range", "", 29, 3555523146u), + MAKE_STATIC_ENT("content-type", "", 30, 4244048277u), + MAKE_STATIC_ENT("cookie", "", 31, 2007449791u), + MAKE_STATIC_ENT("date", "", 32, 3564297305u), + MAKE_STATIC_ENT("etag", "", 33, 113792960u), + MAKE_STATIC_ENT("expect", "", 34, 2530896728u), + MAKE_STATIC_ENT("expires", "", 35, 1049544579u), + MAKE_STATIC_ENT("from", "", 36, 2513272949u), + MAKE_STATIC_ENT("host", "", 37, 2952701295u), + MAKE_STATIC_ENT("if-match", "", 38, 3597694698u), + MAKE_STATIC_ENT("if-modified-since", "", 39, 2213050793u), + MAKE_STATIC_ENT("if-none-match", "", 40, 2536202615u), + MAKE_STATIC_ENT("if-range", "", 41, 2340978238u), + MAKE_STATIC_ENT("if-unmodified-since", "", 42, 3794814858u), + MAKE_STATIC_ENT("last-modified", "", 43, 3226950251u), + MAKE_STATIC_ENT("link", "", 44, 232457833u), + MAKE_STATIC_ENT("location", "", 45, 200649126u), + MAKE_STATIC_ENT("max-forwards", "", 46, 1826162134u), + MAKE_STATIC_ENT("proxy-authenticate", "", 47, 2709445359u), + MAKE_STATIC_ENT("proxy-authorization", "", 48, 2686392507u), + MAKE_STATIC_ENT("range", "", 49, 4208725202u), + MAKE_STATIC_ENT("referer", "", 50, 3969579366u), + MAKE_STATIC_ENT("refresh", "", 51, 3572655668u), + MAKE_STATIC_ENT("retry-after", "", 52, 3336180598u), + MAKE_STATIC_ENT("server", "", 53, 1085029842u), + MAKE_STATIC_ENT("set-cookie", "", 54, 1848371000u), + MAKE_STATIC_ENT("strict-transport-security", "", 55, 4138147361u), + MAKE_STATIC_ENT("transfer-encoding", "", 56, 3719590988u), + MAKE_STATIC_ENT("user-agent", "", 57, 606444526u), + MAKE_STATIC_ENT("vary", "", 58, 1085005381u), + MAKE_STATIC_ENT("via", "", 59, 1762798611u), + MAKE_STATIC_ENT("www-authenticate", "", 60, 779865858u), }; static int memeq(const void *s1, const void *s2, size_t n) { @@ -593,8 +594,19 @@ static int hd_ringbuf_init(nghttp2_hd_ringbuf *ringbuf, size_t bufsize, nghttp2_mem *mem) { size_t size; + const size_t max_size = SIZE_MAX / sizeof(nghttp2_hd_entry *); + + if (bufsize > max_size) { + return NGHTTP2_ERR_NOMEM; + } + for (size = 1; size < bufsize; size <<= 1) ; + + if (size > max_size) { + return NGHTTP2_ERR_NOMEM; + } + ringbuf->buffer = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry *) * size); if (ringbuf->buffer == NULL) { return NGHTTP2_ERR_NOMEM; @@ -677,8 +689,8 @@ context->bad = 0; context->hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE; rv = hd_ringbuf_init( - &context->hd_table, - context->hd_table_bufsize_max / NGHTTP2_HD_ENTRY_OVERHEAD, mem); + &context->hd_table, + context->hd_table_bufsize_max / NGHTTP2_HD_ENTRY_OVERHEAD, mem); if (rv != 0) { return rv; } @@ -695,7 +707,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem) { return nghttp2_hd_deflate_init2( - deflater, NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE, mem); + deflater, NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE, mem); } int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater, @@ -850,9 +862,10 @@ * in the next call will be stored in |*shift_ptr|) and returns number * of bytes processed, or returns -1, indicating decoding error. */ -static ssize_t decode_length(uint32_t *res, size_t *shift_ptr, int *fin, - uint32_t initial, size_t shift, const uint8_t *in, - const uint8_t *last, size_t prefix) { +static nghttp2_ssize decode_length(uint32_t *res, size_t *shift_ptr, int *fin, + uint32_t initial, size_t shift, + const uint8_t *in, const uint8_t *last, + size_t prefix) { uint32_t k = (uint8_t)((1 << prefix) - 1); uint32_t n = initial; const uint8_t *start = in; @@ -871,7 +884,7 @@ if (++in == last) { *res = n; - return (ssize_t)(in - start); + return (nghttp2_ssize)(in - start); } } @@ -906,12 +919,12 @@ if (in == last) { *res = n; - return (ssize_t)(in - start); + return (nghttp2_ssize)(in - start); } *res = n; *fin = 1; - return (ssize_t)(in + 1 - start); + return (nghttp2_ssize)(in + 1 - start); } static int emit_table_size(nghttp2_bufs *bufs, size_t table_size) { @@ -1076,8 +1089,8 @@ int rv; DEBUGF( - "deflatehd: emit newname namelen=%zu, valuelen=%zu, indexing_mode=%d\n", - nv->namelen, nv->valuelen, indexing_mode); + "deflatehd: emit newname namelen=%zu, valuelen=%zu, indexing_mode=%d\n", + nv->namelen, nv->valuelen, indexing_mode); rv = nghttp2_bufs_addb(bufs, pack_first_byte(indexing_mode)); if (rv != 0) { @@ -1110,12 +1123,11 @@ while (context->hd_table_bufsize + room > context->hd_table_bufsize_max && context->hd_table.len > 0) { - size_t idx = context->hd_table.len - 1; nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx); context->hd_table_bufsize -= - entry_room(ent->nv.name->len, ent->nv.value->len); + entry_room(ent->nv.name->len, ent->nv.value->len); DEBUGF("hpack: remove item from header table: %s: %s\n", (char *)ent->nv.name->base, (char *)ent->nv.value->base); @@ -1164,7 +1176,7 @@ } typedef struct { - ssize_t index; + nghttp2_ssize index; /* Nonzero if both name and value are matched. */ int name_value_match; } search_result; @@ -1213,8 +1225,8 @@ return res; } - res.index = - (ssize_t)(context->next_seq - 1 - ent->seq + NGHTTP2_STATIC_TABLE_LENGTH); + res.index = (nghttp2_ssize)(context->next_seq - 1 - ent->seq + + NGHTTP2_STATIC_TABLE_LENGTH); res.name_value_match = exact_match; return res; @@ -1231,7 +1243,7 @@ size_t idx = context->hd_table.len - 1; nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx); context->hd_table_bufsize -= - entry_room(ent->nv.name->len, ent->nv.value->len); + entry_room(ent->nv.name->len, ent->nv.value->len); hd_ringbuf_pop_back(&context->hd_table); if (map) { hd_map_remove(map, ent); @@ -1243,14 +1255,14 @@ } int nghttp2_hd_deflate_change_table_size( - nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size) { - size_t next_bufsize = nghttp2_min(settings_max_dynamic_table_size, - deflater->deflate_hd_table_bufsize_max); + nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size) { + size_t next_bufsize = nghttp2_min_size( + settings_max_dynamic_table_size, deflater->deflate_hd_table_bufsize_max); deflater->ctx.hd_table_bufsize_max = next_bufsize; deflater->min_hd_table_bufsize_max = - nghttp2_min(deflater->min_hd_table_bufsize_max, next_bufsize); + nghttp2_min_size(deflater->min_hd_table_bufsize_max, next_bufsize); deflater->notify_table_size_change = 1; @@ -1259,7 +1271,7 @@ } int nghttp2_hd_inflate_change_table_size( - nghttp2_hd_inflater *inflater, size_t settings_max_dynamic_table_size) { + nghttp2_hd_inflater *inflater, size_t settings_max_dynamic_table_size) { switch (inflater->state) { case NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE: case NGHTTP2_HD_STATE_INFLATE_START: @@ -1302,7 +1314,7 @@ assert(INDEX_RANGE_VALID(context, idx)); if (idx >= NGHTTP2_STATIC_TABLE_LENGTH) { return hd_ringbuf_get(&context->hd_table, idx - NGHTTP2_STATIC_TABLE_LENGTH) - ->nv; + ->nv; } else { const nghttp2_hd_static_entry *ent = &static_table[idx]; nghttp2_hd_nv nv = {(nghttp2_rcbuf *)&ent->name, @@ -1318,7 +1330,7 @@ if (idx >= NGHTTP2_STATIC_TABLE_LENGTH) { return &hd_ringbuf_get(&context->hd_table, idx - NGHTTP2_STATIC_TABLE_LENGTH) - ->cnv; + ->cnv; } return &static_table[idx].cnv; @@ -1332,7 +1344,7 @@ token == NGHTTP2_TOKEN_IF_NONE_MATCH || token == NGHTTP2_TOKEN_LOCATION || token == NGHTTP2_TOKEN_SET_COOKIE || entry_room(nv->namelen, nv->valuelen) > - deflater->ctx.hd_table_bufsize_max * 3 / 4) { + deflater->ctx.hd_table_bufsize_max * 3 / 4) { return NGHTTP2_HD_WITHOUT_INDEXING; } @@ -1343,7 +1355,7 @@ const nghttp2_nv *nv) { int rv; search_result res; - ssize_t idx; + nghttp2_ssize idx; int indexing_mode; int32_t token; nghttp2_mem *mem; @@ -1365,12 +1377,11 @@ entropy secret data (e.g., id/password). Also cookie header field with less than 20 bytes value is also never indexed. This is the same criteria used in Firefox codebase. */ - indexing_mode = - token == NGHTTP2_TOKEN_AUTHORIZATION || - (token == NGHTTP2_TOKEN_COOKIE && nv->valuelen < 20) || - (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) - ? NGHTTP2_HD_NEVER_INDEXING - : hd_deflate_decide_indexing(deflater, nv, token); + indexing_mode = token == NGHTTP2_TOKEN_AUTHORIZATION || + (token == NGHTTP2_TOKEN_COOKIE && nv->valuelen < 20) || + (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) + ? NGHTTP2_HD_NEVER_INDEXING + : hd_deflate_decide_indexing(deflater, nv, token); res = search_hd_table(&deflater->ctx, nv, token, indexing_mode, &deflater->map, hash); @@ -1378,8 +1389,7 @@ idx = res.index; if (res.name_value_match) { - - DEBUGF("deflatehd: name/value match index=%zd\n", idx); + DEBUGF("deflatehd: name/value match index=%td\n", idx); rv = emit_indexed_block(bufs, (size_t)idx); if (rv != 0) { @@ -1390,7 +1400,7 @@ } if (res.index != -1) { - DEBUGF("deflatehd: name match index=%zd\n", res.index); + DEBUGF("deflatehd: name match index=%td\n", res.index); } if (indexing_mode == NGHTTP2_HD_WITH_INDEXING) { @@ -1456,7 +1466,6 @@ deflater->min_hd_table_bufsize_max = UINT32_MAX; if (deflater->ctx.hd_table_bufsize_max > min_hd_table_bufsize_max) { - rv = emit_table_size(bufs, min_hd_table_bufsize_max); if (rv != 0) { @@ -1491,6 +1500,12 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf, size_t buflen, const nghttp2_nv *nv, size_t nvlen) { + return (ssize_t)nghttp2_hd_deflate_hd2(deflater, buf, buflen, nv, nvlen); +} + +nghttp2_ssize nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater, + uint8_t *buf, size_t buflen, + const nghttp2_nv *nv, size_t nvlen) { nghttp2_bufs bufs; int rv; nghttp2_mem *mem; @@ -1517,12 +1532,18 @@ return rv; } - return (ssize_t)buflen; + return (nghttp2_ssize)buflen; } ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater, const nghttp2_vec *vec, size_t veclen, const nghttp2_nv *nv, size_t nvlen) { + return (ssize_t)nghttp2_hd_deflate_hd_vec2(deflater, vec, veclen, nv, nvlen); +} + +nghttp2_ssize nghttp2_hd_deflate_hd_vec2(nghttp2_hd_deflater *deflater, + const nghttp2_vec *vec, size_t veclen, + const nghttp2_nv *nv, size_t nvlen) { nghttp2_bufs bufs; int rv; nghttp2_mem *mem; @@ -1550,7 +1571,7 @@ return rv; } - return (ssize_t)buflen; + return (nghttp2_ssize)buflen; } size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater, @@ -1643,10 +1664,11 @@ * NGHTTP2_ERR_HEADER_COMP * Integer decoding failed */ -static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater, int *rfin, - const uint8_t *in, const uint8_t *last, - size_t prefix, size_t maxlen) { - ssize_t rv; +static nghttp2_ssize hd_inflate_read_len(nghttp2_hd_inflater *inflater, + int *rfin, const uint8_t *in, + const uint8_t *last, size_t prefix, + size_t maxlen) { + nghttp2_ssize rv; uint32_t out; *rfin = 0; @@ -1684,10 +1706,10 @@ * NGHTTP2_ERR_HEADER_COMP * Huffman decoding failed */ -static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater, - nghttp2_buf *buf, const uint8_t *in, - const uint8_t *last) { - ssize_t readlen; +static nghttp2_ssize hd_inflate_read_huff(nghttp2_hd_inflater *inflater, + nghttp2_buf *buf, const uint8_t *in, + const uint8_t *last) { + nghttp2_ssize readlen; int fin = 0; if ((size_t)(last - in) >= inflater->left) { last = in + inflater->left; @@ -1721,14 +1743,15 @@ * NGHTTP2_ERR_HEADER_COMP * Header decompression failed */ -static ssize_t hd_inflate_read(nghttp2_hd_inflater *inflater, nghttp2_buf *buf, - const uint8_t *in, const uint8_t *last) { - size_t len = nghttp2_min((size_t)(last - in), inflater->left); +static nghttp2_ssize hd_inflate_read(nghttp2_hd_inflater *inflater, + nghttp2_buf *buf, const uint8_t *in, + const uint8_t *last) { + size_t len = nghttp2_min_size((size_t)(last - in), inflater->left); buf->last = nghttp2_cpymem(buf->last, in, len); inflater->left -= len; - return (ssize_t)len; + return (nghttp2_ssize)len; } /* @@ -1843,7 +1866,15 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out, int *inflate_flags, const uint8_t *in, size_t inlen, int in_final) { - ssize_t rv; + return (nghttp2_ssize)nghttp2_hd_inflate_hd3(inflater, nv_out, inflate_flags, + in, inlen, in_final); +} + +nghttp2_ssize nghttp2_hd_inflate_hd3(nghttp2_hd_inflater *inflater, + nghttp2_nv *nv_out, int *inflate_flags, + const uint8_t *in, size_t inlen, + int in_final) { + nghttp2_ssize rv; nghttp2_hd_nv hd_nv; rv = nghttp2_hd_inflate_hd_nv(inflater, &hd_nv, inflate_flags, in, inlen, @@ -1866,11 +1897,11 @@ return rv; } -ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater, - nghttp2_hd_nv *nv_out, int *inflate_flags, - const uint8_t *in, size_t inlen, - int in_final) { - ssize_t rv = 0; +nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater, + nghttp2_hd_nv *nv_out, + int *inflate_flags, const uint8_t *in, + size_t inlen, int in_final) { + nghttp2_ssize rv = 0; const uint8_t *first = in; const uint8_t *last = in + inlen; int rfin = 0; @@ -1938,9 +1969,9 @@ case NGHTTP2_HD_STATE_READ_TABLE_SIZE: rfin = 0; rv = hd_inflate_read_len( - inflater, &rfin, in, last, 5, - nghttp2_min(inflater->min_hd_table_bufsize_max, - inflater->settings_hd_table_bufsize_max)); + inflater, &rfin, in, last, 5, + nghttp2_min_size(inflater->min_hd_table_bufsize_max, + inflater->settings_hd_table_bufsize_max)); if (rv < 0) { goto fail; } @@ -1992,7 +2023,7 @@ inflater->state = NGHTTP2_HD_STATE_OPCODE; *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT; - return (ssize_t)(in - first); + return (nghttp2_ssize)(in - first); } else { inflater->index = inflater->left; --inflater->index; @@ -2027,8 +2058,8 @@ inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF; - rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1, - mem); + rv = + nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1, mem); } else { inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAME; rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left + 1, mem); @@ -2050,7 +2081,7 @@ in += rv; - DEBUGF("inflatehd: %zd bytes read\n", rv); + DEBUGF("inflatehd: %td bytes read\n", rv); if (inflater->left) { DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left); @@ -2072,7 +2103,7 @@ in += rv; - DEBUGF("inflatehd: %zd bytes read\n", rv); + DEBUGF("inflatehd: %td bytes read\n", rv); if (inflater->left) { DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left); @@ -2112,8 +2143,8 @@ inflater->state = NGHTTP2_HD_STATE_READ_VALUEHUFF; - rv = nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1, - mem); + rv = + nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1, mem); } else { inflater->state = NGHTTP2_HD_STATE_READ_VALUE; @@ -2138,7 +2169,7 @@ in += rv; - DEBUGF("inflatehd: %zd bytes read\n", rv); + DEBUGF("inflatehd: %td bytes read\n", rv); if (inflater->left) { DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left); @@ -2162,18 +2193,18 @@ inflater->state = NGHTTP2_HD_STATE_OPCODE; *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT; - return (ssize_t)(in - first); + return (nghttp2_ssize)(in - first); case NGHTTP2_HD_STATE_READ_VALUE: rv = hd_inflate_read(inflater, &inflater->valuebuf, in, last); if (rv < 0) { - DEBUGF("inflatehd: value read failure %zd: %s\n", rv, + DEBUGF("inflatehd: value read failure %td: %s\n", rv, nghttp2_strerror((int)rv)); goto fail; } in += rv; - DEBUGF("inflatehd: %zd bytes read\n", rv); + DEBUGF("inflatehd: %td bytes read\n", rv); if (inflater->left) { DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left); @@ -2196,7 +2227,7 @@ inflater->state = NGHTTP2_HD_STATE_OPCODE; *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT; - return (ssize_t)(in - first); + return (nghttp2_ssize)(in - first); } } @@ -2216,7 +2247,7 @@ } *inflate_flags |= NGHTTP2_HD_INFLATE_FINAL; } - return (ssize_t)(in - first); + return (nghttp2_ssize)(in - first); almost_ok: if (in_final) { @@ -2226,10 +2257,10 @@ goto fail; } - return (ssize_t)(in - first); + return (nghttp2_ssize)(in - first); fail: - DEBUGF("inflatehd: error return %zd\n", rv); + DEBUGF("inflatehd: error return %td\n", rv); inflater->ctx.bad = 1; return rv; @@ -2284,7 +2315,6 @@ int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t idx, nghttp2_nv *nv, int indexing_mode) { - return emit_indname_block(bufs, idx, nv, indexing_mode); } @@ -2297,9 +2327,10 @@ return emit_table_size(bufs, table_size); } -ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin, - uint32_t initial, size_t shift, uint8_t *in, - uint8_t *last, size_t prefix) { +nghttp2_ssize nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, + int *fin, uint32_t initial, size_t shift, + uint8_t *in, uint8_t *last, + size_t prefix) { return decode_length(res, shift_ptr, fin, initial, shift, in, last, prefix); }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd.h b/Utilities/cmnghttp2/lib/nghttp2_hd.h index 6de0052..bdc7fad 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_hd.h +++ b/Utilities/cmnghttp2/lib/nghttp2_hd.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -357,9 +357,10 @@ * that return values and semantics are the same as * nghttp2_hd_inflate_hd(). */ -ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater, - nghttp2_hd_nv *nv_out, int *inflate_flags, - const uint8_t *in, size_t inlen, int in_final); +nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater, + nghttp2_hd_nv *nv_out, + int *inflate_flags, const uint8_t *in, + size_t inlen, int in_final); /* For unittesting purpose */ int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index, @@ -376,9 +377,10 @@ nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index); /* For unittesting purpose */ -ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin, - uint32_t initial, size_t shift, uint8_t *in, - uint8_t *last, size_t prefix); +nghttp2_ssize nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, + int *fin, uint32_t initial, size_t shift, + uint8_t *in, uint8_t *last, + size_t prefix); /* Huffman encoding/decoding functions */ @@ -427,9 +429,9 @@ * NGHTTP2_ERR_HEADER_COMP * Decoding process has failed. */ -ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, - nghttp2_buf *buf, const uint8_t *src, - size_t srclen, int fin); +nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, + nghttp2_buf *buf, const uint8_t *src, + size_t srclen, int fin); /* * nghttp2_hd_huff_decode_failure_state returns nonzero if |ctx| @@ -437,4 +439,4 @@ */ int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx); -#endif /* NGHTTP2_HD_H */ +#endif /* !defined(NGHTTP2_HD_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c index ac90f49..de26200 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c +++ b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c
@@ -94,7 +94,7 @@ if (nbits) { rv = nghttp2_bufs_addb( - bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1))); + bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1))); if (rv != 0) { return rv; } @@ -107,16 +107,18 @@ ctx->fstate = NGHTTP2_HUFF_ACCEPTED; } -ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, - nghttp2_buf *buf, const uint8_t *src, - size_t srclen, int final) { +nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, + nghttp2_buf *buf, const uint8_t *src, + size_t srclen, int final) { const uint8_t *end = src + srclen; nghttp2_huff_decode node = {ctx->fstate, 0}; const nghttp2_huff_decode *t = &node; uint8_t c; /* We use the decoding algorithm described in - http://graphics.ics.uci.edu/pub/Prefix.pdf */ + - http://graphics.ics.uci.edu/pub/Prefix.pdf [!!! NO LONGER VALID !!!] + - https://ics.uci.edu/~dan/pubs/Prefix.pdf + - https://github.com/nghttp2/nghttp2/files/15141264/Prefix.pdf */ for (; src != end;) { c = *src++; t = &huff_decode_table[t->fstate & 0x1ff][c >> 4]; @@ -136,7 +138,7 @@ return NGHTTP2_ERR_HEADER_COMP; } - return (ssize_t)srclen; + return (nghttp2_ssize)srclen; } int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) {
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h index 2bfd531..df037a8 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h +++ b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -69,4 +69,4 @@ extern const nghttp2_huff_sym huff_sym_table[]; extern const nghttp2_huff_decode huff_decode_table[][16]; -#endif /* NGHTTP2_HD_HUFFMAN_H */ +#endif /* !defined(NGHTTP2_HD_HUFFMAN_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c index 2e2e13f..c8f4a6f 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c +++ b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c
@@ -27,4954 +27,4954 @@ /* Generated by mkhufftbl.py */ const nghttp2_huff_sym huff_sym_table[] = { - {13, 0xffc00000u}, {23, 0xffffb000u}, {28, 0xfffffe20u}, {28, 0xfffffe30u}, - {28, 0xfffffe40u}, {28, 0xfffffe50u}, {28, 0xfffffe60u}, {28, 0xfffffe70u}, - {28, 0xfffffe80u}, {24, 0xffffea00u}, {30, 0xfffffff0u}, {28, 0xfffffe90u}, - {28, 0xfffffea0u}, {30, 0xfffffff4u}, {28, 0xfffffeb0u}, {28, 0xfffffec0u}, - {28, 0xfffffed0u}, {28, 0xfffffee0u}, {28, 0xfffffef0u}, {28, 0xffffff00u}, - {28, 0xffffff10u}, {28, 0xffffff20u}, {30, 0xfffffff8u}, {28, 0xffffff30u}, - {28, 0xffffff40u}, {28, 0xffffff50u}, {28, 0xffffff60u}, {28, 0xffffff70u}, - {28, 0xffffff80u}, {28, 0xffffff90u}, {28, 0xffffffa0u}, {28, 0xffffffb0u}, - {6, 0x50000000u}, {10, 0xfe000000u}, {10, 0xfe400000u}, {12, 0xffa00000u}, - {13, 0xffc80000u}, {6, 0x54000000u}, {8, 0xf8000000u}, {11, 0xff400000u}, - {10, 0xfe800000u}, {10, 0xfec00000u}, {8, 0xf9000000u}, {11, 0xff600000u}, - {8, 0xfa000000u}, {6, 0x58000000u}, {6, 0x5c000000u}, {6, 0x60000000u}, - {5, 0x0u}, {5, 0x8000000u}, {5, 0x10000000u}, {6, 0x64000000u}, - {6, 0x68000000u}, {6, 0x6c000000u}, {6, 0x70000000u}, {6, 0x74000000u}, - {6, 0x78000000u}, {6, 0x7c000000u}, {7, 0xb8000000u}, {8, 0xfb000000u}, - {15, 0xfff80000u}, {6, 0x80000000u}, {12, 0xffb00000u}, {10, 0xff000000u}, - {13, 0xffd00000u}, {6, 0x84000000u}, {7, 0xba000000u}, {7, 0xbc000000u}, - {7, 0xbe000000u}, {7, 0xc0000000u}, {7, 0xc2000000u}, {7, 0xc4000000u}, - {7, 0xc6000000u}, {7, 0xc8000000u}, {7, 0xca000000u}, {7, 0xcc000000u}, - {7, 0xce000000u}, {7, 0xd0000000u}, {7, 0xd2000000u}, {7, 0xd4000000u}, - {7, 0xd6000000u}, {7, 0xd8000000u}, {7, 0xda000000u}, {7, 0xdc000000u}, - {7, 0xde000000u}, {7, 0xe0000000u}, {7, 0xe2000000u}, {7, 0xe4000000u}, - {8, 0xfc000000u}, {7, 0xe6000000u}, {8, 0xfd000000u}, {13, 0xffd80000u}, - {19, 0xfffe0000u}, {13, 0xffe00000u}, {14, 0xfff00000u}, {6, 0x88000000u}, - {15, 0xfffa0000u}, {5, 0x18000000u}, {6, 0x8c000000u}, {5, 0x20000000u}, - {6, 0x90000000u}, {5, 0x28000000u}, {6, 0x94000000u}, {6, 0x98000000u}, - {6, 0x9c000000u}, {5, 0x30000000u}, {7, 0xe8000000u}, {7, 0xea000000u}, - {6, 0xa0000000u}, {6, 0xa4000000u}, {6, 0xa8000000u}, {5, 0x38000000u}, - {6, 0xac000000u}, {7, 0xec000000u}, {6, 0xb0000000u}, {5, 0x40000000u}, - {5, 0x48000000u}, {6, 0xb4000000u}, {7, 0xee000000u}, {7, 0xf0000000u}, - {7, 0xf2000000u}, {7, 0xf4000000u}, {7, 0xf6000000u}, {15, 0xfffc0000u}, - {11, 0xff800000u}, {14, 0xfff40000u}, {13, 0xffe80000u}, {28, 0xffffffc0u}, - {20, 0xfffe6000u}, {22, 0xffff4800u}, {20, 0xfffe7000u}, {20, 0xfffe8000u}, - {22, 0xffff4c00u}, {22, 0xffff5000u}, {22, 0xffff5400u}, {23, 0xffffb200u}, - {22, 0xffff5800u}, {23, 0xffffb400u}, {23, 0xffffb600u}, {23, 0xffffb800u}, - {23, 0xffffba00u}, {23, 0xffffbc00u}, {24, 0xffffeb00u}, {23, 0xffffbe00u}, - {24, 0xffffec00u}, {24, 0xffffed00u}, {22, 0xffff5c00u}, {23, 0xffffc000u}, - {24, 0xffffee00u}, {23, 0xffffc200u}, {23, 0xffffc400u}, {23, 0xffffc600u}, - {23, 0xffffc800u}, {21, 0xfffee000u}, {22, 0xffff6000u}, {23, 0xffffca00u}, - {22, 0xffff6400u}, {23, 0xffffcc00u}, {23, 0xffffce00u}, {24, 0xffffef00u}, - {22, 0xffff6800u}, {21, 0xfffee800u}, {20, 0xfffe9000u}, {22, 0xffff6c00u}, - {22, 0xffff7000u}, {23, 0xffffd000u}, {23, 0xffffd200u}, {21, 0xfffef000u}, - {23, 0xffffd400u}, {22, 0xffff7400u}, {22, 0xffff7800u}, {24, 0xfffff000u}, - {21, 0xfffef800u}, {22, 0xffff7c00u}, {23, 0xffffd600u}, {23, 0xffffd800u}, - {21, 0xffff0000u}, {21, 0xffff0800u}, {22, 0xffff8000u}, {21, 0xffff1000u}, - {23, 0xffffda00u}, {22, 0xffff8400u}, {23, 0xffffdc00u}, {23, 0xffffde00u}, - {20, 0xfffea000u}, {22, 0xffff8800u}, {22, 0xffff8c00u}, {22, 0xffff9000u}, - {23, 0xffffe000u}, {22, 0xffff9400u}, {22, 0xffff9800u}, {23, 0xffffe200u}, - {26, 0xfffff800u}, {26, 0xfffff840u}, {20, 0xfffeb000u}, {19, 0xfffe2000u}, - {22, 0xffff9c00u}, {23, 0xffffe400u}, {22, 0xffffa000u}, {25, 0xfffff600u}, - {26, 0xfffff880u}, {26, 0xfffff8c0u}, {26, 0xfffff900u}, {27, 0xfffffbc0u}, - {27, 0xfffffbe0u}, {26, 0xfffff940u}, {24, 0xfffff100u}, {25, 0xfffff680u}, - {19, 0xfffe4000u}, {21, 0xffff1800u}, {26, 0xfffff980u}, {27, 0xfffffc00u}, - {27, 0xfffffc20u}, {26, 0xfffff9c0u}, {27, 0xfffffc40u}, {24, 0xfffff200u}, - {21, 0xffff2000u}, {21, 0xffff2800u}, {26, 0xfffffa00u}, {26, 0xfffffa40u}, - {28, 0xffffffd0u}, {27, 0xfffffc60u}, {27, 0xfffffc80u}, {27, 0xfffffca0u}, - {20, 0xfffec000u}, {24, 0xfffff300u}, {20, 0xfffed000u}, {21, 0xffff3000u}, - {22, 0xffffa400u}, {21, 0xffff3800u}, {21, 0xffff4000u}, {23, 0xffffe600u}, - {22, 0xffffa800u}, {22, 0xffffac00u}, {25, 0xfffff700u}, {25, 0xfffff780u}, - {24, 0xfffff400u}, {24, 0xfffff500u}, {26, 0xfffffa80u}, {23, 0xffffe800u}, - {26, 0xfffffac0u}, {27, 0xfffffcc0u}, {26, 0xfffffb00u}, {26, 0xfffffb40u}, - {27, 0xfffffce0u}, {27, 0xfffffd00u}, {27, 0xfffffd20u}, {27, 0xfffffd40u}, - {27, 0xfffffd60u}, {28, 0xffffffe0u}, {27, 0xfffffd80u}, {27, 0xfffffda0u}, - {27, 0xfffffdc0u}, {27, 0xfffffde0u}, {27, 0xfffffe00u}, {26, 0xfffffb80u}, - {30, 0xfffffffcu}}; + {13, 0xffc00000u}, {23, 0xffffb000u}, {28, 0xfffffe20u}, {28, 0xfffffe30u}, + {28, 0xfffffe40u}, {28, 0xfffffe50u}, {28, 0xfffffe60u}, {28, 0xfffffe70u}, + {28, 0xfffffe80u}, {24, 0xffffea00u}, {30, 0xfffffff0u}, {28, 0xfffffe90u}, + {28, 0xfffffea0u}, {30, 0xfffffff4u}, {28, 0xfffffeb0u}, {28, 0xfffffec0u}, + {28, 0xfffffed0u}, {28, 0xfffffee0u}, {28, 0xfffffef0u}, {28, 0xffffff00u}, + {28, 0xffffff10u}, {28, 0xffffff20u}, {30, 0xfffffff8u}, {28, 0xffffff30u}, + {28, 0xffffff40u}, {28, 0xffffff50u}, {28, 0xffffff60u}, {28, 0xffffff70u}, + {28, 0xffffff80u}, {28, 0xffffff90u}, {28, 0xffffffa0u}, {28, 0xffffffb0u}, + {6, 0x50000000u}, {10, 0xfe000000u}, {10, 0xfe400000u}, {12, 0xffa00000u}, + {13, 0xffc80000u}, {6, 0x54000000u}, {8, 0xf8000000u}, {11, 0xff400000u}, + {10, 0xfe800000u}, {10, 0xfec00000u}, {8, 0xf9000000u}, {11, 0xff600000u}, + {8, 0xfa000000u}, {6, 0x58000000u}, {6, 0x5c000000u}, {6, 0x60000000u}, + {5, 0x0u}, {5, 0x8000000u}, {5, 0x10000000u}, {6, 0x64000000u}, + {6, 0x68000000u}, {6, 0x6c000000u}, {6, 0x70000000u}, {6, 0x74000000u}, + {6, 0x78000000u}, {6, 0x7c000000u}, {7, 0xb8000000u}, {8, 0xfb000000u}, + {15, 0xfff80000u}, {6, 0x80000000u}, {12, 0xffb00000u}, {10, 0xff000000u}, + {13, 0xffd00000u}, {6, 0x84000000u}, {7, 0xba000000u}, {7, 0xbc000000u}, + {7, 0xbe000000u}, {7, 0xc0000000u}, {7, 0xc2000000u}, {7, 0xc4000000u}, + {7, 0xc6000000u}, {7, 0xc8000000u}, {7, 0xca000000u}, {7, 0xcc000000u}, + {7, 0xce000000u}, {7, 0xd0000000u}, {7, 0xd2000000u}, {7, 0xd4000000u}, + {7, 0xd6000000u}, {7, 0xd8000000u}, {7, 0xda000000u}, {7, 0xdc000000u}, + {7, 0xde000000u}, {7, 0xe0000000u}, {7, 0xe2000000u}, {7, 0xe4000000u}, + {8, 0xfc000000u}, {7, 0xe6000000u}, {8, 0xfd000000u}, {13, 0xffd80000u}, + {19, 0xfffe0000u}, {13, 0xffe00000u}, {14, 0xfff00000u}, {6, 0x88000000u}, + {15, 0xfffa0000u}, {5, 0x18000000u}, {6, 0x8c000000u}, {5, 0x20000000u}, + {6, 0x90000000u}, {5, 0x28000000u}, {6, 0x94000000u}, {6, 0x98000000u}, + {6, 0x9c000000u}, {5, 0x30000000u}, {7, 0xe8000000u}, {7, 0xea000000u}, + {6, 0xa0000000u}, {6, 0xa4000000u}, {6, 0xa8000000u}, {5, 0x38000000u}, + {6, 0xac000000u}, {7, 0xec000000u}, {6, 0xb0000000u}, {5, 0x40000000u}, + {5, 0x48000000u}, {6, 0xb4000000u}, {7, 0xee000000u}, {7, 0xf0000000u}, + {7, 0xf2000000u}, {7, 0xf4000000u}, {7, 0xf6000000u}, {15, 0xfffc0000u}, + {11, 0xff800000u}, {14, 0xfff40000u}, {13, 0xffe80000u}, {28, 0xffffffc0u}, + {20, 0xfffe6000u}, {22, 0xffff4800u}, {20, 0xfffe7000u}, {20, 0xfffe8000u}, + {22, 0xffff4c00u}, {22, 0xffff5000u}, {22, 0xffff5400u}, {23, 0xffffb200u}, + {22, 0xffff5800u}, {23, 0xffffb400u}, {23, 0xffffb600u}, {23, 0xffffb800u}, + {23, 0xffffba00u}, {23, 0xffffbc00u}, {24, 0xffffeb00u}, {23, 0xffffbe00u}, + {24, 0xffffec00u}, {24, 0xffffed00u}, {22, 0xffff5c00u}, {23, 0xffffc000u}, + {24, 0xffffee00u}, {23, 0xffffc200u}, {23, 0xffffc400u}, {23, 0xffffc600u}, + {23, 0xffffc800u}, {21, 0xfffee000u}, {22, 0xffff6000u}, {23, 0xffffca00u}, + {22, 0xffff6400u}, {23, 0xffffcc00u}, {23, 0xffffce00u}, {24, 0xffffef00u}, + {22, 0xffff6800u}, {21, 0xfffee800u}, {20, 0xfffe9000u}, {22, 0xffff6c00u}, + {22, 0xffff7000u}, {23, 0xffffd000u}, {23, 0xffffd200u}, {21, 0xfffef000u}, + {23, 0xffffd400u}, {22, 0xffff7400u}, {22, 0xffff7800u}, {24, 0xfffff000u}, + {21, 0xfffef800u}, {22, 0xffff7c00u}, {23, 0xffffd600u}, {23, 0xffffd800u}, + {21, 0xffff0000u}, {21, 0xffff0800u}, {22, 0xffff8000u}, {21, 0xffff1000u}, + {23, 0xffffda00u}, {22, 0xffff8400u}, {23, 0xffffdc00u}, {23, 0xffffde00u}, + {20, 0xfffea000u}, {22, 0xffff8800u}, {22, 0xffff8c00u}, {22, 0xffff9000u}, + {23, 0xffffe000u}, {22, 0xffff9400u}, {22, 0xffff9800u}, {23, 0xffffe200u}, + {26, 0xfffff800u}, {26, 0xfffff840u}, {20, 0xfffeb000u}, {19, 0xfffe2000u}, + {22, 0xffff9c00u}, {23, 0xffffe400u}, {22, 0xffffa000u}, {25, 0xfffff600u}, + {26, 0xfffff880u}, {26, 0xfffff8c0u}, {26, 0xfffff900u}, {27, 0xfffffbc0u}, + {27, 0xfffffbe0u}, {26, 0xfffff940u}, {24, 0xfffff100u}, {25, 0xfffff680u}, + {19, 0xfffe4000u}, {21, 0xffff1800u}, {26, 0xfffff980u}, {27, 0xfffffc00u}, + {27, 0xfffffc20u}, {26, 0xfffff9c0u}, {27, 0xfffffc40u}, {24, 0xfffff200u}, + {21, 0xffff2000u}, {21, 0xffff2800u}, {26, 0xfffffa00u}, {26, 0xfffffa40u}, + {28, 0xffffffd0u}, {27, 0xfffffc60u}, {27, 0xfffffc80u}, {27, 0xfffffca0u}, + {20, 0xfffec000u}, {24, 0xfffff300u}, {20, 0xfffed000u}, {21, 0xffff3000u}, + {22, 0xffffa400u}, {21, 0xffff3800u}, {21, 0xffff4000u}, {23, 0xffffe600u}, + {22, 0xffffa800u}, {22, 0xffffac00u}, {25, 0xfffff700u}, {25, 0xfffff780u}, + {24, 0xfffff400u}, {24, 0xfffff500u}, {26, 0xfffffa80u}, {23, 0xffffe800u}, + {26, 0xfffffac0u}, {27, 0xfffffcc0u}, {26, 0xfffffb00u}, {26, 0xfffffb40u}, + {27, 0xfffffce0u}, {27, 0xfffffd00u}, {27, 0xfffffd20u}, {27, 0xfffffd40u}, + {27, 0xfffffd60u}, {28, 0xffffffe0u}, {27, 0xfffffd80u}, {27, 0xfffffda0u}, + {27, 0xfffffdc0u}, {27, 0xfffffde0u}, {27, 0xfffffe00u}, {26, 0xfffffb80u}, + {30, 0xfffffffcu}}; const nghttp2_huff_decode huff_decode_table[][16] = { - /* 0 */ - { - {0x04, 0}, - {0x05, 0}, - {0x07, 0}, - {0x08, 0}, - {0x0b, 0}, - {0x0c, 0}, - {0x10, 0}, - {0x13, 0}, - {0x19, 0}, - {0x1c, 0}, - {0x20, 0}, - {0x23, 0}, - {0x2a, 0}, - {0x31, 0}, - {0x39, 0}, - {0x4040, 0}, - }, - /* 1 */ - { - {0xc000, 48}, - {0xc000, 49}, - {0xc000, 50}, - {0xc000, 97}, - {0xc000, 99}, - {0xc000, 101}, - {0xc000, 105}, - {0xc000, 111}, - {0xc000, 115}, - {0xc000, 116}, - {0x0d, 0}, - {0x0e, 0}, - {0x11, 0}, - {0x12, 0}, - {0x14, 0}, - {0x15, 0}, - }, - /* 2 */ - { - {0x8001, 48}, - {0xc016, 48}, - {0x8001, 49}, - {0xc016, 49}, - {0x8001, 50}, - {0xc016, 50}, - {0x8001, 97}, - {0xc016, 97}, - {0x8001, 99}, - {0xc016, 99}, - {0x8001, 101}, - {0xc016, 101}, - {0x8001, 105}, - {0xc016, 105}, - {0x8001, 111}, - {0xc016, 111}, - }, - /* 3 */ - { - {0x8002, 48}, - {0x8009, 48}, - {0x8017, 48}, - {0xc028, 48}, - {0x8002, 49}, - {0x8009, 49}, - {0x8017, 49}, - {0xc028, 49}, - {0x8002, 50}, - {0x8009, 50}, - {0x8017, 50}, - {0xc028, 50}, - {0x8002, 97}, - {0x8009, 97}, - {0x8017, 97}, - {0xc028, 97}, - }, - /* 4 */ - { - {0x8003, 48}, - {0x8006, 48}, - {0x800a, 48}, - {0x800f, 48}, - {0x8018, 48}, - {0x801f, 48}, - {0x8029, 48}, - {0xc038, 48}, - {0x8003, 49}, - {0x8006, 49}, - {0x800a, 49}, - {0x800f, 49}, - {0x8018, 49}, - {0x801f, 49}, - {0x8029, 49}, - {0xc038, 49}, - }, - /* 5 */ - { - {0x8003, 50}, - {0x8006, 50}, - {0x800a, 50}, - {0x800f, 50}, - {0x8018, 50}, - {0x801f, 50}, - {0x8029, 50}, - {0xc038, 50}, - {0x8003, 97}, - {0x8006, 97}, - {0x800a, 97}, - {0x800f, 97}, - {0x8018, 97}, - {0x801f, 97}, - {0x8029, 97}, - {0xc038, 97}, - }, - /* 6 */ - { - {0x8002, 99}, - {0x8009, 99}, - {0x8017, 99}, - {0xc028, 99}, - {0x8002, 101}, - {0x8009, 101}, - {0x8017, 101}, - {0xc028, 101}, - {0x8002, 105}, - {0x8009, 105}, - {0x8017, 105}, - {0xc028, 105}, - {0x8002, 111}, - {0x8009, 111}, - {0x8017, 111}, - {0xc028, 111}, - }, - /* 7 */ - { - {0x8003, 99}, - {0x8006, 99}, - {0x800a, 99}, - {0x800f, 99}, - {0x8018, 99}, - {0x801f, 99}, - {0x8029, 99}, - {0xc038, 99}, - {0x8003, 101}, - {0x8006, 101}, - {0x800a, 101}, - {0x800f, 101}, - {0x8018, 101}, - {0x801f, 101}, - {0x8029, 101}, - {0xc038, 101}, - }, - /* 8 */ - { - {0x8003, 105}, - {0x8006, 105}, - {0x800a, 105}, - {0x800f, 105}, - {0x8018, 105}, - {0x801f, 105}, - {0x8029, 105}, - {0xc038, 105}, - {0x8003, 111}, - {0x8006, 111}, - {0x800a, 111}, - {0x800f, 111}, - {0x8018, 111}, - {0x801f, 111}, - {0x8029, 111}, - {0xc038, 111}, - }, - /* 9 */ - { - {0x8001, 115}, - {0xc016, 115}, - {0x8001, 116}, - {0xc016, 116}, - {0xc000, 32}, - {0xc000, 37}, - {0xc000, 45}, - {0xc000, 46}, - {0xc000, 47}, - {0xc000, 51}, - {0xc000, 52}, - {0xc000, 53}, - {0xc000, 54}, - {0xc000, 55}, - {0xc000, 56}, - {0xc000, 57}, - }, - /* 10 */ - { - {0x8002, 115}, - {0x8009, 115}, - {0x8017, 115}, - {0xc028, 115}, - {0x8002, 116}, - {0x8009, 116}, - {0x8017, 116}, - {0xc028, 116}, - {0x8001, 32}, - {0xc016, 32}, - {0x8001, 37}, - {0xc016, 37}, - {0x8001, 45}, - {0xc016, 45}, - {0x8001, 46}, - {0xc016, 46}, - }, - /* 11 */ - { - {0x8003, 115}, - {0x8006, 115}, - {0x800a, 115}, - {0x800f, 115}, - {0x8018, 115}, - {0x801f, 115}, - {0x8029, 115}, - {0xc038, 115}, - {0x8003, 116}, - {0x8006, 116}, - {0x800a, 116}, - {0x800f, 116}, - {0x8018, 116}, - {0x801f, 116}, - {0x8029, 116}, - {0xc038, 116}, - }, - /* 12 */ - { - {0x8002, 32}, - {0x8009, 32}, - {0x8017, 32}, - {0xc028, 32}, - {0x8002, 37}, - {0x8009, 37}, - {0x8017, 37}, - {0xc028, 37}, - {0x8002, 45}, - {0x8009, 45}, - {0x8017, 45}, - {0xc028, 45}, - {0x8002, 46}, - {0x8009, 46}, - {0x8017, 46}, - {0xc028, 46}, - }, - /* 13 */ - { - {0x8003, 32}, - {0x8006, 32}, - {0x800a, 32}, - {0x800f, 32}, - {0x8018, 32}, - {0x801f, 32}, - {0x8029, 32}, - {0xc038, 32}, - {0x8003, 37}, - {0x8006, 37}, - {0x800a, 37}, - {0x800f, 37}, - {0x8018, 37}, - {0x801f, 37}, - {0x8029, 37}, - {0xc038, 37}, - }, - /* 14 */ - { - {0x8003, 45}, - {0x8006, 45}, - {0x800a, 45}, - {0x800f, 45}, - {0x8018, 45}, - {0x801f, 45}, - {0x8029, 45}, - {0xc038, 45}, - {0x8003, 46}, - {0x8006, 46}, - {0x800a, 46}, - {0x800f, 46}, - {0x8018, 46}, - {0x801f, 46}, - {0x8029, 46}, - {0xc038, 46}, - }, - /* 15 */ - { - {0x8001, 47}, - {0xc016, 47}, - {0x8001, 51}, - {0xc016, 51}, - {0x8001, 52}, - {0xc016, 52}, - {0x8001, 53}, - {0xc016, 53}, - {0x8001, 54}, - {0xc016, 54}, - {0x8001, 55}, - {0xc016, 55}, - {0x8001, 56}, - {0xc016, 56}, - {0x8001, 57}, - {0xc016, 57}, - }, - /* 16 */ - { - {0x8002, 47}, - {0x8009, 47}, - {0x8017, 47}, - {0xc028, 47}, - {0x8002, 51}, - {0x8009, 51}, - {0x8017, 51}, - {0xc028, 51}, - {0x8002, 52}, - {0x8009, 52}, - {0x8017, 52}, - {0xc028, 52}, - {0x8002, 53}, - {0x8009, 53}, - {0x8017, 53}, - {0xc028, 53}, - }, - /* 17 */ - { - {0x8003, 47}, - {0x8006, 47}, - {0x800a, 47}, - {0x800f, 47}, - {0x8018, 47}, - {0x801f, 47}, - {0x8029, 47}, - {0xc038, 47}, - {0x8003, 51}, - {0x8006, 51}, - {0x800a, 51}, - {0x800f, 51}, - {0x8018, 51}, - {0x801f, 51}, - {0x8029, 51}, - {0xc038, 51}, - }, - /* 18 */ - { - {0x8003, 52}, - {0x8006, 52}, - {0x800a, 52}, - {0x800f, 52}, - {0x8018, 52}, - {0x801f, 52}, - {0x8029, 52}, - {0xc038, 52}, - {0x8003, 53}, - {0x8006, 53}, - {0x800a, 53}, - {0x800f, 53}, - {0x8018, 53}, - {0x801f, 53}, - {0x8029, 53}, - {0xc038, 53}, - }, - /* 19 */ - { - {0x8002, 54}, - {0x8009, 54}, - {0x8017, 54}, - {0xc028, 54}, - {0x8002, 55}, - {0x8009, 55}, - {0x8017, 55}, - {0xc028, 55}, - {0x8002, 56}, - {0x8009, 56}, - {0x8017, 56}, - {0xc028, 56}, - {0x8002, 57}, - {0x8009, 57}, - {0x8017, 57}, - {0xc028, 57}, - }, - /* 20 */ - { - {0x8003, 54}, - {0x8006, 54}, - {0x800a, 54}, - {0x800f, 54}, - {0x8018, 54}, - {0x801f, 54}, - {0x8029, 54}, - {0xc038, 54}, - {0x8003, 55}, - {0x8006, 55}, - {0x800a, 55}, - {0x800f, 55}, - {0x8018, 55}, - {0x801f, 55}, - {0x8029, 55}, - {0xc038, 55}, - }, - /* 21 */ - { - {0x8003, 56}, - {0x8006, 56}, - {0x800a, 56}, - {0x800f, 56}, - {0x8018, 56}, - {0x801f, 56}, - {0x8029, 56}, - {0xc038, 56}, - {0x8003, 57}, - {0x8006, 57}, - {0x800a, 57}, - {0x800f, 57}, - {0x8018, 57}, - {0x801f, 57}, - {0x8029, 57}, - {0xc038, 57}, - }, - /* 22 */ - { - {0x1a, 0}, - {0x1b, 0}, - {0x1d, 0}, - {0x1e, 0}, - {0x21, 0}, - {0x22, 0}, - {0x24, 0}, - {0x25, 0}, - {0x2b, 0}, - {0x2e, 0}, - {0x32, 0}, - {0x35, 0}, - {0x3a, 0}, - {0x3d, 0}, - {0x41, 0}, - {0x4044, 0}, - }, - /* 23 */ - { - {0xc000, 61}, - {0xc000, 65}, - {0xc000, 95}, - {0xc000, 98}, - {0xc000, 100}, - {0xc000, 102}, - {0xc000, 103}, - {0xc000, 104}, - {0xc000, 108}, - {0xc000, 109}, - {0xc000, 110}, - {0xc000, 112}, - {0xc000, 114}, - {0xc000, 117}, - {0x26, 0}, - {0x27, 0}, - }, - /* 24 */ - { - {0x8001, 61}, - {0xc016, 61}, - {0x8001, 65}, - {0xc016, 65}, - {0x8001, 95}, - {0xc016, 95}, - {0x8001, 98}, - {0xc016, 98}, - {0x8001, 100}, - {0xc016, 100}, - {0x8001, 102}, - {0xc016, 102}, - {0x8001, 103}, - {0xc016, 103}, - {0x8001, 104}, - {0xc016, 104}, - }, - /* 25 */ - { - {0x8002, 61}, - {0x8009, 61}, - {0x8017, 61}, - {0xc028, 61}, - {0x8002, 65}, - {0x8009, 65}, - {0x8017, 65}, - {0xc028, 65}, - {0x8002, 95}, - {0x8009, 95}, - {0x8017, 95}, - {0xc028, 95}, - {0x8002, 98}, - {0x8009, 98}, - {0x8017, 98}, - {0xc028, 98}, - }, - /* 26 */ - { - {0x8003, 61}, - {0x8006, 61}, - {0x800a, 61}, - {0x800f, 61}, - {0x8018, 61}, - {0x801f, 61}, - {0x8029, 61}, - {0xc038, 61}, - {0x8003, 65}, - {0x8006, 65}, - {0x800a, 65}, - {0x800f, 65}, - {0x8018, 65}, - {0x801f, 65}, - {0x8029, 65}, - {0xc038, 65}, - }, - /* 27 */ - { - {0x8003, 95}, - {0x8006, 95}, - {0x800a, 95}, - {0x800f, 95}, - {0x8018, 95}, - {0x801f, 95}, - {0x8029, 95}, - {0xc038, 95}, - {0x8003, 98}, - {0x8006, 98}, - {0x800a, 98}, - {0x800f, 98}, - {0x8018, 98}, - {0x801f, 98}, - {0x8029, 98}, - {0xc038, 98}, - }, - /* 28 */ - { - {0x8002, 100}, - {0x8009, 100}, - {0x8017, 100}, - {0xc028, 100}, - {0x8002, 102}, - {0x8009, 102}, - {0x8017, 102}, - {0xc028, 102}, - {0x8002, 103}, - {0x8009, 103}, - {0x8017, 103}, - {0xc028, 103}, - {0x8002, 104}, - {0x8009, 104}, - {0x8017, 104}, - {0xc028, 104}, - }, - /* 29 */ - { - {0x8003, 100}, - {0x8006, 100}, - {0x800a, 100}, - {0x800f, 100}, - {0x8018, 100}, - {0x801f, 100}, - {0x8029, 100}, - {0xc038, 100}, - {0x8003, 102}, - {0x8006, 102}, - {0x800a, 102}, - {0x800f, 102}, - {0x8018, 102}, - {0x801f, 102}, - {0x8029, 102}, - {0xc038, 102}, - }, - /* 30 */ - { - {0x8003, 103}, - {0x8006, 103}, - {0x800a, 103}, - {0x800f, 103}, - {0x8018, 103}, - {0x801f, 103}, - {0x8029, 103}, - {0xc038, 103}, - {0x8003, 104}, - {0x8006, 104}, - {0x800a, 104}, - {0x800f, 104}, - {0x8018, 104}, - {0x801f, 104}, - {0x8029, 104}, - {0xc038, 104}, - }, - /* 31 */ - { - {0x8001, 108}, - {0xc016, 108}, - {0x8001, 109}, - {0xc016, 109}, - {0x8001, 110}, - {0xc016, 110}, - {0x8001, 112}, - {0xc016, 112}, - {0x8001, 114}, - {0xc016, 114}, - {0x8001, 117}, - {0xc016, 117}, - {0xc000, 58}, - {0xc000, 66}, - {0xc000, 67}, - {0xc000, 68}, - }, - /* 32 */ - { - {0x8002, 108}, - {0x8009, 108}, - {0x8017, 108}, - {0xc028, 108}, - {0x8002, 109}, - {0x8009, 109}, - {0x8017, 109}, - {0xc028, 109}, - {0x8002, 110}, - {0x8009, 110}, - {0x8017, 110}, - {0xc028, 110}, - {0x8002, 112}, - {0x8009, 112}, - {0x8017, 112}, - {0xc028, 112}, - }, - /* 33 */ - { - {0x8003, 108}, - {0x8006, 108}, - {0x800a, 108}, - {0x800f, 108}, - {0x8018, 108}, - {0x801f, 108}, - {0x8029, 108}, - {0xc038, 108}, - {0x8003, 109}, - {0x8006, 109}, - {0x800a, 109}, - {0x800f, 109}, - {0x8018, 109}, - {0x801f, 109}, - {0x8029, 109}, - {0xc038, 109}, - }, - /* 34 */ - { - {0x8003, 110}, - {0x8006, 110}, - {0x800a, 110}, - {0x800f, 110}, - {0x8018, 110}, - {0x801f, 110}, - {0x8029, 110}, - {0xc038, 110}, - {0x8003, 112}, - {0x8006, 112}, - {0x800a, 112}, - {0x800f, 112}, - {0x8018, 112}, - {0x801f, 112}, - {0x8029, 112}, - {0xc038, 112}, - }, - /* 35 */ - { - {0x8002, 114}, - {0x8009, 114}, - {0x8017, 114}, - {0xc028, 114}, - {0x8002, 117}, - {0x8009, 117}, - {0x8017, 117}, - {0xc028, 117}, - {0x8001, 58}, - {0xc016, 58}, - {0x8001, 66}, - {0xc016, 66}, - {0x8001, 67}, - {0xc016, 67}, - {0x8001, 68}, - {0xc016, 68}, - }, - /* 36 */ - { - {0x8003, 114}, - {0x8006, 114}, - {0x800a, 114}, - {0x800f, 114}, - {0x8018, 114}, - {0x801f, 114}, - {0x8029, 114}, - {0xc038, 114}, - {0x8003, 117}, - {0x8006, 117}, - {0x800a, 117}, - {0x800f, 117}, - {0x8018, 117}, - {0x801f, 117}, - {0x8029, 117}, - {0xc038, 117}, - }, - /* 37 */ - { - {0x8002, 58}, - {0x8009, 58}, - {0x8017, 58}, - {0xc028, 58}, - {0x8002, 66}, - {0x8009, 66}, - {0x8017, 66}, - {0xc028, 66}, - {0x8002, 67}, - {0x8009, 67}, - {0x8017, 67}, - {0xc028, 67}, - {0x8002, 68}, - {0x8009, 68}, - {0x8017, 68}, - {0xc028, 68}, - }, - /* 38 */ - { - {0x8003, 58}, - {0x8006, 58}, - {0x800a, 58}, - {0x800f, 58}, - {0x8018, 58}, - {0x801f, 58}, - {0x8029, 58}, - {0xc038, 58}, - {0x8003, 66}, - {0x8006, 66}, - {0x800a, 66}, - {0x800f, 66}, - {0x8018, 66}, - {0x801f, 66}, - {0x8029, 66}, - {0xc038, 66}, - }, - /* 39 */ - { - {0x8003, 67}, - {0x8006, 67}, - {0x800a, 67}, - {0x800f, 67}, - {0x8018, 67}, - {0x801f, 67}, - {0x8029, 67}, - {0xc038, 67}, - {0x8003, 68}, - {0x8006, 68}, - {0x800a, 68}, - {0x800f, 68}, - {0x8018, 68}, - {0x801f, 68}, - {0x8029, 68}, - {0xc038, 68}, - }, - /* 40 */ - { - {0x2c, 0}, - {0x2d, 0}, - {0x2f, 0}, - {0x30, 0}, - {0x33, 0}, - {0x34, 0}, - {0x36, 0}, - {0x37, 0}, - {0x3b, 0}, - {0x3c, 0}, - {0x3e, 0}, - {0x3f, 0}, - {0x42, 0}, - {0x43, 0}, - {0x45, 0}, - {0x4048, 0}, - }, - /* 41 */ - { - {0xc000, 69}, - {0xc000, 70}, - {0xc000, 71}, - {0xc000, 72}, - {0xc000, 73}, - {0xc000, 74}, - {0xc000, 75}, - {0xc000, 76}, - {0xc000, 77}, - {0xc000, 78}, - {0xc000, 79}, - {0xc000, 80}, - {0xc000, 81}, - {0xc000, 82}, - {0xc000, 83}, - {0xc000, 84}, - }, - /* 42 */ - { - {0x8001, 69}, - {0xc016, 69}, - {0x8001, 70}, - {0xc016, 70}, - {0x8001, 71}, - {0xc016, 71}, - {0x8001, 72}, - {0xc016, 72}, - {0x8001, 73}, - {0xc016, 73}, - {0x8001, 74}, - {0xc016, 74}, - {0x8001, 75}, - {0xc016, 75}, - {0x8001, 76}, - {0xc016, 76}, - }, - /* 43 */ - { - {0x8002, 69}, - {0x8009, 69}, - {0x8017, 69}, - {0xc028, 69}, - {0x8002, 70}, - {0x8009, 70}, - {0x8017, 70}, - {0xc028, 70}, - {0x8002, 71}, - {0x8009, 71}, - {0x8017, 71}, - {0xc028, 71}, - {0x8002, 72}, - {0x8009, 72}, - {0x8017, 72}, - {0xc028, 72}, - }, - /* 44 */ - { - {0x8003, 69}, - {0x8006, 69}, - {0x800a, 69}, - {0x800f, 69}, - {0x8018, 69}, - {0x801f, 69}, - {0x8029, 69}, - {0xc038, 69}, - {0x8003, 70}, - {0x8006, 70}, - {0x800a, 70}, - {0x800f, 70}, - {0x8018, 70}, - {0x801f, 70}, - {0x8029, 70}, - {0xc038, 70}, - }, - /* 45 */ - { - {0x8003, 71}, - {0x8006, 71}, - {0x800a, 71}, - {0x800f, 71}, - {0x8018, 71}, - {0x801f, 71}, - {0x8029, 71}, - {0xc038, 71}, - {0x8003, 72}, - {0x8006, 72}, - {0x800a, 72}, - {0x800f, 72}, - {0x8018, 72}, - {0x801f, 72}, - {0x8029, 72}, - {0xc038, 72}, - }, - /* 46 */ - { - {0x8002, 73}, - {0x8009, 73}, - {0x8017, 73}, - {0xc028, 73}, - {0x8002, 74}, - {0x8009, 74}, - {0x8017, 74}, - {0xc028, 74}, - {0x8002, 75}, - {0x8009, 75}, - {0x8017, 75}, - {0xc028, 75}, - {0x8002, 76}, - {0x8009, 76}, - {0x8017, 76}, - {0xc028, 76}, - }, - /* 47 */ - { - {0x8003, 73}, - {0x8006, 73}, - {0x800a, 73}, - {0x800f, 73}, - {0x8018, 73}, - {0x801f, 73}, - {0x8029, 73}, - {0xc038, 73}, - {0x8003, 74}, - {0x8006, 74}, - {0x800a, 74}, - {0x800f, 74}, - {0x8018, 74}, - {0x801f, 74}, - {0x8029, 74}, - {0xc038, 74}, - }, - /* 48 */ - { - {0x8003, 75}, - {0x8006, 75}, - {0x800a, 75}, - {0x800f, 75}, - {0x8018, 75}, - {0x801f, 75}, - {0x8029, 75}, - {0xc038, 75}, - {0x8003, 76}, - {0x8006, 76}, - {0x800a, 76}, - {0x800f, 76}, - {0x8018, 76}, - {0x801f, 76}, - {0x8029, 76}, - {0xc038, 76}, - }, - /* 49 */ - { - {0x8001, 77}, - {0xc016, 77}, - {0x8001, 78}, - {0xc016, 78}, - {0x8001, 79}, - {0xc016, 79}, - {0x8001, 80}, - {0xc016, 80}, - {0x8001, 81}, - {0xc016, 81}, - {0x8001, 82}, - {0xc016, 82}, - {0x8001, 83}, - {0xc016, 83}, - {0x8001, 84}, - {0xc016, 84}, - }, - /* 50 */ - { - {0x8002, 77}, - {0x8009, 77}, - {0x8017, 77}, - {0xc028, 77}, - {0x8002, 78}, - {0x8009, 78}, - {0x8017, 78}, - {0xc028, 78}, - {0x8002, 79}, - {0x8009, 79}, - {0x8017, 79}, - {0xc028, 79}, - {0x8002, 80}, - {0x8009, 80}, - {0x8017, 80}, - {0xc028, 80}, - }, - /* 51 */ - { - {0x8003, 77}, - {0x8006, 77}, - {0x800a, 77}, - {0x800f, 77}, - {0x8018, 77}, - {0x801f, 77}, - {0x8029, 77}, - {0xc038, 77}, - {0x8003, 78}, - {0x8006, 78}, - {0x800a, 78}, - {0x800f, 78}, - {0x8018, 78}, - {0x801f, 78}, - {0x8029, 78}, - {0xc038, 78}, - }, - /* 52 */ - { - {0x8003, 79}, - {0x8006, 79}, - {0x800a, 79}, - {0x800f, 79}, - {0x8018, 79}, - {0x801f, 79}, - {0x8029, 79}, - {0xc038, 79}, - {0x8003, 80}, - {0x8006, 80}, - {0x800a, 80}, - {0x800f, 80}, - {0x8018, 80}, - {0x801f, 80}, - {0x8029, 80}, - {0xc038, 80}, - }, - /* 53 */ - { - {0x8002, 81}, - {0x8009, 81}, - {0x8017, 81}, - {0xc028, 81}, - {0x8002, 82}, - {0x8009, 82}, - {0x8017, 82}, - {0xc028, 82}, - {0x8002, 83}, - {0x8009, 83}, - {0x8017, 83}, - {0xc028, 83}, - {0x8002, 84}, - {0x8009, 84}, - {0x8017, 84}, - {0xc028, 84}, - }, - /* 54 */ - { - {0x8003, 81}, - {0x8006, 81}, - {0x800a, 81}, - {0x800f, 81}, - {0x8018, 81}, - {0x801f, 81}, - {0x8029, 81}, - {0xc038, 81}, - {0x8003, 82}, - {0x8006, 82}, - {0x800a, 82}, - {0x800f, 82}, - {0x8018, 82}, - {0x801f, 82}, - {0x8029, 82}, - {0xc038, 82}, - }, - /* 55 */ - { - {0x8003, 83}, - {0x8006, 83}, - {0x800a, 83}, - {0x800f, 83}, - {0x8018, 83}, - {0x801f, 83}, - {0x8029, 83}, - {0xc038, 83}, - {0x8003, 84}, - {0x8006, 84}, - {0x800a, 84}, - {0x800f, 84}, - {0x8018, 84}, - {0x801f, 84}, - {0x8029, 84}, - {0xc038, 84}, - }, - /* 56 */ - { - {0xc000, 85}, - {0xc000, 86}, - {0xc000, 87}, - {0xc000, 89}, - {0xc000, 106}, - {0xc000, 107}, - {0xc000, 113}, - {0xc000, 118}, - {0xc000, 119}, - {0xc000, 120}, - {0xc000, 121}, - {0xc000, 122}, - {0x46, 0}, - {0x47, 0}, - {0x49, 0}, - {0x404a, 0}, - }, - /* 57 */ - { - {0x8001, 85}, - {0xc016, 85}, - {0x8001, 86}, - {0xc016, 86}, - {0x8001, 87}, - {0xc016, 87}, - {0x8001, 89}, - {0xc016, 89}, - {0x8001, 106}, - {0xc016, 106}, - {0x8001, 107}, - {0xc016, 107}, - {0x8001, 113}, - {0xc016, 113}, - {0x8001, 118}, - {0xc016, 118}, - }, - /* 58 */ - { - {0x8002, 85}, - {0x8009, 85}, - {0x8017, 85}, - {0xc028, 85}, - {0x8002, 86}, - {0x8009, 86}, - {0x8017, 86}, - {0xc028, 86}, - {0x8002, 87}, - {0x8009, 87}, - {0x8017, 87}, - {0xc028, 87}, - {0x8002, 89}, - {0x8009, 89}, - {0x8017, 89}, - {0xc028, 89}, - }, - /* 59 */ - { - {0x8003, 85}, - {0x8006, 85}, - {0x800a, 85}, - {0x800f, 85}, - {0x8018, 85}, - {0x801f, 85}, - {0x8029, 85}, - {0xc038, 85}, - {0x8003, 86}, - {0x8006, 86}, - {0x800a, 86}, - {0x800f, 86}, - {0x8018, 86}, - {0x801f, 86}, - {0x8029, 86}, - {0xc038, 86}, - }, - /* 60 */ - { - {0x8003, 87}, - {0x8006, 87}, - {0x800a, 87}, - {0x800f, 87}, - {0x8018, 87}, - {0x801f, 87}, - {0x8029, 87}, - {0xc038, 87}, - {0x8003, 89}, - {0x8006, 89}, - {0x800a, 89}, - {0x800f, 89}, - {0x8018, 89}, - {0x801f, 89}, - {0x8029, 89}, - {0xc038, 89}, - }, - /* 61 */ - { - {0x8002, 106}, - {0x8009, 106}, - {0x8017, 106}, - {0xc028, 106}, - {0x8002, 107}, - {0x8009, 107}, - {0x8017, 107}, - {0xc028, 107}, - {0x8002, 113}, - {0x8009, 113}, - {0x8017, 113}, - {0xc028, 113}, - {0x8002, 118}, - {0x8009, 118}, - {0x8017, 118}, - {0xc028, 118}, - }, - /* 62 */ - { - {0x8003, 106}, - {0x8006, 106}, - {0x800a, 106}, - {0x800f, 106}, - {0x8018, 106}, - {0x801f, 106}, - {0x8029, 106}, - {0xc038, 106}, - {0x8003, 107}, - {0x8006, 107}, - {0x800a, 107}, - {0x800f, 107}, - {0x8018, 107}, - {0x801f, 107}, - {0x8029, 107}, - {0xc038, 107}, - }, - /* 63 */ - { - {0x8003, 113}, - {0x8006, 113}, - {0x800a, 113}, - {0x800f, 113}, - {0x8018, 113}, - {0x801f, 113}, - {0x8029, 113}, - {0xc038, 113}, - {0x8003, 118}, - {0x8006, 118}, - {0x800a, 118}, - {0x800f, 118}, - {0x8018, 118}, - {0x801f, 118}, - {0x8029, 118}, - {0xc038, 118}, - }, - /* 64 */ - { - {0x8001, 119}, - {0xc016, 119}, - {0x8001, 120}, - {0xc016, 120}, - {0x8001, 121}, - {0xc016, 121}, - {0x8001, 122}, - {0xc016, 122}, - {0xc000, 38}, - {0xc000, 42}, - {0xc000, 44}, - {0xc000, 59}, - {0xc000, 88}, - {0xc000, 90}, - {0x4b, 0}, - {0x4e, 0}, - }, - /* 65 */ - { - {0x8002, 119}, - {0x8009, 119}, - {0x8017, 119}, - {0xc028, 119}, - {0x8002, 120}, - {0x8009, 120}, - {0x8017, 120}, - {0xc028, 120}, - {0x8002, 121}, - {0x8009, 121}, - {0x8017, 121}, - {0xc028, 121}, - {0x8002, 122}, - {0x8009, 122}, - {0x8017, 122}, - {0xc028, 122}, - }, - /* 66 */ - { - {0x8003, 119}, - {0x8006, 119}, - {0x800a, 119}, - {0x800f, 119}, - {0x8018, 119}, - {0x801f, 119}, - {0x8029, 119}, - {0xc038, 119}, - {0x8003, 120}, - {0x8006, 120}, - {0x800a, 120}, - {0x800f, 120}, - {0x8018, 120}, - {0x801f, 120}, - {0x8029, 120}, - {0xc038, 120}, - }, - /* 67 */ - { - {0x8003, 121}, - {0x8006, 121}, - {0x800a, 121}, - {0x800f, 121}, - {0x8018, 121}, - {0x801f, 121}, - {0x8029, 121}, - {0xc038, 121}, - {0x8003, 122}, - {0x8006, 122}, - {0x800a, 122}, - {0x800f, 122}, - {0x8018, 122}, - {0x801f, 122}, - {0x8029, 122}, - {0xc038, 122}, - }, - /* 68 */ - { - {0x8001, 38}, - {0xc016, 38}, - {0x8001, 42}, - {0xc016, 42}, - {0x8001, 44}, - {0xc016, 44}, - {0x8001, 59}, - {0xc016, 59}, - {0x8001, 88}, - {0xc016, 88}, - {0x8001, 90}, - {0xc016, 90}, - {0x4c, 0}, - {0x4d, 0}, - {0x4f, 0}, - {0x51, 0}, - }, - /* 69 */ - { - {0x8002, 38}, - {0x8009, 38}, - {0x8017, 38}, - {0xc028, 38}, - {0x8002, 42}, - {0x8009, 42}, - {0x8017, 42}, - {0xc028, 42}, - {0x8002, 44}, - {0x8009, 44}, - {0x8017, 44}, - {0xc028, 44}, - {0x8002, 59}, - {0x8009, 59}, - {0x8017, 59}, - {0xc028, 59}, - }, - /* 70 */ - { - {0x8003, 38}, - {0x8006, 38}, - {0x800a, 38}, - {0x800f, 38}, - {0x8018, 38}, - {0x801f, 38}, - {0x8029, 38}, - {0xc038, 38}, - {0x8003, 42}, - {0x8006, 42}, - {0x800a, 42}, - {0x800f, 42}, - {0x8018, 42}, - {0x801f, 42}, - {0x8029, 42}, - {0xc038, 42}, - }, - /* 71 */ - { - {0x8003, 44}, - {0x8006, 44}, - {0x800a, 44}, - {0x800f, 44}, - {0x8018, 44}, - {0x801f, 44}, - {0x8029, 44}, - {0xc038, 44}, - {0x8003, 59}, - {0x8006, 59}, - {0x800a, 59}, - {0x800f, 59}, - {0x8018, 59}, - {0x801f, 59}, - {0x8029, 59}, - {0xc038, 59}, - }, - /* 72 */ - { - {0x8002, 88}, - {0x8009, 88}, - {0x8017, 88}, - {0xc028, 88}, - {0x8002, 90}, - {0x8009, 90}, - {0x8017, 90}, - {0xc028, 90}, - {0xc000, 33}, - {0xc000, 34}, - {0xc000, 40}, - {0xc000, 41}, - {0xc000, 63}, - {0x50, 0}, - {0x52, 0}, - {0x54, 0}, - }, - /* 73 */ - { - {0x8003, 88}, - {0x8006, 88}, - {0x800a, 88}, - {0x800f, 88}, - {0x8018, 88}, - {0x801f, 88}, - {0x8029, 88}, - {0xc038, 88}, - {0x8003, 90}, - {0x8006, 90}, - {0x800a, 90}, - {0x800f, 90}, - {0x8018, 90}, - {0x801f, 90}, - {0x8029, 90}, - {0xc038, 90}, - }, - /* 74 */ - { - {0x8001, 33}, - {0xc016, 33}, - {0x8001, 34}, - {0xc016, 34}, - {0x8001, 40}, - {0xc016, 40}, - {0x8001, 41}, - {0xc016, 41}, - {0x8001, 63}, - {0xc016, 63}, - {0xc000, 39}, - {0xc000, 43}, - {0xc000, 124}, - {0x53, 0}, - {0x55, 0}, - {0x58, 0}, - }, - /* 75 */ - { - {0x8002, 33}, - {0x8009, 33}, - {0x8017, 33}, - {0xc028, 33}, - {0x8002, 34}, - {0x8009, 34}, - {0x8017, 34}, - {0xc028, 34}, - {0x8002, 40}, - {0x8009, 40}, - {0x8017, 40}, - {0xc028, 40}, - {0x8002, 41}, - {0x8009, 41}, - {0x8017, 41}, - {0xc028, 41}, - }, - /* 76 */ - { - {0x8003, 33}, - {0x8006, 33}, - {0x800a, 33}, - {0x800f, 33}, - {0x8018, 33}, - {0x801f, 33}, - {0x8029, 33}, - {0xc038, 33}, - {0x8003, 34}, - {0x8006, 34}, - {0x800a, 34}, - {0x800f, 34}, - {0x8018, 34}, - {0x801f, 34}, - {0x8029, 34}, - {0xc038, 34}, - }, - /* 77 */ - { - {0x8003, 40}, - {0x8006, 40}, - {0x800a, 40}, - {0x800f, 40}, - {0x8018, 40}, - {0x801f, 40}, - {0x8029, 40}, - {0xc038, 40}, - {0x8003, 41}, - {0x8006, 41}, - {0x800a, 41}, - {0x800f, 41}, - {0x8018, 41}, - {0x801f, 41}, - {0x8029, 41}, - {0xc038, 41}, - }, - /* 78 */ - { - {0x8002, 63}, - {0x8009, 63}, - {0x8017, 63}, - {0xc028, 63}, - {0x8001, 39}, - {0xc016, 39}, - {0x8001, 43}, - {0xc016, 43}, - {0x8001, 124}, - {0xc016, 124}, - {0xc000, 35}, - {0xc000, 62}, - {0x56, 0}, - {0x57, 0}, - {0x59, 0}, - {0x5a, 0}, - }, - /* 79 */ - { - {0x8003, 63}, - {0x8006, 63}, - {0x800a, 63}, - {0x800f, 63}, - {0x8018, 63}, - {0x801f, 63}, - {0x8029, 63}, - {0xc038, 63}, - {0x8002, 39}, - {0x8009, 39}, - {0x8017, 39}, - {0xc028, 39}, - {0x8002, 43}, - {0x8009, 43}, - {0x8017, 43}, - {0xc028, 43}, - }, - /* 80 */ - { - {0x8003, 39}, - {0x8006, 39}, - {0x800a, 39}, - {0x800f, 39}, - {0x8018, 39}, - {0x801f, 39}, - {0x8029, 39}, - {0xc038, 39}, - {0x8003, 43}, - {0x8006, 43}, - {0x800a, 43}, - {0x800f, 43}, - {0x8018, 43}, - {0x801f, 43}, - {0x8029, 43}, - {0xc038, 43}, - }, - /* 81 */ - { - {0x8002, 124}, - {0x8009, 124}, - {0x8017, 124}, - {0xc028, 124}, - {0x8001, 35}, - {0xc016, 35}, - {0x8001, 62}, - {0xc016, 62}, - {0xc000, 0}, - {0xc000, 36}, - {0xc000, 64}, - {0xc000, 91}, - {0xc000, 93}, - {0xc000, 126}, - {0x5b, 0}, - {0x5c, 0}, - }, - /* 82 */ - { - {0x8003, 124}, - {0x8006, 124}, - {0x800a, 124}, - {0x800f, 124}, - {0x8018, 124}, - {0x801f, 124}, - {0x8029, 124}, - {0xc038, 124}, - {0x8002, 35}, - {0x8009, 35}, - {0x8017, 35}, - {0xc028, 35}, - {0x8002, 62}, - {0x8009, 62}, - {0x8017, 62}, - {0xc028, 62}, - }, - /* 83 */ - { - {0x8003, 35}, - {0x8006, 35}, - {0x800a, 35}, - {0x800f, 35}, - {0x8018, 35}, - {0x801f, 35}, - {0x8029, 35}, - {0xc038, 35}, - {0x8003, 62}, - {0x8006, 62}, - {0x800a, 62}, - {0x800f, 62}, - {0x8018, 62}, - {0x801f, 62}, - {0x8029, 62}, - {0xc038, 62}, - }, - /* 84 */ - { - {0x8001, 0}, - {0xc016, 0}, - {0x8001, 36}, - {0xc016, 36}, - {0x8001, 64}, - {0xc016, 64}, - {0x8001, 91}, - {0xc016, 91}, - {0x8001, 93}, - {0xc016, 93}, - {0x8001, 126}, - {0xc016, 126}, - {0xc000, 94}, - {0xc000, 125}, - {0x5d, 0}, - {0x5e, 0}, - }, - /* 85 */ - { - {0x8002, 0}, - {0x8009, 0}, - {0x8017, 0}, - {0xc028, 0}, - {0x8002, 36}, - {0x8009, 36}, - {0x8017, 36}, - {0xc028, 36}, - {0x8002, 64}, - {0x8009, 64}, - {0x8017, 64}, - {0xc028, 64}, - {0x8002, 91}, - {0x8009, 91}, - {0x8017, 91}, - {0xc028, 91}, - }, - /* 86 */ - { - {0x8003, 0}, - {0x8006, 0}, - {0x800a, 0}, - {0x800f, 0}, - {0x8018, 0}, - {0x801f, 0}, - {0x8029, 0}, - {0xc038, 0}, - {0x8003, 36}, - {0x8006, 36}, - {0x800a, 36}, - {0x800f, 36}, - {0x8018, 36}, - {0x801f, 36}, - {0x8029, 36}, - {0xc038, 36}, - }, - /* 87 */ - { - {0x8003, 64}, - {0x8006, 64}, - {0x800a, 64}, - {0x800f, 64}, - {0x8018, 64}, - {0x801f, 64}, - {0x8029, 64}, - {0xc038, 64}, - {0x8003, 91}, - {0x8006, 91}, - {0x800a, 91}, - {0x800f, 91}, - {0x8018, 91}, - {0x801f, 91}, - {0x8029, 91}, - {0xc038, 91}, - }, - /* 88 */ - { - {0x8002, 93}, - {0x8009, 93}, - {0x8017, 93}, - {0xc028, 93}, - {0x8002, 126}, - {0x8009, 126}, - {0x8017, 126}, - {0xc028, 126}, - {0x8001, 94}, - {0xc016, 94}, - {0x8001, 125}, - {0xc016, 125}, - {0xc000, 60}, - {0xc000, 96}, - {0xc000, 123}, - {0x5f, 0}, - }, - /* 89 */ - { - {0x8003, 93}, - {0x8006, 93}, - {0x800a, 93}, - {0x800f, 93}, - {0x8018, 93}, - {0x801f, 93}, - {0x8029, 93}, - {0xc038, 93}, - {0x8003, 126}, - {0x8006, 126}, - {0x800a, 126}, - {0x800f, 126}, - {0x8018, 126}, - {0x801f, 126}, - {0x8029, 126}, - {0xc038, 126}, - }, - /* 90 */ - { - {0x8002, 94}, - {0x8009, 94}, - {0x8017, 94}, - {0xc028, 94}, - {0x8002, 125}, - {0x8009, 125}, - {0x8017, 125}, - {0xc028, 125}, - {0x8001, 60}, - {0xc016, 60}, - {0x8001, 96}, - {0xc016, 96}, - {0x8001, 123}, - {0xc016, 123}, - {0x60, 0}, - {0x6e, 0}, - }, - /* 91 */ - { - {0x8003, 94}, - {0x8006, 94}, - {0x800a, 94}, - {0x800f, 94}, - {0x8018, 94}, - {0x801f, 94}, - {0x8029, 94}, - {0xc038, 94}, - {0x8003, 125}, - {0x8006, 125}, - {0x800a, 125}, - {0x800f, 125}, - {0x8018, 125}, - {0x801f, 125}, - {0x8029, 125}, - {0xc038, 125}, - }, - /* 92 */ - { - {0x8002, 60}, - {0x8009, 60}, - {0x8017, 60}, - {0xc028, 60}, - {0x8002, 96}, - {0x8009, 96}, - {0x8017, 96}, - {0xc028, 96}, - {0x8002, 123}, - {0x8009, 123}, - {0x8017, 123}, - {0xc028, 123}, - {0x61, 0}, - {0x65, 0}, - {0x6f, 0}, - {0x85, 0}, - }, - /* 93 */ - { - {0x8003, 60}, - {0x8006, 60}, - {0x800a, 60}, - {0x800f, 60}, - {0x8018, 60}, - {0x801f, 60}, - {0x8029, 60}, - {0xc038, 60}, - {0x8003, 96}, - {0x8006, 96}, - {0x800a, 96}, - {0x800f, 96}, - {0x8018, 96}, - {0x801f, 96}, - {0x8029, 96}, - {0xc038, 96}, - }, - /* 94 */ - { - {0x8003, 123}, - {0x8006, 123}, - {0x800a, 123}, - {0x800f, 123}, - {0x8018, 123}, - {0x801f, 123}, - {0x8029, 123}, - {0xc038, 123}, - {0x62, 0}, - {0x63, 0}, - {0x66, 0}, - {0x69, 0}, - {0x70, 0}, - {0x77, 0}, - {0x86, 0}, - {0x99, 0}, - }, - /* 95 */ - { - {0xc000, 92}, - {0xc000, 195}, - {0xc000, 208}, - {0x64, 0}, - {0x67, 0}, - {0x68, 0}, - {0x6a, 0}, - {0x6b, 0}, - {0x71, 0}, - {0x74, 0}, - {0x78, 0}, - {0x7e, 0}, - {0x87, 0}, - {0x8e, 0}, - {0x9a, 0}, - {0xa9, 0}, - }, - /* 96 */ - { - {0x8001, 92}, - {0xc016, 92}, - {0x8001, 195}, - {0xc016, 195}, - {0x8001, 208}, - {0xc016, 208}, - {0xc000, 128}, - {0xc000, 130}, - {0xc000, 131}, - {0xc000, 162}, - {0xc000, 184}, - {0xc000, 194}, - {0xc000, 224}, - {0xc000, 226}, - {0x6c, 0}, - {0x6d, 0}, - }, - /* 97 */ - { - {0x8002, 92}, - {0x8009, 92}, - {0x8017, 92}, - {0xc028, 92}, - {0x8002, 195}, - {0x8009, 195}, - {0x8017, 195}, - {0xc028, 195}, - {0x8002, 208}, - {0x8009, 208}, - {0x8017, 208}, - {0xc028, 208}, - {0x8001, 128}, - {0xc016, 128}, - {0x8001, 130}, - {0xc016, 130}, - }, - /* 98 */ - { - {0x8003, 92}, - {0x8006, 92}, - {0x800a, 92}, - {0x800f, 92}, - {0x8018, 92}, - {0x801f, 92}, - {0x8029, 92}, - {0xc038, 92}, - {0x8003, 195}, - {0x8006, 195}, - {0x800a, 195}, - {0x800f, 195}, - {0x8018, 195}, - {0x801f, 195}, - {0x8029, 195}, - {0xc038, 195}, - }, - /* 99 */ - { - {0x8003, 208}, - {0x8006, 208}, - {0x800a, 208}, - {0x800f, 208}, - {0x8018, 208}, - {0x801f, 208}, - {0x8029, 208}, - {0xc038, 208}, - {0x8002, 128}, - {0x8009, 128}, - {0x8017, 128}, - {0xc028, 128}, - {0x8002, 130}, - {0x8009, 130}, - {0x8017, 130}, - {0xc028, 130}, - }, - /* 100 */ - { - {0x8003, 128}, - {0x8006, 128}, - {0x800a, 128}, - {0x800f, 128}, - {0x8018, 128}, - {0x801f, 128}, - {0x8029, 128}, - {0xc038, 128}, - {0x8003, 130}, - {0x8006, 130}, - {0x800a, 130}, - {0x800f, 130}, - {0x8018, 130}, - {0x801f, 130}, - {0x8029, 130}, - {0xc038, 130}, - }, - /* 101 */ - { - {0x8001, 131}, - {0xc016, 131}, - {0x8001, 162}, - {0xc016, 162}, - {0x8001, 184}, - {0xc016, 184}, - {0x8001, 194}, - {0xc016, 194}, - {0x8001, 224}, - {0xc016, 224}, - {0x8001, 226}, - {0xc016, 226}, - {0xc000, 153}, - {0xc000, 161}, - {0xc000, 167}, - {0xc000, 172}, - }, - /* 102 */ - { - {0x8002, 131}, - {0x8009, 131}, - {0x8017, 131}, - {0xc028, 131}, - {0x8002, 162}, - {0x8009, 162}, - {0x8017, 162}, - {0xc028, 162}, - {0x8002, 184}, - {0x8009, 184}, - {0x8017, 184}, - {0xc028, 184}, - {0x8002, 194}, - {0x8009, 194}, - {0x8017, 194}, - {0xc028, 194}, - }, - /* 103 */ - { - {0x8003, 131}, - {0x8006, 131}, - {0x800a, 131}, - {0x800f, 131}, - {0x8018, 131}, - {0x801f, 131}, - {0x8029, 131}, - {0xc038, 131}, - {0x8003, 162}, - {0x8006, 162}, - {0x800a, 162}, - {0x800f, 162}, - {0x8018, 162}, - {0x801f, 162}, - {0x8029, 162}, - {0xc038, 162}, - }, - /* 104 */ - { - {0x8003, 184}, - {0x8006, 184}, - {0x800a, 184}, - {0x800f, 184}, - {0x8018, 184}, - {0x801f, 184}, - {0x8029, 184}, - {0xc038, 184}, - {0x8003, 194}, - {0x8006, 194}, - {0x800a, 194}, - {0x800f, 194}, - {0x8018, 194}, - {0x801f, 194}, - {0x8029, 194}, - {0xc038, 194}, - }, - /* 105 */ - { - {0x8002, 224}, - {0x8009, 224}, - {0x8017, 224}, - {0xc028, 224}, - {0x8002, 226}, - {0x8009, 226}, - {0x8017, 226}, - {0xc028, 226}, - {0x8001, 153}, - {0xc016, 153}, - {0x8001, 161}, - {0xc016, 161}, - {0x8001, 167}, - {0xc016, 167}, - {0x8001, 172}, - {0xc016, 172}, - }, - /* 106 */ - { - {0x8003, 224}, - {0x8006, 224}, - {0x800a, 224}, - {0x800f, 224}, - {0x8018, 224}, - {0x801f, 224}, - {0x8029, 224}, - {0xc038, 224}, - {0x8003, 226}, - {0x8006, 226}, - {0x800a, 226}, - {0x800f, 226}, - {0x8018, 226}, - {0x801f, 226}, - {0x8029, 226}, - {0xc038, 226}, - }, - /* 107 */ - { - {0x8002, 153}, - {0x8009, 153}, - {0x8017, 153}, - {0xc028, 153}, - {0x8002, 161}, - {0x8009, 161}, - {0x8017, 161}, - {0xc028, 161}, - {0x8002, 167}, - {0x8009, 167}, - {0x8017, 167}, - {0xc028, 167}, - {0x8002, 172}, - {0x8009, 172}, - {0x8017, 172}, - {0xc028, 172}, - }, - /* 108 */ - { - {0x8003, 153}, - {0x8006, 153}, - {0x800a, 153}, - {0x800f, 153}, - {0x8018, 153}, - {0x801f, 153}, - {0x8029, 153}, - {0xc038, 153}, - {0x8003, 161}, - {0x8006, 161}, - {0x800a, 161}, - {0x800f, 161}, - {0x8018, 161}, - {0x801f, 161}, - {0x8029, 161}, - {0xc038, 161}, - }, - /* 109 */ - { - {0x8003, 167}, - {0x8006, 167}, - {0x800a, 167}, - {0x800f, 167}, - {0x8018, 167}, - {0x801f, 167}, - {0x8029, 167}, - {0xc038, 167}, - {0x8003, 172}, - {0x8006, 172}, - {0x800a, 172}, - {0x800f, 172}, - {0x8018, 172}, - {0x801f, 172}, - {0x8029, 172}, - {0xc038, 172}, - }, - /* 110 */ - { - {0x72, 0}, - {0x73, 0}, - {0x75, 0}, - {0x76, 0}, - {0x79, 0}, - {0x7b, 0}, - {0x7f, 0}, - {0x82, 0}, - {0x88, 0}, - {0x8b, 0}, - {0x8f, 0}, - {0x92, 0}, - {0x9b, 0}, - {0xa2, 0}, - {0xaa, 0}, - {0xb4, 0}, - }, - /* 111 */ - { - {0xc000, 176}, - {0xc000, 177}, - {0xc000, 179}, - {0xc000, 209}, - {0xc000, 216}, - {0xc000, 217}, - {0xc000, 227}, - {0xc000, 229}, - {0xc000, 230}, - {0x7a, 0}, - {0x7c, 0}, - {0x7d, 0}, - {0x80, 0}, - {0x81, 0}, - {0x83, 0}, - {0x84, 0}, - }, - /* 112 */ - { - {0x8001, 176}, - {0xc016, 176}, - {0x8001, 177}, - {0xc016, 177}, - {0x8001, 179}, - {0xc016, 179}, - {0x8001, 209}, - {0xc016, 209}, - {0x8001, 216}, - {0xc016, 216}, - {0x8001, 217}, - {0xc016, 217}, - {0x8001, 227}, - {0xc016, 227}, - {0x8001, 229}, - {0xc016, 229}, - }, - /* 113 */ - { - {0x8002, 176}, - {0x8009, 176}, - {0x8017, 176}, - {0xc028, 176}, - {0x8002, 177}, - {0x8009, 177}, - {0x8017, 177}, - {0xc028, 177}, - {0x8002, 179}, - {0x8009, 179}, - {0x8017, 179}, - {0xc028, 179}, - {0x8002, 209}, - {0x8009, 209}, - {0x8017, 209}, - {0xc028, 209}, - }, - /* 114 */ - { - {0x8003, 176}, - {0x8006, 176}, - {0x800a, 176}, - {0x800f, 176}, - {0x8018, 176}, - {0x801f, 176}, - {0x8029, 176}, - {0xc038, 176}, - {0x8003, 177}, - {0x8006, 177}, - {0x800a, 177}, - {0x800f, 177}, - {0x8018, 177}, - {0x801f, 177}, - {0x8029, 177}, - {0xc038, 177}, - }, - /* 115 */ - { - {0x8003, 179}, - {0x8006, 179}, - {0x800a, 179}, - {0x800f, 179}, - {0x8018, 179}, - {0x801f, 179}, - {0x8029, 179}, - {0xc038, 179}, - {0x8003, 209}, - {0x8006, 209}, - {0x800a, 209}, - {0x800f, 209}, - {0x8018, 209}, - {0x801f, 209}, - {0x8029, 209}, - {0xc038, 209}, - }, - /* 116 */ - { - {0x8002, 216}, - {0x8009, 216}, - {0x8017, 216}, - {0xc028, 216}, - {0x8002, 217}, - {0x8009, 217}, - {0x8017, 217}, - {0xc028, 217}, - {0x8002, 227}, - {0x8009, 227}, - {0x8017, 227}, - {0xc028, 227}, - {0x8002, 229}, - {0x8009, 229}, - {0x8017, 229}, - {0xc028, 229}, - }, - /* 117 */ - { - {0x8003, 216}, - {0x8006, 216}, - {0x800a, 216}, - {0x800f, 216}, - {0x8018, 216}, - {0x801f, 216}, - {0x8029, 216}, - {0xc038, 216}, - {0x8003, 217}, - {0x8006, 217}, - {0x800a, 217}, - {0x800f, 217}, - {0x8018, 217}, - {0x801f, 217}, - {0x8029, 217}, - {0xc038, 217}, - }, - /* 118 */ - { - {0x8003, 227}, - {0x8006, 227}, - {0x800a, 227}, - {0x800f, 227}, - {0x8018, 227}, - {0x801f, 227}, - {0x8029, 227}, - {0xc038, 227}, - {0x8003, 229}, - {0x8006, 229}, - {0x800a, 229}, - {0x800f, 229}, - {0x8018, 229}, - {0x801f, 229}, - {0x8029, 229}, - {0xc038, 229}, - }, - /* 119 */ - { - {0x8001, 230}, - {0xc016, 230}, - {0xc000, 129}, - {0xc000, 132}, - {0xc000, 133}, - {0xc000, 134}, - {0xc000, 136}, - {0xc000, 146}, - {0xc000, 154}, - {0xc000, 156}, - {0xc000, 160}, - {0xc000, 163}, - {0xc000, 164}, - {0xc000, 169}, - {0xc000, 170}, - {0xc000, 173}, - }, - /* 120 */ - { - {0x8002, 230}, - {0x8009, 230}, - {0x8017, 230}, - {0xc028, 230}, - {0x8001, 129}, - {0xc016, 129}, - {0x8001, 132}, - {0xc016, 132}, - {0x8001, 133}, - {0xc016, 133}, - {0x8001, 134}, - {0xc016, 134}, - {0x8001, 136}, - {0xc016, 136}, - {0x8001, 146}, - {0xc016, 146}, - }, - /* 121 */ - { - {0x8003, 230}, - {0x8006, 230}, - {0x800a, 230}, - {0x800f, 230}, - {0x8018, 230}, - {0x801f, 230}, - {0x8029, 230}, - {0xc038, 230}, - {0x8002, 129}, - {0x8009, 129}, - {0x8017, 129}, - {0xc028, 129}, - {0x8002, 132}, - {0x8009, 132}, - {0x8017, 132}, - {0xc028, 132}, - }, - /* 122 */ - { - {0x8003, 129}, - {0x8006, 129}, - {0x800a, 129}, - {0x800f, 129}, - {0x8018, 129}, - {0x801f, 129}, - {0x8029, 129}, - {0xc038, 129}, - {0x8003, 132}, - {0x8006, 132}, - {0x800a, 132}, - {0x800f, 132}, - {0x8018, 132}, - {0x801f, 132}, - {0x8029, 132}, - {0xc038, 132}, - }, - /* 123 */ - { - {0x8002, 133}, - {0x8009, 133}, - {0x8017, 133}, - {0xc028, 133}, - {0x8002, 134}, - {0x8009, 134}, - {0x8017, 134}, - {0xc028, 134}, - {0x8002, 136}, - {0x8009, 136}, - {0x8017, 136}, - {0xc028, 136}, - {0x8002, 146}, - {0x8009, 146}, - {0x8017, 146}, - {0xc028, 146}, - }, - /* 124 */ - { - {0x8003, 133}, - {0x8006, 133}, - {0x800a, 133}, - {0x800f, 133}, - {0x8018, 133}, - {0x801f, 133}, - {0x8029, 133}, - {0xc038, 133}, - {0x8003, 134}, - {0x8006, 134}, - {0x800a, 134}, - {0x800f, 134}, - {0x8018, 134}, - {0x801f, 134}, - {0x8029, 134}, - {0xc038, 134}, - }, - /* 125 */ - { - {0x8003, 136}, - {0x8006, 136}, - {0x800a, 136}, - {0x800f, 136}, - {0x8018, 136}, - {0x801f, 136}, - {0x8029, 136}, - {0xc038, 136}, - {0x8003, 146}, - {0x8006, 146}, - {0x800a, 146}, - {0x800f, 146}, - {0x8018, 146}, - {0x801f, 146}, - {0x8029, 146}, - {0xc038, 146}, - }, - /* 126 */ - { - {0x8001, 154}, - {0xc016, 154}, - {0x8001, 156}, - {0xc016, 156}, - {0x8001, 160}, - {0xc016, 160}, - {0x8001, 163}, - {0xc016, 163}, - {0x8001, 164}, - {0xc016, 164}, - {0x8001, 169}, - {0xc016, 169}, - {0x8001, 170}, - {0xc016, 170}, - {0x8001, 173}, - {0xc016, 173}, - }, - /* 127 */ - { - {0x8002, 154}, - {0x8009, 154}, - {0x8017, 154}, - {0xc028, 154}, - {0x8002, 156}, - {0x8009, 156}, - {0x8017, 156}, - {0xc028, 156}, - {0x8002, 160}, - {0x8009, 160}, - {0x8017, 160}, - {0xc028, 160}, - {0x8002, 163}, - {0x8009, 163}, - {0x8017, 163}, - {0xc028, 163}, - }, - /* 128 */ - { - {0x8003, 154}, - {0x8006, 154}, - {0x800a, 154}, - {0x800f, 154}, - {0x8018, 154}, - {0x801f, 154}, - {0x8029, 154}, - {0xc038, 154}, - {0x8003, 156}, - {0x8006, 156}, - {0x800a, 156}, - {0x800f, 156}, - {0x8018, 156}, - {0x801f, 156}, - {0x8029, 156}, - {0xc038, 156}, - }, - /* 129 */ - { - {0x8003, 160}, - {0x8006, 160}, - {0x800a, 160}, - {0x800f, 160}, - {0x8018, 160}, - {0x801f, 160}, - {0x8029, 160}, - {0xc038, 160}, - {0x8003, 163}, - {0x8006, 163}, - {0x800a, 163}, - {0x800f, 163}, - {0x8018, 163}, - {0x801f, 163}, - {0x8029, 163}, - {0xc038, 163}, - }, - /* 130 */ - { - {0x8002, 164}, - {0x8009, 164}, - {0x8017, 164}, - {0xc028, 164}, - {0x8002, 169}, - {0x8009, 169}, - {0x8017, 169}, - {0xc028, 169}, - {0x8002, 170}, - {0x8009, 170}, - {0x8017, 170}, - {0xc028, 170}, - {0x8002, 173}, - {0x8009, 173}, - {0x8017, 173}, - {0xc028, 173}, - }, - /* 131 */ - { - {0x8003, 164}, - {0x8006, 164}, - {0x800a, 164}, - {0x800f, 164}, - {0x8018, 164}, - {0x801f, 164}, - {0x8029, 164}, - {0xc038, 164}, - {0x8003, 169}, - {0x8006, 169}, - {0x800a, 169}, - {0x800f, 169}, - {0x8018, 169}, - {0x801f, 169}, - {0x8029, 169}, - {0xc038, 169}, - }, - /* 132 */ - { - {0x8003, 170}, - {0x8006, 170}, - {0x800a, 170}, - {0x800f, 170}, - {0x8018, 170}, - {0x801f, 170}, - {0x8029, 170}, - {0xc038, 170}, - {0x8003, 173}, - {0x8006, 173}, - {0x800a, 173}, - {0x800f, 173}, - {0x8018, 173}, - {0x801f, 173}, - {0x8029, 173}, - {0xc038, 173}, - }, - /* 133 */ - { - {0x89, 0}, - {0x8a, 0}, - {0x8c, 0}, - {0x8d, 0}, - {0x90, 0}, - {0x91, 0}, - {0x93, 0}, - {0x96, 0}, - {0x9c, 0}, - {0x9f, 0}, - {0xa3, 0}, - {0xa6, 0}, - {0xab, 0}, - {0xae, 0}, - {0xb5, 0}, - {0xbe, 0}, - }, - /* 134 */ - { - {0xc000, 178}, - {0xc000, 181}, - {0xc000, 185}, - {0xc000, 186}, - {0xc000, 187}, - {0xc000, 189}, - {0xc000, 190}, - {0xc000, 196}, - {0xc000, 198}, - {0xc000, 228}, - {0xc000, 232}, - {0xc000, 233}, - {0x94, 0}, - {0x95, 0}, - {0x97, 0}, - {0x98, 0}, - }, - /* 135 */ - { - {0x8001, 178}, - {0xc016, 178}, - {0x8001, 181}, - {0xc016, 181}, - {0x8001, 185}, - {0xc016, 185}, - {0x8001, 186}, - {0xc016, 186}, - {0x8001, 187}, - {0xc016, 187}, - {0x8001, 189}, - {0xc016, 189}, - {0x8001, 190}, - {0xc016, 190}, - {0x8001, 196}, - {0xc016, 196}, - }, - /* 136 */ - { - {0x8002, 178}, - {0x8009, 178}, - {0x8017, 178}, - {0xc028, 178}, - {0x8002, 181}, - {0x8009, 181}, - {0x8017, 181}, - {0xc028, 181}, - {0x8002, 185}, - {0x8009, 185}, - {0x8017, 185}, - {0xc028, 185}, - {0x8002, 186}, - {0x8009, 186}, - {0x8017, 186}, - {0xc028, 186}, - }, - /* 137 */ - { - {0x8003, 178}, - {0x8006, 178}, - {0x800a, 178}, - {0x800f, 178}, - {0x8018, 178}, - {0x801f, 178}, - {0x8029, 178}, - {0xc038, 178}, - {0x8003, 181}, - {0x8006, 181}, - {0x800a, 181}, - {0x800f, 181}, - {0x8018, 181}, - {0x801f, 181}, - {0x8029, 181}, - {0xc038, 181}, - }, - /* 138 */ - { - {0x8003, 185}, - {0x8006, 185}, - {0x800a, 185}, - {0x800f, 185}, - {0x8018, 185}, - {0x801f, 185}, - {0x8029, 185}, - {0xc038, 185}, - {0x8003, 186}, - {0x8006, 186}, - {0x800a, 186}, - {0x800f, 186}, - {0x8018, 186}, - {0x801f, 186}, - {0x8029, 186}, - {0xc038, 186}, - }, - /* 139 */ - { - {0x8002, 187}, - {0x8009, 187}, - {0x8017, 187}, - {0xc028, 187}, - {0x8002, 189}, - {0x8009, 189}, - {0x8017, 189}, - {0xc028, 189}, - {0x8002, 190}, - {0x8009, 190}, - {0x8017, 190}, - {0xc028, 190}, - {0x8002, 196}, - {0x8009, 196}, - {0x8017, 196}, - {0xc028, 196}, - }, - /* 140 */ - { - {0x8003, 187}, - {0x8006, 187}, - {0x800a, 187}, - {0x800f, 187}, - {0x8018, 187}, - {0x801f, 187}, - {0x8029, 187}, - {0xc038, 187}, - {0x8003, 189}, - {0x8006, 189}, - {0x800a, 189}, - {0x800f, 189}, - {0x8018, 189}, - {0x801f, 189}, - {0x8029, 189}, - {0xc038, 189}, - }, - /* 141 */ - { - {0x8003, 190}, - {0x8006, 190}, - {0x800a, 190}, - {0x800f, 190}, - {0x8018, 190}, - {0x801f, 190}, - {0x8029, 190}, - {0xc038, 190}, - {0x8003, 196}, - {0x8006, 196}, - {0x800a, 196}, - {0x800f, 196}, - {0x8018, 196}, - {0x801f, 196}, - {0x8029, 196}, - {0xc038, 196}, - }, - /* 142 */ - { - {0x8001, 198}, - {0xc016, 198}, - {0x8001, 228}, - {0xc016, 228}, - {0x8001, 232}, - {0xc016, 232}, - {0x8001, 233}, - {0xc016, 233}, - {0xc000, 1}, - {0xc000, 135}, - {0xc000, 137}, - {0xc000, 138}, - {0xc000, 139}, - {0xc000, 140}, - {0xc000, 141}, - {0xc000, 143}, - }, - /* 143 */ - { - {0x8002, 198}, - {0x8009, 198}, - {0x8017, 198}, - {0xc028, 198}, - {0x8002, 228}, - {0x8009, 228}, - {0x8017, 228}, - {0xc028, 228}, - {0x8002, 232}, - {0x8009, 232}, - {0x8017, 232}, - {0xc028, 232}, - {0x8002, 233}, - {0x8009, 233}, - {0x8017, 233}, - {0xc028, 233}, - }, - /* 144 */ - { - {0x8003, 198}, - {0x8006, 198}, - {0x800a, 198}, - {0x800f, 198}, - {0x8018, 198}, - {0x801f, 198}, - {0x8029, 198}, - {0xc038, 198}, - {0x8003, 228}, - {0x8006, 228}, - {0x800a, 228}, - {0x800f, 228}, - {0x8018, 228}, - {0x801f, 228}, - {0x8029, 228}, - {0xc038, 228}, - }, - /* 145 */ - { - {0x8003, 232}, - {0x8006, 232}, - {0x800a, 232}, - {0x800f, 232}, - {0x8018, 232}, - {0x801f, 232}, - {0x8029, 232}, - {0xc038, 232}, - {0x8003, 233}, - {0x8006, 233}, - {0x800a, 233}, - {0x800f, 233}, - {0x8018, 233}, - {0x801f, 233}, - {0x8029, 233}, - {0xc038, 233}, - }, - /* 146 */ - { - {0x8001, 1}, - {0xc016, 1}, - {0x8001, 135}, - {0xc016, 135}, - {0x8001, 137}, - {0xc016, 137}, - {0x8001, 138}, - {0xc016, 138}, - {0x8001, 139}, - {0xc016, 139}, - {0x8001, 140}, - {0xc016, 140}, - {0x8001, 141}, - {0xc016, 141}, - {0x8001, 143}, - {0xc016, 143}, - }, - /* 147 */ - { - {0x8002, 1}, - {0x8009, 1}, - {0x8017, 1}, - {0xc028, 1}, - {0x8002, 135}, - {0x8009, 135}, - {0x8017, 135}, - {0xc028, 135}, - {0x8002, 137}, - {0x8009, 137}, - {0x8017, 137}, - {0xc028, 137}, - {0x8002, 138}, - {0x8009, 138}, - {0x8017, 138}, - {0xc028, 138}, - }, - /* 148 */ - { - {0x8003, 1}, - {0x8006, 1}, - {0x800a, 1}, - {0x800f, 1}, - {0x8018, 1}, - {0x801f, 1}, - {0x8029, 1}, - {0xc038, 1}, - {0x8003, 135}, - {0x8006, 135}, - {0x800a, 135}, - {0x800f, 135}, - {0x8018, 135}, - {0x801f, 135}, - {0x8029, 135}, - {0xc038, 135}, - }, - /* 149 */ - { - {0x8003, 137}, - {0x8006, 137}, - {0x800a, 137}, - {0x800f, 137}, - {0x8018, 137}, - {0x801f, 137}, - {0x8029, 137}, - {0xc038, 137}, - {0x8003, 138}, - {0x8006, 138}, - {0x800a, 138}, - {0x800f, 138}, - {0x8018, 138}, - {0x801f, 138}, - {0x8029, 138}, - {0xc038, 138}, - }, - /* 150 */ - { - {0x8002, 139}, - {0x8009, 139}, - {0x8017, 139}, - {0xc028, 139}, - {0x8002, 140}, - {0x8009, 140}, - {0x8017, 140}, - {0xc028, 140}, - {0x8002, 141}, - {0x8009, 141}, - {0x8017, 141}, - {0xc028, 141}, - {0x8002, 143}, - {0x8009, 143}, - {0x8017, 143}, - {0xc028, 143}, - }, - /* 151 */ - { - {0x8003, 139}, - {0x8006, 139}, - {0x800a, 139}, - {0x800f, 139}, - {0x8018, 139}, - {0x801f, 139}, - {0x8029, 139}, - {0xc038, 139}, - {0x8003, 140}, - {0x8006, 140}, - {0x800a, 140}, - {0x800f, 140}, - {0x8018, 140}, - {0x801f, 140}, - {0x8029, 140}, - {0xc038, 140}, - }, - /* 152 */ - { - {0x8003, 141}, - {0x8006, 141}, - {0x800a, 141}, - {0x800f, 141}, - {0x8018, 141}, - {0x801f, 141}, - {0x8029, 141}, - {0xc038, 141}, - {0x8003, 143}, - {0x8006, 143}, - {0x800a, 143}, - {0x800f, 143}, - {0x8018, 143}, - {0x801f, 143}, - {0x8029, 143}, - {0xc038, 143}, - }, - /* 153 */ - { - {0x9d, 0}, - {0x9e, 0}, - {0xa0, 0}, - {0xa1, 0}, - {0xa4, 0}, - {0xa5, 0}, - {0xa7, 0}, - {0xa8, 0}, - {0xac, 0}, - {0xad, 0}, - {0xaf, 0}, - {0xb1, 0}, - {0xb6, 0}, - {0xb9, 0}, - {0xbf, 0}, - {0xcf, 0}, - }, - /* 154 */ - { - {0xc000, 147}, - {0xc000, 149}, - {0xc000, 150}, - {0xc000, 151}, - {0xc000, 152}, - {0xc000, 155}, - {0xc000, 157}, - {0xc000, 158}, - {0xc000, 165}, - {0xc000, 166}, - {0xc000, 168}, - {0xc000, 174}, - {0xc000, 175}, - {0xc000, 180}, - {0xc000, 182}, - {0xc000, 183}, - }, - /* 155 */ - { - {0x8001, 147}, - {0xc016, 147}, - {0x8001, 149}, - {0xc016, 149}, - {0x8001, 150}, - {0xc016, 150}, - {0x8001, 151}, - {0xc016, 151}, - {0x8001, 152}, - {0xc016, 152}, - {0x8001, 155}, - {0xc016, 155}, - {0x8001, 157}, - {0xc016, 157}, - {0x8001, 158}, - {0xc016, 158}, - }, - /* 156 */ - { - {0x8002, 147}, - {0x8009, 147}, - {0x8017, 147}, - {0xc028, 147}, - {0x8002, 149}, - {0x8009, 149}, - {0x8017, 149}, - {0xc028, 149}, - {0x8002, 150}, - {0x8009, 150}, - {0x8017, 150}, - {0xc028, 150}, - {0x8002, 151}, - {0x8009, 151}, - {0x8017, 151}, - {0xc028, 151}, - }, - /* 157 */ - { - {0x8003, 147}, - {0x8006, 147}, - {0x800a, 147}, - {0x800f, 147}, - {0x8018, 147}, - {0x801f, 147}, - {0x8029, 147}, - {0xc038, 147}, - {0x8003, 149}, - {0x8006, 149}, - {0x800a, 149}, - {0x800f, 149}, - {0x8018, 149}, - {0x801f, 149}, - {0x8029, 149}, - {0xc038, 149}, - }, - /* 158 */ - { - {0x8003, 150}, - {0x8006, 150}, - {0x800a, 150}, - {0x800f, 150}, - {0x8018, 150}, - {0x801f, 150}, - {0x8029, 150}, - {0xc038, 150}, - {0x8003, 151}, - {0x8006, 151}, - {0x800a, 151}, - {0x800f, 151}, - {0x8018, 151}, - {0x801f, 151}, - {0x8029, 151}, - {0xc038, 151}, - }, - /* 159 */ - { - {0x8002, 152}, - {0x8009, 152}, - {0x8017, 152}, - {0xc028, 152}, - {0x8002, 155}, - {0x8009, 155}, - {0x8017, 155}, - {0xc028, 155}, - {0x8002, 157}, - {0x8009, 157}, - {0x8017, 157}, - {0xc028, 157}, - {0x8002, 158}, - {0x8009, 158}, - {0x8017, 158}, - {0xc028, 158}, - }, - /* 160 */ - { - {0x8003, 152}, - {0x8006, 152}, - {0x800a, 152}, - {0x800f, 152}, - {0x8018, 152}, - {0x801f, 152}, - {0x8029, 152}, - {0xc038, 152}, - {0x8003, 155}, - {0x8006, 155}, - {0x800a, 155}, - {0x800f, 155}, - {0x8018, 155}, - {0x801f, 155}, - {0x8029, 155}, - {0xc038, 155}, - }, - /* 161 */ - { - {0x8003, 157}, - {0x8006, 157}, - {0x800a, 157}, - {0x800f, 157}, - {0x8018, 157}, - {0x801f, 157}, - {0x8029, 157}, - {0xc038, 157}, - {0x8003, 158}, - {0x8006, 158}, - {0x800a, 158}, - {0x800f, 158}, - {0x8018, 158}, - {0x801f, 158}, - {0x8029, 158}, - {0xc038, 158}, - }, - /* 162 */ - { - {0x8001, 165}, - {0xc016, 165}, - {0x8001, 166}, - {0xc016, 166}, - {0x8001, 168}, - {0xc016, 168}, - {0x8001, 174}, - {0xc016, 174}, - {0x8001, 175}, - {0xc016, 175}, - {0x8001, 180}, - {0xc016, 180}, - {0x8001, 182}, - {0xc016, 182}, - {0x8001, 183}, - {0xc016, 183}, - }, - /* 163 */ - { - {0x8002, 165}, - {0x8009, 165}, - {0x8017, 165}, - {0xc028, 165}, - {0x8002, 166}, - {0x8009, 166}, - {0x8017, 166}, - {0xc028, 166}, - {0x8002, 168}, - {0x8009, 168}, - {0x8017, 168}, - {0xc028, 168}, - {0x8002, 174}, - {0x8009, 174}, - {0x8017, 174}, - {0xc028, 174}, - }, - /* 164 */ - { - {0x8003, 165}, - {0x8006, 165}, - {0x800a, 165}, - {0x800f, 165}, - {0x8018, 165}, - {0x801f, 165}, - {0x8029, 165}, - {0xc038, 165}, - {0x8003, 166}, - {0x8006, 166}, - {0x800a, 166}, - {0x800f, 166}, - {0x8018, 166}, - {0x801f, 166}, - {0x8029, 166}, - {0xc038, 166}, - }, - /* 165 */ - { - {0x8003, 168}, - {0x8006, 168}, - {0x800a, 168}, - {0x800f, 168}, - {0x8018, 168}, - {0x801f, 168}, - {0x8029, 168}, - {0xc038, 168}, - {0x8003, 174}, - {0x8006, 174}, - {0x800a, 174}, - {0x800f, 174}, - {0x8018, 174}, - {0x801f, 174}, - {0x8029, 174}, - {0xc038, 174}, - }, - /* 166 */ - { - {0x8002, 175}, - {0x8009, 175}, - {0x8017, 175}, - {0xc028, 175}, - {0x8002, 180}, - {0x8009, 180}, - {0x8017, 180}, - {0xc028, 180}, - {0x8002, 182}, - {0x8009, 182}, - {0x8017, 182}, - {0xc028, 182}, - {0x8002, 183}, - {0x8009, 183}, - {0x8017, 183}, - {0xc028, 183}, - }, - /* 167 */ - { - {0x8003, 175}, - {0x8006, 175}, - {0x800a, 175}, - {0x800f, 175}, - {0x8018, 175}, - {0x801f, 175}, - {0x8029, 175}, - {0xc038, 175}, - {0x8003, 180}, - {0x8006, 180}, - {0x800a, 180}, - {0x800f, 180}, - {0x8018, 180}, - {0x801f, 180}, - {0x8029, 180}, - {0xc038, 180}, - }, - /* 168 */ - { - {0x8003, 182}, - {0x8006, 182}, - {0x800a, 182}, - {0x800f, 182}, - {0x8018, 182}, - {0x801f, 182}, - {0x8029, 182}, - {0xc038, 182}, - {0x8003, 183}, - {0x8006, 183}, - {0x800a, 183}, - {0x800f, 183}, - {0x8018, 183}, - {0x801f, 183}, - {0x8029, 183}, - {0xc038, 183}, - }, - /* 169 */ - { - {0xc000, 188}, - {0xc000, 191}, - {0xc000, 197}, - {0xc000, 231}, - {0xc000, 239}, - {0xb0, 0}, - {0xb2, 0}, - {0xb3, 0}, - {0xb7, 0}, - {0xb8, 0}, - {0xba, 0}, - {0xbb, 0}, - {0xc0, 0}, - {0xc7, 0}, - {0xd0, 0}, - {0xdf, 0}, - }, - /* 170 */ - { - {0x8001, 188}, - {0xc016, 188}, - {0x8001, 191}, - {0xc016, 191}, - {0x8001, 197}, - {0xc016, 197}, - {0x8001, 231}, - {0xc016, 231}, - {0x8001, 239}, - {0xc016, 239}, - {0xc000, 9}, - {0xc000, 142}, - {0xc000, 144}, - {0xc000, 145}, - {0xc000, 148}, - {0xc000, 159}, - }, - /* 171 */ - { - {0x8002, 188}, - {0x8009, 188}, - {0x8017, 188}, - {0xc028, 188}, - {0x8002, 191}, - {0x8009, 191}, - {0x8017, 191}, - {0xc028, 191}, - {0x8002, 197}, - {0x8009, 197}, - {0x8017, 197}, - {0xc028, 197}, - {0x8002, 231}, - {0x8009, 231}, - {0x8017, 231}, - {0xc028, 231}, - }, - /* 172 */ - { - {0x8003, 188}, - {0x8006, 188}, - {0x800a, 188}, - {0x800f, 188}, - {0x8018, 188}, - {0x801f, 188}, - {0x8029, 188}, - {0xc038, 188}, - {0x8003, 191}, - {0x8006, 191}, - {0x800a, 191}, - {0x800f, 191}, - {0x8018, 191}, - {0x801f, 191}, - {0x8029, 191}, - {0xc038, 191}, - }, - /* 173 */ - { - {0x8003, 197}, - {0x8006, 197}, - {0x800a, 197}, - {0x800f, 197}, - {0x8018, 197}, - {0x801f, 197}, - {0x8029, 197}, - {0xc038, 197}, - {0x8003, 231}, - {0x8006, 231}, - {0x800a, 231}, - {0x800f, 231}, - {0x8018, 231}, - {0x801f, 231}, - {0x8029, 231}, - {0xc038, 231}, - }, - /* 174 */ - { - {0x8002, 239}, - {0x8009, 239}, - {0x8017, 239}, - {0xc028, 239}, - {0x8001, 9}, - {0xc016, 9}, - {0x8001, 142}, - {0xc016, 142}, - {0x8001, 144}, - {0xc016, 144}, - {0x8001, 145}, - {0xc016, 145}, - {0x8001, 148}, - {0xc016, 148}, - {0x8001, 159}, - {0xc016, 159}, - }, - /* 175 */ - { - {0x8003, 239}, - {0x8006, 239}, - {0x800a, 239}, - {0x800f, 239}, - {0x8018, 239}, - {0x801f, 239}, - {0x8029, 239}, - {0xc038, 239}, - {0x8002, 9}, - {0x8009, 9}, - {0x8017, 9}, - {0xc028, 9}, - {0x8002, 142}, - {0x8009, 142}, - {0x8017, 142}, - {0xc028, 142}, - }, - /* 176 */ - { - {0x8003, 9}, - {0x8006, 9}, - {0x800a, 9}, - {0x800f, 9}, - {0x8018, 9}, - {0x801f, 9}, - {0x8029, 9}, - {0xc038, 9}, - {0x8003, 142}, - {0x8006, 142}, - {0x800a, 142}, - {0x800f, 142}, - {0x8018, 142}, - {0x801f, 142}, - {0x8029, 142}, - {0xc038, 142}, - }, - /* 177 */ - { - {0x8002, 144}, - {0x8009, 144}, - {0x8017, 144}, - {0xc028, 144}, - {0x8002, 145}, - {0x8009, 145}, - {0x8017, 145}, - {0xc028, 145}, - {0x8002, 148}, - {0x8009, 148}, - {0x8017, 148}, - {0xc028, 148}, - {0x8002, 159}, - {0x8009, 159}, - {0x8017, 159}, - {0xc028, 159}, - }, - /* 178 */ - { - {0x8003, 144}, - {0x8006, 144}, - {0x800a, 144}, - {0x800f, 144}, - {0x8018, 144}, - {0x801f, 144}, - {0x8029, 144}, - {0xc038, 144}, - {0x8003, 145}, - {0x8006, 145}, - {0x800a, 145}, - {0x800f, 145}, - {0x8018, 145}, - {0x801f, 145}, - {0x8029, 145}, - {0xc038, 145}, - }, - /* 179 */ - { - {0x8003, 148}, - {0x8006, 148}, - {0x800a, 148}, - {0x800f, 148}, - {0x8018, 148}, - {0x801f, 148}, - {0x8029, 148}, - {0xc038, 148}, - {0x8003, 159}, - {0x8006, 159}, - {0x800a, 159}, - {0x800f, 159}, - {0x8018, 159}, - {0x801f, 159}, - {0x8029, 159}, - {0xc038, 159}, - }, - /* 180 */ - { - {0xc000, 171}, - {0xc000, 206}, - {0xc000, 215}, - {0xc000, 225}, - {0xc000, 236}, - {0xc000, 237}, - {0xbc, 0}, - {0xbd, 0}, - {0xc1, 0}, - {0xc4, 0}, - {0xc8, 0}, - {0xcb, 0}, - {0xd1, 0}, - {0xd8, 0}, - {0xe0, 0}, - {0xee, 0}, - }, - /* 181 */ - { - {0x8001, 171}, - {0xc016, 171}, - {0x8001, 206}, - {0xc016, 206}, - {0x8001, 215}, - {0xc016, 215}, - {0x8001, 225}, - {0xc016, 225}, - {0x8001, 236}, - {0xc016, 236}, - {0x8001, 237}, - {0xc016, 237}, - {0xc000, 199}, - {0xc000, 207}, - {0xc000, 234}, - {0xc000, 235}, - }, - /* 182 */ - { - {0x8002, 171}, - {0x8009, 171}, - {0x8017, 171}, - {0xc028, 171}, - {0x8002, 206}, - {0x8009, 206}, - {0x8017, 206}, - {0xc028, 206}, - {0x8002, 215}, - {0x8009, 215}, - {0x8017, 215}, - {0xc028, 215}, - {0x8002, 225}, - {0x8009, 225}, - {0x8017, 225}, - {0xc028, 225}, - }, - /* 183 */ - { - {0x8003, 171}, - {0x8006, 171}, - {0x800a, 171}, - {0x800f, 171}, - {0x8018, 171}, - {0x801f, 171}, - {0x8029, 171}, - {0xc038, 171}, - {0x8003, 206}, - {0x8006, 206}, - {0x800a, 206}, - {0x800f, 206}, - {0x8018, 206}, - {0x801f, 206}, - {0x8029, 206}, - {0xc038, 206}, - }, - /* 184 */ - { - {0x8003, 215}, - {0x8006, 215}, - {0x800a, 215}, - {0x800f, 215}, - {0x8018, 215}, - {0x801f, 215}, - {0x8029, 215}, - {0xc038, 215}, - {0x8003, 225}, - {0x8006, 225}, - {0x800a, 225}, - {0x800f, 225}, - {0x8018, 225}, - {0x801f, 225}, - {0x8029, 225}, - {0xc038, 225}, - }, - /* 185 */ - { - {0x8002, 236}, - {0x8009, 236}, - {0x8017, 236}, - {0xc028, 236}, - {0x8002, 237}, - {0x8009, 237}, - {0x8017, 237}, - {0xc028, 237}, - {0x8001, 199}, - {0xc016, 199}, - {0x8001, 207}, - {0xc016, 207}, - {0x8001, 234}, - {0xc016, 234}, - {0x8001, 235}, - {0xc016, 235}, - }, - /* 186 */ - { - {0x8003, 236}, - {0x8006, 236}, - {0x800a, 236}, - {0x800f, 236}, - {0x8018, 236}, - {0x801f, 236}, - {0x8029, 236}, - {0xc038, 236}, - {0x8003, 237}, - {0x8006, 237}, - {0x800a, 237}, - {0x800f, 237}, - {0x8018, 237}, - {0x801f, 237}, - {0x8029, 237}, - {0xc038, 237}, - }, - /* 187 */ - { - {0x8002, 199}, - {0x8009, 199}, - {0x8017, 199}, - {0xc028, 199}, - {0x8002, 207}, - {0x8009, 207}, - {0x8017, 207}, - {0xc028, 207}, - {0x8002, 234}, - {0x8009, 234}, - {0x8017, 234}, - {0xc028, 234}, - {0x8002, 235}, - {0x8009, 235}, - {0x8017, 235}, - {0xc028, 235}, - }, - /* 188 */ - { - {0x8003, 199}, - {0x8006, 199}, - {0x800a, 199}, - {0x800f, 199}, - {0x8018, 199}, - {0x801f, 199}, - {0x8029, 199}, - {0xc038, 199}, - {0x8003, 207}, - {0x8006, 207}, - {0x800a, 207}, - {0x800f, 207}, - {0x8018, 207}, - {0x801f, 207}, - {0x8029, 207}, - {0xc038, 207}, - }, - /* 189 */ - { - {0x8003, 234}, - {0x8006, 234}, - {0x800a, 234}, - {0x800f, 234}, - {0x8018, 234}, - {0x801f, 234}, - {0x8029, 234}, - {0xc038, 234}, - {0x8003, 235}, - {0x8006, 235}, - {0x800a, 235}, - {0x800f, 235}, - {0x8018, 235}, - {0x801f, 235}, - {0x8029, 235}, - {0xc038, 235}, - }, - /* 190 */ - { - {0xc2, 0}, - {0xc3, 0}, - {0xc5, 0}, - {0xc6, 0}, - {0xc9, 0}, - {0xca, 0}, - {0xcc, 0}, - {0xcd, 0}, - {0xd2, 0}, - {0xd5, 0}, - {0xd9, 0}, - {0xdc, 0}, - {0xe1, 0}, - {0xe7, 0}, - {0xef, 0}, - {0xf6, 0}, - }, - /* 191 */ - { - {0xc000, 192}, - {0xc000, 193}, - {0xc000, 200}, - {0xc000, 201}, - {0xc000, 202}, - {0xc000, 205}, - {0xc000, 210}, - {0xc000, 213}, - {0xc000, 218}, - {0xc000, 219}, - {0xc000, 238}, - {0xc000, 240}, - {0xc000, 242}, - {0xc000, 243}, - {0xc000, 255}, - {0xce, 0}, - }, - /* 192 */ - { - {0x8001, 192}, - {0xc016, 192}, - {0x8001, 193}, - {0xc016, 193}, - {0x8001, 200}, - {0xc016, 200}, - {0x8001, 201}, - {0xc016, 201}, - {0x8001, 202}, - {0xc016, 202}, - {0x8001, 205}, - {0xc016, 205}, - {0x8001, 210}, - {0xc016, 210}, - {0x8001, 213}, - {0xc016, 213}, - }, - /* 193 */ - { - {0x8002, 192}, - {0x8009, 192}, - {0x8017, 192}, - {0xc028, 192}, - {0x8002, 193}, - {0x8009, 193}, - {0x8017, 193}, - {0xc028, 193}, - {0x8002, 200}, - {0x8009, 200}, - {0x8017, 200}, - {0xc028, 200}, - {0x8002, 201}, - {0x8009, 201}, - {0x8017, 201}, - {0xc028, 201}, - }, - /* 194 */ - { - {0x8003, 192}, - {0x8006, 192}, - {0x800a, 192}, - {0x800f, 192}, - {0x8018, 192}, - {0x801f, 192}, - {0x8029, 192}, - {0xc038, 192}, - {0x8003, 193}, - {0x8006, 193}, - {0x800a, 193}, - {0x800f, 193}, - {0x8018, 193}, - {0x801f, 193}, - {0x8029, 193}, - {0xc038, 193}, - }, - /* 195 */ - { - {0x8003, 200}, - {0x8006, 200}, - {0x800a, 200}, - {0x800f, 200}, - {0x8018, 200}, - {0x801f, 200}, - {0x8029, 200}, - {0xc038, 200}, - {0x8003, 201}, - {0x8006, 201}, - {0x800a, 201}, - {0x800f, 201}, - {0x8018, 201}, - {0x801f, 201}, - {0x8029, 201}, - {0xc038, 201}, - }, - /* 196 */ - { - {0x8002, 202}, - {0x8009, 202}, - {0x8017, 202}, - {0xc028, 202}, - {0x8002, 205}, - {0x8009, 205}, - {0x8017, 205}, - {0xc028, 205}, - {0x8002, 210}, - {0x8009, 210}, - {0x8017, 210}, - {0xc028, 210}, - {0x8002, 213}, - {0x8009, 213}, - {0x8017, 213}, - {0xc028, 213}, - }, - /* 197 */ - { - {0x8003, 202}, - {0x8006, 202}, - {0x800a, 202}, - {0x800f, 202}, - {0x8018, 202}, - {0x801f, 202}, - {0x8029, 202}, - {0xc038, 202}, - {0x8003, 205}, - {0x8006, 205}, - {0x800a, 205}, - {0x800f, 205}, - {0x8018, 205}, - {0x801f, 205}, - {0x8029, 205}, - {0xc038, 205}, - }, - /* 198 */ - { - {0x8003, 210}, - {0x8006, 210}, - {0x800a, 210}, - {0x800f, 210}, - {0x8018, 210}, - {0x801f, 210}, - {0x8029, 210}, - {0xc038, 210}, - {0x8003, 213}, - {0x8006, 213}, - {0x800a, 213}, - {0x800f, 213}, - {0x8018, 213}, - {0x801f, 213}, - {0x8029, 213}, - {0xc038, 213}, - }, - /* 199 */ - { - {0x8001, 218}, - {0xc016, 218}, - {0x8001, 219}, - {0xc016, 219}, - {0x8001, 238}, - {0xc016, 238}, - {0x8001, 240}, - {0xc016, 240}, - {0x8001, 242}, - {0xc016, 242}, - {0x8001, 243}, - {0xc016, 243}, - {0x8001, 255}, - {0xc016, 255}, - {0xc000, 203}, - {0xc000, 204}, - }, - /* 200 */ - { - {0x8002, 218}, - {0x8009, 218}, - {0x8017, 218}, - {0xc028, 218}, - {0x8002, 219}, - {0x8009, 219}, - {0x8017, 219}, - {0xc028, 219}, - {0x8002, 238}, - {0x8009, 238}, - {0x8017, 238}, - {0xc028, 238}, - {0x8002, 240}, - {0x8009, 240}, - {0x8017, 240}, - {0xc028, 240}, - }, - /* 201 */ - { - {0x8003, 218}, - {0x8006, 218}, - {0x800a, 218}, - {0x800f, 218}, - {0x8018, 218}, - {0x801f, 218}, - {0x8029, 218}, - {0xc038, 218}, - {0x8003, 219}, - {0x8006, 219}, - {0x800a, 219}, - {0x800f, 219}, - {0x8018, 219}, - {0x801f, 219}, - {0x8029, 219}, - {0xc038, 219}, - }, - /* 202 */ - { - {0x8003, 238}, - {0x8006, 238}, - {0x800a, 238}, - {0x800f, 238}, - {0x8018, 238}, - {0x801f, 238}, - {0x8029, 238}, - {0xc038, 238}, - {0x8003, 240}, - {0x8006, 240}, - {0x800a, 240}, - {0x800f, 240}, - {0x8018, 240}, - {0x801f, 240}, - {0x8029, 240}, - {0xc038, 240}, - }, - /* 203 */ - { - {0x8002, 242}, - {0x8009, 242}, - {0x8017, 242}, - {0xc028, 242}, - {0x8002, 243}, - {0x8009, 243}, - {0x8017, 243}, - {0xc028, 243}, - {0x8002, 255}, - {0x8009, 255}, - {0x8017, 255}, - {0xc028, 255}, - {0x8001, 203}, - {0xc016, 203}, - {0x8001, 204}, - {0xc016, 204}, - }, - /* 204 */ - { - {0x8003, 242}, - {0x8006, 242}, - {0x800a, 242}, - {0x800f, 242}, - {0x8018, 242}, - {0x801f, 242}, - {0x8029, 242}, - {0xc038, 242}, - {0x8003, 243}, - {0x8006, 243}, - {0x800a, 243}, - {0x800f, 243}, - {0x8018, 243}, - {0x801f, 243}, - {0x8029, 243}, - {0xc038, 243}, - }, - /* 205 */ - { - {0x8003, 255}, - {0x8006, 255}, - {0x800a, 255}, - {0x800f, 255}, - {0x8018, 255}, - {0x801f, 255}, - {0x8029, 255}, - {0xc038, 255}, - {0x8002, 203}, - {0x8009, 203}, - {0x8017, 203}, - {0xc028, 203}, - {0x8002, 204}, - {0x8009, 204}, - {0x8017, 204}, - {0xc028, 204}, - }, - /* 206 */ - { - {0x8003, 203}, - {0x8006, 203}, - {0x800a, 203}, - {0x800f, 203}, - {0x8018, 203}, - {0x801f, 203}, - {0x8029, 203}, - {0xc038, 203}, - {0x8003, 204}, - {0x8006, 204}, - {0x800a, 204}, - {0x800f, 204}, - {0x8018, 204}, - {0x801f, 204}, - {0x8029, 204}, - {0xc038, 204}, - }, - /* 207 */ - { - {0xd3, 0}, - {0xd4, 0}, - {0xd6, 0}, - {0xd7, 0}, - {0xda, 0}, - {0xdb, 0}, - {0xdd, 0}, - {0xde, 0}, - {0xe2, 0}, - {0xe4, 0}, - {0xe8, 0}, - {0xeb, 0}, - {0xf0, 0}, - {0xf3, 0}, - {0xf7, 0}, - {0xfa, 0}, - }, - /* 208 */ - { - {0xc000, 211}, - {0xc000, 212}, - {0xc000, 214}, - {0xc000, 221}, - {0xc000, 222}, - {0xc000, 223}, - {0xc000, 241}, - {0xc000, 244}, - {0xc000, 245}, - {0xc000, 246}, - {0xc000, 247}, - {0xc000, 248}, - {0xc000, 250}, - {0xc000, 251}, - {0xc000, 252}, - {0xc000, 253}, - }, - /* 209 */ - { - {0x8001, 211}, - {0xc016, 211}, - {0x8001, 212}, - {0xc016, 212}, - {0x8001, 214}, - {0xc016, 214}, - {0x8001, 221}, - {0xc016, 221}, - {0x8001, 222}, - {0xc016, 222}, - {0x8001, 223}, - {0xc016, 223}, - {0x8001, 241}, - {0xc016, 241}, - {0x8001, 244}, - {0xc016, 244}, - }, - /* 210 */ - { - {0x8002, 211}, - {0x8009, 211}, - {0x8017, 211}, - {0xc028, 211}, - {0x8002, 212}, - {0x8009, 212}, - {0x8017, 212}, - {0xc028, 212}, - {0x8002, 214}, - {0x8009, 214}, - {0x8017, 214}, - {0xc028, 214}, - {0x8002, 221}, - {0x8009, 221}, - {0x8017, 221}, - {0xc028, 221}, - }, - /* 211 */ - { - {0x8003, 211}, - {0x8006, 211}, - {0x800a, 211}, - {0x800f, 211}, - {0x8018, 211}, - {0x801f, 211}, - {0x8029, 211}, - {0xc038, 211}, - {0x8003, 212}, - {0x8006, 212}, - {0x800a, 212}, - {0x800f, 212}, - {0x8018, 212}, - {0x801f, 212}, - {0x8029, 212}, - {0xc038, 212}, - }, - /* 212 */ - { - {0x8003, 214}, - {0x8006, 214}, - {0x800a, 214}, - {0x800f, 214}, - {0x8018, 214}, - {0x801f, 214}, - {0x8029, 214}, - {0xc038, 214}, - {0x8003, 221}, - {0x8006, 221}, - {0x800a, 221}, - {0x800f, 221}, - {0x8018, 221}, - {0x801f, 221}, - {0x8029, 221}, - {0xc038, 221}, - }, - /* 213 */ - { - {0x8002, 222}, - {0x8009, 222}, - {0x8017, 222}, - {0xc028, 222}, - {0x8002, 223}, - {0x8009, 223}, - {0x8017, 223}, - {0xc028, 223}, - {0x8002, 241}, - {0x8009, 241}, - {0x8017, 241}, - {0xc028, 241}, - {0x8002, 244}, - {0x8009, 244}, - {0x8017, 244}, - {0xc028, 244}, - }, - /* 214 */ - { - {0x8003, 222}, - {0x8006, 222}, - {0x800a, 222}, - {0x800f, 222}, - {0x8018, 222}, - {0x801f, 222}, - {0x8029, 222}, - {0xc038, 222}, - {0x8003, 223}, - {0x8006, 223}, - {0x800a, 223}, - {0x800f, 223}, - {0x8018, 223}, - {0x801f, 223}, - {0x8029, 223}, - {0xc038, 223}, - }, - /* 215 */ - { - {0x8003, 241}, - {0x8006, 241}, - {0x800a, 241}, - {0x800f, 241}, - {0x8018, 241}, - {0x801f, 241}, - {0x8029, 241}, - {0xc038, 241}, - {0x8003, 244}, - {0x8006, 244}, - {0x800a, 244}, - {0x800f, 244}, - {0x8018, 244}, - {0x801f, 244}, - {0x8029, 244}, - {0xc038, 244}, - }, - /* 216 */ - { - {0x8001, 245}, - {0xc016, 245}, - {0x8001, 246}, - {0xc016, 246}, - {0x8001, 247}, - {0xc016, 247}, - {0x8001, 248}, - {0xc016, 248}, - {0x8001, 250}, - {0xc016, 250}, - {0x8001, 251}, - {0xc016, 251}, - {0x8001, 252}, - {0xc016, 252}, - {0x8001, 253}, - {0xc016, 253}, - }, - /* 217 */ - { - {0x8002, 245}, - {0x8009, 245}, - {0x8017, 245}, - {0xc028, 245}, - {0x8002, 246}, - {0x8009, 246}, - {0x8017, 246}, - {0xc028, 246}, - {0x8002, 247}, - {0x8009, 247}, - {0x8017, 247}, - {0xc028, 247}, - {0x8002, 248}, - {0x8009, 248}, - {0x8017, 248}, - {0xc028, 248}, - }, - /* 218 */ - { - {0x8003, 245}, - {0x8006, 245}, - {0x800a, 245}, - {0x800f, 245}, - {0x8018, 245}, - {0x801f, 245}, - {0x8029, 245}, - {0xc038, 245}, - {0x8003, 246}, - {0x8006, 246}, - {0x800a, 246}, - {0x800f, 246}, - {0x8018, 246}, - {0x801f, 246}, - {0x8029, 246}, - {0xc038, 246}, - }, - /* 219 */ - { - {0x8003, 247}, - {0x8006, 247}, - {0x800a, 247}, - {0x800f, 247}, - {0x8018, 247}, - {0x801f, 247}, - {0x8029, 247}, - {0xc038, 247}, - {0x8003, 248}, - {0x8006, 248}, - {0x800a, 248}, - {0x800f, 248}, - {0x8018, 248}, - {0x801f, 248}, - {0x8029, 248}, - {0xc038, 248}, - }, - /* 220 */ - { - {0x8002, 250}, - {0x8009, 250}, - {0x8017, 250}, - {0xc028, 250}, - {0x8002, 251}, - {0x8009, 251}, - {0x8017, 251}, - {0xc028, 251}, - {0x8002, 252}, - {0x8009, 252}, - {0x8017, 252}, - {0xc028, 252}, - {0x8002, 253}, - {0x8009, 253}, - {0x8017, 253}, - {0xc028, 253}, - }, - /* 221 */ - { - {0x8003, 250}, - {0x8006, 250}, - {0x800a, 250}, - {0x800f, 250}, - {0x8018, 250}, - {0x801f, 250}, - {0x8029, 250}, - {0xc038, 250}, - {0x8003, 251}, - {0x8006, 251}, - {0x800a, 251}, - {0x800f, 251}, - {0x8018, 251}, - {0x801f, 251}, - {0x8029, 251}, - {0xc038, 251}, - }, - /* 222 */ - { - {0x8003, 252}, - {0x8006, 252}, - {0x800a, 252}, - {0x800f, 252}, - {0x8018, 252}, - {0x801f, 252}, - {0x8029, 252}, - {0xc038, 252}, - {0x8003, 253}, - {0x8006, 253}, - {0x800a, 253}, - {0x800f, 253}, - {0x8018, 253}, - {0x801f, 253}, - {0x8029, 253}, - {0xc038, 253}, - }, - /* 223 */ - { - {0xc000, 254}, - {0xe3, 0}, - {0xe5, 0}, - {0xe6, 0}, - {0xe9, 0}, - {0xea, 0}, - {0xec, 0}, - {0xed, 0}, - {0xf1, 0}, - {0xf2, 0}, - {0xf4, 0}, - {0xf5, 0}, - {0xf8, 0}, - {0xf9, 0}, - {0xfb, 0}, - {0xfc, 0}, - }, - /* 224 */ - { - {0x8001, 254}, - {0xc016, 254}, - {0xc000, 2}, - {0xc000, 3}, - {0xc000, 4}, - {0xc000, 5}, - {0xc000, 6}, - {0xc000, 7}, - {0xc000, 8}, - {0xc000, 11}, - {0xc000, 12}, - {0xc000, 14}, - {0xc000, 15}, - {0xc000, 16}, - {0xc000, 17}, - {0xc000, 18}, - }, - /* 225 */ - { - {0x8002, 254}, - {0x8009, 254}, - {0x8017, 254}, - {0xc028, 254}, - {0x8001, 2}, - {0xc016, 2}, - {0x8001, 3}, - {0xc016, 3}, - {0x8001, 4}, - {0xc016, 4}, - {0x8001, 5}, - {0xc016, 5}, - {0x8001, 6}, - {0xc016, 6}, - {0x8001, 7}, - {0xc016, 7}, - }, - /* 226 */ - { - {0x8003, 254}, - {0x8006, 254}, - {0x800a, 254}, - {0x800f, 254}, - {0x8018, 254}, - {0x801f, 254}, - {0x8029, 254}, - {0xc038, 254}, - {0x8002, 2}, - {0x8009, 2}, - {0x8017, 2}, - {0xc028, 2}, - {0x8002, 3}, - {0x8009, 3}, - {0x8017, 3}, - {0xc028, 3}, - }, - /* 227 */ - { - {0x8003, 2}, - {0x8006, 2}, - {0x800a, 2}, - {0x800f, 2}, - {0x8018, 2}, - {0x801f, 2}, - {0x8029, 2}, - {0xc038, 2}, - {0x8003, 3}, - {0x8006, 3}, - {0x800a, 3}, - {0x800f, 3}, - {0x8018, 3}, - {0x801f, 3}, - {0x8029, 3}, - {0xc038, 3}, - }, - /* 228 */ - { - {0x8002, 4}, - {0x8009, 4}, - {0x8017, 4}, - {0xc028, 4}, - {0x8002, 5}, - {0x8009, 5}, - {0x8017, 5}, - {0xc028, 5}, - {0x8002, 6}, - {0x8009, 6}, - {0x8017, 6}, - {0xc028, 6}, - {0x8002, 7}, - {0x8009, 7}, - {0x8017, 7}, - {0xc028, 7}, - }, - /* 229 */ - { - {0x8003, 4}, - {0x8006, 4}, - {0x800a, 4}, - {0x800f, 4}, - {0x8018, 4}, - {0x801f, 4}, - {0x8029, 4}, - {0xc038, 4}, - {0x8003, 5}, - {0x8006, 5}, - {0x800a, 5}, - {0x800f, 5}, - {0x8018, 5}, - {0x801f, 5}, - {0x8029, 5}, - {0xc038, 5}, - }, - /* 230 */ - { - {0x8003, 6}, - {0x8006, 6}, - {0x800a, 6}, - {0x800f, 6}, - {0x8018, 6}, - {0x801f, 6}, - {0x8029, 6}, - {0xc038, 6}, - {0x8003, 7}, - {0x8006, 7}, - {0x800a, 7}, - {0x800f, 7}, - {0x8018, 7}, - {0x801f, 7}, - {0x8029, 7}, - {0xc038, 7}, - }, - /* 231 */ - { - {0x8001, 8}, - {0xc016, 8}, - {0x8001, 11}, - {0xc016, 11}, - {0x8001, 12}, - {0xc016, 12}, - {0x8001, 14}, - {0xc016, 14}, - {0x8001, 15}, - {0xc016, 15}, - {0x8001, 16}, - {0xc016, 16}, - {0x8001, 17}, - {0xc016, 17}, - {0x8001, 18}, - {0xc016, 18}, - }, - /* 232 */ - { - {0x8002, 8}, - {0x8009, 8}, - {0x8017, 8}, - {0xc028, 8}, - {0x8002, 11}, - {0x8009, 11}, - {0x8017, 11}, - {0xc028, 11}, - {0x8002, 12}, - {0x8009, 12}, - {0x8017, 12}, - {0xc028, 12}, - {0x8002, 14}, - {0x8009, 14}, - {0x8017, 14}, - {0xc028, 14}, - }, - /* 233 */ - { - {0x8003, 8}, - {0x8006, 8}, - {0x800a, 8}, - {0x800f, 8}, - {0x8018, 8}, - {0x801f, 8}, - {0x8029, 8}, - {0xc038, 8}, - {0x8003, 11}, - {0x8006, 11}, - {0x800a, 11}, - {0x800f, 11}, - {0x8018, 11}, - {0x801f, 11}, - {0x8029, 11}, - {0xc038, 11}, - }, - /* 234 */ - { - {0x8003, 12}, - {0x8006, 12}, - {0x800a, 12}, - {0x800f, 12}, - {0x8018, 12}, - {0x801f, 12}, - {0x8029, 12}, - {0xc038, 12}, - {0x8003, 14}, - {0x8006, 14}, - {0x800a, 14}, - {0x800f, 14}, - {0x8018, 14}, - {0x801f, 14}, - {0x8029, 14}, - {0xc038, 14}, - }, - /* 235 */ - { - {0x8002, 15}, - {0x8009, 15}, - {0x8017, 15}, - {0xc028, 15}, - {0x8002, 16}, - {0x8009, 16}, - {0x8017, 16}, - {0xc028, 16}, - {0x8002, 17}, - {0x8009, 17}, - {0x8017, 17}, - {0xc028, 17}, - {0x8002, 18}, - {0x8009, 18}, - {0x8017, 18}, - {0xc028, 18}, - }, - /* 236 */ - { - {0x8003, 15}, - {0x8006, 15}, - {0x800a, 15}, - {0x800f, 15}, - {0x8018, 15}, - {0x801f, 15}, - {0x8029, 15}, - {0xc038, 15}, - {0x8003, 16}, - {0x8006, 16}, - {0x800a, 16}, - {0x800f, 16}, - {0x8018, 16}, - {0x801f, 16}, - {0x8029, 16}, - {0xc038, 16}, - }, - /* 237 */ - { - {0x8003, 17}, - {0x8006, 17}, - {0x800a, 17}, - {0x800f, 17}, - {0x8018, 17}, - {0x801f, 17}, - {0x8029, 17}, - {0xc038, 17}, - {0x8003, 18}, - {0x8006, 18}, - {0x800a, 18}, - {0x800f, 18}, - {0x8018, 18}, - {0x801f, 18}, - {0x8029, 18}, - {0xc038, 18}, - }, - /* 238 */ - { - {0xc000, 19}, - {0xc000, 20}, - {0xc000, 21}, - {0xc000, 23}, - {0xc000, 24}, - {0xc000, 25}, - {0xc000, 26}, - {0xc000, 27}, - {0xc000, 28}, - {0xc000, 29}, - {0xc000, 30}, - {0xc000, 31}, - {0xc000, 127}, - {0xc000, 220}, - {0xc000, 249}, - {0xfd, 0}, - }, - /* 239 */ - { - {0x8001, 19}, - {0xc016, 19}, - {0x8001, 20}, - {0xc016, 20}, - {0x8001, 21}, - {0xc016, 21}, - {0x8001, 23}, - {0xc016, 23}, - {0x8001, 24}, - {0xc016, 24}, - {0x8001, 25}, - {0xc016, 25}, - {0x8001, 26}, - {0xc016, 26}, - {0x8001, 27}, - {0xc016, 27}, - }, - /* 240 */ - { - {0x8002, 19}, - {0x8009, 19}, - {0x8017, 19}, - {0xc028, 19}, - {0x8002, 20}, - {0x8009, 20}, - {0x8017, 20}, - {0xc028, 20}, - {0x8002, 21}, - {0x8009, 21}, - {0x8017, 21}, - {0xc028, 21}, - {0x8002, 23}, - {0x8009, 23}, - {0x8017, 23}, - {0xc028, 23}, - }, - /* 241 */ - { - {0x8003, 19}, - {0x8006, 19}, - {0x800a, 19}, - {0x800f, 19}, - {0x8018, 19}, - {0x801f, 19}, - {0x8029, 19}, - {0xc038, 19}, - {0x8003, 20}, - {0x8006, 20}, - {0x800a, 20}, - {0x800f, 20}, - {0x8018, 20}, - {0x801f, 20}, - {0x8029, 20}, - {0xc038, 20}, - }, - /* 242 */ - { - {0x8003, 21}, - {0x8006, 21}, - {0x800a, 21}, - {0x800f, 21}, - {0x8018, 21}, - {0x801f, 21}, - {0x8029, 21}, - {0xc038, 21}, - {0x8003, 23}, - {0x8006, 23}, - {0x800a, 23}, - {0x800f, 23}, - {0x8018, 23}, - {0x801f, 23}, - {0x8029, 23}, - {0xc038, 23}, - }, - /* 243 */ - { - {0x8002, 24}, - {0x8009, 24}, - {0x8017, 24}, - {0xc028, 24}, - {0x8002, 25}, - {0x8009, 25}, - {0x8017, 25}, - {0xc028, 25}, - {0x8002, 26}, - {0x8009, 26}, - {0x8017, 26}, - {0xc028, 26}, - {0x8002, 27}, - {0x8009, 27}, - {0x8017, 27}, - {0xc028, 27}, - }, - /* 244 */ - { - {0x8003, 24}, - {0x8006, 24}, - {0x800a, 24}, - {0x800f, 24}, - {0x8018, 24}, - {0x801f, 24}, - {0x8029, 24}, - {0xc038, 24}, - {0x8003, 25}, - {0x8006, 25}, - {0x800a, 25}, - {0x800f, 25}, - {0x8018, 25}, - {0x801f, 25}, - {0x8029, 25}, - {0xc038, 25}, - }, - /* 245 */ - { - {0x8003, 26}, - {0x8006, 26}, - {0x800a, 26}, - {0x800f, 26}, - {0x8018, 26}, - {0x801f, 26}, - {0x8029, 26}, - {0xc038, 26}, - {0x8003, 27}, - {0x8006, 27}, - {0x800a, 27}, - {0x800f, 27}, - {0x8018, 27}, - {0x801f, 27}, - {0x8029, 27}, - {0xc038, 27}, - }, - /* 246 */ - { - {0x8001, 28}, - {0xc016, 28}, - {0x8001, 29}, - {0xc016, 29}, - {0x8001, 30}, - {0xc016, 30}, - {0x8001, 31}, - {0xc016, 31}, - {0x8001, 127}, - {0xc016, 127}, - {0x8001, 220}, - {0xc016, 220}, - {0x8001, 249}, - {0xc016, 249}, - {0xfe, 0}, - {0xff, 0}, - }, - /* 247 */ - { - {0x8002, 28}, - {0x8009, 28}, - {0x8017, 28}, - {0xc028, 28}, - {0x8002, 29}, - {0x8009, 29}, - {0x8017, 29}, - {0xc028, 29}, - {0x8002, 30}, - {0x8009, 30}, - {0x8017, 30}, - {0xc028, 30}, - {0x8002, 31}, - {0x8009, 31}, - {0x8017, 31}, - {0xc028, 31}, - }, - /* 248 */ - { - {0x8003, 28}, - {0x8006, 28}, - {0x800a, 28}, - {0x800f, 28}, - {0x8018, 28}, - {0x801f, 28}, - {0x8029, 28}, - {0xc038, 28}, - {0x8003, 29}, - {0x8006, 29}, - {0x800a, 29}, - {0x800f, 29}, - {0x8018, 29}, - {0x801f, 29}, - {0x8029, 29}, - {0xc038, 29}, - }, - /* 249 */ - { - {0x8003, 30}, - {0x8006, 30}, - {0x800a, 30}, - {0x800f, 30}, - {0x8018, 30}, - {0x801f, 30}, - {0x8029, 30}, - {0xc038, 30}, - {0x8003, 31}, - {0x8006, 31}, - {0x800a, 31}, - {0x800f, 31}, - {0x8018, 31}, - {0x801f, 31}, - {0x8029, 31}, - {0xc038, 31}, - }, - /* 250 */ - { - {0x8002, 127}, - {0x8009, 127}, - {0x8017, 127}, - {0xc028, 127}, - {0x8002, 220}, - {0x8009, 220}, - {0x8017, 220}, - {0xc028, 220}, - {0x8002, 249}, - {0x8009, 249}, - {0x8017, 249}, - {0xc028, 249}, - {0xc000, 10}, - {0xc000, 13}, - {0xc000, 22}, - {0x100, 0}, - }, - /* 251 */ - { - {0x8003, 127}, - {0x8006, 127}, - {0x800a, 127}, - {0x800f, 127}, - {0x8018, 127}, - {0x801f, 127}, - {0x8029, 127}, - {0xc038, 127}, - {0x8003, 220}, - {0x8006, 220}, - {0x800a, 220}, - {0x800f, 220}, - {0x8018, 220}, - {0x801f, 220}, - {0x8029, 220}, - {0xc038, 220}, - }, - /* 252 */ - { - {0x8003, 249}, - {0x8006, 249}, - {0x800a, 249}, - {0x800f, 249}, - {0x8018, 249}, - {0x801f, 249}, - {0x8029, 249}, - {0xc038, 249}, - {0x8001, 10}, - {0xc016, 10}, - {0x8001, 13}, - {0xc016, 13}, - {0x8001, 22}, - {0xc016, 22}, - {0x100, 0}, - {0x100, 0}, - }, - /* 253 */ - { - {0x8002, 10}, - {0x8009, 10}, - {0x8017, 10}, - {0xc028, 10}, - {0x8002, 13}, - {0x8009, 13}, - {0x8017, 13}, - {0xc028, 13}, - {0x8002, 22}, - {0x8009, 22}, - {0x8017, 22}, - {0xc028, 22}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - }, - /* 254 */ - { - {0x8003, 10}, - {0x8006, 10}, - {0x800a, 10}, - {0x800f, 10}, - {0x8018, 10}, - {0x801f, 10}, - {0x8029, 10}, - {0xc038, 10}, - {0x8003, 13}, - {0x8006, 13}, - {0x800a, 13}, - {0x800f, 13}, - {0x8018, 13}, - {0x801f, 13}, - {0x8029, 13}, - {0xc038, 13}, - }, - /* 255 */ - { - {0x8003, 22}, - {0x8006, 22}, - {0x800a, 22}, - {0x800f, 22}, - {0x8018, 22}, - {0x801f, 22}, - {0x8029, 22}, - {0xc038, 22}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - }, - /* 256 */ - { - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - }, + /* 0 */ + { + {0x04, 0}, + {0x05, 0}, + {0x07, 0}, + {0x08, 0}, + {0x0b, 0}, + {0x0c, 0}, + {0x10, 0}, + {0x13, 0}, + {0x19, 0}, + {0x1c, 0}, + {0x20, 0}, + {0x23, 0}, + {0x2a, 0}, + {0x31, 0}, + {0x39, 0}, + {0x4040, 0}, + }, + /* 1 */ + { + {0xc000, 48}, + {0xc000, 49}, + {0xc000, 50}, + {0xc000, 97}, + {0xc000, 99}, + {0xc000, 101}, + {0xc000, 105}, + {0xc000, 111}, + {0xc000, 115}, + {0xc000, 116}, + {0x0d, 0}, + {0x0e, 0}, + {0x11, 0}, + {0x12, 0}, + {0x14, 0}, + {0x15, 0}, + }, + /* 2 */ + { + {0x8001, 48}, + {0xc016, 48}, + {0x8001, 49}, + {0xc016, 49}, + {0x8001, 50}, + {0xc016, 50}, + {0x8001, 97}, + {0xc016, 97}, + {0x8001, 99}, + {0xc016, 99}, + {0x8001, 101}, + {0xc016, 101}, + {0x8001, 105}, + {0xc016, 105}, + {0x8001, 111}, + {0xc016, 111}, + }, + /* 3 */ + { + {0x8002, 48}, + {0x8009, 48}, + {0x8017, 48}, + {0xc028, 48}, + {0x8002, 49}, + {0x8009, 49}, + {0x8017, 49}, + {0xc028, 49}, + {0x8002, 50}, + {0x8009, 50}, + {0x8017, 50}, + {0xc028, 50}, + {0x8002, 97}, + {0x8009, 97}, + {0x8017, 97}, + {0xc028, 97}, + }, + /* 4 */ + { + {0x8003, 48}, + {0x8006, 48}, + {0x800a, 48}, + {0x800f, 48}, + {0x8018, 48}, + {0x801f, 48}, + {0x8029, 48}, + {0xc038, 48}, + {0x8003, 49}, + {0x8006, 49}, + {0x800a, 49}, + {0x800f, 49}, + {0x8018, 49}, + {0x801f, 49}, + {0x8029, 49}, + {0xc038, 49}, + }, + /* 5 */ + { + {0x8003, 50}, + {0x8006, 50}, + {0x800a, 50}, + {0x800f, 50}, + {0x8018, 50}, + {0x801f, 50}, + {0x8029, 50}, + {0xc038, 50}, + {0x8003, 97}, + {0x8006, 97}, + {0x800a, 97}, + {0x800f, 97}, + {0x8018, 97}, + {0x801f, 97}, + {0x8029, 97}, + {0xc038, 97}, + }, + /* 6 */ + { + {0x8002, 99}, + {0x8009, 99}, + {0x8017, 99}, + {0xc028, 99}, + {0x8002, 101}, + {0x8009, 101}, + {0x8017, 101}, + {0xc028, 101}, + {0x8002, 105}, + {0x8009, 105}, + {0x8017, 105}, + {0xc028, 105}, + {0x8002, 111}, + {0x8009, 111}, + {0x8017, 111}, + {0xc028, 111}, + }, + /* 7 */ + { + {0x8003, 99}, + {0x8006, 99}, + {0x800a, 99}, + {0x800f, 99}, + {0x8018, 99}, + {0x801f, 99}, + {0x8029, 99}, + {0xc038, 99}, + {0x8003, 101}, + {0x8006, 101}, + {0x800a, 101}, + {0x800f, 101}, + {0x8018, 101}, + {0x801f, 101}, + {0x8029, 101}, + {0xc038, 101}, + }, + /* 8 */ + { + {0x8003, 105}, + {0x8006, 105}, + {0x800a, 105}, + {0x800f, 105}, + {0x8018, 105}, + {0x801f, 105}, + {0x8029, 105}, + {0xc038, 105}, + {0x8003, 111}, + {0x8006, 111}, + {0x800a, 111}, + {0x800f, 111}, + {0x8018, 111}, + {0x801f, 111}, + {0x8029, 111}, + {0xc038, 111}, + }, + /* 9 */ + { + {0x8001, 115}, + {0xc016, 115}, + {0x8001, 116}, + {0xc016, 116}, + {0xc000, 32}, + {0xc000, 37}, + {0xc000, 45}, + {0xc000, 46}, + {0xc000, 47}, + {0xc000, 51}, + {0xc000, 52}, + {0xc000, 53}, + {0xc000, 54}, + {0xc000, 55}, + {0xc000, 56}, + {0xc000, 57}, + }, + /* 10 */ + { + {0x8002, 115}, + {0x8009, 115}, + {0x8017, 115}, + {0xc028, 115}, + {0x8002, 116}, + {0x8009, 116}, + {0x8017, 116}, + {0xc028, 116}, + {0x8001, 32}, + {0xc016, 32}, + {0x8001, 37}, + {0xc016, 37}, + {0x8001, 45}, + {0xc016, 45}, + {0x8001, 46}, + {0xc016, 46}, + }, + /* 11 */ + { + {0x8003, 115}, + {0x8006, 115}, + {0x800a, 115}, + {0x800f, 115}, + {0x8018, 115}, + {0x801f, 115}, + {0x8029, 115}, + {0xc038, 115}, + {0x8003, 116}, + {0x8006, 116}, + {0x800a, 116}, + {0x800f, 116}, + {0x8018, 116}, + {0x801f, 116}, + {0x8029, 116}, + {0xc038, 116}, + }, + /* 12 */ + { + {0x8002, 32}, + {0x8009, 32}, + {0x8017, 32}, + {0xc028, 32}, + {0x8002, 37}, + {0x8009, 37}, + {0x8017, 37}, + {0xc028, 37}, + {0x8002, 45}, + {0x8009, 45}, + {0x8017, 45}, + {0xc028, 45}, + {0x8002, 46}, + {0x8009, 46}, + {0x8017, 46}, + {0xc028, 46}, + }, + /* 13 */ + { + {0x8003, 32}, + {0x8006, 32}, + {0x800a, 32}, + {0x800f, 32}, + {0x8018, 32}, + {0x801f, 32}, + {0x8029, 32}, + {0xc038, 32}, + {0x8003, 37}, + {0x8006, 37}, + {0x800a, 37}, + {0x800f, 37}, + {0x8018, 37}, + {0x801f, 37}, + {0x8029, 37}, + {0xc038, 37}, + }, + /* 14 */ + { + {0x8003, 45}, + {0x8006, 45}, + {0x800a, 45}, + {0x800f, 45}, + {0x8018, 45}, + {0x801f, 45}, + {0x8029, 45}, + {0xc038, 45}, + {0x8003, 46}, + {0x8006, 46}, + {0x800a, 46}, + {0x800f, 46}, + {0x8018, 46}, + {0x801f, 46}, + {0x8029, 46}, + {0xc038, 46}, + }, + /* 15 */ + { + {0x8001, 47}, + {0xc016, 47}, + {0x8001, 51}, + {0xc016, 51}, + {0x8001, 52}, + {0xc016, 52}, + {0x8001, 53}, + {0xc016, 53}, + {0x8001, 54}, + {0xc016, 54}, + {0x8001, 55}, + {0xc016, 55}, + {0x8001, 56}, + {0xc016, 56}, + {0x8001, 57}, + {0xc016, 57}, + }, + /* 16 */ + { + {0x8002, 47}, + {0x8009, 47}, + {0x8017, 47}, + {0xc028, 47}, + {0x8002, 51}, + {0x8009, 51}, + {0x8017, 51}, + {0xc028, 51}, + {0x8002, 52}, + {0x8009, 52}, + {0x8017, 52}, + {0xc028, 52}, + {0x8002, 53}, + {0x8009, 53}, + {0x8017, 53}, + {0xc028, 53}, + }, + /* 17 */ + { + {0x8003, 47}, + {0x8006, 47}, + {0x800a, 47}, + {0x800f, 47}, + {0x8018, 47}, + {0x801f, 47}, + {0x8029, 47}, + {0xc038, 47}, + {0x8003, 51}, + {0x8006, 51}, + {0x800a, 51}, + {0x800f, 51}, + {0x8018, 51}, + {0x801f, 51}, + {0x8029, 51}, + {0xc038, 51}, + }, + /* 18 */ + { + {0x8003, 52}, + {0x8006, 52}, + {0x800a, 52}, + {0x800f, 52}, + {0x8018, 52}, + {0x801f, 52}, + {0x8029, 52}, + {0xc038, 52}, + {0x8003, 53}, + {0x8006, 53}, + {0x800a, 53}, + {0x800f, 53}, + {0x8018, 53}, + {0x801f, 53}, + {0x8029, 53}, + {0xc038, 53}, + }, + /* 19 */ + { + {0x8002, 54}, + {0x8009, 54}, + {0x8017, 54}, + {0xc028, 54}, + {0x8002, 55}, + {0x8009, 55}, + {0x8017, 55}, + {0xc028, 55}, + {0x8002, 56}, + {0x8009, 56}, + {0x8017, 56}, + {0xc028, 56}, + {0x8002, 57}, + {0x8009, 57}, + {0x8017, 57}, + {0xc028, 57}, + }, + /* 20 */ + { + {0x8003, 54}, + {0x8006, 54}, + {0x800a, 54}, + {0x800f, 54}, + {0x8018, 54}, + {0x801f, 54}, + {0x8029, 54}, + {0xc038, 54}, + {0x8003, 55}, + {0x8006, 55}, + {0x800a, 55}, + {0x800f, 55}, + {0x8018, 55}, + {0x801f, 55}, + {0x8029, 55}, + {0xc038, 55}, + }, + /* 21 */ + { + {0x8003, 56}, + {0x8006, 56}, + {0x800a, 56}, + {0x800f, 56}, + {0x8018, 56}, + {0x801f, 56}, + {0x8029, 56}, + {0xc038, 56}, + {0x8003, 57}, + {0x8006, 57}, + {0x800a, 57}, + {0x800f, 57}, + {0x8018, 57}, + {0x801f, 57}, + {0x8029, 57}, + {0xc038, 57}, + }, + /* 22 */ + { + {0x1a, 0}, + {0x1b, 0}, + {0x1d, 0}, + {0x1e, 0}, + {0x21, 0}, + {0x22, 0}, + {0x24, 0}, + {0x25, 0}, + {0x2b, 0}, + {0x2e, 0}, + {0x32, 0}, + {0x35, 0}, + {0x3a, 0}, + {0x3d, 0}, + {0x41, 0}, + {0x4044, 0}, + }, + /* 23 */ + { + {0xc000, 61}, + {0xc000, 65}, + {0xc000, 95}, + {0xc000, 98}, + {0xc000, 100}, + {0xc000, 102}, + {0xc000, 103}, + {0xc000, 104}, + {0xc000, 108}, + {0xc000, 109}, + {0xc000, 110}, + {0xc000, 112}, + {0xc000, 114}, + {0xc000, 117}, + {0x26, 0}, + {0x27, 0}, + }, + /* 24 */ + { + {0x8001, 61}, + {0xc016, 61}, + {0x8001, 65}, + {0xc016, 65}, + {0x8001, 95}, + {0xc016, 95}, + {0x8001, 98}, + {0xc016, 98}, + {0x8001, 100}, + {0xc016, 100}, + {0x8001, 102}, + {0xc016, 102}, + {0x8001, 103}, + {0xc016, 103}, + {0x8001, 104}, + {0xc016, 104}, + }, + /* 25 */ + { + {0x8002, 61}, + {0x8009, 61}, + {0x8017, 61}, + {0xc028, 61}, + {0x8002, 65}, + {0x8009, 65}, + {0x8017, 65}, + {0xc028, 65}, + {0x8002, 95}, + {0x8009, 95}, + {0x8017, 95}, + {0xc028, 95}, + {0x8002, 98}, + {0x8009, 98}, + {0x8017, 98}, + {0xc028, 98}, + }, + /* 26 */ + { + {0x8003, 61}, + {0x8006, 61}, + {0x800a, 61}, + {0x800f, 61}, + {0x8018, 61}, + {0x801f, 61}, + {0x8029, 61}, + {0xc038, 61}, + {0x8003, 65}, + {0x8006, 65}, + {0x800a, 65}, + {0x800f, 65}, + {0x8018, 65}, + {0x801f, 65}, + {0x8029, 65}, + {0xc038, 65}, + }, + /* 27 */ + { + {0x8003, 95}, + {0x8006, 95}, + {0x800a, 95}, + {0x800f, 95}, + {0x8018, 95}, + {0x801f, 95}, + {0x8029, 95}, + {0xc038, 95}, + {0x8003, 98}, + {0x8006, 98}, + {0x800a, 98}, + {0x800f, 98}, + {0x8018, 98}, + {0x801f, 98}, + {0x8029, 98}, + {0xc038, 98}, + }, + /* 28 */ + { + {0x8002, 100}, + {0x8009, 100}, + {0x8017, 100}, + {0xc028, 100}, + {0x8002, 102}, + {0x8009, 102}, + {0x8017, 102}, + {0xc028, 102}, + {0x8002, 103}, + {0x8009, 103}, + {0x8017, 103}, + {0xc028, 103}, + {0x8002, 104}, + {0x8009, 104}, + {0x8017, 104}, + {0xc028, 104}, + }, + /* 29 */ + { + {0x8003, 100}, + {0x8006, 100}, + {0x800a, 100}, + {0x800f, 100}, + {0x8018, 100}, + {0x801f, 100}, + {0x8029, 100}, + {0xc038, 100}, + {0x8003, 102}, + {0x8006, 102}, + {0x800a, 102}, + {0x800f, 102}, + {0x8018, 102}, + {0x801f, 102}, + {0x8029, 102}, + {0xc038, 102}, + }, + /* 30 */ + { + {0x8003, 103}, + {0x8006, 103}, + {0x800a, 103}, + {0x800f, 103}, + {0x8018, 103}, + {0x801f, 103}, + {0x8029, 103}, + {0xc038, 103}, + {0x8003, 104}, + {0x8006, 104}, + {0x800a, 104}, + {0x800f, 104}, + {0x8018, 104}, + {0x801f, 104}, + {0x8029, 104}, + {0xc038, 104}, + }, + /* 31 */ + { + {0x8001, 108}, + {0xc016, 108}, + {0x8001, 109}, + {0xc016, 109}, + {0x8001, 110}, + {0xc016, 110}, + {0x8001, 112}, + {0xc016, 112}, + {0x8001, 114}, + {0xc016, 114}, + {0x8001, 117}, + {0xc016, 117}, + {0xc000, 58}, + {0xc000, 66}, + {0xc000, 67}, + {0xc000, 68}, + }, + /* 32 */ + { + {0x8002, 108}, + {0x8009, 108}, + {0x8017, 108}, + {0xc028, 108}, + {0x8002, 109}, + {0x8009, 109}, + {0x8017, 109}, + {0xc028, 109}, + {0x8002, 110}, + {0x8009, 110}, + {0x8017, 110}, + {0xc028, 110}, + {0x8002, 112}, + {0x8009, 112}, + {0x8017, 112}, + {0xc028, 112}, + }, + /* 33 */ + { + {0x8003, 108}, + {0x8006, 108}, + {0x800a, 108}, + {0x800f, 108}, + {0x8018, 108}, + {0x801f, 108}, + {0x8029, 108}, + {0xc038, 108}, + {0x8003, 109}, + {0x8006, 109}, + {0x800a, 109}, + {0x800f, 109}, + {0x8018, 109}, + {0x801f, 109}, + {0x8029, 109}, + {0xc038, 109}, + }, + /* 34 */ + { + {0x8003, 110}, + {0x8006, 110}, + {0x800a, 110}, + {0x800f, 110}, + {0x8018, 110}, + {0x801f, 110}, + {0x8029, 110}, + {0xc038, 110}, + {0x8003, 112}, + {0x8006, 112}, + {0x800a, 112}, + {0x800f, 112}, + {0x8018, 112}, + {0x801f, 112}, + {0x8029, 112}, + {0xc038, 112}, + }, + /* 35 */ + { + {0x8002, 114}, + {0x8009, 114}, + {0x8017, 114}, + {0xc028, 114}, + {0x8002, 117}, + {0x8009, 117}, + {0x8017, 117}, + {0xc028, 117}, + {0x8001, 58}, + {0xc016, 58}, + {0x8001, 66}, + {0xc016, 66}, + {0x8001, 67}, + {0xc016, 67}, + {0x8001, 68}, + {0xc016, 68}, + }, + /* 36 */ + { + {0x8003, 114}, + {0x8006, 114}, + {0x800a, 114}, + {0x800f, 114}, + {0x8018, 114}, + {0x801f, 114}, + {0x8029, 114}, + {0xc038, 114}, + {0x8003, 117}, + {0x8006, 117}, + {0x800a, 117}, + {0x800f, 117}, + {0x8018, 117}, + {0x801f, 117}, + {0x8029, 117}, + {0xc038, 117}, + }, + /* 37 */ + { + {0x8002, 58}, + {0x8009, 58}, + {0x8017, 58}, + {0xc028, 58}, + {0x8002, 66}, + {0x8009, 66}, + {0x8017, 66}, + {0xc028, 66}, + {0x8002, 67}, + {0x8009, 67}, + {0x8017, 67}, + {0xc028, 67}, + {0x8002, 68}, + {0x8009, 68}, + {0x8017, 68}, + {0xc028, 68}, + }, + /* 38 */ + { + {0x8003, 58}, + {0x8006, 58}, + {0x800a, 58}, + {0x800f, 58}, + {0x8018, 58}, + {0x801f, 58}, + {0x8029, 58}, + {0xc038, 58}, + {0x8003, 66}, + {0x8006, 66}, + {0x800a, 66}, + {0x800f, 66}, + {0x8018, 66}, + {0x801f, 66}, + {0x8029, 66}, + {0xc038, 66}, + }, + /* 39 */ + { + {0x8003, 67}, + {0x8006, 67}, + {0x800a, 67}, + {0x800f, 67}, + {0x8018, 67}, + {0x801f, 67}, + {0x8029, 67}, + {0xc038, 67}, + {0x8003, 68}, + {0x8006, 68}, + {0x800a, 68}, + {0x800f, 68}, + {0x8018, 68}, + {0x801f, 68}, + {0x8029, 68}, + {0xc038, 68}, + }, + /* 40 */ + { + {0x2c, 0}, + {0x2d, 0}, + {0x2f, 0}, + {0x30, 0}, + {0x33, 0}, + {0x34, 0}, + {0x36, 0}, + {0x37, 0}, + {0x3b, 0}, + {0x3c, 0}, + {0x3e, 0}, + {0x3f, 0}, + {0x42, 0}, + {0x43, 0}, + {0x45, 0}, + {0x4048, 0}, + }, + /* 41 */ + { + {0xc000, 69}, + {0xc000, 70}, + {0xc000, 71}, + {0xc000, 72}, + {0xc000, 73}, + {0xc000, 74}, + {0xc000, 75}, + {0xc000, 76}, + {0xc000, 77}, + {0xc000, 78}, + {0xc000, 79}, + {0xc000, 80}, + {0xc000, 81}, + {0xc000, 82}, + {0xc000, 83}, + {0xc000, 84}, + }, + /* 42 */ + { + {0x8001, 69}, + {0xc016, 69}, + {0x8001, 70}, + {0xc016, 70}, + {0x8001, 71}, + {0xc016, 71}, + {0x8001, 72}, + {0xc016, 72}, + {0x8001, 73}, + {0xc016, 73}, + {0x8001, 74}, + {0xc016, 74}, + {0x8001, 75}, + {0xc016, 75}, + {0x8001, 76}, + {0xc016, 76}, + }, + /* 43 */ + { + {0x8002, 69}, + {0x8009, 69}, + {0x8017, 69}, + {0xc028, 69}, + {0x8002, 70}, + {0x8009, 70}, + {0x8017, 70}, + {0xc028, 70}, + {0x8002, 71}, + {0x8009, 71}, + {0x8017, 71}, + {0xc028, 71}, + {0x8002, 72}, + {0x8009, 72}, + {0x8017, 72}, + {0xc028, 72}, + }, + /* 44 */ + { + {0x8003, 69}, + {0x8006, 69}, + {0x800a, 69}, + {0x800f, 69}, + {0x8018, 69}, + {0x801f, 69}, + {0x8029, 69}, + {0xc038, 69}, + {0x8003, 70}, + {0x8006, 70}, + {0x800a, 70}, + {0x800f, 70}, + {0x8018, 70}, + {0x801f, 70}, + {0x8029, 70}, + {0xc038, 70}, + }, + /* 45 */ + { + {0x8003, 71}, + {0x8006, 71}, + {0x800a, 71}, + {0x800f, 71}, + {0x8018, 71}, + {0x801f, 71}, + {0x8029, 71}, + {0xc038, 71}, + {0x8003, 72}, + {0x8006, 72}, + {0x800a, 72}, + {0x800f, 72}, + {0x8018, 72}, + {0x801f, 72}, + {0x8029, 72}, + {0xc038, 72}, + }, + /* 46 */ + { + {0x8002, 73}, + {0x8009, 73}, + {0x8017, 73}, + {0xc028, 73}, + {0x8002, 74}, + {0x8009, 74}, + {0x8017, 74}, + {0xc028, 74}, + {0x8002, 75}, + {0x8009, 75}, + {0x8017, 75}, + {0xc028, 75}, + {0x8002, 76}, + {0x8009, 76}, + {0x8017, 76}, + {0xc028, 76}, + }, + /* 47 */ + { + {0x8003, 73}, + {0x8006, 73}, + {0x800a, 73}, + {0x800f, 73}, + {0x8018, 73}, + {0x801f, 73}, + {0x8029, 73}, + {0xc038, 73}, + {0x8003, 74}, + {0x8006, 74}, + {0x800a, 74}, + {0x800f, 74}, + {0x8018, 74}, + {0x801f, 74}, + {0x8029, 74}, + {0xc038, 74}, + }, + /* 48 */ + { + {0x8003, 75}, + {0x8006, 75}, + {0x800a, 75}, + {0x800f, 75}, + {0x8018, 75}, + {0x801f, 75}, + {0x8029, 75}, + {0xc038, 75}, + {0x8003, 76}, + {0x8006, 76}, + {0x800a, 76}, + {0x800f, 76}, + {0x8018, 76}, + {0x801f, 76}, + {0x8029, 76}, + {0xc038, 76}, + }, + /* 49 */ + { + {0x8001, 77}, + {0xc016, 77}, + {0x8001, 78}, + {0xc016, 78}, + {0x8001, 79}, + {0xc016, 79}, + {0x8001, 80}, + {0xc016, 80}, + {0x8001, 81}, + {0xc016, 81}, + {0x8001, 82}, + {0xc016, 82}, + {0x8001, 83}, + {0xc016, 83}, + {0x8001, 84}, + {0xc016, 84}, + }, + /* 50 */ + { + {0x8002, 77}, + {0x8009, 77}, + {0x8017, 77}, + {0xc028, 77}, + {0x8002, 78}, + {0x8009, 78}, + {0x8017, 78}, + {0xc028, 78}, + {0x8002, 79}, + {0x8009, 79}, + {0x8017, 79}, + {0xc028, 79}, + {0x8002, 80}, + {0x8009, 80}, + {0x8017, 80}, + {0xc028, 80}, + }, + /* 51 */ + { + {0x8003, 77}, + {0x8006, 77}, + {0x800a, 77}, + {0x800f, 77}, + {0x8018, 77}, + {0x801f, 77}, + {0x8029, 77}, + {0xc038, 77}, + {0x8003, 78}, + {0x8006, 78}, + {0x800a, 78}, + {0x800f, 78}, + {0x8018, 78}, + {0x801f, 78}, + {0x8029, 78}, + {0xc038, 78}, + }, + /* 52 */ + { + {0x8003, 79}, + {0x8006, 79}, + {0x800a, 79}, + {0x800f, 79}, + {0x8018, 79}, + {0x801f, 79}, + {0x8029, 79}, + {0xc038, 79}, + {0x8003, 80}, + {0x8006, 80}, + {0x800a, 80}, + {0x800f, 80}, + {0x8018, 80}, + {0x801f, 80}, + {0x8029, 80}, + {0xc038, 80}, + }, + /* 53 */ + { + {0x8002, 81}, + {0x8009, 81}, + {0x8017, 81}, + {0xc028, 81}, + {0x8002, 82}, + {0x8009, 82}, + {0x8017, 82}, + {0xc028, 82}, + {0x8002, 83}, + {0x8009, 83}, + {0x8017, 83}, + {0xc028, 83}, + {0x8002, 84}, + {0x8009, 84}, + {0x8017, 84}, + {0xc028, 84}, + }, + /* 54 */ + { + {0x8003, 81}, + {0x8006, 81}, + {0x800a, 81}, + {0x800f, 81}, + {0x8018, 81}, + {0x801f, 81}, + {0x8029, 81}, + {0xc038, 81}, + {0x8003, 82}, + {0x8006, 82}, + {0x800a, 82}, + {0x800f, 82}, + {0x8018, 82}, + {0x801f, 82}, + {0x8029, 82}, + {0xc038, 82}, + }, + /* 55 */ + { + {0x8003, 83}, + {0x8006, 83}, + {0x800a, 83}, + {0x800f, 83}, + {0x8018, 83}, + {0x801f, 83}, + {0x8029, 83}, + {0xc038, 83}, + {0x8003, 84}, + {0x8006, 84}, + {0x800a, 84}, + {0x800f, 84}, + {0x8018, 84}, + {0x801f, 84}, + {0x8029, 84}, + {0xc038, 84}, + }, + /* 56 */ + { + {0xc000, 85}, + {0xc000, 86}, + {0xc000, 87}, + {0xc000, 89}, + {0xc000, 106}, + {0xc000, 107}, + {0xc000, 113}, + {0xc000, 118}, + {0xc000, 119}, + {0xc000, 120}, + {0xc000, 121}, + {0xc000, 122}, + {0x46, 0}, + {0x47, 0}, + {0x49, 0}, + {0x404a, 0}, + }, + /* 57 */ + { + {0x8001, 85}, + {0xc016, 85}, + {0x8001, 86}, + {0xc016, 86}, + {0x8001, 87}, + {0xc016, 87}, + {0x8001, 89}, + {0xc016, 89}, + {0x8001, 106}, + {0xc016, 106}, + {0x8001, 107}, + {0xc016, 107}, + {0x8001, 113}, + {0xc016, 113}, + {0x8001, 118}, + {0xc016, 118}, + }, + /* 58 */ + { + {0x8002, 85}, + {0x8009, 85}, + {0x8017, 85}, + {0xc028, 85}, + {0x8002, 86}, + {0x8009, 86}, + {0x8017, 86}, + {0xc028, 86}, + {0x8002, 87}, + {0x8009, 87}, + {0x8017, 87}, + {0xc028, 87}, + {0x8002, 89}, + {0x8009, 89}, + {0x8017, 89}, + {0xc028, 89}, + }, + /* 59 */ + { + {0x8003, 85}, + {0x8006, 85}, + {0x800a, 85}, + {0x800f, 85}, + {0x8018, 85}, + {0x801f, 85}, + {0x8029, 85}, + {0xc038, 85}, + {0x8003, 86}, + {0x8006, 86}, + {0x800a, 86}, + {0x800f, 86}, + {0x8018, 86}, + {0x801f, 86}, + {0x8029, 86}, + {0xc038, 86}, + }, + /* 60 */ + { + {0x8003, 87}, + {0x8006, 87}, + {0x800a, 87}, + {0x800f, 87}, + {0x8018, 87}, + {0x801f, 87}, + {0x8029, 87}, + {0xc038, 87}, + {0x8003, 89}, + {0x8006, 89}, + {0x800a, 89}, + {0x800f, 89}, + {0x8018, 89}, + {0x801f, 89}, + {0x8029, 89}, + {0xc038, 89}, + }, + /* 61 */ + { + {0x8002, 106}, + {0x8009, 106}, + {0x8017, 106}, + {0xc028, 106}, + {0x8002, 107}, + {0x8009, 107}, + {0x8017, 107}, + {0xc028, 107}, + {0x8002, 113}, + {0x8009, 113}, + {0x8017, 113}, + {0xc028, 113}, + {0x8002, 118}, + {0x8009, 118}, + {0x8017, 118}, + {0xc028, 118}, + }, + /* 62 */ + { + {0x8003, 106}, + {0x8006, 106}, + {0x800a, 106}, + {0x800f, 106}, + {0x8018, 106}, + {0x801f, 106}, + {0x8029, 106}, + {0xc038, 106}, + {0x8003, 107}, + {0x8006, 107}, + {0x800a, 107}, + {0x800f, 107}, + {0x8018, 107}, + {0x801f, 107}, + {0x8029, 107}, + {0xc038, 107}, + }, + /* 63 */ + { + {0x8003, 113}, + {0x8006, 113}, + {0x800a, 113}, + {0x800f, 113}, + {0x8018, 113}, + {0x801f, 113}, + {0x8029, 113}, + {0xc038, 113}, + {0x8003, 118}, + {0x8006, 118}, + {0x800a, 118}, + {0x800f, 118}, + {0x8018, 118}, + {0x801f, 118}, + {0x8029, 118}, + {0xc038, 118}, + }, + /* 64 */ + { + {0x8001, 119}, + {0xc016, 119}, + {0x8001, 120}, + {0xc016, 120}, + {0x8001, 121}, + {0xc016, 121}, + {0x8001, 122}, + {0xc016, 122}, + {0xc000, 38}, + {0xc000, 42}, + {0xc000, 44}, + {0xc000, 59}, + {0xc000, 88}, + {0xc000, 90}, + {0x4b, 0}, + {0x4e, 0}, + }, + /* 65 */ + { + {0x8002, 119}, + {0x8009, 119}, + {0x8017, 119}, + {0xc028, 119}, + {0x8002, 120}, + {0x8009, 120}, + {0x8017, 120}, + {0xc028, 120}, + {0x8002, 121}, + {0x8009, 121}, + {0x8017, 121}, + {0xc028, 121}, + {0x8002, 122}, + {0x8009, 122}, + {0x8017, 122}, + {0xc028, 122}, + }, + /* 66 */ + { + {0x8003, 119}, + {0x8006, 119}, + {0x800a, 119}, + {0x800f, 119}, + {0x8018, 119}, + {0x801f, 119}, + {0x8029, 119}, + {0xc038, 119}, + {0x8003, 120}, + {0x8006, 120}, + {0x800a, 120}, + {0x800f, 120}, + {0x8018, 120}, + {0x801f, 120}, + {0x8029, 120}, + {0xc038, 120}, + }, + /* 67 */ + { + {0x8003, 121}, + {0x8006, 121}, + {0x800a, 121}, + {0x800f, 121}, + {0x8018, 121}, + {0x801f, 121}, + {0x8029, 121}, + {0xc038, 121}, + {0x8003, 122}, + {0x8006, 122}, + {0x800a, 122}, + {0x800f, 122}, + {0x8018, 122}, + {0x801f, 122}, + {0x8029, 122}, + {0xc038, 122}, + }, + /* 68 */ + { + {0x8001, 38}, + {0xc016, 38}, + {0x8001, 42}, + {0xc016, 42}, + {0x8001, 44}, + {0xc016, 44}, + {0x8001, 59}, + {0xc016, 59}, + {0x8001, 88}, + {0xc016, 88}, + {0x8001, 90}, + {0xc016, 90}, + {0x4c, 0}, + {0x4d, 0}, + {0x4f, 0}, + {0x51, 0}, + }, + /* 69 */ + { + {0x8002, 38}, + {0x8009, 38}, + {0x8017, 38}, + {0xc028, 38}, + {0x8002, 42}, + {0x8009, 42}, + {0x8017, 42}, + {0xc028, 42}, + {0x8002, 44}, + {0x8009, 44}, + {0x8017, 44}, + {0xc028, 44}, + {0x8002, 59}, + {0x8009, 59}, + {0x8017, 59}, + {0xc028, 59}, + }, + /* 70 */ + { + {0x8003, 38}, + {0x8006, 38}, + {0x800a, 38}, + {0x800f, 38}, + {0x8018, 38}, + {0x801f, 38}, + {0x8029, 38}, + {0xc038, 38}, + {0x8003, 42}, + {0x8006, 42}, + {0x800a, 42}, + {0x800f, 42}, + {0x8018, 42}, + {0x801f, 42}, + {0x8029, 42}, + {0xc038, 42}, + }, + /* 71 */ + { + {0x8003, 44}, + {0x8006, 44}, + {0x800a, 44}, + {0x800f, 44}, + {0x8018, 44}, + {0x801f, 44}, + {0x8029, 44}, + {0xc038, 44}, + {0x8003, 59}, + {0x8006, 59}, + {0x800a, 59}, + {0x800f, 59}, + {0x8018, 59}, + {0x801f, 59}, + {0x8029, 59}, + {0xc038, 59}, + }, + /* 72 */ + { + {0x8002, 88}, + {0x8009, 88}, + {0x8017, 88}, + {0xc028, 88}, + {0x8002, 90}, + {0x8009, 90}, + {0x8017, 90}, + {0xc028, 90}, + {0xc000, 33}, + {0xc000, 34}, + {0xc000, 40}, + {0xc000, 41}, + {0xc000, 63}, + {0x50, 0}, + {0x52, 0}, + {0x54, 0}, + }, + /* 73 */ + { + {0x8003, 88}, + {0x8006, 88}, + {0x800a, 88}, + {0x800f, 88}, + {0x8018, 88}, + {0x801f, 88}, + {0x8029, 88}, + {0xc038, 88}, + {0x8003, 90}, + {0x8006, 90}, + {0x800a, 90}, + {0x800f, 90}, + {0x8018, 90}, + {0x801f, 90}, + {0x8029, 90}, + {0xc038, 90}, + }, + /* 74 */ + { + {0x8001, 33}, + {0xc016, 33}, + {0x8001, 34}, + {0xc016, 34}, + {0x8001, 40}, + {0xc016, 40}, + {0x8001, 41}, + {0xc016, 41}, + {0x8001, 63}, + {0xc016, 63}, + {0xc000, 39}, + {0xc000, 43}, + {0xc000, 124}, + {0x53, 0}, + {0x55, 0}, + {0x58, 0}, + }, + /* 75 */ + { + {0x8002, 33}, + {0x8009, 33}, + {0x8017, 33}, + {0xc028, 33}, + {0x8002, 34}, + {0x8009, 34}, + {0x8017, 34}, + {0xc028, 34}, + {0x8002, 40}, + {0x8009, 40}, + {0x8017, 40}, + {0xc028, 40}, + {0x8002, 41}, + {0x8009, 41}, + {0x8017, 41}, + {0xc028, 41}, + }, + /* 76 */ + { + {0x8003, 33}, + {0x8006, 33}, + {0x800a, 33}, + {0x800f, 33}, + {0x8018, 33}, + {0x801f, 33}, + {0x8029, 33}, + {0xc038, 33}, + {0x8003, 34}, + {0x8006, 34}, + {0x800a, 34}, + {0x800f, 34}, + {0x8018, 34}, + {0x801f, 34}, + {0x8029, 34}, + {0xc038, 34}, + }, + /* 77 */ + { + {0x8003, 40}, + {0x8006, 40}, + {0x800a, 40}, + {0x800f, 40}, + {0x8018, 40}, + {0x801f, 40}, + {0x8029, 40}, + {0xc038, 40}, + {0x8003, 41}, + {0x8006, 41}, + {0x800a, 41}, + {0x800f, 41}, + {0x8018, 41}, + {0x801f, 41}, + {0x8029, 41}, + {0xc038, 41}, + }, + /* 78 */ + { + {0x8002, 63}, + {0x8009, 63}, + {0x8017, 63}, + {0xc028, 63}, + {0x8001, 39}, + {0xc016, 39}, + {0x8001, 43}, + {0xc016, 43}, + {0x8001, 124}, + {0xc016, 124}, + {0xc000, 35}, + {0xc000, 62}, + {0x56, 0}, + {0x57, 0}, + {0x59, 0}, + {0x5a, 0}, + }, + /* 79 */ + { + {0x8003, 63}, + {0x8006, 63}, + {0x800a, 63}, + {0x800f, 63}, + {0x8018, 63}, + {0x801f, 63}, + {0x8029, 63}, + {0xc038, 63}, + {0x8002, 39}, + {0x8009, 39}, + {0x8017, 39}, + {0xc028, 39}, + {0x8002, 43}, + {0x8009, 43}, + {0x8017, 43}, + {0xc028, 43}, + }, + /* 80 */ + { + {0x8003, 39}, + {0x8006, 39}, + {0x800a, 39}, + {0x800f, 39}, + {0x8018, 39}, + {0x801f, 39}, + {0x8029, 39}, + {0xc038, 39}, + {0x8003, 43}, + {0x8006, 43}, + {0x800a, 43}, + {0x800f, 43}, + {0x8018, 43}, + {0x801f, 43}, + {0x8029, 43}, + {0xc038, 43}, + }, + /* 81 */ + { + {0x8002, 124}, + {0x8009, 124}, + {0x8017, 124}, + {0xc028, 124}, + {0x8001, 35}, + {0xc016, 35}, + {0x8001, 62}, + {0xc016, 62}, + {0xc000, 0}, + {0xc000, 36}, + {0xc000, 64}, + {0xc000, 91}, + {0xc000, 93}, + {0xc000, 126}, + {0x5b, 0}, + {0x5c, 0}, + }, + /* 82 */ + { + {0x8003, 124}, + {0x8006, 124}, + {0x800a, 124}, + {0x800f, 124}, + {0x8018, 124}, + {0x801f, 124}, + {0x8029, 124}, + {0xc038, 124}, + {0x8002, 35}, + {0x8009, 35}, + {0x8017, 35}, + {0xc028, 35}, + {0x8002, 62}, + {0x8009, 62}, + {0x8017, 62}, + {0xc028, 62}, + }, + /* 83 */ + { + {0x8003, 35}, + {0x8006, 35}, + {0x800a, 35}, + {0x800f, 35}, + {0x8018, 35}, + {0x801f, 35}, + {0x8029, 35}, + {0xc038, 35}, + {0x8003, 62}, + {0x8006, 62}, + {0x800a, 62}, + {0x800f, 62}, + {0x8018, 62}, + {0x801f, 62}, + {0x8029, 62}, + {0xc038, 62}, + }, + /* 84 */ + { + {0x8001, 0}, + {0xc016, 0}, + {0x8001, 36}, + {0xc016, 36}, + {0x8001, 64}, + {0xc016, 64}, + {0x8001, 91}, + {0xc016, 91}, + {0x8001, 93}, + {0xc016, 93}, + {0x8001, 126}, + {0xc016, 126}, + {0xc000, 94}, + {0xc000, 125}, + {0x5d, 0}, + {0x5e, 0}, + }, + /* 85 */ + { + {0x8002, 0}, + {0x8009, 0}, + {0x8017, 0}, + {0xc028, 0}, + {0x8002, 36}, + {0x8009, 36}, + {0x8017, 36}, + {0xc028, 36}, + {0x8002, 64}, + {0x8009, 64}, + {0x8017, 64}, + {0xc028, 64}, + {0x8002, 91}, + {0x8009, 91}, + {0x8017, 91}, + {0xc028, 91}, + }, + /* 86 */ + { + {0x8003, 0}, + {0x8006, 0}, + {0x800a, 0}, + {0x800f, 0}, + {0x8018, 0}, + {0x801f, 0}, + {0x8029, 0}, + {0xc038, 0}, + {0x8003, 36}, + {0x8006, 36}, + {0x800a, 36}, + {0x800f, 36}, + {0x8018, 36}, + {0x801f, 36}, + {0x8029, 36}, + {0xc038, 36}, + }, + /* 87 */ + { + {0x8003, 64}, + {0x8006, 64}, + {0x800a, 64}, + {0x800f, 64}, + {0x8018, 64}, + {0x801f, 64}, + {0x8029, 64}, + {0xc038, 64}, + {0x8003, 91}, + {0x8006, 91}, + {0x800a, 91}, + {0x800f, 91}, + {0x8018, 91}, + {0x801f, 91}, + {0x8029, 91}, + {0xc038, 91}, + }, + /* 88 */ + { + {0x8002, 93}, + {0x8009, 93}, + {0x8017, 93}, + {0xc028, 93}, + {0x8002, 126}, + {0x8009, 126}, + {0x8017, 126}, + {0xc028, 126}, + {0x8001, 94}, + {0xc016, 94}, + {0x8001, 125}, + {0xc016, 125}, + {0xc000, 60}, + {0xc000, 96}, + {0xc000, 123}, + {0x5f, 0}, + }, + /* 89 */ + { + {0x8003, 93}, + {0x8006, 93}, + {0x800a, 93}, + {0x800f, 93}, + {0x8018, 93}, + {0x801f, 93}, + {0x8029, 93}, + {0xc038, 93}, + {0x8003, 126}, + {0x8006, 126}, + {0x800a, 126}, + {0x800f, 126}, + {0x8018, 126}, + {0x801f, 126}, + {0x8029, 126}, + {0xc038, 126}, + }, + /* 90 */ + { + {0x8002, 94}, + {0x8009, 94}, + {0x8017, 94}, + {0xc028, 94}, + {0x8002, 125}, + {0x8009, 125}, + {0x8017, 125}, + {0xc028, 125}, + {0x8001, 60}, + {0xc016, 60}, + {0x8001, 96}, + {0xc016, 96}, + {0x8001, 123}, + {0xc016, 123}, + {0x60, 0}, + {0x6e, 0}, + }, + /* 91 */ + { + {0x8003, 94}, + {0x8006, 94}, + {0x800a, 94}, + {0x800f, 94}, + {0x8018, 94}, + {0x801f, 94}, + {0x8029, 94}, + {0xc038, 94}, + {0x8003, 125}, + {0x8006, 125}, + {0x800a, 125}, + {0x800f, 125}, + {0x8018, 125}, + {0x801f, 125}, + {0x8029, 125}, + {0xc038, 125}, + }, + /* 92 */ + { + {0x8002, 60}, + {0x8009, 60}, + {0x8017, 60}, + {0xc028, 60}, + {0x8002, 96}, + {0x8009, 96}, + {0x8017, 96}, + {0xc028, 96}, + {0x8002, 123}, + {0x8009, 123}, + {0x8017, 123}, + {0xc028, 123}, + {0x61, 0}, + {0x65, 0}, + {0x6f, 0}, + {0x85, 0}, + }, + /* 93 */ + { + {0x8003, 60}, + {0x8006, 60}, + {0x800a, 60}, + {0x800f, 60}, + {0x8018, 60}, + {0x801f, 60}, + {0x8029, 60}, + {0xc038, 60}, + {0x8003, 96}, + {0x8006, 96}, + {0x800a, 96}, + {0x800f, 96}, + {0x8018, 96}, + {0x801f, 96}, + {0x8029, 96}, + {0xc038, 96}, + }, + /* 94 */ + { + {0x8003, 123}, + {0x8006, 123}, + {0x800a, 123}, + {0x800f, 123}, + {0x8018, 123}, + {0x801f, 123}, + {0x8029, 123}, + {0xc038, 123}, + {0x62, 0}, + {0x63, 0}, + {0x66, 0}, + {0x69, 0}, + {0x70, 0}, + {0x77, 0}, + {0x86, 0}, + {0x99, 0}, + }, + /* 95 */ + { + {0xc000, 92}, + {0xc000, 195}, + {0xc000, 208}, + {0x64, 0}, + {0x67, 0}, + {0x68, 0}, + {0x6a, 0}, + {0x6b, 0}, + {0x71, 0}, + {0x74, 0}, + {0x78, 0}, + {0x7e, 0}, + {0x87, 0}, + {0x8e, 0}, + {0x9a, 0}, + {0xa9, 0}, + }, + /* 96 */ + { + {0x8001, 92}, + {0xc016, 92}, + {0x8001, 195}, + {0xc016, 195}, + {0x8001, 208}, + {0xc016, 208}, + {0xc000, 128}, + {0xc000, 130}, + {0xc000, 131}, + {0xc000, 162}, + {0xc000, 184}, + {0xc000, 194}, + {0xc000, 224}, + {0xc000, 226}, + {0x6c, 0}, + {0x6d, 0}, + }, + /* 97 */ + { + {0x8002, 92}, + {0x8009, 92}, + {0x8017, 92}, + {0xc028, 92}, + {0x8002, 195}, + {0x8009, 195}, + {0x8017, 195}, + {0xc028, 195}, + {0x8002, 208}, + {0x8009, 208}, + {0x8017, 208}, + {0xc028, 208}, + {0x8001, 128}, + {0xc016, 128}, + {0x8001, 130}, + {0xc016, 130}, + }, + /* 98 */ + { + {0x8003, 92}, + {0x8006, 92}, + {0x800a, 92}, + {0x800f, 92}, + {0x8018, 92}, + {0x801f, 92}, + {0x8029, 92}, + {0xc038, 92}, + {0x8003, 195}, + {0x8006, 195}, + {0x800a, 195}, + {0x800f, 195}, + {0x8018, 195}, + {0x801f, 195}, + {0x8029, 195}, + {0xc038, 195}, + }, + /* 99 */ + { + {0x8003, 208}, + {0x8006, 208}, + {0x800a, 208}, + {0x800f, 208}, + {0x8018, 208}, + {0x801f, 208}, + {0x8029, 208}, + {0xc038, 208}, + {0x8002, 128}, + {0x8009, 128}, + {0x8017, 128}, + {0xc028, 128}, + {0x8002, 130}, + {0x8009, 130}, + {0x8017, 130}, + {0xc028, 130}, + }, + /* 100 */ + { + {0x8003, 128}, + {0x8006, 128}, + {0x800a, 128}, + {0x800f, 128}, + {0x8018, 128}, + {0x801f, 128}, + {0x8029, 128}, + {0xc038, 128}, + {0x8003, 130}, + {0x8006, 130}, + {0x800a, 130}, + {0x800f, 130}, + {0x8018, 130}, + {0x801f, 130}, + {0x8029, 130}, + {0xc038, 130}, + }, + /* 101 */ + { + {0x8001, 131}, + {0xc016, 131}, + {0x8001, 162}, + {0xc016, 162}, + {0x8001, 184}, + {0xc016, 184}, + {0x8001, 194}, + {0xc016, 194}, + {0x8001, 224}, + {0xc016, 224}, + {0x8001, 226}, + {0xc016, 226}, + {0xc000, 153}, + {0xc000, 161}, + {0xc000, 167}, + {0xc000, 172}, + }, + /* 102 */ + { + {0x8002, 131}, + {0x8009, 131}, + {0x8017, 131}, + {0xc028, 131}, + {0x8002, 162}, + {0x8009, 162}, + {0x8017, 162}, + {0xc028, 162}, + {0x8002, 184}, + {0x8009, 184}, + {0x8017, 184}, + {0xc028, 184}, + {0x8002, 194}, + {0x8009, 194}, + {0x8017, 194}, + {0xc028, 194}, + }, + /* 103 */ + { + {0x8003, 131}, + {0x8006, 131}, + {0x800a, 131}, + {0x800f, 131}, + {0x8018, 131}, + {0x801f, 131}, + {0x8029, 131}, + {0xc038, 131}, + {0x8003, 162}, + {0x8006, 162}, + {0x800a, 162}, + {0x800f, 162}, + {0x8018, 162}, + {0x801f, 162}, + {0x8029, 162}, + {0xc038, 162}, + }, + /* 104 */ + { + {0x8003, 184}, + {0x8006, 184}, + {0x800a, 184}, + {0x800f, 184}, + {0x8018, 184}, + {0x801f, 184}, + {0x8029, 184}, + {0xc038, 184}, + {0x8003, 194}, + {0x8006, 194}, + {0x800a, 194}, + {0x800f, 194}, + {0x8018, 194}, + {0x801f, 194}, + {0x8029, 194}, + {0xc038, 194}, + }, + /* 105 */ + { + {0x8002, 224}, + {0x8009, 224}, + {0x8017, 224}, + {0xc028, 224}, + {0x8002, 226}, + {0x8009, 226}, + {0x8017, 226}, + {0xc028, 226}, + {0x8001, 153}, + {0xc016, 153}, + {0x8001, 161}, + {0xc016, 161}, + {0x8001, 167}, + {0xc016, 167}, + {0x8001, 172}, + {0xc016, 172}, + }, + /* 106 */ + { + {0x8003, 224}, + {0x8006, 224}, + {0x800a, 224}, + {0x800f, 224}, + {0x8018, 224}, + {0x801f, 224}, + {0x8029, 224}, + {0xc038, 224}, + {0x8003, 226}, + {0x8006, 226}, + {0x800a, 226}, + {0x800f, 226}, + {0x8018, 226}, + {0x801f, 226}, + {0x8029, 226}, + {0xc038, 226}, + }, + /* 107 */ + { + {0x8002, 153}, + {0x8009, 153}, + {0x8017, 153}, + {0xc028, 153}, + {0x8002, 161}, + {0x8009, 161}, + {0x8017, 161}, + {0xc028, 161}, + {0x8002, 167}, + {0x8009, 167}, + {0x8017, 167}, + {0xc028, 167}, + {0x8002, 172}, + {0x8009, 172}, + {0x8017, 172}, + {0xc028, 172}, + }, + /* 108 */ + { + {0x8003, 153}, + {0x8006, 153}, + {0x800a, 153}, + {0x800f, 153}, + {0x8018, 153}, + {0x801f, 153}, + {0x8029, 153}, + {0xc038, 153}, + {0x8003, 161}, + {0x8006, 161}, + {0x800a, 161}, + {0x800f, 161}, + {0x8018, 161}, + {0x801f, 161}, + {0x8029, 161}, + {0xc038, 161}, + }, + /* 109 */ + { + {0x8003, 167}, + {0x8006, 167}, + {0x800a, 167}, + {0x800f, 167}, + {0x8018, 167}, + {0x801f, 167}, + {0x8029, 167}, + {0xc038, 167}, + {0x8003, 172}, + {0x8006, 172}, + {0x800a, 172}, + {0x800f, 172}, + {0x8018, 172}, + {0x801f, 172}, + {0x8029, 172}, + {0xc038, 172}, + }, + /* 110 */ + { + {0x72, 0}, + {0x73, 0}, + {0x75, 0}, + {0x76, 0}, + {0x79, 0}, + {0x7b, 0}, + {0x7f, 0}, + {0x82, 0}, + {0x88, 0}, + {0x8b, 0}, + {0x8f, 0}, + {0x92, 0}, + {0x9b, 0}, + {0xa2, 0}, + {0xaa, 0}, + {0xb4, 0}, + }, + /* 111 */ + { + {0xc000, 176}, + {0xc000, 177}, + {0xc000, 179}, + {0xc000, 209}, + {0xc000, 216}, + {0xc000, 217}, + {0xc000, 227}, + {0xc000, 229}, + {0xc000, 230}, + {0x7a, 0}, + {0x7c, 0}, + {0x7d, 0}, + {0x80, 0}, + {0x81, 0}, + {0x83, 0}, + {0x84, 0}, + }, + /* 112 */ + { + {0x8001, 176}, + {0xc016, 176}, + {0x8001, 177}, + {0xc016, 177}, + {0x8001, 179}, + {0xc016, 179}, + {0x8001, 209}, + {0xc016, 209}, + {0x8001, 216}, + {0xc016, 216}, + {0x8001, 217}, + {0xc016, 217}, + {0x8001, 227}, + {0xc016, 227}, + {0x8001, 229}, + {0xc016, 229}, + }, + /* 113 */ + { + {0x8002, 176}, + {0x8009, 176}, + {0x8017, 176}, + {0xc028, 176}, + {0x8002, 177}, + {0x8009, 177}, + {0x8017, 177}, + {0xc028, 177}, + {0x8002, 179}, + {0x8009, 179}, + {0x8017, 179}, + {0xc028, 179}, + {0x8002, 209}, + {0x8009, 209}, + {0x8017, 209}, + {0xc028, 209}, + }, + /* 114 */ + { + {0x8003, 176}, + {0x8006, 176}, + {0x800a, 176}, + {0x800f, 176}, + {0x8018, 176}, + {0x801f, 176}, + {0x8029, 176}, + {0xc038, 176}, + {0x8003, 177}, + {0x8006, 177}, + {0x800a, 177}, + {0x800f, 177}, + {0x8018, 177}, + {0x801f, 177}, + {0x8029, 177}, + {0xc038, 177}, + }, + /* 115 */ + { + {0x8003, 179}, + {0x8006, 179}, + {0x800a, 179}, + {0x800f, 179}, + {0x8018, 179}, + {0x801f, 179}, + {0x8029, 179}, + {0xc038, 179}, + {0x8003, 209}, + {0x8006, 209}, + {0x800a, 209}, + {0x800f, 209}, + {0x8018, 209}, + {0x801f, 209}, + {0x8029, 209}, + {0xc038, 209}, + }, + /* 116 */ + { + {0x8002, 216}, + {0x8009, 216}, + {0x8017, 216}, + {0xc028, 216}, + {0x8002, 217}, + {0x8009, 217}, + {0x8017, 217}, + {0xc028, 217}, + {0x8002, 227}, + {0x8009, 227}, + {0x8017, 227}, + {0xc028, 227}, + {0x8002, 229}, + {0x8009, 229}, + {0x8017, 229}, + {0xc028, 229}, + }, + /* 117 */ + { + {0x8003, 216}, + {0x8006, 216}, + {0x800a, 216}, + {0x800f, 216}, + {0x8018, 216}, + {0x801f, 216}, + {0x8029, 216}, + {0xc038, 216}, + {0x8003, 217}, + {0x8006, 217}, + {0x800a, 217}, + {0x800f, 217}, + {0x8018, 217}, + {0x801f, 217}, + {0x8029, 217}, + {0xc038, 217}, + }, + /* 118 */ + { + {0x8003, 227}, + {0x8006, 227}, + {0x800a, 227}, + {0x800f, 227}, + {0x8018, 227}, + {0x801f, 227}, + {0x8029, 227}, + {0xc038, 227}, + {0x8003, 229}, + {0x8006, 229}, + {0x800a, 229}, + {0x800f, 229}, + {0x8018, 229}, + {0x801f, 229}, + {0x8029, 229}, + {0xc038, 229}, + }, + /* 119 */ + { + {0x8001, 230}, + {0xc016, 230}, + {0xc000, 129}, + {0xc000, 132}, + {0xc000, 133}, + {0xc000, 134}, + {0xc000, 136}, + {0xc000, 146}, + {0xc000, 154}, + {0xc000, 156}, + {0xc000, 160}, + {0xc000, 163}, + {0xc000, 164}, + {0xc000, 169}, + {0xc000, 170}, + {0xc000, 173}, + }, + /* 120 */ + { + {0x8002, 230}, + {0x8009, 230}, + {0x8017, 230}, + {0xc028, 230}, + {0x8001, 129}, + {0xc016, 129}, + {0x8001, 132}, + {0xc016, 132}, + {0x8001, 133}, + {0xc016, 133}, + {0x8001, 134}, + {0xc016, 134}, + {0x8001, 136}, + {0xc016, 136}, + {0x8001, 146}, + {0xc016, 146}, + }, + /* 121 */ + { + {0x8003, 230}, + {0x8006, 230}, + {0x800a, 230}, + {0x800f, 230}, + {0x8018, 230}, + {0x801f, 230}, + {0x8029, 230}, + {0xc038, 230}, + {0x8002, 129}, + {0x8009, 129}, + {0x8017, 129}, + {0xc028, 129}, + {0x8002, 132}, + {0x8009, 132}, + {0x8017, 132}, + {0xc028, 132}, + }, + /* 122 */ + { + {0x8003, 129}, + {0x8006, 129}, + {0x800a, 129}, + {0x800f, 129}, + {0x8018, 129}, + {0x801f, 129}, + {0x8029, 129}, + {0xc038, 129}, + {0x8003, 132}, + {0x8006, 132}, + {0x800a, 132}, + {0x800f, 132}, + {0x8018, 132}, + {0x801f, 132}, + {0x8029, 132}, + {0xc038, 132}, + }, + /* 123 */ + { + {0x8002, 133}, + {0x8009, 133}, + {0x8017, 133}, + {0xc028, 133}, + {0x8002, 134}, + {0x8009, 134}, + {0x8017, 134}, + {0xc028, 134}, + {0x8002, 136}, + {0x8009, 136}, + {0x8017, 136}, + {0xc028, 136}, + {0x8002, 146}, + {0x8009, 146}, + {0x8017, 146}, + {0xc028, 146}, + }, + /* 124 */ + { + {0x8003, 133}, + {0x8006, 133}, + {0x800a, 133}, + {0x800f, 133}, + {0x8018, 133}, + {0x801f, 133}, + {0x8029, 133}, + {0xc038, 133}, + {0x8003, 134}, + {0x8006, 134}, + {0x800a, 134}, + {0x800f, 134}, + {0x8018, 134}, + {0x801f, 134}, + {0x8029, 134}, + {0xc038, 134}, + }, + /* 125 */ + { + {0x8003, 136}, + {0x8006, 136}, + {0x800a, 136}, + {0x800f, 136}, + {0x8018, 136}, + {0x801f, 136}, + {0x8029, 136}, + {0xc038, 136}, + {0x8003, 146}, + {0x8006, 146}, + {0x800a, 146}, + {0x800f, 146}, + {0x8018, 146}, + {0x801f, 146}, + {0x8029, 146}, + {0xc038, 146}, + }, + /* 126 */ + { + {0x8001, 154}, + {0xc016, 154}, + {0x8001, 156}, + {0xc016, 156}, + {0x8001, 160}, + {0xc016, 160}, + {0x8001, 163}, + {0xc016, 163}, + {0x8001, 164}, + {0xc016, 164}, + {0x8001, 169}, + {0xc016, 169}, + {0x8001, 170}, + {0xc016, 170}, + {0x8001, 173}, + {0xc016, 173}, + }, + /* 127 */ + { + {0x8002, 154}, + {0x8009, 154}, + {0x8017, 154}, + {0xc028, 154}, + {0x8002, 156}, + {0x8009, 156}, + {0x8017, 156}, + {0xc028, 156}, + {0x8002, 160}, + {0x8009, 160}, + {0x8017, 160}, + {0xc028, 160}, + {0x8002, 163}, + {0x8009, 163}, + {0x8017, 163}, + {0xc028, 163}, + }, + /* 128 */ + { + {0x8003, 154}, + {0x8006, 154}, + {0x800a, 154}, + {0x800f, 154}, + {0x8018, 154}, + {0x801f, 154}, + {0x8029, 154}, + {0xc038, 154}, + {0x8003, 156}, + {0x8006, 156}, + {0x800a, 156}, + {0x800f, 156}, + {0x8018, 156}, + {0x801f, 156}, + {0x8029, 156}, + {0xc038, 156}, + }, + /* 129 */ + { + {0x8003, 160}, + {0x8006, 160}, + {0x800a, 160}, + {0x800f, 160}, + {0x8018, 160}, + {0x801f, 160}, + {0x8029, 160}, + {0xc038, 160}, + {0x8003, 163}, + {0x8006, 163}, + {0x800a, 163}, + {0x800f, 163}, + {0x8018, 163}, + {0x801f, 163}, + {0x8029, 163}, + {0xc038, 163}, + }, + /* 130 */ + { + {0x8002, 164}, + {0x8009, 164}, + {0x8017, 164}, + {0xc028, 164}, + {0x8002, 169}, + {0x8009, 169}, + {0x8017, 169}, + {0xc028, 169}, + {0x8002, 170}, + {0x8009, 170}, + {0x8017, 170}, + {0xc028, 170}, + {0x8002, 173}, + {0x8009, 173}, + {0x8017, 173}, + {0xc028, 173}, + }, + /* 131 */ + { + {0x8003, 164}, + {0x8006, 164}, + {0x800a, 164}, + {0x800f, 164}, + {0x8018, 164}, + {0x801f, 164}, + {0x8029, 164}, + {0xc038, 164}, + {0x8003, 169}, + {0x8006, 169}, + {0x800a, 169}, + {0x800f, 169}, + {0x8018, 169}, + {0x801f, 169}, + {0x8029, 169}, + {0xc038, 169}, + }, + /* 132 */ + { + {0x8003, 170}, + {0x8006, 170}, + {0x800a, 170}, + {0x800f, 170}, + {0x8018, 170}, + {0x801f, 170}, + {0x8029, 170}, + {0xc038, 170}, + {0x8003, 173}, + {0x8006, 173}, + {0x800a, 173}, + {0x800f, 173}, + {0x8018, 173}, + {0x801f, 173}, + {0x8029, 173}, + {0xc038, 173}, + }, + /* 133 */ + { + {0x89, 0}, + {0x8a, 0}, + {0x8c, 0}, + {0x8d, 0}, + {0x90, 0}, + {0x91, 0}, + {0x93, 0}, + {0x96, 0}, + {0x9c, 0}, + {0x9f, 0}, + {0xa3, 0}, + {0xa6, 0}, + {0xab, 0}, + {0xae, 0}, + {0xb5, 0}, + {0xbe, 0}, + }, + /* 134 */ + { + {0xc000, 178}, + {0xc000, 181}, + {0xc000, 185}, + {0xc000, 186}, + {0xc000, 187}, + {0xc000, 189}, + {0xc000, 190}, + {0xc000, 196}, + {0xc000, 198}, + {0xc000, 228}, + {0xc000, 232}, + {0xc000, 233}, + {0x94, 0}, + {0x95, 0}, + {0x97, 0}, + {0x98, 0}, + }, + /* 135 */ + { + {0x8001, 178}, + {0xc016, 178}, + {0x8001, 181}, + {0xc016, 181}, + {0x8001, 185}, + {0xc016, 185}, + {0x8001, 186}, + {0xc016, 186}, + {0x8001, 187}, + {0xc016, 187}, + {0x8001, 189}, + {0xc016, 189}, + {0x8001, 190}, + {0xc016, 190}, + {0x8001, 196}, + {0xc016, 196}, + }, + /* 136 */ + { + {0x8002, 178}, + {0x8009, 178}, + {0x8017, 178}, + {0xc028, 178}, + {0x8002, 181}, + {0x8009, 181}, + {0x8017, 181}, + {0xc028, 181}, + {0x8002, 185}, + {0x8009, 185}, + {0x8017, 185}, + {0xc028, 185}, + {0x8002, 186}, + {0x8009, 186}, + {0x8017, 186}, + {0xc028, 186}, + }, + /* 137 */ + { + {0x8003, 178}, + {0x8006, 178}, + {0x800a, 178}, + {0x800f, 178}, + {0x8018, 178}, + {0x801f, 178}, + {0x8029, 178}, + {0xc038, 178}, + {0x8003, 181}, + {0x8006, 181}, + {0x800a, 181}, + {0x800f, 181}, + {0x8018, 181}, + {0x801f, 181}, + {0x8029, 181}, + {0xc038, 181}, + }, + /* 138 */ + { + {0x8003, 185}, + {0x8006, 185}, + {0x800a, 185}, + {0x800f, 185}, + {0x8018, 185}, + {0x801f, 185}, + {0x8029, 185}, + {0xc038, 185}, + {0x8003, 186}, + {0x8006, 186}, + {0x800a, 186}, + {0x800f, 186}, + {0x8018, 186}, + {0x801f, 186}, + {0x8029, 186}, + {0xc038, 186}, + }, + /* 139 */ + { + {0x8002, 187}, + {0x8009, 187}, + {0x8017, 187}, + {0xc028, 187}, + {0x8002, 189}, + {0x8009, 189}, + {0x8017, 189}, + {0xc028, 189}, + {0x8002, 190}, + {0x8009, 190}, + {0x8017, 190}, + {0xc028, 190}, + {0x8002, 196}, + {0x8009, 196}, + {0x8017, 196}, + {0xc028, 196}, + }, + /* 140 */ + { + {0x8003, 187}, + {0x8006, 187}, + {0x800a, 187}, + {0x800f, 187}, + {0x8018, 187}, + {0x801f, 187}, + {0x8029, 187}, + {0xc038, 187}, + {0x8003, 189}, + {0x8006, 189}, + {0x800a, 189}, + {0x800f, 189}, + {0x8018, 189}, + {0x801f, 189}, + {0x8029, 189}, + {0xc038, 189}, + }, + /* 141 */ + { + {0x8003, 190}, + {0x8006, 190}, + {0x800a, 190}, + {0x800f, 190}, + {0x8018, 190}, + {0x801f, 190}, + {0x8029, 190}, + {0xc038, 190}, + {0x8003, 196}, + {0x8006, 196}, + {0x800a, 196}, + {0x800f, 196}, + {0x8018, 196}, + {0x801f, 196}, + {0x8029, 196}, + {0xc038, 196}, + }, + /* 142 */ + { + {0x8001, 198}, + {0xc016, 198}, + {0x8001, 228}, + {0xc016, 228}, + {0x8001, 232}, + {0xc016, 232}, + {0x8001, 233}, + {0xc016, 233}, + {0xc000, 1}, + {0xc000, 135}, + {0xc000, 137}, + {0xc000, 138}, + {0xc000, 139}, + {0xc000, 140}, + {0xc000, 141}, + {0xc000, 143}, + }, + /* 143 */ + { + {0x8002, 198}, + {0x8009, 198}, + {0x8017, 198}, + {0xc028, 198}, + {0x8002, 228}, + {0x8009, 228}, + {0x8017, 228}, + {0xc028, 228}, + {0x8002, 232}, + {0x8009, 232}, + {0x8017, 232}, + {0xc028, 232}, + {0x8002, 233}, + {0x8009, 233}, + {0x8017, 233}, + {0xc028, 233}, + }, + /* 144 */ + { + {0x8003, 198}, + {0x8006, 198}, + {0x800a, 198}, + {0x800f, 198}, + {0x8018, 198}, + {0x801f, 198}, + {0x8029, 198}, + {0xc038, 198}, + {0x8003, 228}, + {0x8006, 228}, + {0x800a, 228}, + {0x800f, 228}, + {0x8018, 228}, + {0x801f, 228}, + {0x8029, 228}, + {0xc038, 228}, + }, + /* 145 */ + { + {0x8003, 232}, + {0x8006, 232}, + {0x800a, 232}, + {0x800f, 232}, + {0x8018, 232}, + {0x801f, 232}, + {0x8029, 232}, + {0xc038, 232}, + {0x8003, 233}, + {0x8006, 233}, + {0x800a, 233}, + {0x800f, 233}, + {0x8018, 233}, + {0x801f, 233}, + {0x8029, 233}, + {0xc038, 233}, + }, + /* 146 */ + { + {0x8001, 1}, + {0xc016, 1}, + {0x8001, 135}, + {0xc016, 135}, + {0x8001, 137}, + {0xc016, 137}, + {0x8001, 138}, + {0xc016, 138}, + {0x8001, 139}, + {0xc016, 139}, + {0x8001, 140}, + {0xc016, 140}, + {0x8001, 141}, + {0xc016, 141}, + {0x8001, 143}, + {0xc016, 143}, + }, + /* 147 */ + { + {0x8002, 1}, + {0x8009, 1}, + {0x8017, 1}, + {0xc028, 1}, + {0x8002, 135}, + {0x8009, 135}, + {0x8017, 135}, + {0xc028, 135}, + {0x8002, 137}, + {0x8009, 137}, + {0x8017, 137}, + {0xc028, 137}, + {0x8002, 138}, + {0x8009, 138}, + {0x8017, 138}, + {0xc028, 138}, + }, + /* 148 */ + { + {0x8003, 1}, + {0x8006, 1}, + {0x800a, 1}, + {0x800f, 1}, + {0x8018, 1}, + {0x801f, 1}, + {0x8029, 1}, + {0xc038, 1}, + {0x8003, 135}, + {0x8006, 135}, + {0x800a, 135}, + {0x800f, 135}, + {0x8018, 135}, + {0x801f, 135}, + {0x8029, 135}, + {0xc038, 135}, + }, + /* 149 */ + { + {0x8003, 137}, + {0x8006, 137}, + {0x800a, 137}, + {0x800f, 137}, + {0x8018, 137}, + {0x801f, 137}, + {0x8029, 137}, + {0xc038, 137}, + {0x8003, 138}, + {0x8006, 138}, + {0x800a, 138}, + {0x800f, 138}, + {0x8018, 138}, + {0x801f, 138}, + {0x8029, 138}, + {0xc038, 138}, + }, + /* 150 */ + { + {0x8002, 139}, + {0x8009, 139}, + {0x8017, 139}, + {0xc028, 139}, + {0x8002, 140}, + {0x8009, 140}, + {0x8017, 140}, + {0xc028, 140}, + {0x8002, 141}, + {0x8009, 141}, + {0x8017, 141}, + {0xc028, 141}, + {0x8002, 143}, + {0x8009, 143}, + {0x8017, 143}, + {0xc028, 143}, + }, + /* 151 */ + { + {0x8003, 139}, + {0x8006, 139}, + {0x800a, 139}, + {0x800f, 139}, + {0x8018, 139}, + {0x801f, 139}, + {0x8029, 139}, + {0xc038, 139}, + {0x8003, 140}, + {0x8006, 140}, + {0x800a, 140}, + {0x800f, 140}, + {0x8018, 140}, + {0x801f, 140}, + {0x8029, 140}, + {0xc038, 140}, + }, + /* 152 */ + { + {0x8003, 141}, + {0x8006, 141}, + {0x800a, 141}, + {0x800f, 141}, + {0x8018, 141}, + {0x801f, 141}, + {0x8029, 141}, + {0xc038, 141}, + {0x8003, 143}, + {0x8006, 143}, + {0x800a, 143}, + {0x800f, 143}, + {0x8018, 143}, + {0x801f, 143}, + {0x8029, 143}, + {0xc038, 143}, + }, + /* 153 */ + { + {0x9d, 0}, + {0x9e, 0}, + {0xa0, 0}, + {0xa1, 0}, + {0xa4, 0}, + {0xa5, 0}, + {0xa7, 0}, + {0xa8, 0}, + {0xac, 0}, + {0xad, 0}, + {0xaf, 0}, + {0xb1, 0}, + {0xb6, 0}, + {0xb9, 0}, + {0xbf, 0}, + {0xcf, 0}, + }, + /* 154 */ + { + {0xc000, 147}, + {0xc000, 149}, + {0xc000, 150}, + {0xc000, 151}, + {0xc000, 152}, + {0xc000, 155}, + {0xc000, 157}, + {0xc000, 158}, + {0xc000, 165}, + {0xc000, 166}, + {0xc000, 168}, + {0xc000, 174}, + {0xc000, 175}, + {0xc000, 180}, + {0xc000, 182}, + {0xc000, 183}, + }, + /* 155 */ + { + {0x8001, 147}, + {0xc016, 147}, + {0x8001, 149}, + {0xc016, 149}, + {0x8001, 150}, + {0xc016, 150}, + {0x8001, 151}, + {0xc016, 151}, + {0x8001, 152}, + {0xc016, 152}, + {0x8001, 155}, + {0xc016, 155}, + {0x8001, 157}, + {0xc016, 157}, + {0x8001, 158}, + {0xc016, 158}, + }, + /* 156 */ + { + {0x8002, 147}, + {0x8009, 147}, + {0x8017, 147}, + {0xc028, 147}, + {0x8002, 149}, + {0x8009, 149}, + {0x8017, 149}, + {0xc028, 149}, + {0x8002, 150}, + {0x8009, 150}, + {0x8017, 150}, + {0xc028, 150}, + {0x8002, 151}, + {0x8009, 151}, + {0x8017, 151}, + {0xc028, 151}, + }, + /* 157 */ + { + {0x8003, 147}, + {0x8006, 147}, + {0x800a, 147}, + {0x800f, 147}, + {0x8018, 147}, + {0x801f, 147}, + {0x8029, 147}, + {0xc038, 147}, + {0x8003, 149}, + {0x8006, 149}, + {0x800a, 149}, + {0x800f, 149}, + {0x8018, 149}, + {0x801f, 149}, + {0x8029, 149}, + {0xc038, 149}, + }, + /* 158 */ + { + {0x8003, 150}, + {0x8006, 150}, + {0x800a, 150}, + {0x800f, 150}, + {0x8018, 150}, + {0x801f, 150}, + {0x8029, 150}, + {0xc038, 150}, + {0x8003, 151}, + {0x8006, 151}, + {0x800a, 151}, + {0x800f, 151}, + {0x8018, 151}, + {0x801f, 151}, + {0x8029, 151}, + {0xc038, 151}, + }, + /* 159 */ + { + {0x8002, 152}, + {0x8009, 152}, + {0x8017, 152}, + {0xc028, 152}, + {0x8002, 155}, + {0x8009, 155}, + {0x8017, 155}, + {0xc028, 155}, + {0x8002, 157}, + {0x8009, 157}, + {0x8017, 157}, + {0xc028, 157}, + {0x8002, 158}, + {0x8009, 158}, + {0x8017, 158}, + {0xc028, 158}, + }, + /* 160 */ + { + {0x8003, 152}, + {0x8006, 152}, + {0x800a, 152}, + {0x800f, 152}, + {0x8018, 152}, + {0x801f, 152}, + {0x8029, 152}, + {0xc038, 152}, + {0x8003, 155}, + {0x8006, 155}, + {0x800a, 155}, + {0x800f, 155}, + {0x8018, 155}, + {0x801f, 155}, + {0x8029, 155}, + {0xc038, 155}, + }, + /* 161 */ + { + {0x8003, 157}, + {0x8006, 157}, + {0x800a, 157}, + {0x800f, 157}, + {0x8018, 157}, + {0x801f, 157}, + {0x8029, 157}, + {0xc038, 157}, + {0x8003, 158}, + {0x8006, 158}, + {0x800a, 158}, + {0x800f, 158}, + {0x8018, 158}, + {0x801f, 158}, + {0x8029, 158}, + {0xc038, 158}, + }, + /* 162 */ + { + {0x8001, 165}, + {0xc016, 165}, + {0x8001, 166}, + {0xc016, 166}, + {0x8001, 168}, + {0xc016, 168}, + {0x8001, 174}, + {0xc016, 174}, + {0x8001, 175}, + {0xc016, 175}, + {0x8001, 180}, + {0xc016, 180}, + {0x8001, 182}, + {0xc016, 182}, + {0x8001, 183}, + {0xc016, 183}, + }, + /* 163 */ + { + {0x8002, 165}, + {0x8009, 165}, + {0x8017, 165}, + {0xc028, 165}, + {0x8002, 166}, + {0x8009, 166}, + {0x8017, 166}, + {0xc028, 166}, + {0x8002, 168}, + {0x8009, 168}, + {0x8017, 168}, + {0xc028, 168}, + {0x8002, 174}, + {0x8009, 174}, + {0x8017, 174}, + {0xc028, 174}, + }, + /* 164 */ + { + {0x8003, 165}, + {0x8006, 165}, + {0x800a, 165}, + {0x800f, 165}, + {0x8018, 165}, + {0x801f, 165}, + {0x8029, 165}, + {0xc038, 165}, + {0x8003, 166}, + {0x8006, 166}, + {0x800a, 166}, + {0x800f, 166}, + {0x8018, 166}, + {0x801f, 166}, + {0x8029, 166}, + {0xc038, 166}, + }, + /* 165 */ + { + {0x8003, 168}, + {0x8006, 168}, + {0x800a, 168}, + {0x800f, 168}, + {0x8018, 168}, + {0x801f, 168}, + {0x8029, 168}, + {0xc038, 168}, + {0x8003, 174}, + {0x8006, 174}, + {0x800a, 174}, + {0x800f, 174}, + {0x8018, 174}, + {0x801f, 174}, + {0x8029, 174}, + {0xc038, 174}, + }, + /* 166 */ + { + {0x8002, 175}, + {0x8009, 175}, + {0x8017, 175}, + {0xc028, 175}, + {0x8002, 180}, + {0x8009, 180}, + {0x8017, 180}, + {0xc028, 180}, + {0x8002, 182}, + {0x8009, 182}, + {0x8017, 182}, + {0xc028, 182}, + {0x8002, 183}, + {0x8009, 183}, + {0x8017, 183}, + {0xc028, 183}, + }, + /* 167 */ + { + {0x8003, 175}, + {0x8006, 175}, + {0x800a, 175}, + {0x800f, 175}, + {0x8018, 175}, + {0x801f, 175}, + {0x8029, 175}, + {0xc038, 175}, + {0x8003, 180}, + {0x8006, 180}, + {0x800a, 180}, + {0x800f, 180}, + {0x8018, 180}, + {0x801f, 180}, + {0x8029, 180}, + {0xc038, 180}, + }, + /* 168 */ + { + {0x8003, 182}, + {0x8006, 182}, + {0x800a, 182}, + {0x800f, 182}, + {0x8018, 182}, + {0x801f, 182}, + {0x8029, 182}, + {0xc038, 182}, + {0x8003, 183}, + {0x8006, 183}, + {0x800a, 183}, + {0x800f, 183}, + {0x8018, 183}, + {0x801f, 183}, + {0x8029, 183}, + {0xc038, 183}, + }, + /* 169 */ + { + {0xc000, 188}, + {0xc000, 191}, + {0xc000, 197}, + {0xc000, 231}, + {0xc000, 239}, + {0xb0, 0}, + {0xb2, 0}, + {0xb3, 0}, + {0xb7, 0}, + {0xb8, 0}, + {0xba, 0}, + {0xbb, 0}, + {0xc0, 0}, + {0xc7, 0}, + {0xd0, 0}, + {0xdf, 0}, + }, + /* 170 */ + { + {0x8001, 188}, + {0xc016, 188}, + {0x8001, 191}, + {0xc016, 191}, + {0x8001, 197}, + {0xc016, 197}, + {0x8001, 231}, + {0xc016, 231}, + {0x8001, 239}, + {0xc016, 239}, + {0xc000, 9}, + {0xc000, 142}, + {0xc000, 144}, + {0xc000, 145}, + {0xc000, 148}, + {0xc000, 159}, + }, + /* 171 */ + { + {0x8002, 188}, + {0x8009, 188}, + {0x8017, 188}, + {0xc028, 188}, + {0x8002, 191}, + {0x8009, 191}, + {0x8017, 191}, + {0xc028, 191}, + {0x8002, 197}, + {0x8009, 197}, + {0x8017, 197}, + {0xc028, 197}, + {0x8002, 231}, + {0x8009, 231}, + {0x8017, 231}, + {0xc028, 231}, + }, + /* 172 */ + { + {0x8003, 188}, + {0x8006, 188}, + {0x800a, 188}, + {0x800f, 188}, + {0x8018, 188}, + {0x801f, 188}, + {0x8029, 188}, + {0xc038, 188}, + {0x8003, 191}, + {0x8006, 191}, + {0x800a, 191}, + {0x800f, 191}, + {0x8018, 191}, + {0x801f, 191}, + {0x8029, 191}, + {0xc038, 191}, + }, + /* 173 */ + { + {0x8003, 197}, + {0x8006, 197}, + {0x800a, 197}, + {0x800f, 197}, + {0x8018, 197}, + {0x801f, 197}, + {0x8029, 197}, + {0xc038, 197}, + {0x8003, 231}, + {0x8006, 231}, + {0x800a, 231}, + {0x800f, 231}, + {0x8018, 231}, + {0x801f, 231}, + {0x8029, 231}, + {0xc038, 231}, + }, + /* 174 */ + { + {0x8002, 239}, + {0x8009, 239}, + {0x8017, 239}, + {0xc028, 239}, + {0x8001, 9}, + {0xc016, 9}, + {0x8001, 142}, + {0xc016, 142}, + {0x8001, 144}, + {0xc016, 144}, + {0x8001, 145}, + {0xc016, 145}, + {0x8001, 148}, + {0xc016, 148}, + {0x8001, 159}, + {0xc016, 159}, + }, + /* 175 */ + { + {0x8003, 239}, + {0x8006, 239}, + {0x800a, 239}, + {0x800f, 239}, + {0x8018, 239}, + {0x801f, 239}, + {0x8029, 239}, + {0xc038, 239}, + {0x8002, 9}, + {0x8009, 9}, + {0x8017, 9}, + {0xc028, 9}, + {0x8002, 142}, + {0x8009, 142}, + {0x8017, 142}, + {0xc028, 142}, + }, + /* 176 */ + { + {0x8003, 9}, + {0x8006, 9}, + {0x800a, 9}, + {0x800f, 9}, + {0x8018, 9}, + {0x801f, 9}, + {0x8029, 9}, + {0xc038, 9}, + {0x8003, 142}, + {0x8006, 142}, + {0x800a, 142}, + {0x800f, 142}, + {0x8018, 142}, + {0x801f, 142}, + {0x8029, 142}, + {0xc038, 142}, + }, + /* 177 */ + { + {0x8002, 144}, + {0x8009, 144}, + {0x8017, 144}, + {0xc028, 144}, + {0x8002, 145}, + {0x8009, 145}, + {0x8017, 145}, + {0xc028, 145}, + {0x8002, 148}, + {0x8009, 148}, + {0x8017, 148}, + {0xc028, 148}, + {0x8002, 159}, + {0x8009, 159}, + {0x8017, 159}, + {0xc028, 159}, + }, + /* 178 */ + { + {0x8003, 144}, + {0x8006, 144}, + {0x800a, 144}, + {0x800f, 144}, + {0x8018, 144}, + {0x801f, 144}, + {0x8029, 144}, + {0xc038, 144}, + {0x8003, 145}, + {0x8006, 145}, + {0x800a, 145}, + {0x800f, 145}, + {0x8018, 145}, + {0x801f, 145}, + {0x8029, 145}, + {0xc038, 145}, + }, + /* 179 */ + { + {0x8003, 148}, + {0x8006, 148}, + {0x800a, 148}, + {0x800f, 148}, + {0x8018, 148}, + {0x801f, 148}, + {0x8029, 148}, + {0xc038, 148}, + {0x8003, 159}, + {0x8006, 159}, + {0x800a, 159}, + {0x800f, 159}, + {0x8018, 159}, + {0x801f, 159}, + {0x8029, 159}, + {0xc038, 159}, + }, + /* 180 */ + { + {0xc000, 171}, + {0xc000, 206}, + {0xc000, 215}, + {0xc000, 225}, + {0xc000, 236}, + {0xc000, 237}, + {0xbc, 0}, + {0xbd, 0}, + {0xc1, 0}, + {0xc4, 0}, + {0xc8, 0}, + {0xcb, 0}, + {0xd1, 0}, + {0xd8, 0}, + {0xe0, 0}, + {0xee, 0}, + }, + /* 181 */ + { + {0x8001, 171}, + {0xc016, 171}, + {0x8001, 206}, + {0xc016, 206}, + {0x8001, 215}, + {0xc016, 215}, + {0x8001, 225}, + {0xc016, 225}, + {0x8001, 236}, + {0xc016, 236}, + {0x8001, 237}, + {0xc016, 237}, + {0xc000, 199}, + {0xc000, 207}, + {0xc000, 234}, + {0xc000, 235}, + }, + /* 182 */ + { + {0x8002, 171}, + {0x8009, 171}, + {0x8017, 171}, + {0xc028, 171}, + {0x8002, 206}, + {0x8009, 206}, + {0x8017, 206}, + {0xc028, 206}, + {0x8002, 215}, + {0x8009, 215}, + {0x8017, 215}, + {0xc028, 215}, + {0x8002, 225}, + {0x8009, 225}, + {0x8017, 225}, + {0xc028, 225}, + }, + /* 183 */ + { + {0x8003, 171}, + {0x8006, 171}, + {0x800a, 171}, + {0x800f, 171}, + {0x8018, 171}, + {0x801f, 171}, + {0x8029, 171}, + {0xc038, 171}, + {0x8003, 206}, + {0x8006, 206}, + {0x800a, 206}, + {0x800f, 206}, + {0x8018, 206}, + {0x801f, 206}, + {0x8029, 206}, + {0xc038, 206}, + }, + /* 184 */ + { + {0x8003, 215}, + {0x8006, 215}, + {0x800a, 215}, + {0x800f, 215}, + {0x8018, 215}, + {0x801f, 215}, + {0x8029, 215}, + {0xc038, 215}, + {0x8003, 225}, + {0x8006, 225}, + {0x800a, 225}, + {0x800f, 225}, + {0x8018, 225}, + {0x801f, 225}, + {0x8029, 225}, + {0xc038, 225}, + }, + /* 185 */ + { + {0x8002, 236}, + {0x8009, 236}, + {0x8017, 236}, + {0xc028, 236}, + {0x8002, 237}, + {0x8009, 237}, + {0x8017, 237}, + {0xc028, 237}, + {0x8001, 199}, + {0xc016, 199}, + {0x8001, 207}, + {0xc016, 207}, + {0x8001, 234}, + {0xc016, 234}, + {0x8001, 235}, + {0xc016, 235}, + }, + /* 186 */ + { + {0x8003, 236}, + {0x8006, 236}, + {0x800a, 236}, + {0x800f, 236}, + {0x8018, 236}, + {0x801f, 236}, + {0x8029, 236}, + {0xc038, 236}, + {0x8003, 237}, + {0x8006, 237}, + {0x800a, 237}, + {0x800f, 237}, + {0x8018, 237}, + {0x801f, 237}, + {0x8029, 237}, + {0xc038, 237}, + }, + /* 187 */ + { + {0x8002, 199}, + {0x8009, 199}, + {0x8017, 199}, + {0xc028, 199}, + {0x8002, 207}, + {0x8009, 207}, + {0x8017, 207}, + {0xc028, 207}, + {0x8002, 234}, + {0x8009, 234}, + {0x8017, 234}, + {0xc028, 234}, + {0x8002, 235}, + {0x8009, 235}, + {0x8017, 235}, + {0xc028, 235}, + }, + /* 188 */ + { + {0x8003, 199}, + {0x8006, 199}, + {0x800a, 199}, + {0x800f, 199}, + {0x8018, 199}, + {0x801f, 199}, + {0x8029, 199}, + {0xc038, 199}, + {0x8003, 207}, + {0x8006, 207}, + {0x800a, 207}, + {0x800f, 207}, + {0x8018, 207}, + {0x801f, 207}, + {0x8029, 207}, + {0xc038, 207}, + }, + /* 189 */ + { + {0x8003, 234}, + {0x8006, 234}, + {0x800a, 234}, + {0x800f, 234}, + {0x8018, 234}, + {0x801f, 234}, + {0x8029, 234}, + {0xc038, 234}, + {0x8003, 235}, + {0x8006, 235}, + {0x800a, 235}, + {0x800f, 235}, + {0x8018, 235}, + {0x801f, 235}, + {0x8029, 235}, + {0xc038, 235}, + }, + /* 190 */ + { + {0xc2, 0}, + {0xc3, 0}, + {0xc5, 0}, + {0xc6, 0}, + {0xc9, 0}, + {0xca, 0}, + {0xcc, 0}, + {0xcd, 0}, + {0xd2, 0}, + {0xd5, 0}, + {0xd9, 0}, + {0xdc, 0}, + {0xe1, 0}, + {0xe7, 0}, + {0xef, 0}, + {0xf6, 0}, + }, + /* 191 */ + { + {0xc000, 192}, + {0xc000, 193}, + {0xc000, 200}, + {0xc000, 201}, + {0xc000, 202}, + {0xc000, 205}, + {0xc000, 210}, + {0xc000, 213}, + {0xc000, 218}, + {0xc000, 219}, + {0xc000, 238}, + {0xc000, 240}, + {0xc000, 242}, + {0xc000, 243}, + {0xc000, 255}, + {0xce, 0}, + }, + /* 192 */ + { + {0x8001, 192}, + {0xc016, 192}, + {0x8001, 193}, + {0xc016, 193}, + {0x8001, 200}, + {0xc016, 200}, + {0x8001, 201}, + {0xc016, 201}, + {0x8001, 202}, + {0xc016, 202}, + {0x8001, 205}, + {0xc016, 205}, + {0x8001, 210}, + {0xc016, 210}, + {0x8001, 213}, + {0xc016, 213}, + }, + /* 193 */ + { + {0x8002, 192}, + {0x8009, 192}, + {0x8017, 192}, + {0xc028, 192}, + {0x8002, 193}, + {0x8009, 193}, + {0x8017, 193}, + {0xc028, 193}, + {0x8002, 200}, + {0x8009, 200}, + {0x8017, 200}, + {0xc028, 200}, + {0x8002, 201}, + {0x8009, 201}, + {0x8017, 201}, + {0xc028, 201}, + }, + /* 194 */ + { + {0x8003, 192}, + {0x8006, 192}, + {0x800a, 192}, + {0x800f, 192}, + {0x8018, 192}, + {0x801f, 192}, + {0x8029, 192}, + {0xc038, 192}, + {0x8003, 193}, + {0x8006, 193}, + {0x800a, 193}, + {0x800f, 193}, + {0x8018, 193}, + {0x801f, 193}, + {0x8029, 193}, + {0xc038, 193}, + }, + /* 195 */ + { + {0x8003, 200}, + {0x8006, 200}, + {0x800a, 200}, + {0x800f, 200}, + {0x8018, 200}, + {0x801f, 200}, + {0x8029, 200}, + {0xc038, 200}, + {0x8003, 201}, + {0x8006, 201}, + {0x800a, 201}, + {0x800f, 201}, + {0x8018, 201}, + {0x801f, 201}, + {0x8029, 201}, + {0xc038, 201}, + }, + /* 196 */ + { + {0x8002, 202}, + {0x8009, 202}, + {0x8017, 202}, + {0xc028, 202}, + {0x8002, 205}, + {0x8009, 205}, + {0x8017, 205}, + {0xc028, 205}, + {0x8002, 210}, + {0x8009, 210}, + {0x8017, 210}, + {0xc028, 210}, + {0x8002, 213}, + {0x8009, 213}, + {0x8017, 213}, + {0xc028, 213}, + }, + /* 197 */ + { + {0x8003, 202}, + {0x8006, 202}, + {0x800a, 202}, + {0x800f, 202}, + {0x8018, 202}, + {0x801f, 202}, + {0x8029, 202}, + {0xc038, 202}, + {0x8003, 205}, + {0x8006, 205}, + {0x800a, 205}, + {0x800f, 205}, + {0x8018, 205}, + {0x801f, 205}, + {0x8029, 205}, + {0xc038, 205}, + }, + /* 198 */ + { + {0x8003, 210}, + {0x8006, 210}, + {0x800a, 210}, + {0x800f, 210}, + {0x8018, 210}, + {0x801f, 210}, + {0x8029, 210}, + {0xc038, 210}, + {0x8003, 213}, + {0x8006, 213}, + {0x800a, 213}, + {0x800f, 213}, + {0x8018, 213}, + {0x801f, 213}, + {0x8029, 213}, + {0xc038, 213}, + }, + /* 199 */ + { + {0x8001, 218}, + {0xc016, 218}, + {0x8001, 219}, + {0xc016, 219}, + {0x8001, 238}, + {0xc016, 238}, + {0x8001, 240}, + {0xc016, 240}, + {0x8001, 242}, + {0xc016, 242}, + {0x8001, 243}, + {0xc016, 243}, + {0x8001, 255}, + {0xc016, 255}, + {0xc000, 203}, + {0xc000, 204}, + }, + /* 200 */ + { + {0x8002, 218}, + {0x8009, 218}, + {0x8017, 218}, + {0xc028, 218}, + {0x8002, 219}, + {0x8009, 219}, + {0x8017, 219}, + {0xc028, 219}, + {0x8002, 238}, + {0x8009, 238}, + {0x8017, 238}, + {0xc028, 238}, + {0x8002, 240}, + {0x8009, 240}, + {0x8017, 240}, + {0xc028, 240}, + }, + /* 201 */ + { + {0x8003, 218}, + {0x8006, 218}, + {0x800a, 218}, + {0x800f, 218}, + {0x8018, 218}, + {0x801f, 218}, + {0x8029, 218}, + {0xc038, 218}, + {0x8003, 219}, + {0x8006, 219}, + {0x800a, 219}, + {0x800f, 219}, + {0x8018, 219}, + {0x801f, 219}, + {0x8029, 219}, + {0xc038, 219}, + }, + /* 202 */ + { + {0x8003, 238}, + {0x8006, 238}, + {0x800a, 238}, + {0x800f, 238}, + {0x8018, 238}, + {0x801f, 238}, + {0x8029, 238}, + {0xc038, 238}, + {0x8003, 240}, + {0x8006, 240}, + {0x800a, 240}, + {0x800f, 240}, + {0x8018, 240}, + {0x801f, 240}, + {0x8029, 240}, + {0xc038, 240}, + }, + /* 203 */ + { + {0x8002, 242}, + {0x8009, 242}, + {0x8017, 242}, + {0xc028, 242}, + {0x8002, 243}, + {0x8009, 243}, + {0x8017, 243}, + {0xc028, 243}, + {0x8002, 255}, + {0x8009, 255}, + {0x8017, 255}, + {0xc028, 255}, + {0x8001, 203}, + {0xc016, 203}, + {0x8001, 204}, + {0xc016, 204}, + }, + /* 204 */ + { + {0x8003, 242}, + {0x8006, 242}, + {0x800a, 242}, + {0x800f, 242}, + {0x8018, 242}, + {0x801f, 242}, + {0x8029, 242}, + {0xc038, 242}, + {0x8003, 243}, + {0x8006, 243}, + {0x800a, 243}, + {0x800f, 243}, + {0x8018, 243}, + {0x801f, 243}, + {0x8029, 243}, + {0xc038, 243}, + }, + /* 205 */ + { + {0x8003, 255}, + {0x8006, 255}, + {0x800a, 255}, + {0x800f, 255}, + {0x8018, 255}, + {0x801f, 255}, + {0x8029, 255}, + {0xc038, 255}, + {0x8002, 203}, + {0x8009, 203}, + {0x8017, 203}, + {0xc028, 203}, + {0x8002, 204}, + {0x8009, 204}, + {0x8017, 204}, + {0xc028, 204}, + }, + /* 206 */ + { + {0x8003, 203}, + {0x8006, 203}, + {0x800a, 203}, + {0x800f, 203}, + {0x8018, 203}, + {0x801f, 203}, + {0x8029, 203}, + {0xc038, 203}, + {0x8003, 204}, + {0x8006, 204}, + {0x800a, 204}, + {0x800f, 204}, + {0x8018, 204}, + {0x801f, 204}, + {0x8029, 204}, + {0xc038, 204}, + }, + /* 207 */ + { + {0xd3, 0}, + {0xd4, 0}, + {0xd6, 0}, + {0xd7, 0}, + {0xda, 0}, + {0xdb, 0}, + {0xdd, 0}, + {0xde, 0}, + {0xe2, 0}, + {0xe4, 0}, + {0xe8, 0}, + {0xeb, 0}, + {0xf0, 0}, + {0xf3, 0}, + {0xf7, 0}, + {0xfa, 0}, + }, + /* 208 */ + { + {0xc000, 211}, + {0xc000, 212}, + {0xc000, 214}, + {0xc000, 221}, + {0xc000, 222}, + {0xc000, 223}, + {0xc000, 241}, + {0xc000, 244}, + {0xc000, 245}, + {0xc000, 246}, + {0xc000, 247}, + {0xc000, 248}, + {0xc000, 250}, + {0xc000, 251}, + {0xc000, 252}, + {0xc000, 253}, + }, + /* 209 */ + { + {0x8001, 211}, + {0xc016, 211}, + {0x8001, 212}, + {0xc016, 212}, + {0x8001, 214}, + {0xc016, 214}, + {0x8001, 221}, + {0xc016, 221}, + {0x8001, 222}, + {0xc016, 222}, + {0x8001, 223}, + {0xc016, 223}, + {0x8001, 241}, + {0xc016, 241}, + {0x8001, 244}, + {0xc016, 244}, + }, + /* 210 */ + { + {0x8002, 211}, + {0x8009, 211}, + {0x8017, 211}, + {0xc028, 211}, + {0x8002, 212}, + {0x8009, 212}, + {0x8017, 212}, + {0xc028, 212}, + {0x8002, 214}, + {0x8009, 214}, + {0x8017, 214}, + {0xc028, 214}, + {0x8002, 221}, + {0x8009, 221}, + {0x8017, 221}, + {0xc028, 221}, + }, + /* 211 */ + { + {0x8003, 211}, + {0x8006, 211}, + {0x800a, 211}, + {0x800f, 211}, + {0x8018, 211}, + {0x801f, 211}, + {0x8029, 211}, + {0xc038, 211}, + {0x8003, 212}, + {0x8006, 212}, + {0x800a, 212}, + {0x800f, 212}, + {0x8018, 212}, + {0x801f, 212}, + {0x8029, 212}, + {0xc038, 212}, + }, + /* 212 */ + { + {0x8003, 214}, + {0x8006, 214}, + {0x800a, 214}, + {0x800f, 214}, + {0x8018, 214}, + {0x801f, 214}, + {0x8029, 214}, + {0xc038, 214}, + {0x8003, 221}, + {0x8006, 221}, + {0x800a, 221}, + {0x800f, 221}, + {0x8018, 221}, + {0x801f, 221}, + {0x8029, 221}, + {0xc038, 221}, + }, + /* 213 */ + { + {0x8002, 222}, + {0x8009, 222}, + {0x8017, 222}, + {0xc028, 222}, + {0x8002, 223}, + {0x8009, 223}, + {0x8017, 223}, + {0xc028, 223}, + {0x8002, 241}, + {0x8009, 241}, + {0x8017, 241}, + {0xc028, 241}, + {0x8002, 244}, + {0x8009, 244}, + {0x8017, 244}, + {0xc028, 244}, + }, + /* 214 */ + { + {0x8003, 222}, + {0x8006, 222}, + {0x800a, 222}, + {0x800f, 222}, + {0x8018, 222}, + {0x801f, 222}, + {0x8029, 222}, + {0xc038, 222}, + {0x8003, 223}, + {0x8006, 223}, + {0x800a, 223}, + {0x800f, 223}, + {0x8018, 223}, + {0x801f, 223}, + {0x8029, 223}, + {0xc038, 223}, + }, + /* 215 */ + { + {0x8003, 241}, + {0x8006, 241}, + {0x800a, 241}, + {0x800f, 241}, + {0x8018, 241}, + {0x801f, 241}, + {0x8029, 241}, + {0xc038, 241}, + {0x8003, 244}, + {0x8006, 244}, + {0x800a, 244}, + {0x800f, 244}, + {0x8018, 244}, + {0x801f, 244}, + {0x8029, 244}, + {0xc038, 244}, + }, + /* 216 */ + { + {0x8001, 245}, + {0xc016, 245}, + {0x8001, 246}, + {0xc016, 246}, + {0x8001, 247}, + {0xc016, 247}, + {0x8001, 248}, + {0xc016, 248}, + {0x8001, 250}, + {0xc016, 250}, + {0x8001, 251}, + {0xc016, 251}, + {0x8001, 252}, + {0xc016, 252}, + {0x8001, 253}, + {0xc016, 253}, + }, + /* 217 */ + { + {0x8002, 245}, + {0x8009, 245}, + {0x8017, 245}, + {0xc028, 245}, + {0x8002, 246}, + {0x8009, 246}, + {0x8017, 246}, + {0xc028, 246}, + {0x8002, 247}, + {0x8009, 247}, + {0x8017, 247}, + {0xc028, 247}, + {0x8002, 248}, + {0x8009, 248}, + {0x8017, 248}, + {0xc028, 248}, + }, + /* 218 */ + { + {0x8003, 245}, + {0x8006, 245}, + {0x800a, 245}, + {0x800f, 245}, + {0x8018, 245}, + {0x801f, 245}, + {0x8029, 245}, + {0xc038, 245}, + {0x8003, 246}, + {0x8006, 246}, + {0x800a, 246}, + {0x800f, 246}, + {0x8018, 246}, + {0x801f, 246}, + {0x8029, 246}, + {0xc038, 246}, + }, + /* 219 */ + { + {0x8003, 247}, + {0x8006, 247}, + {0x800a, 247}, + {0x800f, 247}, + {0x8018, 247}, + {0x801f, 247}, + {0x8029, 247}, + {0xc038, 247}, + {0x8003, 248}, + {0x8006, 248}, + {0x800a, 248}, + {0x800f, 248}, + {0x8018, 248}, + {0x801f, 248}, + {0x8029, 248}, + {0xc038, 248}, + }, + /* 220 */ + { + {0x8002, 250}, + {0x8009, 250}, + {0x8017, 250}, + {0xc028, 250}, + {0x8002, 251}, + {0x8009, 251}, + {0x8017, 251}, + {0xc028, 251}, + {0x8002, 252}, + {0x8009, 252}, + {0x8017, 252}, + {0xc028, 252}, + {0x8002, 253}, + {0x8009, 253}, + {0x8017, 253}, + {0xc028, 253}, + }, + /* 221 */ + { + {0x8003, 250}, + {0x8006, 250}, + {0x800a, 250}, + {0x800f, 250}, + {0x8018, 250}, + {0x801f, 250}, + {0x8029, 250}, + {0xc038, 250}, + {0x8003, 251}, + {0x8006, 251}, + {0x800a, 251}, + {0x800f, 251}, + {0x8018, 251}, + {0x801f, 251}, + {0x8029, 251}, + {0xc038, 251}, + }, + /* 222 */ + { + {0x8003, 252}, + {0x8006, 252}, + {0x800a, 252}, + {0x800f, 252}, + {0x8018, 252}, + {0x801f, 252}, + {0x8029, 252}, + {0xc038, 252}, + {0x8003, 253}, + {0x8006, 253}, + {0x800a, 253}, + {0x800f, 253}, + {0x8018, 253}, + {0x801f, 253}, + {0x8029, 253}, + {0xc038, 253}, + }, + /* 223 */ + { + {0xc000, 254}, + {0xe3, 0}, + {0xe5, 0}, + {0xe6, 0}, + {0xe9, 0}, + {0xea, 0}, + {0xec, 0}, + {0xed, 0}, + {0xf1, 0}, + {0xf2, 0}, + {0xf4, 0}, + {0xf5, 0}, + {0xf8, 0}, + {0xf9, 0}, + {0xfb, 0}, + {0xfc, 0}, + }, + /* 224 */ + { + {0x8001, 254}, + {0xc016, 254}, + {0xc000, 2}, + {0xc000, 3}, + {0xc000, 4}, + {0xc000, 5}, + {0xc000, 6}, + {0xc000, 7}, + {0xc000, 8}, + {0xc000, 11}, + {0xc000, 12}, + {0xc000, 14}, + {0xc000, 15}, + {0xc000, 16}, + {0xc000, 17}, + {0xc000, 18}, + }, + /* 225 */ + { + {0x8002, 254}, + {0x8009, 254}, + {0x8017, 254}, + {0xc028, 254}, + {0x8001, 2}, + {0xc016, 2}, + {0x8001, 3}, + {0xc016, 3}, + {0x8001, 4}, + {0xc016, 4}, + {0x8001, 5}, + {0xc016, 5}, + {0x8001, 6}, + {0xc016, 6}, + {0x8001, 7}, + {0xc016, 7}, + }, + /* 226 */ + { + {0x8003, 254}, + {0x8006, 254}, + {0x800a, 254}, + {0x800f, 254}, + {0x8018, 254}, + {0x801f, 254}, + {0x8029, 254}, + {0xc038, 254}, + {0x8002, 2}, + {0x8009, 2}, + {0x8017, 2}, + {0xc028, 2}, + {0x8002, 3}, + {0x8009, 3}, + {0x8017, 3}, + {0xc028, 3}, + }, + /* 227 */ + { + {0x8003, 2}, + {0x8006, 2}, + {0x800a, 2}, + {0x800f, 2}, + {0x8018, 2}, + {0x801f, 2}, + {0x8029, 2}, + {0xc038, 2}, + {0x8003, 3}, + {0x8006, 3}, + {0x800a, 3}, + {0x800f, 3}, + {0x8018, 3}, + {0x801f, 3}, + {0x8029, 3}, + {0xc038, 3}, + }, + /* 228 */ + { + {0x8002, 4}, + {0x8009, 4}, + {0x8017, 4}, + {0xc028, 4}, + {0x8002, 5}, + {0x8009, 5}, + {0x8017, 5}, + {0xc028, 5}, + {0x8002, 6}, + {0x8009, 6}, + {0x8017, 6}, + {0xc028, 6}, + {0x8002, 7}, + {0x8009, 7}, + {0x8017, 7}, + {0xc028, 7}, + }, + /* 229 */ + { + {0x8003, 4}, + {0x8006, 4}, + {0x800a, 4}, + {0x800f, 4}, + {0x8018, 4}, + {0x801f, 4}, + {0x8029, 4}, + {0xc038, 4}, + {0x8003, 5}, + {0x8006, 5}, + {0x800a, 5}, + {0x800f, 5}, + {0x8018, 5}, + {0x801f, 5}, + {0x8029, 5}, + {0xc038, 5}, + }, + /* 230 */ + { + {0x8003, 6}, + {0x8006, 6}, + {0x800a, 6}, + {0x800f, 6}, + {0x8018, 6}, + {0x801f, 6}, + {0x8029, 6}, + {0xc038, 6}, + {0x8003, 7}, + {0x8006, 7}, + {0x800a, 7}, + {0x800f, 7}, + {0x8018, 7}, + {0x801f, 7}, + {0x8029, 7}, + {0xc038, 7}, + }, + /* 231 */ + { + {0x8001, 8}, + {0xc016, 8}, + {0x8001, 11}, + {0xc016, 11}, + {0x8001, 12}, + {0xc016, 12}, + {0x8001, 14}, + {0xc016, 14}, + {0x8001, 15}, + {0xc016, 15}, + {0x8001, 16}, + {0xc016, 16}, + {0x8001, 17}, + {0xc016, 17}, + {0x8001, 18}, + {0xc016, 18}, + }, + /* 232 */ + { + {0x8002, 8}, + {0x8009, 8}, + {0x8017, 8}, + {0xc028, 8}, + {0x8002, 11}, + {0x8009, 11}, + {0x8017, 11}, + {0xc028, 11}, + {0x8002, 12}, + {0x8009, 12}, + {0x8017, 12}, + {0xc028, 12}, + {0x8002, 14}, + {0x8009, 14}, + {0x8017, 14}, + {0xc028, 14}, + }, + /* 233 */ + { + {0x8003, 8}, + {0x8006, 8}, + {0x800a, 8}, + {0x800f, 8}, + {0x8018, 8}, + {0x801f, 8}, + {0x8029, 8}, + {0xc038, 8}, + {0x8003, 11}, + {0x8006, 11}, + {0x800a, 11}, + {0x800f, 11}, + {0x8018, 11}, + {0x801f, 11}, + {0x8029, 11}, + {0xc038, 11}, + }, + /* 234 */ + { + {0x8003, 12}, + {0x8006, 12}, + {0x800a, 12}, + {0x800f, 12}, + {0x8018, 12}, + {0x801f, 12}, + {0x8029, 12}, + {0xc038, 12}, + {0x8003, 14}, + {0x8006, 14}, + {0x800a, 14}, + {0x800f, 14}, + {0x8018, 14}, + {0x801f, 14}, + {0x8029, 14}, + {0xc038, 14}, + }, + /* 235 */ + { + {0x8002, 15}, + {0x8009, 15}, + {0x8017, 15}, + {0xc028, 15}, + {0x8002, 16}, + {0x8009, 16}, + {0x8017, 16}, + {0xc028, 16}, + {0x8002, 17}, + {0x8009, 17}, + {0x8017, 17}, + {0xc028, 17}, + {0x8002, 18}, + {0x8009, 18}, + {0x8017, 18}, + {0xc028, 18}, + }, + /* 236 */ + { + {0x8003, 15}, + {0x8006, 15}, + {0x800a, 15}, + {0x800f, 15}, + {0x8018, 15}, + {0x801f, 15}, + {0x8029, 15}, + {0xc038, 15}, + {0x8003, 16}, + {0x8006, 16}, + {0x800a, 16}, + {0x800f, 16}, + {0x8018, 16}, + {0x801f, 16}, + {0x8029, 16}, + {0xc038, 16}, + }, + /* 237 */ + { + {0x8003, 17}, + {0x8006, 17}, + {0x800a, 17}, + {0x800f, 17}, + {0x8018, 17}, + {0x801f, 17}, + {0x8029, 17}, + {0xc038, 17}, + {0x8003, 18}, + {0x8006, 18}, + {0x800a, 18}, + {0x800f, 18}, + {0x8018, 18}, + {0x801f, 18}, + {0x8029, 18}, + {0xc038, 18}, + }, + /* 238 */ + { + {0xc000, 19}, + {0xc000, 20}, + {0xc000, 21}, + {0xc000, 23}, + {0xc000, 24}, + {0xc000, 25}, + {0xc000, 26}, + {0xc000, 27}, + {0xc000, 28}, + {0xc000, 29}, + {0xc000, 30}, + {0xc000, 31}, + {0xc000, 127}, + {0xc000, 220}, + {0xc000, 249}, + {0xfd, 0}, + }, + /* 239 */ + { + {0x8001, 19}, + {0xc016, 19}, + {0x8001, 20}, + {0xc016, 20}, + {0x8001, 21}, + {0xc016, 21}, + {0x8001, 23}, + {0xc016, 23}, + {0x8001, 24}, + {0xc016, 24}, + {0x8001, 25}, + {0xc016, 25}, + {0x8001, 26}, + {0xc016, 26}, + {0x8001, 27}, + {0xc016, 27}, + }, + /* 240 */ + { + {0x8002, 19}, + {0x8009, 19}, + {0x8017, 19}, + {0xc028, 19}, + {0x8002, 20}, + {0x8009, 20}, + {0x8017, 20}, + {0xc028, 20}, + {0x8002, 21}, + {0x8009, 21}, + {0x8017, 21}, + {0xc028, 21}, + {0x8002, 23}, + {0x8009, 23}, + {0x8017, 23}, + {0xc028, 23}, + }, + /* 241 */ + { + {0x8003, 19}, + {0x8006, 19}, + {0x800a, 19}, + {0x800f, 19}, + {0x8018, 19}, + {0x801f, 19}, + {0x8029, 19}, + {0xc038, 19}, + {0x8003, 20}, + {0x8006, 20}, + {0x800a, 20}, + {0x800f, 20}, + {0x8018, 20}, + {0x801f, 20}, + {0x8029, 20}, + {0xc038, 20}, + }, + /* 242 */ + { + {0x8003, 21}, + {0x8006, 21}, + {0x800a, 21}, + {0x800f, 21}, + {0x8018, 21}, + {0x801f, 21}, + {0x8029, 21}, + {0xc038, 21}, + {0x8003, 23}, + {0x8006, 23}, + {0x800a, 23}, + {0x800f, 23}, + {0x8018, 23}, + {0x801f, 23}, + {0x8029, 23}, + {0xc038, 23}, + }, + /* 243 */ + { + {0x8002, 24}, + {0x8009, 24}, + {0x8017, 24}, + {0xc028, 24}, + {0x8002, 25}, + {0x8009, 25}, + {0x8017, 25}, + {0xc028, 25}, + {0x8002, 26}, + {0x8009, 26}, + {0x8017, 26}, + {0xc028, 26}, + {0x8002, 27}, + {0x8009, 27}, + {0x8017, 27}, + {0xc028, 27}, + }, + /* 244 */ + { + {0x8003, 24}, + {0x8006, 24}, + {0x800a, 24}, + {0x800f, 24}, + {0x8018, 24}, + {0x801f, 24}, + {0x8029, 24}, + {0xc038, 24}, + {0x8003, 25}, + {0x8006, 25}, + {0x800a, 25}, + {0x800f, 25}, + {0x8018, 25}, + {0x801f, 25}, + {0x8029, 25}, + {0xc038, 25}, + }, + /* 245 */ + { + {0x8003, 26}, + {0x8006, 26}, + {0x800a, 26}, + {0x800f, 26}, + {0x8018, 26}, + {0x801f, 26}, + {0x8029, 26}, + {0xc038, 26}, + {0x8003, 27}, + {0x8006, 27}, + {0x800a, 27}, + {0x800f, 27}, + {0x8018, 27}, + {0x801f, 27}, + {0x8029, 27}, + {0xc038, 27}, + }, + /* 246 */ + { + {0x8001, 28}, + {0xc016, 28}, + {0x8001, 29}, + {0xc016, 29}, + {0x8001, 30}, + {0xc016, 30}, + {0x8001, 31}, + {0xc016, 31}, + {0x8001, 127}, + {0xc016, 127}, + {0x8001, 220}, + {0xc016, 220}, + {0x8001, 249}, + {0xc016, 249}, + {0xfe, 0}, + {0xff, 0}, + }, + /* 247 */ + { + {0x8002, 28}, + {0x8009, 28}, + {0x8017, 28}, + {0xc028, 28}, + {0x8002, 29}, + {0x8009, 29}, + {0x8017, 29}, + {0xc028, 29}, + {0x8002, 30}, + {0x8009, 30}, + {0x8017, 30}, + {0xc028, 30}, + {0x8002, 31}, + {0x8009, 31}, + {0x8017, 31}, + {0xc028, 31}, + }, + /* 248 */ + { + {0x8003, 28}, + {0x8006, 28}, + {0x800a, 28}, + {0x800f, 28}, + {0x8018, 28}, + {0x801f, 28}, + {0x8029, 28}, + {0xc038, 28}, + {0x8003, 29}, + {0x8006, 29}, + {0x800a, 29}, + {0x800f, 29}, + {0x8018, 29}, + {0x801f, 29}, + {0x8029, 29}, + {0xc038, 29}, + }, + /* 249 */ + { + {0x8003, 30}, + {0x8006, 30}, + {0x800a, 30}, + {0x800f, 30}, + {0x8018, 30}, + {0x801f, 30}, + {0x8029, 30}, + {0xc038, 30}, + {0x8003, 31}, + {0x8006, 31}, + {0x800a, 31}, + {0x800f, 31}, + {0x8018, 31}, + {0x801f, 31}, + {0x8029, 31}, + {0xc038, 31}, + }, + /* 250 */ + { + {0x8002, 127}, + {0x8009, 127}, + {0x8017, 127}, + {0xc028, 127}, + {0x8002, 220}, + {0x8009, 220}, + {0x8017, 220}, + {0xc028, 220}, + {0x8002, 249}, + {0x8009, 249}, + {0x8017, 249}, + {0xc028, 249}, + {0xc000, 10}, + {0xc000, 13}, + {0xc000, 22}, + {0x100, 0}, + }, + /* 251 */ + { + {0x8003, 127}, + {0x8006, 127}, + {0x800a, 127}, + {0x800f, 127}, + {0x8018, 127}, + {0x801f, 127}, + {0x8029, 127}, + {0xc038, 127}, + {0x8003, 220}, + {0x8006, 220}, + {0x800a, 220}, + {0x800f, 220}, + {0x8018, 220}, + {0x801f, 220}, + {0x8029, 220}, + {0xc038, 220}, + }, + /* 252 */ + { + {0x8003, 249}, + {0x8006, 249}, + {0x800a, 249}, + {0x800f, 249}, + {0x8018, 249}, + {0x801f, 249}, + {0x8029, 249}, + {0xc038, 249}, + {0x8001, 10}, + {0xc016, 10}, + {0x8001, 13}, + {0xc016, 13}, + {0x8001, 22}, + {0xc016, 22}, + {0x100, 0}, + {0x100, 0}, + }, + /* 253 */ + { + {0x8002, 10}, + {0x8009, 10}, + {0x8017, 10}, + {0xc028, 10}, + {0x8002, 13}, + {0x8009, 13}, + {0x8017, 13}, + {0xc028, 13}, + {0x8002, 22}, + {0x8009, 22}, + {0x8017, 22}, + {0xc028, 22}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + }, + /* 254 */ + { + {0x8003, 10}, + {0x8006, 10}, + {0x800a, 10}, + {0x800f, 10}, + {0x8018, 10}, + {0x801f, 10}, + {0x8029, 10}, + {0xc038, 10}, + {0x8003, 13}, + {0x8006, 13}, + {0x800a, 13}, + {0x800f, 13}, + {0x8018, 13}, + {0x801f, 13}, + {0x8029, 13}, + {0xc038, 13}, + }, + /* 255 */ + { + {0x8003, 22}, + {0x8006, 22}, + {0x800a, 22}, + {0x800f, 22}, + {0x8018, 22}, + {0x801f, 22}, + {0x8029, 22}, + {0xc038, 22}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + }, + /* 256 */ + { + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + }, };
diff --git a/Utilities/cmnghttp2/lib/nghttp2_helper.c b/Utilities/cmnghttp2/lib/nghttp2_helper.c index 93dd475..f54f37c 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_helper.c +++ b/Utilities/cmnghttp2/lib/nghttp2_helper.c
@@ -53,70 +53,70 @@ /* Generated by gendowncasetbl.py */ static const uint8_t DOWNCASE_TBL[] = { - 0 /* NUL */, 1 /* SOH */, 2 /* STX */, 3 /* ETX */, - 4 /* EOT */, 5 /* ENQ */, 6 /* ACK */, 7 /* BEL */, - 8 /* BS */, 9 /* HT */, 10 /* LF */, 11 /* VT */, - 12 /* FF */, 13 /* CR */, 14 /* SO */, 15 /* SI */, - 16 /* DLE */, 17 /* DC1 */, 18 /* DC2 */, 19 /* DC3 */, - 20 /* DC4 */, 21 /* NAK */, 22 /* SYN */, 23 /* ETB */, - 24 /* CAN */, 25 /* EM */, 26 /* SUB */, 27 /* ESC */, - 28 /* FS */, 29 /* GS */, 30 /* RS */, 31 /* US */, - 32 /* SPC */, 33 /* ! */, 34 /* " */, 35 /* # */, - 36 /* $ */, 37 /* % */, 38 /* & */, 39 /* ' */, - 40 /* ( */, 41 /* ) */, 42 /* * */, 43 /* + */, - 44 /* , */, 45 /* - */, 46 /* . */, 47 /* / */, - 48 /* 0 */, 49 /* 1 */, 50 /* 2 */, 51 /* 3 */, - 52 /* 4 */, 53 /* 5 */, 54 /* 6 */, 55 /* 7 */, - 56 /* 8 */, 57 /* 9 */, 58 /* : */, 59 /* ; */, - 60 /* < */, 61 /* = */, 62 /* > */, 63 /* ? */, - 64 /* @ */, 97 /* A */, 98 /* B */, 99 /* C */, - 100 /* D */, 101 /* E */, 102 /* F */, 103 /* G */, - 104 /* H */, 105 /* I */, 106 /* J */, 107 /* K */, - 108 /* L */, 109 /* M */, 110 /* N */, 111 /* O */, - 112 /* P */, 113 /* Q */, 114 /* R */, 115 /* S */, - 116 /* T */, 117 /* U */, 118 /* V */, 119 /* W */, - 120 /* X */, 121 /* Y */, 122 /* Z */, 91 /* [ */, - 92 /* \ */, 93 /* ] */, 94 /* ^ */, 95 /* _ */, - 96 /* ` */, 97 /* a */, 98 /* b */, 99 /* c */, - 100 /* d */, 101 /* e */, 102 /* f */, 103 /* g */, - 104 /* h */, 105 /* i */, 106 /* j */, 107 /* k */, - 108 /* l */, 109 /* m */, 110 /* n */, 111 /* o */, - 112 /* p */, 113 /* q */, 114 /* r */, 115 /* s */, - 116 /* t */, 117 /* u */, 118 /* v */, 119 /* w */, - 120 /* x */, 121 /* y */, 122 /* z */, 123 /* { */, - 124 /* | */, 125 /* } */, 126 /* ~ */, 127 /* DEL */, - 128 /* 0x80 */, 129 /* 0x81 */, 130 /* 0x82 */, 131 /* 0x83 */, - 132 /* 0x84 */, 133 /* 0x85 */, 134 /* 0x86 */, 135 /* 0x87 */, - 136 /* 0x88 */, 137 /* 0x89 */, 138 /* 0x8a */, 139 /* 0x8b */, - 140 /* 0x8c */, 141 /* 0x8d */, 142 /* 0x8e */, 143 /* 0x8f */, - 144 /* 0x90 */, 145 /* 0x91 */, 146 /* 0x92 */, 147 /* 0x93 */, - 148 /* 0x94 */, 149 /* 0x95 */, 150 /* 0x96 */, 151 /* 0x97 */, - 152 /* 0x98 */, 153 /* 0x99 */, 154 /* 0x9a */, 155 /* 0x9b */, - 156 /* 0x9c */, 157 /* 0x9d */, 158 /* 0x9e */, 159 /* 0x9f */, - 160 /* 0xa0 */, 161 /* 0xa1 */, 162 /* 0xa2 */, 163 /* 0xa3 */, - 164 /* 0xa4 */, 165 /* 0xa5 */, 166 /* 0xa6 */, 167 /* 0xa7 */, - 168 /* 0xa8 */, 169 /* 0xa9 */, 170 /* 0xaa */, 171 /* 0xab */, - 172 /* 0xac */, 173 /* 0xad */, 174 /* 0xae */, 175 /* 0xaf */, - 176 /* 0xb0 */, 177 /* 0xb1 */, 178 /* 0xb2 */, 179 /* 0xb3 */, - 180 /* 0xb4 */, 181 /* 0xb5 */, 182 /* 0xb6 */, 183 /* 0xb7 */, - 184 /* 0xb8 */, 185 /* 0xb9 */, 186 /* 0xba */, 187 /* 0xbb */, - 188 /* 0xbc */, 189 /* 0xbd */, 190 /* 0xbe */, 191 /* 0xbf */, - 192 /* 0xc0 */, 193 /* 0xc1 */, 194 /* 0xc2 */, 195 /* 0xc3 */, - 196 /* 0xc4 */, 197 /* 0xc5 */, 198 /* 0xc6 */, 199 /* 0xc7 */, - 200 /* 0xc8 */, 201 /* 0xc9 */, 202 /* 0xca */, 203 /* 0xcb */, - 204 /* 0xcc */, 205 /* 0xcd */, 206 /* 0xce */, 207 /* 0xcf */, - 208 /* 0xd0 */, 209 /* 0xd1 */, 210 /* 0xd2 */, 211 /* 0xd3 */, - 212 /* 0xd4 */, 213 /* 0xd5 */, 214 /* 0xd6 */, 215 /* 0xd7 */, - 216 /* 0xd8 */, 217 /* 0xd9 */, 218 /* 0xda */, 219 /* 0xdb */, - 220 /* 0xdc */, 221 /* 0xdd */, 222 /* 0xde */, 223 /* 0xdf */, - 224 /* 0xe0 */, 225 /* 0xe1 */, 226 /* 0xe2 */, 227 /* 0xe3 */, - 228 /* 0xe4 */, 229 /* 0xe5 */, 230 /* 0xe6 */, 231 /* 0xe7 */, - 232 /* 0xe8 */, 233 /* 0xe9 */, 234 /* 0xea */, 235 /* 0xeb */, - 236 /* 0xec */, 237 /* 0xed */, 238 /* 0xee */, 239 /* 0xef */, - 240 /* 0xf0 */, 241 /* 0xf1 */, 242 /* 0xf2 */, 243 /* 0xf3 */, - 244 /* 0xf4 */, 245 /* 0xf5 */, 246 /* 0xf6 */, 247 /* 0xf7 */, - 248 /* 0xf8 */, 249 /* 0xf9 */, 250 /* 0xfa */, 251 /* 0xfb */, - 252 /* 0xfc */, 253 /* 0xfd */, 254 /* 0xfe */, 255 /* 0xff */, + 0 /* NUL */, 1 /* SOH */, 2 /* STX */, 3 /* ETX */, + 4 /* EOT */, 5 /* ENQ */, 6 /* ACK */, 7 /* BEL */, + 8 /* BS */, 9 /* HT */, 10 /* LF */, 11 /* VT */, + 12 /* FF */, 13 /* CR */, 14 /* SO */, 15 /* SI */, + 16 /* DLE */, 17 /* DC1 */, 18 /* DC2 */, 19 /* DC3 */, + 20 /* DC4 */, 21 /* NAK */, 22 /* SYN */, 23 /* ETB */, + 24 /* CAN */, 25 /* EM */, 26 /* SUB */, 27 /* ESC */, + 28 /* FS */, 29 /* GS */, 30 /* RS */, 31 /* US */, + 32 /* SPC */, 33 /* ! */, 34 /* " */, 35 /* # */, + 36 /* $ */, 37 /* % */, 38 /* & */, 39 /* ' */, + 40 /* ( */, 41 /* ) */, 42 /* * */, 43 /* + */, + 44 /* , */, 45 /* - */, 46 /* . */, 47 /* / */, + 48 /* 0 */, 49 /* 1 */, 50 /* 2 */, 51 /* 3 */, + 52 /* 4 */, 53 /* 5 */, 54 /* 6 */, 55 /* 7 */, + 56 /* 8 */, 57 /* 9 */, 58 /* : */, 59 /* ; */, + 60 /* < */, 61 /* = */, 62 /* > */, 63 /* ? */, + 64 /* @ */, 97 /* A */, 98 /* B */, 99 /* C */, + 100 /* D */, 101 /* E */, 102 /* F */, 103 /* G */, + 104 /* H */, 105 /* I */, 106 /* J */, 107 /* K */, + 108 /* L */, 109 /* M */, 110 /* N */, 111 /* O */, + 112 /* P */, 113 /* Q */, 114 /* R */, 115 /* S */, + 116 /* T */, 117 /* U */, 118 /* V */, 119 /* W */, + 120 /* X */, 121 /* Y */, 122 /* Z */, 91 /* [ */, + 92 /* \ */, 93 /* ] */, 94 /* ^ */, 95 /* _ */, + 96 /* ` */, 97 /* a */, 98 /* b */, 99 /* c */, + 100 /* d */, 101 /* e */, 102 /* f */, 103 /* g */, + 104 /* h */, 105 /* i */, 106 /* j */, 107 /* k */, + 108 /* l */, 109 /* m */, 110 /* n */, 111 /* o */, + 112 /* p */, 113 /* q */, 114 /* r */, 115 /* s */, + 116 /* t */, 117 /* u */, 118 /* v */, 119 /* w */, + 120 /* x */, 121 /* y */, 122 /* z */, 123 /* { */, + 124 /* | */, 125 /* } */, 126 /* ~ */, 127 /* DEL */, + 128 /* 0x80 */, 129 /* 0x81 */, 130 /* 0x82 */, 131 /* 0x83 */, + 132 /* 0x84 */, 133 /* 0x85 */, 134 /* 0x86 */, 135 /* 0x87 */, + 136 /* 0x88 */, 137 /* 0x89 */, 138 /* 0x8a */, 139 /* 0x8b */, + 140 /* 0x8c */, 141 /* 0x8d */, 142 /* 0x8e */, 143 /* 0x8f */, + 144 /* 0x90 */, 145 /* 0x91 */, 146 /* 0x92 */, 147 /* 0x93 */, + 148 /* 0x94 */, 149 /* 0x95 */, 150 /* 0x96 */, 151 /* 0x97 */, + 152 /* 0x98 */, 153 /* 0x99 */, 154 /* 0x9a */, 155 /* 0x9b */, + 156 /* 0x9c */, 157 /* 0x9d */, 158 /* 0x9e */, 159 /* 0x9f */, + 160 /* 0xa0 */, 161 /* 0xa1 */, 162 /* 0xa2 */, 163 /* 0xa3 */, + 164 /* 0xa4 */, 165 /* 0xa5 */, 166 /* 0xa6 */, 167 /* 0xa7 */, + 168 /* 0xa8 */, 169 /* 0xa9 */, 170 /* 0xaa */, 171 /* 0xab */, + 172 /* 0xac */, 173 /* 0xad */, 174 /* 0xae */, 175 /* 0xaf */, + 176 /* 0xb0 */, 177 /* 0xb1 */, 178 /* 0xb2 */, 179 /* 0xb3 */, + 180 /* 0xb4 */, 181 /* 0xb5 */, 182 /* 0xb6 */, 183 /* 0xb7 */, + 184 /* 0xb8 */, 185 /* 0xb9 */, 186 /* 0xba */, 187 /* 0xbb */, + 188 /* 0xbc */, 189 /* 0xbd */, 190 /* 0xbe */, 191 /* 0xbf */, + 192 /* 0xc0 */, 193 /* 0xc1 */, 194 /* 0xc2 */, 195 /* 0xc3 */, + 196 /* 0xc4 */, 197 /* 0xc5 */, 198 /* 0xc6 */, 199 /* 0xc7 */, + 200 /* 0xc8 */, 201 /* 0xc9 */, 202 /* 0xca */, 203 /* 0xcb */, + 204 /* 0xcc */, 205 /* 0xcd */, 206 /* 0xce */, 207 /* 0xcf */, + 208 /* 0xd0 */, 209 /* 0xd1 */, 210 /* 0xd2 */, 211 /* 0xd3 */, + 212 /* 0xd4 */, 213 /* 0xd5 */, 214 /* 0xd6 */, 215 /* 0xd7 */, + 216 /* 0xd8 */, 217 /* 0xd9 */, 218 /* 0xda */, 219 /* 0xdb */, + 220 /* 0xdc */, 221 /* 0xdd */, 222 /* 0xde */, 223 /* 0xdf */, + 224 /* 0xe0 */, 225 /* 0xe1 */, 226 /* 0xe2 */, 227 /* 0xe3 */, + 228 /* 0xe4 */, 229 /* 0xe5 */, 230 /* 0xe6 */, 231 /* 0xe7 */, + 232 /* 0xe8 */, 233 /* 0xe9 */, 234 /* 0xea */, 235 /* 0xeb */, + 236 /* 0xec */, 237 /* 0xed */, 238 /* 0xee */, 239 /* 0xef */, + 240 /* 0xf0 */, 241 /* 0xf1 */, 242 /* 0xf2 */, 243 /* 0xf3 */, + 244 /* 0xf4 */, 245 /* 0xf5 */, 246 /* 0xf6 */, 247 /* 0xf7 */, + 248 /* 0xf8 */, 249 /* 0xf9 */, 250 /* 0xfa */, 251 /* 0xfb */, + 252 /* 0xfc */, 253 /* 0xfd */, 254 /* 0xfe */, 255 /* 0xff */, }; void nghttp2_downcase(uint8_t *s, size_t len) { @@ -160,7 +160,7 @@ int32_t recv_reduction_delta; int32_t delta; int32_t new_recv_window_size = - nghttp2_max(0, *recv_window_size_ptr) - *delta_ptr; + nghttp2_max_int32(0, *recv_window_size_ptr) - *delta_ptr; if (new_recv_window_size >= 0) { *recv_window_size_ptr = new_recv_window_size; @@ -177,7 +177,7 @@ *local_window_size_ptr += delta; /* If there is recv_reduction due to earlier window_size reduction, we have to adjust it too. */ - recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta); + recv_reduction_delta = nghttp2_min_int32(*recv_reduction_ptr, delta); *recv_reduction_ptr -= recv_reduction_delta; if (*recv_window_size_ptr < 0) { *recv_window_size_ptr += recv_reduction_delta; @@ -233,7 +233,7 @@ *local_window_size_ptr += delta; /* If there is recv_reduction due to earlier window_size reduction, we have to adjust it too. */ - recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta); + recv_reduction_delta = nghttp2_min_int32(*recv_reduction_ptr, delta); *recv_reduction_ptr -= recv_reduction_delta; *recv_window_size_ptr += recv_reduction_delta; @@ -336,6 +336,8 @@ "closed"; case NGHTTP2_ERR_TOO_MANY_SETTINGS: return "SETTINGS frame contained more than the maximum allowed entries"; + case NGHTTP2_ERR_TOO_MANY_CONTINUATIONS: + return "Too many CONTINUATION frames following a HEADER frame"; default: return "Unknown error code"; } @@ -343,70 +345,70 @@ /* Generated by gennmchartbl.py */ static const int VALID_HD_NAME_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, - 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, - 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, - 0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */, - 0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */, - 0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */, - 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */, - 0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, - 0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */, - 0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */, - 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, + 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, + 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, + 0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */, + 0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */, + 0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */, + 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */, + 0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, + 0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */, + 0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */, + 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ }; int nghttp2_check_header_name(const uint8_t *name, size_t len) { @@ -431,70 +433,70 @@ /* Generated by genvchartbl.py */ static const int VALID_HD_VALUE_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, - 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, - 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, - 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, - 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, - 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, - 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, - 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, - 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, - 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, - 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, - 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, - 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, - 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, - 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, - 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, - 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, - 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, - 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, - 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, - 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, - 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, - 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, - 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, - 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, - 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, - 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, - 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, - 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, - 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, - 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, - 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, - 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, - 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, + 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, + 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, + 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, + 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, + 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, + 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, + 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, + 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, + 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, + 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, + 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, + 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, + 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, + 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, + 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, + 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, + 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, + 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, + 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, + 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, + 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, + 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, + 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, + 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, + 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, + 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, + 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, + 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, + 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, + 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, + 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, + 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, + 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, + 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ }; int nghttp2_check_header_value(const uint8_t *value, size_t len) { @@ -522,70 +524,70 @@ /* Generated by genmethodchartbl.py */ static char VALID_METHOD_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, - 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, - 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, - 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 0 /* [ */, - 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, + 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, + 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, + 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 0 /* [ */, + 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ }; int nghttp2_check_method(const uint8_t *value, size_t len) { @@ -603,70 +605,70 @@ /* Generated by genpathchartbl.py */ static char VALID_PATH_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, - 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, - 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, - 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, - 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, - 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, - 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, - 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, - 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, - 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, - 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, - 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, - 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, - 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, - 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, - 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, - 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, - 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, - 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, - 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, - 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, - 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, - 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, - 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, - 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, - 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, - 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, - 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, - 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, - 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, - 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, - 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, - 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, - 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, + 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, + 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, + 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, + 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, + 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, + 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, + 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, + 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, + 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, + 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, + 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, + 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, + 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, + 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, + 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, + 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, + 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, + 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, + 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, + 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, + 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, + 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, + 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, + 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, + 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, + 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, + 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, + 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, + 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, + 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, + 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, + 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, + 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, + 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ }; int nghttp2_check_path(const uint8_t *value, size_t len) { @@ -681,70 +683,70 @@ /* Generated by genauthoritychartbl.py */ static char VALID_AUTHORITY_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, - 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, + 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, + 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ }; int nghttp2_check_authority(const uint8_t *value, size_t len) {
diff --git a/Utilities/cmnghttp2/lib/nghttp2_helper.h b/Utilities/cmnghttp2/lib/nghttp2_helper.h index b1f18ce..7d64076 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_helper.h +++ b/Utilities/cmnghttp2/lib/nghttp2_helper.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <string.h> #include <stddef.h> @@ -35,13 +35,36 @@ #include <nghttp2/nghttp2.h> #include "nghttp2_mem.h" -#define nghttp2_min(A, B) ((A) < (B) ? (A) : (B)) -#define nghttp2_max(A, B) ((A) > (B) ? (A) : (B)) +#define nghttp2_max_def(SUFFIX, T) \ + static inline T nghttp2_max_##SUFFIX(T a, T b) { return a < b ? b : a; } + +nghttp2_max_def(int8, int8_t) +nghttp2_max_def(int16, int16_t) +nghttp2_max_def(int32, int32_t) +nghttp2_max_def(int64, int64_t) +nghttp2_max_def(uint8, uint8_t) +nghttp2_max_def(uint16, uint16_t) +nghttp2_max_def(uint32, uint32_t) +nghttp2_max_def(uint64, uint64_t) +nghttp2_max_def(size, size_t) + +#define nghttp2_min_def(SUFFIX, T) \ + static inline T nghttp2_min_##SUFFIX(T a, T b) { return a < b ? a : b; } + +nghttp2_min_def(int8, int8_t) +nghttp2_min_def(int16, int16_t) +nghttp2_min_def(int32, int32_t) +nghttp2_min_def(int64, int64_t) +nghttp2_min_def(uint8, uint8_t) +nghttp2_min_def(uint16, uint16_t) +nghttp2_min_def(uint32, uint32_t) +nghttp2_min_def(uint64, uint64_t) +nghttp2_min_def(size, size_t) #define lstreq(A, B, N) ((sizeof((A)) - 1) == (N) && memcmp((A), (B), (N)) == 0) #define nghttp2_struct_of(ptr, type, member) \ - ((type *)(void *)((char *)(ptr)-offsetof(type, member))) + ((type *)(void *)((char *)(ptr) - offsetof(type, member))) /* * Copies 2 byte unsigned integer |n| in host byte order to |buf| in @@ -119,4 +142,4 @@ */ uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len); -#endif /* NGHTTP2_HELPER_H */ +#endif /* !defined(NGHTTP2_HELPER_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_http.c b/Utilities/cmnghttp2/lib/nghttp2_http.c index 83e5e66..60a0b01 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_http.c +++ b/Utilities/cmnghttp2/lib/nghttp2_http.c
@@ -31,6 +31,7 @@ #include "nghttp2_hd.h" #include "nghttp2_helper.h" #include "nghttp2_extpri.h" +#include "sfparse.h" static uint8_t downcase(uint8_t c) { return 'A' <= c && c <= 'Z' ? (uint8_t)(c - 'A' + 'a') : c; @@ -206,7 +207,6 @@ if (!trailer && /* Do not parse the header field in PUSH_PROMISE. */ (stream->stream_id & 1) && - (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) && !(stream->http_flags & NGHTTP2_HTTP_FLAG_BAD_PRIORITY)) { nghttp2_extpri_from_uint8(&extpri, stream->http_extpri); if (nghttp2_http_parse_priority(&extpri, nv->value->base, @@ -346,6 +346,84 @@ return 1; } +/* Generated by genauthoritychartbl.py, but '@' is not allowed */ +static char VALID_AUTHORITY_CHARS[] = { + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, + 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, + 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ +}; + +static int check_authority(const uint8_t *value, size_t len) { + const uint8_t *last; + for (last = value + len; value != last; ++value) { + if (!VALID_AUTHORITY_CHARS[*value]) { + return 0; + } + } + return 1; +} + int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, nghttp2_frame *frame, nghttp2_hd_nv *nv, int trailer) { @@ -387,10 +465,10 @@ case NGHTTP2_TOKEN__AUTHORITY: case NGHTTP2_TOKEN_HOST: if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) { - rv = nghttp2_check_authority(nv->value->base, nv->value->len); + rv = check_authority(nv->value->base, nv->value->len); } else if ( - stream->flags & - NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) { + stream->flags & + NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) { rv = nghttp2_check_header_value(nv->value->base, nv->value->len); } else { rv = nghttp2_check_header_value_rfc9113(nv->value->base, nv->value->len); @@ -434,7 +512,7 @@ if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) { return http_request_on_header(stream, nv, trailer, session->server && - session->pending_enable_connect_protocol); + session->pending_enable_connect_protocol); } return http_response_on_header(stream, nv, trailer); @@ -452,7 +530,7 @@ stream->content_length = -1; } else { if ((stream->http_flags & NGHTTP2_HTTP_FLAG_REQ_HEADERS) != - NGHTTP2_HTTP_FLAG_REQ_HEADERS || + NGHTTP2_HTTP_FLAG_REQ_HEADERS || (stream->http_flags & (NGHTTP2_HTTP_FLAG__AUTHORITY | NGHTTP2_HTTP_FLAG_HOST)) == 0) { return -1; @@ -492,7 +570,7 @@ } stream->http_flags = - stream->http_flags & (uint32_t)~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE; + stream->http_flags & (uint32_t)~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE; if (!expect_response_body(stream)) { stream->content_length = 0; @@ -578,713 +656,52 @@ } } -/* Generated by genchartbl.py */ -static const int SF_KEY_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */, - 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */, - 0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */, - 0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */, - 0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */, - 0 /* RS */, 0 /* US */, 0 /* SPC */, 0 /* ! */, 0 /* " */, - 0 /* # */, 0 /* $ */, 0 /* % */, 0 /* & */, 0 /* ' */, - 0 /* ( */, 0 /* ) */, 1 /* * */, 0 /* + */, 0 /* , */, - 1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */, - 1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, - 1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, - 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */, - 0 /* A */, 0 /* B */, 0 /* C */, 0 /* D */, 0 /* E */, - 0 /* F */, 0 /* G */, 0 /* H */, 0 /* I */, 0 /* J */, - 0 /* K */, 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */, - 0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, 0 /* T */, - 0 /* U */, 0 /* V */, 0 /* W */, 0 /* X */, 0 /* Y */, - 0 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 0 /* ^ */, - 1 /* _ */, 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */, - 1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */, - 1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */, - 1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 0 /* | */, - 0 /* } */, 0 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */, - 0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, - 0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */, - 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */, - 0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, - 0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */, - 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */, - 0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, - 0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */, - 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */, - 0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, - 0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */, - 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */, - 0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, - 0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */, - 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */, - 0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, - 0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */, - 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */, - 0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, - 0 /* 0xff */, -}; - -static ssize_t sf_parse_key(const uint8_t *begin, const uint8_t *end) { - const uint8_t *p = begin; - - if ((*p < 'a' || 'z' < *p) && *p != '*') { - return -1; - } - - for (; p != end && SF_KEY_CHARS[*p]; ++p) - ; - - return p - begin; -} - -static ssize_t sf_parse_integer_or_decimal(nghttp2_sf_value *dest, - const uint8_t *begin, - const uint8_t *end) { - const uint8_t *p = begin; - int sign = 1; - int64_t value = 0; - int type = NGHTTP2_SF_VALUE_TYPE_INTEGER; - size_t len = 0; - size_t fpos = 0; - size_t i; - - if (*p == '-') { - if (++p == end) { - return -1; - } - - sign = -1; - } - - if (*p < '0' || '9' < *p) { - return -1; - } - - for (; p != end; ++p) { - switch (*p) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - value *= 10; - value += *p - '0'; - - if (++len > 15) { - return -1; - } - - break; - case '.': - if (type != NGHTTP2_SF_VALUE_TYPE_INTEGER) { - goto fin; - } - - if (len > 12) { - return -1; - } - fpos = len; - type = NGHTTP2_SF_VALUE_TYPE_DECIMAL; - - break; - default: - goto fin; - }; - } - -fin: - switch (type) { - case NGHTTP2_SF_VALUE_TYPE_INTEGER: - if (dest) { - dest->type = (uint8_t)type; - dest->i = value * sign; - } - - return p - begin; - case NGHTTP2_SF_VALUE_TYPE_DECIMAL: - if (fpos == len || len - fpos > 3) { - return -1; - } - - if (dest) { - dest->type = (uint8_t)type; - dest->d = (double)value; - for (i = len - fpos; i > 0; --i) { - dest->d /= (double)10; - } - dest->d *= sign; - } - - return p - begin; - default: - assert(0); - abort(); - } -} - -/* Generated by genchartbl.py */ -static const int SF_DQUOTE_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */, - 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */, - 0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */, - 0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */, - 0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */, - 0 /* RS */, 0 /* US */, 1 /* SPC */, 1 /* ! */, 0 /* " */, - 1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */, - 1 /* - */, 1 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */, - 1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, - 1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, 1 /* @ */, - 1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */, - 1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */, - 1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */, - 1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */, - 1 /* Z */, 1 /* [ */, 0 /* \ */, 1 /* ] */, 1 /* ^ */, - 1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */, - 1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */, - 1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */, - 1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, 1 /* | */, - 1 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */, - 0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, - 0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */, - 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */, - 0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, - 0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */, - 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */, - 0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, - 0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */, - 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */, - 0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, - 0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */, - 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */, - 0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, - 0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */, - 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */, - 0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, - 0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */, - 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */, - 0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, - 0 /* 0xff */, -}; - -static ssize_t sf_parse_string(nghttp2_sf_value *dest, const uint8_t *begin, - const uint8_t *end) { - const uint8_t *p = begin; - - if (*p++ != '"') { - return -1; - } - - for (; p != end; ++p) { - switch (*p) { - case '\\': - if (++p == end) { - return -1; - } - - switch (*p) { - case '"': - case '\\': - break; - default: - return -1; - } - - break; - case '"': - if (dest) { - dest->type = NGHTTP2_SF_VALUE_TYPE_STRING; - dest->s.base = begin + 1; - dest->s.len = (size_t)(p - dest->s.base); - } - - ++p; - - return p - begin; - default: - if (!SF_DQUOTE_CHARS[*p]) { - return -1; - } - } - } - - return -1; -} - -/* Generated by genchartbl.py */ -static const int SF_TOKEN_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */, - 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */, - 0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */, - 0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */, - 0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */, - 0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */, - 1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, 0 /* , */, - 1 /* - */, 1 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */, - 1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, - 1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 0 /* ; */, - 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */, - 1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */, - 1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */, - 1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */, - 1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */, - 1 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 1 /* ^ */, - 1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */, - 1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */, - 1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */, - 1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 1 /* | */, - 0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */, - 0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, - 0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */, - 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */, - 0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, - 0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */, - 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */, - 0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, - 0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */, - 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */, - 0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, - 0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */, - 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */, - 0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, - 0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */, - 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */, - 0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, - 0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */, - 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */, - 0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, - 0 /* 0xff */, -}; - -static ssize_t sf_parse_token(nghttp2_sf_value *dest, const uint8_t *begin, - const uint8_t *end) { - const uint8_t *p = begin; - - if ((*p < 'A' || 'Z' < *p) && (*p < 'a' || 'z' < *p) && *p != '*') { - return -1; - } - - for (; p != end && SF_TOKEN_CHARS[*p]; ++p) - ; - - if (dest) { - dest->type = NGHTTP2_SF_VALUE_TYPE_TOKEN; - dest->s.base = begin; - dest->s.len = (size_t)(p - begin); - } - - return p - begin; -} - -/* Generated by genchartbl.py */ -static const int SF_BYTESEQ_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */, - 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */, - 0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */, - 0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */, - 0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */, - 0 /* RS */, 0 /* US */, 0 /* SPC */, 0 /* ! */, 0 /* " */, - 0 /* # */, 0 /* $ */, 0 /* % */, 0 /* & */, 0 /* ' */, - 0 /* ( */, 0 /* ) */, 0 /* * */, 1 /* + */, 0 /* , */, - 0 /* - */, 0 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */, - 1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, - 1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, - 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */, - 1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */, - 1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */, - 1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */, - 1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */, - 1 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 0 /* ^ */, - 0 /* _ */, 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */, - 1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */, - 1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */, - 1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 0 /* | */, - 0 /* } */, 0 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */, - 0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, - 0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */, - 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */, - 0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, - 0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */, - 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */, - 0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, - 0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */, - 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */, - 0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, - 0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */, - 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */, - 0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, - 0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */, - 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */, - 0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, - 0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */, - 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */, - 0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, - 0 /* 0xff */, -}; - -static ssize_t sf_parse_byteseq(nghttp2_sf_value *dest, const uint8_t *begin, - const uint8_t *end) { - const uint8_t *p = begin; - - if (*p++ != ':') { - return -1; - } - - for (; p != end; ++p) { - switch (*p) { - case ':': - if (dest) { - dest->type = NGHTTP2_SF_VALUE_TYPE_BYTESEQ; - dest->s.base = begin + 1; - dest->s.len = (size_t)(p - dest->s.base); - } - - ++p; - - return p - begin; - default: - if (!SF_BYTESEQ_CHARS[*p]) { - return -1; - } - } - } - - return -1; -} - -static ssize_t sf_parse_boolean(nghttp2_sf_value *dest, const uint8_t *begin, - const uint8_t *end) { - const uint8_t *p = begin; - int b; - - if (*p++ != '?') { - return -1; - } - - if (p == end) { - return -1; - } - - switch (*p++) { - case '0': - b = 0; - break; - case '1': - b = 1; - break; - default: - return -1; - } - - if (dest) { - dest->type = NGHTTP2_SF_VALUE_TYPE_BOOLEAN; - dest->b = b; - } - - return p - begin; -} - -static ssize_t sf_parse_bare_item(nghttp2_sf_value *dest, const uint8_t *begin, - const uint8_t *end) { - switch (*begin) { - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return sf_parse_integer_or_decimal(dest, begin, end); - case '"': - return sf_parse_string(dest, begin, end); - case '*': - return sf_parse_token(dest, begin, end); - case ':': - return sf_parse_byteseq(dest, begin, end); - case '?': - return sf_parse_boolean(dest, begin, end); - default: - if (('A' <= *begin && *begin <= 'Z') || ('a' <= *begin && *begin <= 'z')) { - return sf_parse_token(dest, begin, end); - } - return -1; - } -} - -#define sf_discard_sp_end_err(BEGIN, END, ERR) \ - for (;; ++(BEGIN)) { \ - if ((BEGIN) == (END)) { \ - return (ERR); \ - } \ - if (*(BEGIN) != ' ') { \ - break; \ - } \ - } - -static ssize_t sf_parse_params(const uint8_t *begin, const uint8_t *end) { - const uint8_t *p = begin; - ssize_t slen; - - for (; p != end && *p == ';';) { - ++p; - - sf_discard_sp_end_err(p, end, -1); - - slen = sf_parse_key(p, end); - if (slen < 0) { - return -1; - } - - p += slen; - - if (p == end || *p != '=') { - /* Boolean true */ - } else if (++p == end) { - return -1; - } else { - slen = sf_parse_bare_item(NULL, p, end); - if (slen < 0) { - return -1; - } - - p += slen; - } - } - - return p - begin; -} - -static ssize_t sf_parse_item(nghttp2_sf_value *dest, const uint8_t *begin, - const uint8_t *end) { - const uint8_t *p = begin; - ssize_t slen; - - slen = sf_parse_bare_item(dest, p, end); - if (slen < 0) { - return -1; - } - - p += slen; - - slen = sf_parse_params(p, end); - if (slen < 0) { - return -1; - } - - p += slen; - - return p - begin; -} - -ssize_t nghttp2_sf_parse_item(nghttp2_sf_value *dest, const uint8_t *begin, - const uint8_t *end) { - return sf_parse_item(dest, begin, end); -} - -static ssize_t sf_parse_inner_list(nghttp2_sf_value *dest, const uint8_t *begin, - const uint8_t *end) { - const uint8_t *p = begin; - ssize_t slen; - - if (*p++ != '(') { - return -1; - } - - for (;;) { - sf_discard_sp_end_err(p, end, -1); - - if (*p == ')') { - ++p; - - slen = sf_parse_params(p, end); - if (slen < 0) { - return -1; - } - - p += slen; - - if (dest) { - dest->type = NGHTTP2_SF_VALUE_TYPE_INNER_LIST; - } - - return p - begin; - } - - slen = sf_parse_item(NULL, p, end); - if (slen < 0) { - return -1; - } - - p += slen; - - if (p == end || (*p != ' ' && *p != ')')) { - return -1; - } - } -} - -ssize_t nghttp2_sf_parse_inner_list(nghttp2_sf_value *dest, - const uint8_t *begin, const uint8_t *end) { - return sf_parse_inner_list(dest, begin, end); -} - -static ssize_t sf_parse_item_or_inner_list(nghttp2_sf_value *dest, - const uint8_t *begin, - const uint8_t *end) { - if (*begin == '(') { - return sf_parse_inner_list(dest, begin, end); - } - - return sf_parse_item(dest, begin, end); -} - -#define sf_discard_ows(BEGIN, END) \ - for (;; ++(BEGIN)) { \ - if ((BEGIN) == (END)) { \ - goto fin; \ - } \ - if (*(BEGIN) != ' ' && *(BEGIN) != '\t') { \ - break; \ - } \ - } - -#define sf_discard_ows_end_err(BEGIN, END, ERR) \ - for (;; ++(BEGIN)) { \ - if ((BEGIN) == (END)) { \ - return (ERR); \ - } \ - if (*(BEGIN) != ' ' && *(BEGIN) != '\t') { \ - break; \ - } \ - } - int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value, size_t valuelen) { - const uint8_t *p = value, *end = value + valuelen; - ssize_t slen; - nghttp2_sf_value val; nghttp2_extpri pri = *dest; - const uint8_t *key; - size_t keylen; + sfparse_parser sfp; + sfparse_vec key; + sfparse_value val; + int rv; - for (; p != end && *p == ' '; ++p) - ; + sfparse_parser_init(&sfp, value, valuelen); - for (; p != end;) { - slen = sf_parse_key(p, end); - if (slen < 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - key = p; - keylen = (size_t)slen; - - p += slen; - - if (p == end || *p != '=') { - /* Boolean true */ - val.type = NGHTTP2_SF_VALUE_TYPE_BOOLEAN; - val.b = 1; - - slen = sf_parse_params(p, end); - if (slen < 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - } else if (++p == end) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } else { - slen = sf_parse_item_or_inner_list(&val, p, end); - if (slen < 0) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - } - - p += slen; - - if (keylen == 1) { - switch (key[0]) { - case 'i': - if (val.type != NGHTTP2_SF_VALUE_TYPE_BOOLEAN) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - pri.inc = val.b; - - break; - case 'u': - if (val.type != NGHTTP2_SF_VALUE_TYPE_INTEGER || - val.i < NGHTTP2_EXTPRI_URGENCY_HIGH || - NGHTTP2_EXTPRI_URGENCY_LOW < val.i) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - pri.urgency = (uint32_t)val.i; - + for (;;) { + rv = sfparse_parser_dict(&sfp, &key, &val); + if (rv != 0) { + if (rv == SFPARSE_ERR_EOF) { break; } - } - sf_discard_ows(p, end); - - if (*p++ != ',') { return NGHTTP2_ERR_INVALID_ARGUMENT; } - sf_discard_ows_end_err(p, end, NGHTTP2_ERR_INVALID_ARGUMENT); + if (key.len != 1) { + continue; + } + + switch (key.base[0]) { + case 'i': + if (val.type != SFPARSE_TYPE_BOOLEAN) { + return NGHTTP2_ERR_INVALID_ARGUMENT; + } + + pri.inc = val.boolean; + + break; + case 'u': + if (val.type != SFPARSE_TYPE_INTEGER || + val.integer < NGHTTP2_EXTPRI_URGENCY_HIGH || + NGHTTP2_EXTPRI_URGENCY_LOW < val.integer) { + return NGHTTP2_ERR_INVALID_ARGUMENT; + } + + pri.urgency = (uint32_t)val.integer; + + break; + } } -fin: *dest = pri; return 0;
diff --git a/Utilities/cmnghttp2/lib/nghttp2_http.h b/Utilities/cmnghttp2/lib/nghttp2_http.h index 0c3a78e..2925334 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_http.h +++ b/Utilities/cmnghttp2/lib/nghttp2_http.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> #include "nghttp2_session.h" @@ -94,55 +94,7 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream, nghttp2_frame *frame); -/* - * RFC 8941 Structured Field Values. - */ -typedef enum nghttp2_sf_value_type { - NGHTTP2_SF_VALUE_TYPE_BOOLEAN, - NGHTTP2_SF_VALUE_TYPE_INTEGER, - NGHTTP2_SF_VALUE_TYPE_DECIMAL, - NGHTTP2_SF_VALUE_TYPE_STRING, - NGHTTP2_SF_VALUE_TYPE_TOKEN, - NGHTTP2_SF_VALUE_TYPE_BYTESEQ, - NGHTTP2_SF_VALUE_TYPE_INNER_LIST, -} nghttp2_sf_value_type; - -/* - * nghttp2_sf_value stores Structured Field Values item. For Inner - * List, only type is set to NGHTTP2_SF_VALUE_TYPE_INNER_LIST. - */ -typedef struct nghttp2_sf_value { - uint8_t type; - union { - int b; - int64_t i; - double d; - struct { - const uint8_t *base; - size_t len; - } s; - }; -} nghttp2_sf_value; - -/* - * nghttp2_sf_parse_item parses the input sequence [|begin|, |end|) - * and stores the parsed an Item in |dest|. It returns the number of - * bytes consumed if it succeeds, or -1. This function is declared - * here for unit tests. - */ -ssize_t nghttp2_sf_parse_item(nghttp2_sf_value *dest, const uint8_t *begin, - const uint8_t *end); - -/* - * nghttp2_sf_parse_inner_list parses the input sequence [|begin|, |end|) - * and stores the parsed an Inner List in |dest|. It returns the number of - * bytes consumed if it succeeds, or -1. This function is declared - * here for unit tests. - */ -ssize_t nghttp2_sf_parse_inner_list(nghttp2_sf_value *dest, - const uint8_t *begin, const uint8_t *end); - int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value, size_t valuelen); -#endif /* NGHTTP2_HTTP_H */ +#endif /* !defined(NGHTTP2_HTTP_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_int.h b/Utilities/cmnghttp2/lib/nghttp2_int.h index b23585c..d89cf15 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_int.h +++ b/Utilities/cmnghttp2/lib/nghttp2_int.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -52,7 +52,11 @@ * Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke * nghttp2_on_invalid_header_callback. */ - NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106 + NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106, + /* + * Cancel pushed stream. + */ + NGHTTP2_ERR_PUSH_CANCEL = -107, } nghttp2_internal_error; -#endif /* NGHTTP2_INT_H */ +#endif /* !defined(NGHTTP2_INT_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_map.c b/Utilities/cmnghttp2/lib/nghttp2_map.c index e5db168..f89f310 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_map.c +++ b/Utilities/cmnghttp2/lib/nghttp2_map.c
@@ -31,21 +31,14 @@ #include "nghttp2_helper.h" -#define NGHTTP2_INITIAL_TABLE_LENBITS 8 +#define NGHTTP2_INITIAL_HASHBITS 4 -int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) { +void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem) { map->mem = mem; - map->tablelen = 1 << NGHTTP2_INITIAL_TABLE_LENBITS; - map->tablelenbits = NGHTTP2_INITIAL_TABLE_LENBITS; - map->table = - nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_bucket)); - if (map->table == NULL) { - return NGHTTP2_ERR_NOMEM; - } - + map->hashbits = 0; + map->table = NULL; + map->seed = seed; map->size = 0; - - return 0; } void nghttp2_map_free(nghttp2_map *map) { @@ -56,29 +49,20 @@ nghttp2_mem_free(map->mem, map->table); } -void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr), - void *ptr) { - uint32_t i; - nghttp2_map_bucket *bkt; - - for (i = 0; i < map->tablelen; ++i) { - bkt = &map->table[i]; - - if (bkt->data == NULL) { - continue; - } - - func(bkt->data, ptr); - } -} - -int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr), +int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr), void *ptr) { int rv; - uint32_t i; + size_t i; nghttp2_map_bucket *bkt; + size_t tablelen; - for (i = 0; i < map->tablelen; ++i) { + if (map->size == 0) { + return 0; + } + + tablelen = 1u << map->hashbits; + + for (i = 0; i < tablelen; ++i) { bkt = &map->table[i]; if (bkt->data == NULL) { @@ -94,80 +78,70 @@ return 0; } -static uint32_t hash(nghttp2_map_key_type key) { - return (uint32_t)key * 2654435769u; +static size_t map_hash(const nghttp2_map *map, nghttp2_map_key_type key) { + /* hasher from + https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs + We do not perform finalization here because we use top bits + anyway. */ + uint32_t h = ((uint32_t)key + map->seed) * 0x93d765dd; + return (size_t)((h * 2654435769u) >> (32 - map->hashbits)); } -static size_t h2idx(uint32_t hash, uint32_t bits) { - return hash >> (32 - bits); +static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) { + nghttp2_map_bucket c = *a; + + *a = *b; + *b = c; } -static size_t distance(uint32_t tablelen, uint32_t tablelenbits, - nghttp2_map_bucket *bkt, size_t idx) { - return (idx - h2idx(bkt->hash, tablelenbits)) & (tablelen - 1); -} - -static void map_bucket_swap(nghttp2_map_bucket *bkt, uint32_t *phash, - nghttp2_map_key_type *pkey, void **pdata) { - uint32_t h = bkt->hash; - nghttp2_map_key_type key = bkt->key; - void *data = bkt->data; - - bkt->hash = *phash; - bkt->key = *pkey; - bkt->data = *pdata; - - *phash = h; - *pkey = key; - *pdata = data; -} - -static void map_bucket_set_data(nghttp2_map_bucket *bkt, uint32_t hash, - nghttp2_map_key_type key, void *data) { - bkt->hash = hash; - bkt->key = key; - bkt->data = data; -} - -void nghttp2_map_print_distance(nghttp2_map *map) { - uint32_t i; +#ifndef WIN32 +void nghttp2_map_print_distance(const nghttp2_map *map) { + size_t i; size_t idx; nghttp2_map_bucket *bkt; + size_t tablelen; - for (i = 0; i < map->tablelen; ++i) { + if (map->size == 0) { + return; + } + + tablelen = 1u << map->hashbits; + + for (i = 0; i < tablelen; ++i) { bkt = &map->table[i]; if (bkt->data == NULL) { - fprintf(stderr, "@%u <EMPTY>\n", i); + fprintf(stderr, "@%zu <EMPTY>\n", i); continue; } - idx = h2idx(bkt->hash, map->tablelenbits); - fprintf(stderr, "@%u hash=%08x key=%d base=%zu distance=%zu\n", i, - bkt->hash, bkt->key, idx, - distance(map->tablelen, map->tablelenbits, bkt, idx)); + idx = map_hash(map, bkt->key); + fprintf(stderr, "@%zu hash=%zu key=%d base=%zu distance=%u\n", i, + map_hash(map, bkt->key), bkt->key, idx, bkt->psl); } } +#endif /* !defined(WIN32) */ -static int insert(nghttp2_map_bucket *table, uint32_t tablelen, - uint32_t tablelenbits, uint32_t hash, - nghttp2_map_key_type key, void *data) { - size_t idx = h2idx(hash, tablelenbits); - size_t d = 0, dd; +static int map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) { + size_t idx = map_hash(map, key); + nghttp2_map_bucket b = { + .key = key, + .data = data, + }; nghttp2_map_bucket *bkt; + size_t mask = (1u << map->hashbits) - 1; for (;;) { - bkt = &table[idx]; + bkt = &map->table[idx]; if (bkt->data == NULL) { - map_bucket_set_data(bkt, hash, key, data); + *bkt = b; + ++map->size; return 0; } - dd = distance(tablelen, tablelenbits, bkt, idx); - if (d > dd) { - map_bucket_swap(bkt, &hash, &key, &data); - d = dd; + if (b.psl > bkt->psl) { + map_bucket_swap(bkt, &b); } else if (bkt->key == key) { /* TODO This check is just a waste after first swap or if this function is called from map_resize. That said, there is no @@ -176,42 +150,47 @@ return NGHTTP2_ERR_INVALID_ARGUMENT; } - ++d; - idx = (idx + 1) & (tablelen - 1); + ++b.psl; + idx = (idx + 1) & mask; } } -/* new_tablelen must be power of 2 and new_tablelen == (1 << - new_tablelenbits) must hold. */ -static int map_resize(nghttp2_map *map, uint32_t new_tablelen, - uint32_t new_tablelenbits) { - uint32_t i; - nghttp2_map_bucket *new_table; +static int map_resize(nghttp2_map *map, size_t new_hashbits) { + size_t i; nghttp2_map_bucket *bkt; + size_t tablelen; int rv; + nghttp2_map new_map = { + .table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits, + sizeof(nghttp2_map_bucket)), + .mem = map->mem, + .seed = map->seed, + .hashbits = new_hashbits, + }; (void)rv; - new_table = - nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_bucket)); - if (new_table == NULL) { + if (new_map.table == NULL) { return NGHTTP2_ERR_NOMEM; } - for (i = 0; i < map->tablelen; ++i) { - bkt = &map->table[i]; - if (bkt->data == NULL) { - continue; - } - rv = insert(new_table, new_tablelen, new_tablelenbits, bkt->hash, bkt->key, - bkt->data); + if (map->size) { + tablelen = 1u << map->hashbits; - assert(0 == rv); + for (i = 0; i < tablelen; ++i) { + bkt = &map->table[i]; + if (bkt->data == NULL) { + continue; + } + + rv = map_insert(&new_map, bkt->key, bkt->data); + + assert(0 == rv); + } } nghttp2_mem_free(map->mem, map->table); - map->tablelen = new_tablelen; - map->tablelenbits = new_tablelenbits; - map->table = new_table; + map->table = new_map.table; + map->hashbits = new_hashbits; return 0; } @@ -221,34 +200,48 @@ assert(data); - /* Load factor is 0.75 */ - if ((map->size + 1) * 4 > map->tablelen * 3) { - rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1); - if (rv != 0) { - return rv; + /* Load factor is 7/8 */ + /* Under the very initial condition, that is map->size == 0 and + map->hashbits == 0, 8 > 7 still holds nicely. */ + if ((map->size + 1) * 8 > (1u << map->hashbits) * 7) { + if (map->hashbits) { + rv = map_resize(map, map->hashbits + 1); + if (rv != 0) { + return rv; + } + } else { + rv = map_resize(map, NGHTTP2_INITIAL_HASHBITS); + if (rv != 0) { + return rv; + } } } - rv = insert(map->table, map->tablelen, map->tablelenbits, hash(key), key, - data); + rv = map_insert(map, key, data); if (rv != 0) { return rv; } - ++map->size; + return 0; } -void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) { - uint32_t h = hash(key); - size_t idx = h2idx(h, map->tablelenbits); +void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) { + size_t idx; nghttp2_map_bucket *bkt; - size_t d = 0; + size_t psl = 0; + size_t mask; + + if (map->size == 0) { + return NULL; + } + + idx = map_hash(map, key); + mask = (1u << map->hashbits) - 1; for (;;) { bkt = &map->table[idx]; - if (bkt->data == NULL || - d > distance(map->tablelen, map->tablelenbits, bkt, idx)) { + if (bkt->data == NULL || psl > bkt->psl) { return NULL; } @@ -256,43 +249,47 @@ return bkt->data; } - ++d; - idx = (idx + 1) & (map->tablelen - 1); + ++psl; + idx = (idx + 1) & mask; } } int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) { - uint32_t h = hash(key); - size_t idx = h2idx(h, map->tablelenbits), didx; - nghttp2_map_bucket *bkt; - size_t d = 0; + size_t idx; + nghttp2_map_bucket *b, *bkt; + size_t psl = 0; + size_t mask; + + if (map->size == 0) { + return NGHTTP2_ERR_INVALID_ARGUMENT; + } + + idx = map_hash(map, key); + mask = (1u << map->hashbits) - 1; for (;;) { bkt = &map->table[idx]; - if (bkt->data == NULL || - d > distance(map->tablelen, map->tablelenbits, bkt, idx)) { + if (bkt->data == NULL || psl > bkt->psl) { return NGHTTP2_ERR_INVALID_ARGUMENT; } if (bkt->key == key) { - map_bucket_set_data(bkt, 0, 0, NULL); - - didx = idx; - idx = (idx + 1) & (map->tablelen - 1); + b = bkt; + idx = (idx + 1) & mask; for (;;) { bkt = &map->table[idx]; - if (bkt->data == NULL || - distance(map->tablelen, map->tablelenbits, bkt, idx) == 0) { + if (bkt->data == NULL || bkt->psl == 0) { + b->data = NULL; break; } - map->table[didx] = *bkt; - map_bucket_set_data(bkt, 0, 0, NULL); - didx = idx; + --bkt->psl; + *b = *bkt; + b = bkt; - idx = (idx + 1) & (map->tablelen - 1); + idx = (idx + 1) & mask; } --map->size; @@ -300,14 +297,18 @@ return 0; } - ++d; - idx = (idx + 1) & (map->tablelen - 1); + ++psl; + idx = (idx + 1) & mask; } } void nghttp2_map_clear(nghttp2_map *map) { - memset(map->table, 0, sizeof(*map->table) * map->tablelen); + if (map->size == 0) { + return; + } + + memset(map->table, 0, sizeof(*map->table) * (1u << map->hashbits)); map->size = 0; } -size_t nghttp2_map_size(nghttp2_map *map) { return map->size; } +size_t nghttp2_map_size(const nghttp2_map *map) { return map->size; }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_map.h b/Utilities/cmnghttp2/lib/nghttp2_map.h index 1419a09..e45685b 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_map.h +++ b/Utilities/cmnghttp2/lib/nghttp2_map.h
@@ -28,7 +28,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -39,7 +39,7 @@ typedef int32_t nghttp2_map_key_type; typedef struct nghttp2_map_bucket { - uint32_t hash; + uint32_t psl; nghttp2_map_key_type key; void *data; } nghttp2_map_bucket; @@ -47,40 +47,26 @@ typedef struct nghttp2_map { nghttp2_map_bucket *table; nghttp2_mem *mem; + uint32_t seed; size_t size; - uint32_t tablelen; - uint32_t tablelenbits; + size_t hashbits; } nghttp2_map; /* - * Initializes the map |map|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory + * nghttp2_map_init initializes the map |map|. */ -int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem); +void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem); /* - * Deallocates any resources allocated for |map|. The stored entries - * are not freed by this function. Use nghttp2_map_each_free() to free - * each entries. + * nghttp2_map_free deallocates any resources allocated for |map|. + * The stored entries are not freed by this function. Use + * nghttp2_map_each() to free each entry. */ void nghttp2_map_free(nghttp2_map *map); /* - * Deallocates each entries using |func| function and any resources - * allocated for |map|. The |func| function is responsible for freeing - * given the |data| object. The |ptr| will be passed to the |func| as - * send argument. The return value of the |func| will be ignored. - */ -void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr), - void *ptr); - -/* - * Inserts the new |data| with the |key| to the map |map|. + * nghttp2_map_insert inserts the new |data| with the |key| to the map + * |map|. * * This function returns 0 if it succeeds, or one of the following * negative error codes: @@ -88,55 +74,56 @@ * NGHTTP2_ERR_INVALID_ARGUMENT * The item associated by |key| already exists. * NGHTTP2_ERR_NOMEM - * Out of memory + * Out of memory */ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data); /* - * Returns the data associated by the key |key|. If there is no such - * data, this function returns NULL. + * nghttp2_map_find returns the entry associated by the key |key|. If + * there is no such entry, this function returns NULL. */ -void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key); +void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key); /* - * Removes the data associated by the key |key| from the |map|. The - * removed data is not freed by this function. + * nghttp2_map_remove removes the entry associated by the key |key| + * from the |map|. The removed entry is not freed by this function. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * * NGHTTP2_ERR_INVALID_ARGUMENT - * The data associated by |key| does not exist. + * The entry associated by |key| does not exist. */ int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key); /* - * Removes all entries from |map|. + * nghttp2_map_clear removes all entries from |map|. The removed + * entry is not freed by this function. */ void nghttp2_map_clear(nghttp2_map *map); /* - * Returns the number of items stored in the map |map|. + * nghttp2_map_size returns the number of items stored in the map + * |map|. */ -size_t nghttp2_map_size(nghttp2_map *map); +size_t nghttp2_map_size(const nghttp2_map *map); /* - * Applies the function |func| to each data in the |map| with the - * optional user supplied pointer |ptr|. + * nghttp2_map_each applies the function |func| to each entry in the + * |map| with the optional user supplied pointer |ptr|. * * If the |func| returns 0, this function calls the |func| with the - * next data. If the |func| returns nonzero, it will not call the + * next entry. If the |func| returns nonzero, it will not call the * |func| for further entries and return the return value of the * |func| immediately. Thus, this function returns 0 if all the * invocations of the |func| return 0, or nonzero value which the last * invocation of |func| returns. - * - * Don't use this function to free each data. Use - * nghttp2_map_each_free() instead. */ -int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr), +int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr), void *ptr); -void nghttp2_map_print_distance(nghttp2_map *map); +#ifndef WIN32 +void nghttp2_map_print_distance(const nghttp2_map *map); +#endif /* !defined(WIN32) */ -#endif /* NGHTTP2_MAP_H */ +#endif /* !defined(NGHTTP2_MAP_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_mem.h b/Utilities/cmnghttp2/lib/nghttp2_mem.h index f83dbcb..10af7c6 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_mem.h +++ b/Utilities/cmnghttp2/lib/nghttp2_mem.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -42,4 +42,4 @@ void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size); void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size); -#endif /* NGHTTP2_MEM_H */ +#endif /* !defined(NGHTTP2_MEM_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_net.h b/Utilities/cmnghttp2/lib/nghttp2_net.h index 521f981..0c57d94 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_net.h +++ b/Utilities/cmnghttp2/lib/nghttp2_net.h
@@ -27,28 +27,28 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #ifdef HAVE_ARPA_INET_H # include <arpa/inet.h> -#endif /* HAVE_ARPA_INET_H */ +#endif /* defined(HAVE_ARPA_INET_H) */ #ifdef HAVE_NETINET_IN_H # include <netinet/in.h> -#endif /* HAVE_NETINET_IN_H */ +#endif /* defined(HAVE_NETINET_IN_H) */ #include <nghttp2/nghttp2.h> -#if defined(WIN32) +#ifdef WIN32 /* Windows requires ws2_32 library for ntonl family functions. We define inline functions for those function so that we don't have dependency on that lib. */ # ifdef _MSC_VER # define STIN static __inline -# else +# else /* !defined(_MSC_VER) */ # define STIN static inline -# endif +# endif /* !defined(_MSC_VER) */ STIN uint32_t htonl(uint32_t hostlong) { uint32_t res; @@ -86,6 +86,6 @@ return res; } -#endif /* WIN32 */ +#endif /* defined(WIN32) */ -#endif /* NGHTTP2_NET_H */ +#endif /* !defined(NGHTTP2_NET_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_option.c b/Utilities/cmnghttp2/lib/nghttp2_option.c index ee0cd0f..7e44a24 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_option.c +++ b/Utilities/cmnghttp2/lib/nghttp2_option.c
@@ -132,14 +132,33 @@ } void nghttp2_option_set_server_fallback_rfc7540_priorities( - nghttp2_option *option, int val) { + nghttp2_option *option, int val) { option->opt_set_mask |= NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES; option->server_fallback_rfc7540_priorities = val; } void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation( - nghttp2_option *option, int val) { + nghttp2_option *option, int val) { option->opt_set_mask |= - NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; + NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; option->no_rfc9113_leading_and_trailing_ws_validation = val; } + +void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, + uint64_t burst, uint64_t rate) { + option->opt_set_mask |= NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT; + option->stream_reset_burst = burst; + option->stream_reset_rate = rate; +} + +void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) { + option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS; + option->max_continuations = val; +} + +void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option, + uint64_t burst, uint64_t rate) { + option->opt_set_mask |= NGHTTP2_OPT_GLITCH_RATE_LIMIT; + option->glitch_burst = burst; + option->glitch_rate = rate; +}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_option.h b/Utilities/cmnghttp2/lib/nghttp2_option.h index b228a07..711185b 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_option.h +++ b/Utilities/cmnghttp2/lib/nghttp2_option.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -70,6 +70,9 @@ NGHTTP2_OPT_MAX_SETTINGS = 1 << 12, NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 13, NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14, + NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15, + NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16, + NGHTTP2_OPT_GLITCH_RATE_LIMIT = 1 << 17, } nghttp2_option_flag; /** @@ -77,6 +80,16 @@ */ struct nghttp2_option { /** + * NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT + */ + uint64_t stream_reset_burst; + uint64_t stream_reset_rate; + /** + * NGHTTP2_OPT_GLITCH_RATE_LIMIT + */ + uint64_t glitch_burst; + uint64_t glitch_rate; + /** * NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH */ size_t max_send_header_block_length; @@ -93,6 +106,10 @@ */ size_t max_settings; /** + * NGHTTP2_OPT_MAX_CONTINUATIONS + */ + size_t max_continuations; + /** * Bitwise OR of nghttp2_option_flag to determine that which fields * are specified. */ @@ -143,4 +160,4 @@ uint8_t user_recv_ext_types[32]; }; -#endif /* NGHTTP2_OPTION_H */ +#endif /* !defined(NGHTTP2_OPTION_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c index 2a3041d..a9e9f76 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c +++ b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c
@@ -27,6 +27,32 @@ #include <assert.h> #include <string.h> +nghttp2_data_provider_wrap * +nghttp2_data_provider_wrap_v1(nghttp2_data_provider_wrap *dpw, + const nghttp2_data_provider *data_prd) { + if (!data_prd) { + return NULL; + } + + dpw->version = NGHTTP2_DATA_PROVIDER_V1; + dpw->data_prd.v1 = *data_prd; + + return dpw; +} + +nghttp2_data_provider_wrap * +nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw, + const nghttp2_data_provider2 *data_prd) { + if (!data_prd) { + return NULL; + } + + dpw->version = NGHTTP2_DATA_PROVIDER_V2; + dpw->data_prd.v2 = *data_prd; + + return dpw; +} + void nghttp2_outbound_item_init(nghttp2_outbound_item *item) { item->cycle = 0; item->qnext = NULL;
diff --git a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h index bd4611b..6e8e310 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h +++ b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h
@@ -27,15 +27,38 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> #include "nghttp2_frame.h" #include "nghttp2_mem.h" +#define NGHTTP2_DATA_PROVIDER_V1 1 +#define NGHTTP2_DATA_PROVIDER_V2 2 + +typedef struct nghttp2_data_provider_wrap { + int version; + union { + struct { + nghttp2_data_source source; + void *read_callback; + }; + nghttp2_data_provider v1; + nghttp2_data_provider2 v2; + } data_prd; +} nghttp2_data_provider_wrap; + +nghttp2_data_provider_wrap * +nghttp2_data_provider_wrap_v1(nghttp2_data_provider_wrap *dpw, + const nghttp2_data_provider *data_prd); + +nghttp2_data_provider_wrap * +nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw, + const nghttp2_data_provider2 *data_prd); + /* struct used for HEADERS and PUSH_PROMISE frame */ typedef struct { - nghttp2_data_provider data_prd; + nghttp2_data_provider_wrap dpw; void *stream_user_data; /* error code when request HEADERS is canceled by RST_STREAM while it is in queue. */ @@ -50,7 +73,7 @@ /** * The data to be sent for this DATA frame. */ - nghttp2_data_provider data_prd; + nghttp2_data_provider_wrap dpw; /** * The flags of DATA frame. We use separate flags here and * nghttp2_data frame. The latter contains flags actually sent to @@ -163,4 +186,4 @@ /* Returns the size of the queue */ #define nghttp2_outbound_queue_size(Q) ((Q)->n) -#endif /* NGHTTP2_OUTBOUND_ITEM_H */ +#endif /* !defined(NGHTTP2_OUTBOUND_ITEM_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_pq.c b/Utilities/cmnghttp2/lib/nghttp2_pq.c index 64353ac..e79ba83 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_pq.c +++ b/Utilities/cmnghttp2/lib/nghttp2_pq.c
@@ -69,7 +69,7 @@ void *nq; size_t ncapacity; - ncapacity = nghttp2_max(4, (pq->capacity * 2)); + ncapacity = nghttp2_max_size(4, (pq->capacity * 2)); nq = nghttp2_mem_realloc(pq->mem, pq->q, ncapacity * sizeof(nghttp2_pq_entry *));
diff --git a/Utilities/cmnghttp2/lib/nghttp2_pq.h b/Utilities/cmnghttp2/lib/nghttp2_pq.h index c8d90ef..5dd863f 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_pq.h +++ b/Utilities/cmnghttp2/lib/nghttp2_pq.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> #include "nghttp2_int.h" @@ -121,4 +121,4 @@ */ void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item); -#endif /* NGHTTP2_PQ_H */ +#endif /* !defined(NGHTTP2_PQ_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h b/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h index 92ece82..158e0dc 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h +++ b/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -39,4 +39,4 @@ */ void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec); -#endif /* NGHTTP2_PRIORITY_SPEC_H */ +#endif /* !defined(NGHTTP2_PRIORITY_SPEC_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_queue.c b/Utilities/cmnghttp2/lib/nghttp2_queue.c index 055eb69..3b63158 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_queue.c +++ b/Utilities/cmnghttp2/lib/nghttp2_queue.c
@@ -46,7 +46,7 @@ int nghttp2_queue_push(nghttp2_queue *queue, void *data) { nghttp2_queue_cell *new_cell = - (nghttp2_queue_cell *)malloc(sizeof(nghttp2_queue_cell)); + (nghttp2_queue_cell *)malloc(sizeof(nghttp2_queue_cell)); if (!new_cell) { return NGHTTP2_ERR_NOMEM; }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_queue.h b/Utilities/cmnghttp2/lib/nghttp2_queue.h index a06fa6c..c63897c 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_queue.h +++ b/Utilities/cmnghttp2/lib/nghttp2_queue.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include "config.h" -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -48,4 +48,4 @@ void *nghttp2_queue_back(nghttp2_queue *queue); int nghttp2_queue_empty(nghttp2_queue *queue); -#endif /* NGHTTP2_QUEUE_H */ +#endif /* !defined(NGHTTP2_QUEUE_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_ratelim.c b/Utilities/cmnghttp2/lib/nghttp2_ratelim.c new file mode 100644 index 0000000..604ac08 --- /dev/null +++ b/Utilities/cmnghttp2/lib/nghttp2_ratelim.c
@@ -0,0 +1,75 @@ +/* + * nghttp2 - HTTP/2 C Library + * + * Copyright (c) 2023 nghttp2 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "nghttp2_ratelim.h" +#include "nghttp2_helper.h" + +void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate) { + rl->val = rl->burst = burst; + rl->rate = rate; + rl->tstamp = 0; +} + +void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp) { + uint64_t d, gain; + + if (tstamp == rl->tstamp) { + return; + } + + if (tstamp > rl->tstamp) { + d = tstamp - rl->tstamp; + } else { + d = 1; + } + + rl->tstamp = tstamp; + + if (UINT64_MAX / d < rl->rate) { + rl->val = rl->burst; + + return; + } + + gain = rl->rate * d; + + if (UINT64_MAX - gain < rl->val) { + rl->val = rl->burst; + + return; + } + + rl->val += gain; + rl->val = nghttp2_min_uint64(rl->val, rl->burst); +} + +int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n) { + if (rl->val < n) { + return -1; + } + + rl->val -= n; + + return 0; +}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_ratelim.h b/Utilities/cmnghttp2/lib/nghttp2_ratelim.h new file mode 100644 index 0000000..d1097f2 --- /dev/null +++ b/Utilities/cmnghttp2/lib/nghttp2_ratelim.h
@@ -0,0 +1,57 @@ +/* + * nghttp2 - HTTP/2 C Library + * + * Copyright (c) 2023 nghttp2 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef NGHTTP2_RATELIM_H +#define NGHTTP2_RATELIM_H + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif /* defined(HAVE_CONFIG_H) */ + +#include <nghttp2/nghttp2.h> + +typedef struct nghttp2_ratelim { + /* burst is the maximum value of val. */ + uint64_t burst; + /* rate is the amount of value that is regenerated per 1 tstamp. */ + uint64_t rate; + /* val is the amount of value available to drain. */ + uint64_t val; + /* tstamp is the last timestamp in second resolution that is known + to this object. */ + uint64_t tstamp; +} nghttp2_ratelim; + +/* nghttp2_ratelim_init initializes |rl| with the given parameters. */ +void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate); + +/* nghttp2_ratelim_update updates rl->val with the current |tstamp| + given in second resolution. */ +void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp); + +/* nghttp2_ratelim_drain drains |n| from rl->val. It returns 0 if it + succeeds, or -1. */ +int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n); + +#endif /* !defined(NGHTTP2_RATELIM_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h b/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h index 6814e70..ef82e1b 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h +++ b/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> @@ -77,4 +77,4 @@ */ void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf); -#endif /* NGHTTP2_RCBUF_H */ +#endif /* !defined(NGHTTP2_RCBUF_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_session.c b/Utilities/cmnghttp2/lib/nghttp2_session.c index 93f3f07..1f4ea54 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_session.c +++ b/Utilities/cmnghttp2/lib/nghttp2_session.c
@@ -37,7 +37,11 @@ #include "nghttp2_http.h" #include "nghttp2_pq.h" #include "nghttp2_extpri.h" +#include "nghttp2_time.h" #include "nghttp2_debug.h" +#include "nghttp2_submit.h" + +nghttp2_stream nghttp2_stream_root; /* * Returns non-zero if the number of outgoing opened streams is larger @@ -144,11 +148,6 @@ return 0; } -static int session_no_rfc7540_pri_no_fallback(nghttp2_session *session) { - return session->pending_no_rfc7540_priorities == 1 && - !session->fallback_rfc7540_priorities; -} - static int check_ext_type_set(const uint8_t *ext_types, uint8_t type) { return (ext_types[type / 8] & (1 << (type & 0x7))) > 0; } @@ -237,9 +236,9 @@ debug_datalen = strlen(reason); } - rv = nghttp2_session_add_goaway(session, last_stream_id, error_code, - debug_data, debug_datalen, - NGHTTP2_GOAWAY_AUX_TERM_ON_SEND); + rv = + nghttp2_session_add_goaway(session, last_stream_id, error_code, debug_data, + debug_datalen, NGHTTP2_GOAWAY_AUX_TERM_ON_SEND); if (rv != 0) { return rv; @@ -437,8 +436,9 @@ int rv; size_t nbuffer; size_t max_deflate_dynamic_table_size = - NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE; + NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE; size_t i; + uint32_t map_seed; if (mem == NULL) { mem = nghttp2_mem_default(); @@ -456,10 +456,6 @@ /* next_stream_id is initialized in either nghttp2_session_client_new2 or nghttp2_session_server_new2 */ - nghttp2_stream_init(&(*session_ptr)->root, 0, NGHTTP2_STREAM_FLAG_NONE, - NGHTTP2_STREAM_IDLE, NGHTTP2_DEFAULT_WEIGHT, 0, 0, NULL, - mem); - (*session_ptr)->remote_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE; (*session_ptr)->recv_window_size = 0; (*session_ptr)->consumed_size = 0; @@ -471,10 +467,18 @@ (*session_ptr)->remote_last_stream_id = (1u << 31) - 1; (*session_ptr)->pending_local_max_concurrent_stream = - NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; + NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; (*session_ptr)->pending_enable_push = 1; (*session_ptr)->pending_no_rfc7540_priorities = UINT8_MAX; + nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim, + NGHTTP2_DEFAULT_STREAM_RESET_BURST, + NGHTTP2_DEFAULT_STREAM_RESET_RATE); + + nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim, + NGHTTP2_DEFAULT_GLITCH_BURST, + NGHTTP2_DEFAULT_GLITCH_RATE); + if (server) { (*session_ptr)->server = 1; } @@ -483,7 +487,7 @@ init_settings(&(*session_ptr)->local_settings); (*session_ptr)->max_incoming_reserved_streams = - NGHTTP2_MAX_INCOMING_RESERVED_STREAMS; + NGHTTP2_MAX_INCOMING_RESERVED_STREAMS; /* Limit max outgoing concurrent streams to sensible value */ (*session_ptr)->remote_settings.max_concurrent_streams = 100; @@ -491,35 +495,31 @@ (*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN; (*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM; (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS; + (*session_ptr)->max_continuations = NGHTTP2_DEFAULT_MAX_CONTINUATIONS; if (option) { if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) && option->no_auto_window_update) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE; } if (option->opt_set_mask & NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS) { - (*session_ptr)->remote_settings.max_concurrent_streams = - option->peer_max_concurrent_streams; + option->peer_max_concurrent_streams; } if (option->opt_set_mask & NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS) { - (*session_ptr)->max_incoming_reserved_streams = - option->max_reserved_remote_streams; + option->max_reserved_remote_streams; } if ((option->opt_set_mask & NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC) && option->no_recv_client_magic) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC; } if ((option->opt_set_mask & NGHTTP2_OPT_NO_HTTP_MESSAGING) && option->no_http_messaging) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_HTTP_MESSAGING; } @@ -539,18 +539,13 @@ if (option->opt_set_mask & NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH) { (*session_ptr)->max_send_header_block_length = - option->max_send_header_block_length; + option->max_send_header_block_length; } if (option->opt_set_mask & NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE) { max_deflate_dynamic_table_size = option->max_deflate_dynamic_table_size; } - if ((option->opt_set_mask & NGHTTP2_OPT_NO_CLOSED_STREAMS) && - option->no_closed_streams) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_CLOSED_STREAMS; - } - if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) { (*session_ptr)->max_outbound_ack = option->max_outbound_ack; } @@ -561,17 +556,25 @@ } if ((option->opt_set_mask & - NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES) && - option->server_fallback_rfc7540_priorities) { - (*session_ptr)->opt_flags |= - NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES; - } - - if ((option->opt_set_mask & NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) && option->no_rfc9113_leading_and_trailing_ws_validation) { (*session_ptr)->opt_flags |= - NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; + NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; + } + + if (option->opt_set_mask & NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT) { + nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim, + option->stream_reset_burst, + option->stream_reset_rate); + } + + if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) { + (*session_ptr)->max_continuations = option->max_continuations; + } + + if (option->opt_set_mask & NGHTTP2_OPT_GLITCH_RATE_LIMIT) { + nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim, + option->glitch_burst, option->glitch_rate); } } @@ -584,10 +587,6 @@ if (rv != 0) { goto fail_hd_inflater; } - rv = nghttp2_map_init(&(*session_ptr)->streams, mem); - if (rv != 0) { - goto fail_map; - } nbuffer = ((*session_ptr)->max_send_header_block_length + NGHTTP2_FRAMEBUF_CHUNKLEN - 1) / @@ -605,6 +604,14 @@ goto fail_aob_framebuf; } + if (callbacks->rand_callback) { + callbacks->rand_callback((uint8_t *)&map_seed, sizeof(map_seed)); + } else { + map_seed = 0; + } + + nghttp2_map_init(&(*session_ptr)->streams, map_seed, mem); + active_outbound_item_reset(&(*session_ptr)->aob, mem); (*session_ptr)->callbacks = *callbacks; @@ -637,8 +644,6 @@ return 0; fail_aob_framebuf: - nghttp2_map_free(&(*session_ptr)->streams); -fail_map: nghttp2_hd_inflate_free(&(*session_ptr)->hd_inflater); fail_hd_inflater: nghttp2_hd_deflate_free(&(*session_ptr)->hd_deflater); @@ -802,11 +807,10 @@ for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) { nghttp2_pq_free(&session->sched[i].ob_data); } - nghttp2_stream_free(&session->root); /* Have to free streams first, so that we can check stream->item->queued */ - nghttp2_map_each_free(&session->streams, free_streams, session); + nghttp2_map_each(&session->streams, free_streams, session); nghttp2_map_free(&session->streams); ob_q_free(&session->ob_urgent, mem); @@ -821,83 +825,6 @@ nghttp2_mem_free(mem, session); } -int nghttp2_session_reprioritize_stream( - nghttp2_session *session, nghttp2_stream *stream, - const nghttp2_priority_spec *pri_spec_in) { - int rv; - nghttp2_stream *dep_stream = NULL; - nghttp2_priority_spec pri_spec_default; - const nghttp2_priority_spec *pri_spec = pri_spec_in; - - assert((!session->server && session->pending_no_rfc7540_priorities != 1) || - (session->server && !session_no_rfc7540_pri_no_fallback(session))); - assert(pri_spec->stream_id != stream->stream_id); - - if (!nghttp2_stream_in_dep_tree(stream)) { - return 0; - } - - if (pri_spec->stream_id != 0) { - dep_stream = nghttp2_session_get_stream_raw(session, pri_spec->stream_id); - - if (!dep_stream && - session_detect_idle_stream(session, pri_spec->stream_id)) { - - nghttp2_priority_spec_default_init(&pri_spec_default); - - dep_stream = nghttp2_session_open_stream( - session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default, - NGHTTP2_STREAM_IDLE, NULL); - - if (dep_stream == NULL) { - return NGHTTP2_ERR_NOMEM; - } - } else if (!dep_stream || !nghttp2_stream_in_dep_tree(dep_stream)) { - nghttp2_priority_spec_default_init(&pri_spec_default); - pri_spec = &pri_spec_default; - } - } - - if (pri_spec->stream_id == 0) { - dep_stream = &session->root; - } else if (nghttp2_stream_dep_find_ancestor(dep_stream, stream)) { - DEBUGF("stream: cycle detected, dep_stream(%p)=%d stream(%p)=%d\n", - dep_stream, dep_stream->stream_id, stream, stream->stream_id); - - nghttp2_stream_dep_remove_subtree(dep_stream); - rv = nghttp2_stream_dep_add_subtree(stream->dep_prev, dep_stream); - if (rv != 0) { - return rv; - } - } - - assert(dep_stream); - - if (dep_stream == stream->dep_prev && !pri_spec->exclusive) { - /* This is minor optimization when just weight is changed. */ - nghttp2_stream_change_weight(stream, pri_spec->weight); - - return 0; - } - - nghttp2_stream_dep_remove_subtree(stream); - - /* We have to update weight after removing stream from tree */ - stream->weight = pri_spec->weight; - - if (pri_spec->exclusive) { - rv = nghttp2_stream_dep_insert_subtree(dep_stream, stream); - } else { - rv = nghttp2_stream_dep_add_subtree(dep_stream, stream); - } - - if (rv != 0) { - return rv; - } - - return 0; -} - static uint64_t pq_get_first_cycle(nghttp2_pq *pq) { nghttp2_stream *stream; @@ -916,7 +843,6 @@ int inc; nghttp2_pq *pq; - assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES); assert(stream->queued == 0); urgency = nghttp2_extpri_uint8_urgency(stream->extpri); @@ -941,11 +867,10 @@ return 0; } -static int session_ob_data_remove(nghttp2_session *session, - nghttp2_stream *stream) { +static void session_ob_data_remove(nghttp2_session *session, + nghttp2_stream *stream) { uint32_t urgency; - assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES); assert(stream->queued == 1); urgency = nghttp2_extpri_uint8_urgency(stream->extpri); @@ -955,8 +880,6 @@ nghttp2_pq_remove(&session->sched[urgency].ob_data, &stream->pq_entry); stream->queued = 0; - - return 0; } static int session_attach_stream_item(nghttp2_session *session, @@ -964,64 +887,46 @@ nghttp2_outbound_item *item) { int rv; - rv = nghttp2_stream_attach_item(stream, item); + nghttp2_stream_attach_item(stream, item); + + rv = session_ob_data_push(session, stream); if (rv != 0) { + nghttp2_stream_detach_item(stream); + return rv; } - if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) { - return 0; - } - - return session_ob_data_push(session, stream); + return 0; } -static int session_detach_stream_item(nghttp2_session *session, - nghttp2_stream *stream) { - int rv; +static void session_detach_stream_item(nghttp2_session *session, + nghttp2_stream *stream) { + nghttp2_stream_detach_item(stream); - rv = nghttp2_stream_detach_item(stream); - if (rv != 0) { - return rv; + if (!stream->queued) { + return; } - if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) || - !stream->queued) { - return 0; - } - - return session_ob_data_remove(session, stream); + session_ob_data_remove(session, stream); } -static int session_defer_stream_item(nghttp2_session *session, - nghttp2_stream *stream, uint8_t flags) { - int rv; +static void session_defer_stream_item(nghttp2_session *session, + nghttp2_stream *stream, uint8_t flags) { + nghttp2_stream_defer_item(stream, flags); - rv = nghttp2_stream_defer_item(stream, flags); - if (rv != 0) { - return rv; + if (!stream->queued) { + return; } - if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) || - !stream->queued) { - return 0; - } - - return session_ob_data_remove(session, stream); + session_ob_data_remove(session, stream); } static int session_resume_deferred_stream_item(nghttp2_session *session, nghttp2_stream *stream, uint8_t flags) { - int rv; + nghttp2_stream_resume_deferred_item(stream, flags); - rv = nghttp2_stream_resume_deferred_item(stream, flags); - if (rv != 0) { - return rv; - } - - if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) || - (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL)) { + if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) { return 0; } @@ -1166,7 +1071,6 @@ return 0; case NGHTTP2_PUSH_PROMISE: { nghttp2_headers_aux_data *aux_data; - nghttp2_priority_spec pri_spec; aux_data = &item->aux_data.headers; @@ -1174,20 +1078,13 @@ return NGHTTP2_ERR_STREAM_CLOSED; } - nghttp2_priority_spec_init(&pri_spec, stream->stream_id, - NGHTTP2_DEFAULT_WEIGHT, 0); - if (!nghttp2_session_open_stream( - session, frame->push_promise.promised_stream_id, - NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_RESERVED, - aux_data->stream_user_data)) { + session, frame->push_promise.promised_stream_id, + NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_RESERVED, + aux_data->stream_user_data)) { return NGHTTP2_ERR_NOMEM; } - /* We don't have to call nghttp2_session_adjust_closed_stream() - here, since stream->stream_id is local stream_id, and it does - not affect closed stream count. */ - nghttp2_outbound_queue_push(&session->ob_reg, item); item->queued = 1; @@ -1211,6 +1108,15 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, uint32_t error_code) { + return nghttp2_session_add_rst_stream_continue( + session, stream_id, error_code, + /* continue_without_stream = */ 1); +} + +int nghttp2_session_add_rst_stream_continue(nghttp2_session *session, + int32_t stream_id, + uint32_t error_code, + int continue_without_stream) { int rv; nghttp2_outbound_item *item; nghttp2_frame *frame; @@ -1246,7 +1152,6 @@ assert(headers_frame->hd.type == NGHTTP2_HEADERS); if (headers_frame->hd.stream_id <= stream_id) { - for (item = session->ob_syn.head; item; item = item->qnext) { aux_data = &item->aux_data.headers; @@ -1268,6 +1173,12 @@ } } + /* To keep the old behaviour, do not fail if stream was not + found. */ + if (!continue_without_stream && !stream) { + return 0; + } + item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); if (item == NULL) { return NGHTTP2_ERR_NOMEM; @@ -1289,15 +1200,11 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, int32_t stream_id, uint8_t flags, - nghttp2_priority_spec *pri_spec_in, nghttp2_stream_state initial_state, void *stream_user_data) { int rv; nghttp2_stream *stream; - nghttp2_stream *dep_stream = NULL; int stream_alloc = 0; - nghttp2_priority_spec pri_spec_default; - nghttp2_priority_spec *pri_spec = pri_spec_in; nghttp2_mem *mem; mem = &session->mem; @@ -1310,21 +1217,9 @@ if (stream) { assert(stream->state == NGHTTP2_STREAM_IDLE); - assert((stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) || - nghttp2_stream_in_dep_tree(stream)); + assert(initial_state != NGHTTP2_STREAM_IDLE); - if (nghttp2_stream_in_dep_tree(stream)) { - assert(!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)); - nghttp2_session_detach_idle_stream(session, stream); - rv = nghttp2_stream_dep_remove(stream); - if (rv != 0) { - return NULL; - } - - if (session_no_rfc7540_pri_no_fallback(session)) { - stream->flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES; - } - } + --session->num_idle_streams; } else { stream = nghttp2_mem_malloc(mem, sizeof(nghttp2_stream)); if (stream == NULL) { @@ -1334,69 +1229,16 @@ stream_alloc = 1; } - if (session_no_rfc7540_pri_no_fallback(session) || - session->remote_settings.no_rfc7540_priorities == 1) { - /* For client which has not received server - SETTINGS_NO_RFC7540_PRIORITIES = 1, send a priority signal - opportunistically. */ - if (session->server || - session->remote_settings.no_rfc7540_priorities == 1) { - nghttp2_priority_spec_default_init(&pri_spec_default); - pri_spec = &pri_spec_default; - } - - if (session->pending_no_rfc7540_priorities == 1) { - flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES; - } - } else if (pri_spec->stream_id != 0) { - dep_stream = nghttp2_session_get_stream_raw(session, pri_spec->stream_id); - - if (!dep_stream && - session_detect_idle_stream(session, pri_spec->stream_id)) { - /* Depends on idle stream, which does not exist in memory. - Assign default priority for it. */ - nghttp2_priority_spec_default_init(&pri_spec_default); - - dep_stream = nghttp2_session_open_stream( - session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default, - NGHTTP2_STREAM_IDLE, NULL); - - if (dep_stream == NULL) { - if (stream_alloc) { - nghttp2_mem_free(mem, stream); - } - - return NULL; - } - } else if (!dep_stream || !nghttp2_stream_in_dep_tree(dep_stream)) { - /* If dep_stream is not part of dependency tree, stream will get - default priority. This handles the case when - pri_spec->stream_id == stream_id. This happens because we - don't check pri_spec->stream_id against new stream ID in - nghttp2_submit_request. This also handles the case when idle - stream created by PRIORITY frame was opened. Somehow we - first remove the idle stream from dependency tree. This is - done to simplify code base, but ideally we should retain old - dependency. But I'm not sure this adds values. */ - nghttp2_priority_spec_default_init(&pri_spec_default); - pri_spec = &pri_spec_default; - } - } - if (initial_state == NGHTTP2_STREAM_RESERVED) { flags |= NGHTTP2_STREAM_FLAG_PUSH; } if (stream_alloc) { nghttp2_stream_init(stream, stream_id, flags, initial_state, - pri_spec->weight, (int32_t)session->remote_settings.initial_window_size, (int32_t)session->local_settings.initial_window_size, - stream_user_data, mem); - - if (session_no_rfc7540_pri_no_fallback(session)) { - stream->seq = session->stream_seq++; - } + stream_user_data); + stream->seq = session->stream_seq++; rv = nghttp2_map_insert(&session->streams, stream_id, stream); if (rv != 0) { @@ -1407,7 +1249,6 @@ } else { stream->flags = flags; stream->state = initial_state; - stream->weight = pri_spec->weight; stream->stream_user_data = stream_user_data; } @@ -1425,9 +1266,7 @@ limit. That is one of the DOS vector. */ break; case NGHTTP2_STREAM_IDLE: - /* Idle stream does not count toward the concurrent streams limit. - This is used as anchor node in dependency tree. */ - nghttp2_session_keep_idle_stream(session, stream); + ++session->num_idle_streams; break; default: if (nghttp2_session_is_my_stream_id(session, stream_id)) { @@ -1437,31 +1276,11 @@ } } - if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { - return stream; - } - - if (pri_spec->stream_id == 0) { - dep_stream = &session->root; - } - - assert(dep_stream); - - if (pri_spec->exclusive) { - rv = nghttp2_stream_dep_insert(dep_stream, stream); - if (rv != 0) { - return NULL; - } - } else { - nghttp2_stream_dep_add(dep_stream, stream); - } - return stream; } int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id, uint32_t error_code) { - int rv; nghttp2_stream *stream; nghttp2_mem *mem; int is_my_stream_id; @@ -1475,27 +1294,6 @@ DEBUGF("stream: stream(%p)=%d close\n", stream, stream->stream_id); - if (stream->item) { - nghttp2_outbound_item *item; - - item = stream->item; - - rv = session_detach_stream_item(session, stream); - - if (rv != 0) { - return rv; - } - - /* If item is queued, it will be deleted when it is popped - (nghttp2_session_prep_frame() will fail). If session->aob.item - points to this item, let active_outbound_item_reset() - free the item. */ - if (!item->queued && item != session->aob.item) { - nghttp2_outbound_item_free(item, mem); - nghttp2_mem_free(mem, item); - } - } - /* We call on_stream_close_callback even if stream->state is NGHTTP2_STREAM_INITIAL. This will happen while sending request HEADERS, a local endpoint receives RST_STREAM for that stream. It @@ -1505,12 +1303,28 @@ if (session->callbacks.on_stream_close_callback) { if (session->callbacks.on_stream_close_callback( - session, stream_id, error_code, session->user_data) != 0) { - + session, stream_id, error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } + if (stream->item) { + nghttp2_outbound_item *item; + + item = stream->item; + + session_detach_stream_item(session, stream); + + /* If item is queued, it will be deleted when it is popped + (nghttp2_session_prep_frame() will fail). If session->aob.item + points to this item, let active_outbound_item_reset() + free the item. */ + if (!item->queued && item != session->aob.item) { + nghttp2_outbound_item_free(item, mem); + nghttp2_mem_free(mem, item); + } + } + is_my_stream_id = nghttp2_session_is_my_stream_id(session, stream_id); /* pushed streams which is not opened yet is not counted toward max @@ -1530,201 +1344,26 @@ /* Closes both directions just in case they are not closed yet */ stream->flags |= NGHTTP2_STREAM_FLAG_CLOSED; - if (session->pending_no_rfc7540_priorities == 1) { - return nghttp2_session_destroy_stream(session, stream); - } - - if ((session->opt_flags & NGHTTP2_OPTMASK_NO_CLOSED_STREAMS) == 0 && - session->server && !is_my_stream_id && - nghttp2_stream_in_dep_tree(stream)) { - /* On server side, retain stream at most MAX_CONCURRENT_STREAMS - combined with the current active incoming streams to make - dependency tree work better. */ - nghttp2_session_keep_closed_stream(session, stream); - } else { - rv = nghttp2_session_destroy_stream(session, stream); - if (rv != 0) { - return rv; - } - } + nghttp2_session_destroy_stream(session, stream); return 0; } -int nghttp2_session_destroy_stream(nghttp2_session *session, - nghttp2_stream *stream) { +void nghttp2_session_destroy_stream(nghttp2_session *session, + nghttp2_stream *stream) { nghttp2_mem *mem; - int rv; DEBUGF("stream: destroy closed stream(%p)=%d\n", stream, stream->stream_id); mem = &session->mem; - if (nghttp2_stream_in_dep_tree(stream)) { - rv = nghttp2_stream_dep_remove(stream); - if (rv != 0) { - return rv; - } + if (stream->queued) { + session_ob_data_remove(session, stream); } nghttp2_map_remove(&session->streams, stream->stream_id); nghttp2_stream_free(stream); nghttp2_mem_free(mem, stream); - - return 0; -} - -void nghttp2_session_keep_closed_stream(nghttp2_session *session, - nghttp2_stream *stream) { - DEBUGF("stream: keep closed stream(%p)=%d, state=%d\n", stream, - stream->stream_id, stream->state); - - if (session->closed_stream_tail) { - session->closed_stream_tail->closed_next = stream; - stream->closed_prev = session->closed_stream_tail; - } else { - session->closed_stream_head = stream; - } - session->closed_stream_tail = stream; - - ++session->num_closed_streams; -} - -void nghttp2_session_keep_idle_stream(nghttp2_session *session, - nghttp2_stream *stream) { - DEBUGF("stream: keep idle stream(%p)=%d, state=%d\n", stream, - stream->stream_id, stream->state); - - if (session->idle_stream_tail) { - session->idle_stream_tail->closed_next = stream; - stream->closed_prev = session->idle_stream_tail; - } else { - session->idle_stream_head = stream; - } - session->idle_stream_tail = stream; - - ++session->num_idle_streams; -} - -void nghttp2_session_detach_idle_stream(nghttp2_session *session, - nghttp2_stream *stream) { - nghttp2_stream *prev_stream, *next_stream; - - DEBUGF("stream: detach idle stream(%p)=%d, state=%d\n", stream, - stream->stream_id, stream->state); - - prev_stream = stream->closed_prev; - next_stream = stream->closed_next; - - if (prev_stream) { - prev_stream->closed_next = next_stream; - } else { - session->idle_stream_head = next_stream; - } - - if (next_stream) { - next_stream->closed_prev = prev_stream; - } else { - session->idle_stream_tail = prev_stream; - } - - stream->closed_prev = NULL; - stream->closed_next = NULL; - - --session->num_idle_streams; -} - -int nghttp2_session_adjust_closed_stream(nghttp2_session *session) { - size_t num_stream_max; - int rv; - - if (session->local_settings.max_concurrent_streams == - NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS) { - num_stream_max = session->pending_local_max_concurrent_stream; - } else { - num_stream_max = session->local_settings.max_concurrent_streams; - } - - DEBUGF("stream: adjusting kept closed streams num_closed_streams=%zu, " - "num_incoming_streams=%zu, max_concurrent_streams=%zu\n", - session->num_closed_streams, session->num_incoming_streams, - num_stream_max); - - while (session->num_closed_streams > 0 && - session->num_closed_streams + session->num_incoming_streams > - num_stream_max) { - nghttp2_stream *head_stream; - nghttp2_stream *next; - - head_stream = session->closed_stream_head; - - assert(head_stream); - - next = head_stream->closed_next; - - rv = nghttp2_session_destroy_stream(session, head_stream); - if (rv != 0) { - return rv; - } - - /* head_stream is now freed */ - - session->closed_stream_head = next; - - if (session->closed_stream_head) { - session->closed_stream_head->closed_prev = NULL; - } else { - session->closed_stream_tail = NULL; - } - - --session->num_closed_streams; - } - - return 0; -} - -int nghttp2_session_adjust_idle_stream(nghttp2_session *session) { - size_t max; - int rv; - - /* Make minimum number of idle streams 16, and maximum 100, which - are arbitrary chosen numbers. */ - max = nghttp2_min( - 100, nghttp2_max( - 16, nghttp2_min(session->local_settings.max_concurrent_streams, - session->pending_local_max_concurrent_stream))); - - DEBUGF("stream: adjusting kept idle streams num_idle_streams=%zu, max=%zu\n", - session->num_idle_streams, max); - - while (session->num_idle_streams > max) { - nghttp2_stream *head; - nghttp2_stream *next; - - head = session->idle_stream_head; - assert(head); - - next = head->closed_next; - - rv = nghttp2_session_destroy_stream(session, head); - if (rv != 0) { - return rv; - } - - /* head is now destroyed */ - - session->idle_stream_head = next; - - if (session->idle_stream_head) { - session->idle_stream_head->closed_prev = NULL; - } else { - session->idle_stream_tail = NULL; - } - - --session->num_idle_streams; - } - - return 0; } /* @@ -2112,19 +1751,19 @@ /* Take into account settings max frame size and both connection-level flow control here */ -static ssize_t -nghttp2_session_enforce_flow_control_limits(nghttp2_session *session, - nghttp2_stream *stream, - ssize_t requested_window_size) { +static nghttp2_ssize nghttp2_session_enforce_flow_control_limits( + nghttp2_session *session, nghttp2_stream *stream, + nghttp2_ssize requested_window_size) { DEBUGF("send: remote windowsize connection=%d, remote maxframsize=%u, " "stream(id %d)=%d\n", session->remote_window_size, session->remote_settings.max_frame_size, stream->stream_id, stream->remote_window_size); - return nghttp2_min(nghttp2_min(nghttp2_min(requested_window_size, - stream->remote_window_size), - session->remote_window_size), - (int32_t)session->remote_settings.max_frame_size); + return nghttp2_min_int32( + nghttp2_min_int32(nghttp2_min_int32((int32_t)requested_window_size, + stream->remote_window_size), + session->remote_window_size), + (int32_t)session->remote_settings.max_frame_size); } /* @@ -2135,12 +1774,12 @@ */ static size_t nghttp2_session_next_data_read(nghttp2_session *session, nghttp2_stream *stream) { - ssize_t window_size; + nghttp2_ssize window_size; window_size = nghttp2_session_enforce_flow_control_limits( - session, stream, NGHTTP2_DATA_PAYLOADLEN); + session, stream, NGHTTP2_DATA_PAYLOADLEN); - DEBUGF("send: available window=%zd\n", window_size); + DEBUGF("send: available window=%td\n", window_size); return window_size > 0 ? (size_t)window_size : 0; } @@ -2195,29 +1834,33 @@ return NGHTTP2_ERR_INVALID_STREAM_STATE; } -static ssize_t session_call_select_padding(nghttp2_session *session, - const nghttp2_frame *frame, - size_t max_payloadlen) { - ssize_t rv; +static nghttp2_ssize session_call_select_padding(nghttp2_session *session, + const nghttp2_frame *frame, + size_t max_payloadlen) { + nghttp2_ssize rv; + size_t max_paddedlen; - if (frame->hd.length >= max_payloadlen) { - return (ssize_t)frame->hd.length; + if (frame->hd.length >= max_payloadlen || + (!session->callbacks.select_padding_callback2 && + !session->callbacks.select_padding_callback)) { + return (nghttp2_ssize)frame->hd.length; } - if (session->callbacks.select_padding_callback) { - size_t max_paddedlen; + max_paddedlen = + nghttp2_min_size(frame->hd.length + NGHTTP2_MAX_PADLEN, max_payloadlen); - max_paddedlen = - nghttp2_min(frame->hd.length + NGHTTP2_MAX_PADLEN, max_payloadlen); - - rv = session->callbacks.select_padding_callback( - session, frame, max_paddedlen, session->user_data); - if (rv < (ssize_t)frame->hd.length || rv > (ssize_t)max_paddedlen) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - return rv; + if (session->callbacks.select_padding_callback2) { + rv = session->callbacks.select_padding_callback2( + session, frame, max_paddedlen, session->user_data); + } else { + rv = (nghttp2_ssize)session->callbacks.select_padding_callback( + session, frame, max_paddedlen, session->user_data); } - return (ssize_t)frame->hd.length; + if (rv < (nghttp2_ssize)frame->hd.length || + rv > (nghttp2_ssize)max_paddedlen) { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + return rv; } /* Add padding to HEADERS or PUSH_PROMISE. We use @@ -2225,8 +1868,7 @@ frame->push_promise has also padlen in the same position. */ static int session_headers_add_pad(nghttp2_session *session, nghttp2_frame *frame) { - int rv; - ssize_t padded_payloadlen; + nghttp2_ssize padded_payloadlen; nghttp2_active_outbound_item *aob; nghttp2_bufs *framebufs; size_t padlen; @@ -2235,11 +1877,11 @@ aob = &session->aob; framebufs = &aob->framebufs; - max_payloadlen = nghttp2_min(NGHTTP2_MAX_PAYLOADLEN, - frame->hd.length + NGHTTP2_MAX_PADLEN); + max_payloadlen = nghttp2_min_size(NGHTTP2_MAX_PAYLOADLEN, + frame->hd.length + NGHTTP2_MAX_PADLEN); padded_payloadlen = - session_call_select_padding(session, frame, max_payloadlen); + session_call_select_padding(session, frame, max_payloadlen); if (nghttp2_is_fatal((int)padded_payloadlen)) { return (int)padded_payloadlen; @@ -2247,14 +1889,10 @@ padlen = (size_t)padded_payloadlen - frame->hd.length; - DEBUGF("send: padding selected: payloadlen=%zd, padlen=%zu\n", + DEBUGF("send: padding selected: payloadlen=%td, padlen=%zu\n", padded_payloadlen, padlen); - rv = nghttp2_frame_add_pad(framebufs, &frame->hd, padlen, 0); - - if (rv != 0) { - return rv; - } + nghttp2_frame_add_pad(framebufs, &frame->hd, padlen, 0); frame->headers.padlen = padlen; @@ -2271,18 +1909,24 @@ static int session_pack_extension(nghttp2_session *session, nghttp2_bufs *bufs, nghttp2_frame *frame) { - ssize_t rv; + nghttp2_ssize rv; nghttp2_buf *buf; size_t buflen; size_t framelen; - assert(session->callbacks.pack_extension_callback); + assert(session->callbacks.pack_extension_callback2 || + session->callbacks.pack_extension_callback); buf = &bufs->head->buf; - buflen = nghttp2_min(nghttp2_buf_avail(buf), NGHTTP2_MAX_PAYLOADLEN); + buflen = nghttp2_min_size(nghttp2_buf_avail(buf), NGHTTP2_MAX_PAYLOADLEN); - rv = session->callbacks.pack_extension_callback(session, buf->last, buflen, - frame, session->user_data); + if (session->callbacks.pack_extension_callback2) { + rv = session->callbacks.pack_extension_callback2(session, buf->last, buflen, + frame, session->user_data); + } else { + rv = (nghttp2_ssize)session->callbacks.pack_extension_callback( + session, buf->last, buflen, frame, session->user_data); + } if (rv == NGHTTP2_ERR_CANCEL) { return (int)rv; } @@ -2337,13 +1981,7 @@ // Search stream including closed again. stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id); if (stream) { - int rv2; - - rv2 = session_detach_stream_item(session, stream); - - if (nghttp2_is_fatal(rv2)) { - return rv2; - } + session_detach_stream_item(session, stream); } return rv; @@ -2353,47 +1991,34 @@ next_readmax = nghttp2_session_next_data_read(session, stream); if (next_readmax == 0) { - /* This must be true since we only pop DATA frame item from queue when session->remote_window_size > 0 */ assert(session->remote_window_size > 0); - rv = session_defer_stream_item(session, stream, - NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); - - if (nghttp2_is_fatal(rv)) { - return rv; - } + session_defer_stream_item(session, stream, + NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); session->aob.item = NULL; active_outbound_item_reset(&session->aob, mem); return NGHTTP2_ERR_DEFERRED; } - rv = nghttp2_session_pack_data(session, &session->aob.framebufs, - next_readmax, frame, &item->aux_data.data, - stream); + rv = + nghttp2_session_pack_data(session, &session->aob.framebufs, next_readmax, + frame, &item->aux_data.data, stream); if (rv == NGHTTP2_ERR_PAUSE) { return rv; } if (rv == NGHTTP2_ERR_DEFERRED) { - rv = session_defer_stream_item(session, stream, - NGHTTP2_STREAM_FLAG_DEFERRED_USER); - - if (nghttp2_is_fatal(rv)) { - return rv; - } + session_defer_stream_item(session, stream, + NGHTTP2_STREAM_FLAG_DEFERRED_USER); session->aob.item = NULL; active_outbound_item_reset(&session->aob, mem); return NGHTTP2_ERR_DEFERRED; } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = session_detach_stream_item(session, stream); - - if (nghttp2_is_fatal(rv)) { - return rv; - } + session_detach_stream_item(session, stream); rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id, NGHTTP2_INTERNAL_ERROR); @@ -2403,13 +2028,7 @@ return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } if (rv != 0) { - int rv2; - - rv2 = session_detach_stream_item(session, stream); - - if (nghttp2_is_fatal(rv2)) { - return rv2; - } + session_detach_stream_item(session, stream); return rv; } @@ -2426,17 +2045,13 @@ nghttp2_stream *stream; stream = nghttp2_session_open_stream( - session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, - &frame->headers.pri_spec, NGHTTP2_STREAM_INITIAL, - aux_data->stream_user_data); + session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, + NGHTTP2_STREAM_INITIAL, aux_data->stream_user_data); if (stream == NULL) { return NGHTTP2_ERR_NOMEM; } - /* We don't call nghttp2_session_adjust_closed_stream() here, - since we don't keep closed stream in client side */ - rv = session_predicate_request_headers_send(session, item); if (rv != 0) { return rv; @@ -2475,8 +2090,8 @@ } estimated_payloadlen = session_estimate_headers_payload( - session, frame->headers.nva, frame->headers.nvlen, - NGHTTP2_PRIORITY_SPECLEN); + session, frame->headers.nva, frame->headers.nvlen, + NGHTTP2_PRIORITY_SPECLEN); if (estimated_payloadlen > session->max_send_header_block_length) { return NGHTTP2_ERR_FRAME_SIZE_ERROR; @@ -2489,7 +2104,7 @@ return rv; } - DEBUGF("send: before padding, HEADERS serialized in %zd bytes\n", + DEBUGF("send: before padding, HEADERS serialized in %zu bytes\n", nghttp2_bufs_len(&session->aob.framebufs)); rv = session_headers_add_pad(session, frame); @@ -2498,7 +2113,7 @@ return rv; } - DEBUGF("send: HEADERS finally serialized in %zd bytes\n", + DEBUGF("send: HEADERS finally serialized in %zu bytes\n", nghttp2_bufs_len(&session->aob.framebufs)); if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) { @@ -2564,14 +2179,14 @@ assert(stream); estimated_payloadlen = session_estimate_headers_payload( - session, frame->push_promise.nva, frame->push_promise.nvlen, 0); + session, frame->push_promise.nva, frame->push_promise.nvlen, 0); if (estimated_payloadlen > session->max_send_header_block_length) { return NGHTTP2_ERR_FRAME_SIZE_ERROR; } rv = nghttp2_frame_pack_push_promise( - &session->aob.framebufs, &frame->push_promise, &session->hd_deflater); + &session->aob.framebufs, &frame->push_promise, &session->hd_deflater); if (rv != 0) { return rv; } @@ -2678,8 +2293,6 @@ nghttp2_outbound_item * nghttp2_session_get_next_ob_item(nghttp2_session *session) { - nghttp2_outbound_item *item; - if (nghttp2_outbound_queue_top(&session->ob_urgent)) { return nghttp2_outbound_queue_top(&session->ob_urgent); } @@ -2695,11 +2308,6 @@ } if (session->remote_window_size > 0) { - item = nghttp2_stream_next_outbound_item(&session->root); - if (item) { - return item; - } - return session_sched_get_next_outbound_item(session); } @@ -2734,11 +2342,6 @@ } if (session->remote_window_size > 0) { - item = nghttp2_stream_next_outbound_item(&session->root); - if (item) { - return item; - } - return session_sched_get_next_outbound_item(session); } @@ -2797,7 +2400,6 @@ nghttp2_session_close_stream() inside nghttp2_map_each(). Reuse closed_next member.. bad choice? */ assert(stream->closed_next == NULL); - assert(stream->closed_prev == NULL); if (arg->head) { stream->closed_next = arg->head; @@ -2853,11 +2455,6 @@ nghttp2_stream *stream) { stream->last_writelen = stream->item->frame.hd.length; - if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) { - nghttp2_stream_reschedule(stream); - return; - } - if (!session->server) { return; } @@ -2911,14 +2508,11 @@ } if (stream && aux_data->eof) { - rv = session_detach_stream_item(session, stream); - if (nghttp2_is_fatal(rv)) { - return rv; - } + session_detach_stream_item(session, stream); /* Call on_frame_send_callback after nghttp2_stream_detach_item(), so that application can issue - nghttp2_submit_data() in the callback. */ + nghttp2_submit_data2() in the callback. */ if (session->callbacks.on_frame_send_callback) { rv = session_call_on_frame_send(session, frame); if (nghttp2_is_fatal(rv)) { @@ -2930,7 +2524,7 @@ int stream_closed; stream_closed = - (stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR; + (stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR; nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR); @@ -2990,15 +2584,17 @@ } /* We assume aux_data is a pointer to nghttp2_headers_aux_data */ aux_data = &item->aux_data.headers; - if (aux_data->data_prd.read_callback) { - /* nghttp2_submit_data() makes a copy of aux_data->data_prd */ - rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM, - frame->hd.stream_id, &aux_data->data_prd); + if (aux_data->dpw.data_prd.read_callback) { + /* nghttp2_submit_data_shared() makes a copy of + aux_data->dpw */ + rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM, + frame->hd.stream_id, &aux_data->dpw); if (nghttp2_is_fatal(rv)) { return rv; } - /* TODO nghttp2_submit_data() may fail if stream has already - DATA frame item. We might have to handle it here. */ + /* TODO nghttp2_submit_data_shared() may fail if stream has + already DATA frame item. We might have to handle it + here. */ } return 0; } @@ -3019,14 +2615,15 @@ } /* We assume aux_data is a pointer to nghttp2_headers_aux_data */ aux_data = &item->aux_data.headers; - if (aux_data->data_prd.read_callback) { - rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM, - frame->hd.stream_id, &aux_data->data_prd); + if (aux_data->dpw.data_prd.read_callback) { + rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM, + frame->hd.stream_id, &aux_data->dpw); if (nghttp2_is_fatal(rv)) { return rv; } - /* TODO nghttp2_submit_data() may fail if stream has already - DATA frame item. We might have to handle it here. */ + /* TODO nghttp2_submit_data_shared() may fail if stream has + already DATA frame item. We might have to handle it + here. */ } return 0; default: @@ -3036,37 +2633,6 @@ } } case NGHTTP2_PRIORITY: - if (session->server || session->pending_no_rfc7540_priorities == 1) { - return 0; - } - - stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id); - - if (!stream) { - if (!session_detect_idle_stream(session, frame->hd.stream_id)) { - return 0; - } - - stream = nghttp2_session_open_stream( - session, frame->hd.stream_id, NGHTTP2_FLAG_NONE, - &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL); - if (!stream) { - return NGHTTP2_ERR_NOMEM; - } - } else { - rv = nghttp2_session_reprioritize_stream(session, stream, - &frame->priority.pri_spec); - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - - rv = nghttp2_session_adjust_idle_stream(session); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - return 0; case NGHTTP2_RST_STREAM: rv = nghttp2_session_close_stream(session, frame->hd.stream_id, @@ -3081,7 +2647,6 @@ aux_data = &item->aux_data.goaway; if ((aux_data->flags & NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE) == 0) { - if (aux_data->flags & NGHTTP2_GOAWAY_AUX_TERM_ON_SEND) { session->goaway_flags |= NGHTTP2_GOAWAY_TERM_SENT; } @@ -3131,7 +2696,7 @@ rv = session_update_stream_consumed_size(session, stream, 0); } else { rv = - nghttp2_session_update_recv_stream_window_size(session, stream, 0, 1); + nghttp2_session_update_recv_stream_window_size(session, stream, 0, 1); } if (nghttp2_is_fatal(rv)) { @@ -3147,17 +2712,8 @@ /* * Called after a frame is sent and session_after_frame_sent1. This * function is responsible to reset session->aob. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_CALLBACK_FAILURE - * The callback function failed. */ -static int session_after_frame_sent2(nghttp2_session *session) { - int rv; +static void session_after_frame_sent2(nghttp2_session *session) { nghttp2_active_outbound_item *aob = &session->aob; nghttp2_outbound_item *item = aob->item; nghttp2_bufs *framebufs = &aob->framebufs; @@ -3170,23 +2726,21 @@ frame = &item->frame; if (frame->hd.type != NGHTTP2_DATA) { - if (frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_PUSH_PROMISE) { - if (nghttp2_bufs_next_present(framebufs)) { framebufs->cur = framebufs->cur->next; DEBUGF("send: next CONTINUATION frame, %zu bytes\n", nghttp2_buf_len(&framebufs->cur->buf)); - return 0; + return; } } active_outbound_item_reset(&session->aob, mem); - return 0; + return; } /* DATA frame */ @@ -3194,13 +2748,13 @@ aux_data = &item->aux_data.data; /* On EOF, we have already detached data. Please note that - application may issue nghttp2_submit_data() in + application may issue nghttp2_submit_data2() in on_frame_send_callback (call from session_after_frame_sent1), which attach data to stream. We don't want to detach it. */ if (aux_data->eof) { active_outbound_item_reset(aob, mem); - return 0; + return; } /* Reset no_copy here because next write may not use this. */ @@ -3212,22 +2766,18 @@ further data. */ if (nghttp2_session_predicate_data_send(session, stream) != 0) { if (stream) { - rv = session_detach_stream_item(session, stream); - - if (nghttp2_is_fatal(rv)) { - return rv; - } + session_detach_stream_item(session, stream); } active_outbound_item_reset(aob, mem); - return 0; + return; } aob->item = NULL; active_outbound_item_reset(&session->aob, mem); - return 0; + return; } static int session_call_send_data(nghttp2_session *session, @@ -3245,7 +2795,7 @@ aux_data = &item->aux_data.data; rv = session->callbacks.send_data_callback(session, frame, buf->pos, length, - &aux_data->data_prd.source, + &aux_data->dpw.data_prd.source, session->user_data); switch (rv) { @@ -3259,9 +2809,9 @@ } } -static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session, - const uint8_t **data_ptr, - int fast_cb) { +static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session, + const uint8_t **data_ptr, + int fast_cb) { int rv; nghttp2_active_outbound_item *aob; nghttp2_bufs *framebufs; @@ -3271,14 +2821,6 @@ aob = &session->aob; framebufs = &aob->framebufs; - /* We may have idle streams more than we expect (e.g., - nghttp2_session_change_stream_priority() or - nghttp2_session_create_idle_stream()). Adjust them here. */ - rv = nghttp2_session_adjust_idle_stream(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - for (;;) { switch (aob->state) { case NGHTTP2_OB_POP_ITEM: { @@ -3300,6 +2842,7 @@ if (rv < 0) { int32_t opened_stream_id = 0; uint32_t error_code = NGHTTP2_INTERNAL_ERROR; + int rv2 = 0; DEBUGF("send: frame preparation failed with %s\n", nghttp2_strerror(rv)); @@ -3313,8 +2856,7 @@ it. */ if (frame->hd.type != NGHTTP2_WINDOW_UPDATE && session->callbacks.on_frame_not_send_callback( - session, frame, rv, session->user_data) != 0) { - + session, frame, rv, session->user_data) != 0) { nghttp2_outbound_item_free(item, mem); nghttp2_mem_free(mem, item); @@ -3342,24 +2884,23 @@ } if (opened_stream_id) { /* careful not to override rv */ - int rv2; - rv2 = nghttp2_session_close_stream(session, opened_stream_id, - error_code); - - if (nghttp2_is_fatal(rv2)) { - return rv2; - } + rv2 = + nghttp2_session_close_stream(session, opened_stream_id, error_code); } nghttp2_outbound_item_free(item, mem); nghttp2_mem_free(mem, item); active_outbound_item_reset(aob, mem); + if (nghttp2_is_fatal(rv2)) { + return rv2; + } + if (rv == NGHTTP2_ERR_HEADER_COMP) { - /* If header compression error occurred, should terminiate + /* If header compression error occurred, should terminate connection. */ - rv = nghttp2_session_terminate_session(session, - NGHTTP2_INTERNAL_ERROR); + rv = + nghttp2_session_terminate_session(session, NGHTTP2_INTERNAL_ERROR); } if (nghttp2_is_fatal(rv)) { return rv; @@ -3392,7 +2933,7 @@ if (session->callbacks.on_frame_not_send_callback) { if (session->callbacks.on_frame_not_send_callback( - session, frame, rv, session->user_data) != 0) { + session, frame, rv, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } @@ -3439,7 +2980,7 @@ } } - DEBUGF("send: start transmitting frame type=%u, length=%zd\n", + DEBUGF("send: start transmitting frame type=%u, length=%td\n", framebufs->cur->buf.pos[3], framebufs->cur->buf.last - framebufs->cur->buf.pos); @@ -3458,7 +2999,7 @@ /* Frame has completely sent */ if (fast_cb) { - rv = session_after_frame_sent2(session); + session_after_frame_sent2(session); } else { rv = session_after_frame_sent1(session); if (rv < 0) { @@ -3466,12 +3007,7 @@ assert(nghttp2_is_fatal(rv)); return rv; } - rv = session_after_frame_sent2(session); - } - if (rv < 0) { - /* FATAL */ - assert(nghttp2_is_fatal(rv)); - return rv; + session_after_frame_sent2(session); } /* We have already adjusted the next state */ break; @@ -3484,7 +3020,7 @@ everything, we will adjust it. */ buf->pos += datalen; - return (ssize_t)datalen; + return (nghttp2_ssize)datalen; } case NGHTTP2_OB_SEND_NO_COPY: { nghttp2_stream *stream; @@ -3510,11 +3046,7 @@ } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = session_detach_stream_item(session, stream); - - if (nghttp2_is_fatal(rv)) { - return rv; - } + session_detach_stream_item(session, stream); rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id, NGHTTP2_INTERNAL_ERROR); @@ -3538,11 +3070,7 @@ assert(nghttp2_is_fatal(rv)); return rv; } - rv = session_after_frame_sent2(session); - if (rv < 0) { - assert(nghttp2_is_fatal(rv)); - return rv; - } + session_after_frame_sent2(session); /* We have already adjusted the next state */ @@ -3569,7 +3097,7 @@ buf->pos += datalen; - return (ssize_t)datalen; + return (nghttp2_ssize)datalen; } } } @@ -3577,8 +3105,13 @@ ssize_t nghttp2_session_mem_send(nghttp2_session *session, const uint8_t **data_ptr) { + return (ssize_t)nghttp2_session_mem_send2(session, data_ptr); +} + +nghttp2_ssize nghttp2_session_mem_send2(nghttp2_session *session, + const uint8_t **data_ptr) { int rv; - ssize_t len; + nghttp2_ssize len; *data_ptr = NULL; @@ -3595,7 +3128,7 @@ rv = session_after_frame_sent1(session); if (rv < 0) { assert(nghttp2_is_fatal(rv)); - return (ssize_t)rv; + return (nghttp2_ssize)rv; } } @@ -3604,8 +3137,8 @@ int nghttp2_session_send(nghttp2_session *session) { const uint8_t *data = NULL; - ssize_t datalen; - ssize_t sentlen; + nghttp2_ssize datalen; + nghttp2_ssize sentlen; nghttp2_bufs *framebufs; framebufs = &session->aob.framebufs; @@ -3615,8 +3148,13 @@ if (datalen <= 0) { return (int)datalen; } - sentlen = session->callbacks.send_callback(session, data, (size_t)datalen, - 0, session->user_data); + if (session->callbacks.send_callback2) { + sentlen = session->callbacks.send_callback2( + session, data, (size_t)datalen, 0, session->user_data); + } else { + sentlen = (nghttp2_ssize)session->callbacks.send_callback( + session, data, (size_t)datalen, 0, session->user_data); + } if (sentlen < 0) { if (sentlen == NGHTTP2_ERR_WOULDBLOCK) { /* Transmission canceled. Rewind the offset */ @@ -3631,11 +3169,17 @@ } } -static ssize_t session_recv(nghttp2_session *session, uint8_t *buf, - size_t len) { - ssize_t rv; - rv = session->callbacks.recv_callback(session, buf, len, 0, - session->user_data); +static nghttp2_ssize session_recv(nghttp2_session *session, uint8_t *buf, + size_t len) { + nghttp2_ssize rv; + + if (session->callbacks.recv_callback2) { + rv = session->callbacks.recv_callback2(session, buf, len, 0, + session->user_data); + } else { + rv = (nghttp2_ssize)session->callbacks.recv_callback(session, buf, len, 0, + session->user_data); + } if (rv > 0) { if ((size_t)rv > len) { return NGHTTP2_ERR_CALLBACK_FAILURE; @@ -3651,7 +3195,6 @@ int rv; if (session->callbacks.on_begin_frame_callback) { - rv = session->callbacks.on_begin_frame_callback(session, hd, session->user_data); @@ -3700,11 +3243,11 @@ int rv = 0; if (session->callbacks.on_header_callback2) { rv = session->callbacks.on_header_callback2( - session, frame, nv->name, nv->value, nv->flags, session->user_data); + session, frame, nv->name, nv->value, nv->flags, session->user_data); } else if (session->callbacks.on_header_callback) { rv = session->callbacks.on_header_callback( - session, frame, nv->name->base, nv->name->len, nv->value->base, - nv->value->len, nv->flags, session->user_data); + session, frame, nv->name->base, nv->name->len, nv->value->base, + nv->value->len, nv->flags, session->user_data); } if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { @@ -3723,13 +3266,15 @@ int rv; if (session->callbacks.on_invalid_header_callback2) { rv = session->callbacks.on_invalid_header_callback2( - session, frame, nv->name, nv->value, nv->flags, session->user_data); + session, frame, nv->name, nv->value, nv->flags, session->user_data); } else if (session->callbacks.on_invalid_header_callback) { rv = session->callbacks.on_invalid_header_callback( - session, frame, nv->name->base, nv->name->len, nv->value->base, - nv->value->len, nv->flags, session->user_data); + session, frame, nv->name->base, nv->name->len, nv->value->base, + nv->value->len, nv->flags, session->user_data); } else { - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + /* If both callbacks are not set, the invalid field nv is + ignored. */ + return 0; } if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { @@ -3751,7 +3296,7 @@ if (session->callbacks.on_extension_chunk_recv_callback) { rv = session->callbacks.on_extension_chunk_recv_callback( - session, &frame->hd, data, len, session->user_data); + session, &frame->hd, data, len, session->user_data); if (rv == NGHTTP2_ERR_CANCEL) { return rv; } @@ -3770,7 +3315,7 @@ void *payload = NULL; rv = session->callbacks.unpack_extension_callback( - session, &payload, &frame->hd, session->user_data); + session, &payload, &frame->hd, session->user_data); if (rv == NGHTTP2_ERR_CANCEL) { return rv; } @@ -3814,6 +3359,10 @@ case NGHTTP2_ERR_HTTP_HEADER: case NGHTTP2_ERR_HTTP_MESSAGING: return NGHTTP2_PROTOCOL_ERROR; + case NGHTTP2_ERR_INTERNAL: + return NGHTTP2_INTERNAL_ERROR; + case NGHTTP2_ERR_PUSH_CANCEL: + return NGHTTP2_CANCEL; default: return NGHTTP2_INTERNAL_ERROR; } @@ -3833,26 +3382,41 @@ int lib_error_code) { if (session->callbacks.on_invalid_frame_recv_callback) { if (session->callbacks.on_invalid_frame_recv_callback( - session, frame, lib_error_code, session->user_data) != 0) { + session, frame, lib_error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } return 0; } +static int session_update_glitch_ratelim(nghttp2_session *session) { + if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) { + return 0; + } + + nghttp2_ratelim_update(&session->glitch_ratelim, nghttp2_time_now_sec()); + + if (nghttp2_ratelim_drain(&session->glitch_ratelim, 1) == 0) { + return 0; + } + + return nghttp2_session_terminate_session(session, NGHTTP2_ENHANCE_YOUR_CALM); +} + static int session_handle_invalid_stream2(nghttp2_session *session, int32_t stream_id, nghttp2_frame *frame, int lib_error_code) { int rv; + rv = nghttp2_session_add_rst_stream( - session, stream_id, get_error_code_from_lib_error_code(lib_error_code)); + session, stream_id, get_error_code_from_lib_error_code(lib_error_code)); if (rv != 0) { return rv; } - if (session->callbacks.on_invalid_frame_recv_callback) { + if (frame && session->callbacks.on_invalid_frame_recv_callback) { if (session->callbacks.on_invalid_frame_recv_callback( - session, frame, lib_error_code, session->user_data) != 0) { + session, frame, lib_error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } @@ -3886,12 +3450,12 @@ const char *reason) { if (session->callbacks.on_invalid_frame_recv_callback) { if (session->callbacks.on_invalid_frame_recv_callback( - session, frame, lib_error_code, session->user_data) != 0) { + session, frame, lib_error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } return nghttp2_session_terminate_session_with_reason( - session, get_error_code_from_lib_error_code(lib_error_code), reason); + session, get_error_code_from_lib_error_code(lib_error_code), reason); } static int session_inflate_handle_invalid_connection(nghttp2_session *session, @@ -3900,7 +3464,7 @@ const char *reason) { int rv; rv = - session_handle_invalid_connection(session, frame, lib_error_code, reason); + session_handle_invalid_connection(session, frame, lib_error_code, reason); if (nghttp2_is_fatal(rv)) { return rv; } @@ -3937,7 +3501,7 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, size_t *readlen_ptr, uint8_t *in, size_t inlen, int final, int call_header_cb) { - ssize_t proclen; + nghttp2_ssize proclen; int rv; int inflate_flags; nghttp2_hd_nv nv; @@ -3950,7 +3514,7 @@ if (frame->hd.type == NGHTTP2_PUSH_PROMISE) { subject_stream = nghttp2_session_get_stream( - session, frame->push_promise.promised_stream_id); + session, frame->push_promise.promised_stream_id); } else { subject_stream = stream; trailer = session_trailer_headers(session, stream, frame); @@ -3971,7 +3535,7 @@ from invoking subsequent callbacks for the same stream ID. */ rv = nghttp2_session_add_rst_stream( - session, subject_stream->stream_id, NGHTTP2_COMPRESSION_ERROR); + session, subject_stream->stream_id, NGHTTP2_COMPRESSION_ERROR); if (nghttp2_is_fatal(rv)) { return rv; @@ -3979,7 +3543,7 @@ } } rv = - nghttp2_session_terminate_session(session, NGHTTP2_COMPRESSION_ERROR); + nghttp2_session_terminate_session(session, NGHTTP2_COMPRESSION_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -3990,7 +3554,7 @@ inlen -= (size_t)proclen; *readlen_ptr += (size_t)proclen; - DEBUGF("recv: proclen=%zd\n", proclen); + DEBUGF("recv: proclen=%td\n", proclen); if (call_header_cb && (inflate_flags & NGHTTP2_HD_INFLATE_EMIT)) { rv = 0; @@ -4005,7 +3569,29 @@ rv2 = session_call_on_invalid_header(session, frame, &nv); if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = NGHTTP2_ERR_HTTP_HEADER; + DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n", + frame->hd.type, frame->hd.stream_id, (int)nv.name->len, + nv.name->base, (int)nv.value->len, nv.value->base); + + rv = session_call_error_callback( + session, NGHTTP2_ERR_HTTP_HEADER, + "Invalid HTTP header field was received: frame type: " + "%u, stream: %d, name: [%.*s], value: [%.*s]", + frame->hd.type, frame->hd.stream_id, (int)nv.name->len, + nv.name->base, (int)nv.value->len, nv.value->base); + + if (nghttp2_is_fatal(rv)) { + return rv; + } + + rv = session_handle_invalid_stream2( + session, subject_stream->stream_id, frame, + NGHTTP2_ERR_HTTP_HEADER); + if (nghttp2_is_fatal(rv)) { + return rv; + } + + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } else { if (rv2 != 0) { return rv2; @@ -4017,11 +3603,11 @@ nv.name->base, (int)nv.value->len, nv.value->base); rv2 = session_call_error_callback( - session, NGHTTP2_ERR_HTTP_HEADER, - "Ignoring received invalid HTTP header field: frame type: " - "%u, stream: %d, name: [%.*s], value: [%.*s]", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); + session, NGHTTP2_ERR_HTTP_HEADER, + "Ignoring received invalid HTTP header field: frame type: " + "%u, stream: %d, name: [%.*s], value: [%.*s]", + frame->hd.type, frame->hd.stream_id, (int)nv.name->len, + nv.name->base, (int)nv.value->len, nv.value->base); if (nghttp2_is_fatal(rv2)) { return rv2; @@ -4035,23 +3621,18 @@ nv.name->base, (int)nv.value->len, nv.value->base); rv = session_call_error_callback( - session, NGHTTP2_ERR_HTTP_HEADER, - "Invalid HTTP header field was received: frame type: " - "%u, stream: %d, name: [%.*s], value: [%.*s]", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); + session, NGHTTP2_ERR_HTTP_HEADER, + "Invalid HTTP header field was received: frame type: " + "%u, stream: %d, name: [%.*s], value: [%.*s]", + frame->hd.type, frame->hd.stream_id, (int)nv.name->len, + nv.name->base, (int)nv.value->len, nv.value->base); if (nghttp2_is_fatal(rv)) { return rv; } - rv = session_handle_invalid_stream2(session, - subject_stream->stream_id, - frame, NGHTTP2_ERR_HTTP_HEADER); - if (nghttp2_is_fatal(rv)) { - return rv; - } - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + return nghttp2_session_terminate_session(session, + NGHTTP2_PROTOCOL_ERROR); } } if (rv == 0) { @@ -4095,7 +3676,6 @@ if (session->server && session_enforce_http_messaging(session) && frame->headers.cat == NGHTTP2_HCAT_REQUEST && - (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) && !(stream->flags & NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES) && (stream->http_flags & NGHTTP2_HTTP_FLAG_PRIORITY)) { rv = session_update_stream_priority(session, stream, stream->http_extpri); @@ -4135,7 +3715,7 @@ nghttp2_stream *subject_stream; subject_stream = nghttp2_session_get_stream( - session, frame->push_promise.promised_stream_id); + session, frame->push_promise.promised_stream_id); if (subject_stream) { rv = nghttp2_http_on_request_headers(subject_stream, frame); } @@ -4165,27 +3745,7 @@ } } if (rv != 0) { - int32_t stream_id; - - if (frame->hd.type == NGHTTP2_PUSH_PROMISE) { - stream_id = frame->push_promise.promised_stream_id; - } else { - stream_id = frame->hd.stream_id; - } - - rv = session_handle_invalid_stream2(session, stream_id, frame, - NGHTTP2_ERR_HTTP_MESSAGING); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (frame->hd.type == NGHTTP2_HEADERS && - (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); - /* Don't call nghttp2_session_close_stream_if_shut_rdwr - because RST_STREAM has been submitted. */ - } - return 0; + return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); } } @@ -4207,7 +3767,7 @@ nghttp2_stream *stream; if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: stream_id == 0"); } /* If client receives idle stream from server, it is invalid @@ -4216,8 +3776,8 @@ if (!session->server) { if (session_detect_idle_stream(session, frame->hd.stream_id)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "request HEADERS: client received request"); + session, frame, NGHTTP2_ERR_PROTO, + "request HEADERS: client received request"); } return NGHTTP2_ERR_IGN_HEADER_BLOCK; @@ -4229,8 +3789,8 @@ if (frame->hd.stream_id == 0 || nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "request HEADERS: invalid stream_id"); + session, frame, NGHTTP2_ERR_PROTO, + "request HEADERS: invalid stream_id"); } /* RFC 7540 says if an endpoint receives a HEADERS with invalid @@ -4256,7 +3816,7 @@ stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id); if (stream && (stream->shut_flags & NGHTTP2_SHUT_RD)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); + session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); } return NGHTTP2_ERR_IGN_HEADER_BLOCK; @@ -4265,8 +3825,8 @@ if (session_is_incoming_concurrent_streams_max(session)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "request HEADERS: max concurrent streams exceeded"); + session, frame, NGHTTP2_ERR_PROTO, + "request HEADERS: max concurrent streams exceeded"); } if (!session_allow_incoming_new_stream(session)) { @@ -4276,7 +3836,7 @@ if (frame->headers.pri_spec.stream_id == frame->hd.stream_id) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: depend on itself"); + session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: depend on itself"); } if (session_is_incoming_concurrent_streams_pending_max(session)) { @@ -4284,18 +3844,13 @@ NGHTTP2_ERR_REFUSED_STREAM); } - stream = nghttp2_session_open_stream( - session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, - &frame->headers.pri_spec, NGHTTP2_STREAM_OPENING, NULL); + stream = nghttp2_session_open_stream(session, frame->hd.stream_id, + NGHTTP2_STREAM_FLAG_NONE, + NGHTTP2_STREAM_OPENING, NULL); if (!stream) { return NGHTTP2_ERR_NOMEM; } - rv = nghttp2_session_adjust_closed_stream(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - session->last_proc_stream_id = session->last_recv_stream_id; rv = session_call_on_begin_headers(session, frame); @@ -4315,7 +3870,7 @@ nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)); if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "response HEADERS: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, "response HEADERS: stream_id == 0"); } if (stream->shut_flags & NGHTTP2_SHUT_RD) { /* half closed (remote): from the spec: @@ -4327,7 +3882,7 @@ We go further, and make it connection error. */ return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); + session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); } stream->state = NGHTTP2_STREAM_OPENED; rv = session_call_on_begin_headers(session, frame); @@ -4344,20 +3899,20 @@ assert(stream->state == NGHTTP2_STREAM_RESERVED); if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "push response HEADERS: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, + "push response HEADERS: stream_id == 0"); } if (session->server) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "HEADERS: no HEADERS allowed from client in reserved state"); + session, frame, NGHTTP2_ERR_PROTO, + "HEADERS: no HEADERS allowed from client in reserved state"); } if (session_is_incoming_concurrent_streams_max(session)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "push response HEADERS: max concurrent streams exceeded"); + session, frame, NGHTTP2_ERR_PROTO, + "push response HEADERS: max concurrent streams exceeded"); } if (!session_allow_incoming_new_stream(session)) { @@ -4388,7 +3943,7 @@ int rv = 0; if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "HEADERS: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, "HEADERS: stream_id == 0"); } if ((stream->shut_flags & NGHTTP2_SHUT_RD)) { /* half closed (remote): from the spec: @@ -4400,7 +3955,7 @@ we go further, and make it connection error. */ return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); + session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); } if (nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { if (stream->state == NGHTTP2_STREAM_OPENED) { @@ -4428,17 +3983,12 @@ } static int session_process_headers_frame(nghttp2_session *session) { - int rv; nghttp2_inbound_frame *iframe = &session->iframe; nghttp2_frame *frame = &iframe->frame; nghttp2_stream *stream; - rv = nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos); + nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos); - if (rv != 0) { - return nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: could not unpack"); - } stream = nghttp2_session_get_stream(session, frame->hd.stream_id); if (!stream) { frame->headers.cat = NGHTTP2_HCAT_REQUEST; @@ -4461,75 +4011,21 @@ return nghttp2_session_on_headers_received(session, frame, stream); } -int nghttp2_session_on_priority_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; - nghttp2_stream *stream; - - assert(!session_no_rfc7540_pri_no_fallback(session)); - - if (frame->hd.stream_id == 0) { - return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO, - "PRIORITY: stream_id == 0"); +static int session_update_stream_reset_ratelim(nghttp2_session *session) { + if (!session->server || (session->goaway_flags & NGHTTP2_GOAWAY_SUBMITTED)) { + return 0; } - if (frame->priority.pri_spec.stream_id == frame->hd.stream_id) { - return nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "depend on itself"); + nghttp2_ratelim_update(&session->stream_reset_ratelim, + nghttp2_time_now_sec()); + + if (nghttp2_ratelim_drain(&session->stream_reset_ratelim, 1) == 0) { + return 0; } - if (!session->server) { - /* Re-prioritization works only in server */ - return session_call_on_frame_received(session, frame); - } - - stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id); - - if (!stream) { - /* PRIORITY against idle stream can create anchor node in - dependency tree. */ - if (!session_detect_idle_stream(session, frame->hd.stream_id)) { - return 0; - } - - stream = nghttp2_session_open_stream( - session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, - &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL); - - if (stream == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - rv = nghttp2_session_adjust_idle_stream(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - } else { - rv = nghttp2_session_reprioritize_stream(session, stream, - &frame->priority.pri_spec); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - rv = nghttp2_session_adjust_idle_stream(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - } - - return session_call_on_frame_received(session, frame); -} - -static int session_process_priority_frame(nghttp2_session *session) { - nghttp2_inbound_frame *iframe = &session->iframe; - nghttp2_frame *frame = &iframe->frame; - - assert(!session_no_rfc7540_pri_no_fallback(session)); - - nghttp2_frame_unpack_priority_payload(&frame->priority, iframe->sbuf.pos); - - return nghttp2_session_on_priority_received(session, frame); + return nghttp2_session_add_goaway(session, session->last_recv_stream_id, + NGHTTP2_INTERNAL_ERROR, NULL, 0, + NGHTTP2_GOAWAY_AUX_NONE); } int nghttp2_session_on_rst_stream_received(nghttp2_session *session, @@ -4561,7 +4057,8 @@ if (nghttp2_is_fatal(rv)) { return rv; } - return 0; + + return session_update_stream_reset_ratelim(session); } static int session_process_rst_stream_frame(nghttp2_session *session) { @@ -4582,19 +4079,17 @@ stream = (nghttp2_stream *)entry; rv = nghttp2_stream_update_remote_initial_window_size( - stream, arg->new_window_size, arg->old_window_size); + stream, arg->new_window_size, arg->old_window_size); if (rv != 0) { - return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, - NGHTTP2_FLOW_CONTROL_ERROR); + return NGHTTP2_ERR_FLOW_CONTROL; } /* If window size gets positive, push deferred DATA frame to outbound queue. */ if (stream->remote_window_size > 0 && nghttp2_stream_check_deferred_by_flow_control(stream)) { - rv = session_resume_deferred_stream_item( - arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); + arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); if (nghttp2_is_fatal(rv)) { return rv; @@ -4612,6 +4107,8 @@ * * NGHTTP2_ERR_NOMEM * Out of memory. + * NGHTTP2_ERR_FLOW_CONTROL + * Window size gets out of range. */ static int session_update_remote_initial_window_size(nghttp2_session *session, @@ -4633,10 +4130,9 @@ arg = (nghttp2_update_window_size_arg *)ptr; stream = (nghttp2_stream *)entry; rv = nghttp2_stream_update_local_initial_window_size( - stream, arg->new_window_size, arg->old_window_size); + stream, arg->new_window_size, arg->old_window_size); if (rv != 0) { - return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, - NGHTTP2_FLOW_CONTROL_ERROR); + return NGHTTP2_ERR_FLOW_CONTROL; } if (stream->window_update_queued) { @@ -4649,7 +4145,6 @@ if (nghttp2_should_send_window_update(stream->local_window_size, stream->recv_window_size)) { - rv = nghttp2_session_add_window_update(arg->session, NGHTTP2_FLAG_NONE, stream->stream_id, stream->recv_window_size); @@ -4671,6 +4166,8 @@ * * NGHTTP2_ERR_NOMEM * Out of memory. + * NGHTTP2_ERR_FLOW_CONTROL + * Window size gets out of range. */ static int session_update_local_initial_window_size(nghttp2_session *session, @@ -4714,7 +4211,8 @@ case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: header_table_size_seen = 1; header_table_size = iv[i].value; - min_header_table_size = nghttp2_min(min_header_table_size, iv[i].value); + min_header_table_size = + nghttp2_min_uint32(min_header_table_size, iv[i].value); break; case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: new_initial_window_size = (int32_t)iv[i].value; @@ -4738,8 +4236,8 @@ } if (new_initial_window_size != -1) { rv = session_update_local_initial_window_size( - session, new_initial_window_size, - (int32_t)session->local_settings.initial_window_size); + session, new_initial_window_size, + (int32_t)session->local_settings.initial_window_size); if (rv != 0) { return rv; } @@ -4793,15 +4291,15 @@ if (frame->hd.flags & NGHTTP2_FLAG_ACK) { if (frame->settings.niv != 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FRAME_SIZE_ERROR, - "SETTINGS: ACK and payload != 0"); + session, frame, NGHTTP2_ERR_FRAME_SIZE_ERROR, + "SETTINGS: ACK and payload != 0"); } settings = session->inflight_settings_head; if (!settings) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "SETTINGS: unexpected ACK"); + session, frame, NGHTTP2_ERR_PROTO, "SETTINGS: unexpected ACK"); } rv = nghttp2_session_update_local_settings(session, settings->iv, @@ -4822,7 +4320,7 @@ if (!session->remote_settings_received) { session->remote_settings.max_concurrent_streams = - NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; + NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; session->remote_settings_received = 1; } @@ -4839,7 +4337,7 @@ return rv; } else { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_HEADER_COMP, NULL); + session, frame, NGHTTP2_ERR_HEADER_COMP, NULL); } } @@ -4850,14 +4348,14 @@ if (entry->value != 0 && entry->value != 1) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_ENBLE_PUSH"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: invalid SETTINGS_ENBLE_PUSH"); } if (!session->server && entry->value != 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: server attempted to enable push"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: server attempted to enable push"); } session->remote_settings.enable_push = entry->value; @@ -4874,8 +4372,8 @@ /* Check that initial_window_size < (1u << 31) */ if (entry->value > NGHTTP2_MAX_WINDOW_SIZE) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FLOW_CONTROL, - "SETTINGS: too large SETTINGS_INITIAL_WINDOW_SIZE"); + session, frame, NGHTTP2_ERR_FLOW_CONTROL, + "SETTINGS: too large SETTINGS_INITIAL_WINDOW_SIZE"); } rv = session_update_remote_initial_window_size(session, @@ -4887,7 +4385,7 @@ if (rv != 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FLOW_CONTROL, NULL); + session, frame, NGHTTP2_ERR_FLOW_CONTROL, NULL); } session->remote_settings.initial_window_size = entry->value; @@ -4898,8 +4396,8 @@ if (entry->value < NGHTTP2_MAX_FRAME_SIZE_MIN || entry->value > NGHTTP2_MAX_FRAME_SIZE_MAX) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_MAX_FRAME_SIZE"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: invalid SETTINGS_MAX_FRAME_SIZE"); } session->remote_settings.max_frame_size = entry->value; @@ -4914,17 +4412,17 @@ if (entry->value != 0 && entry->value != 1) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_ENABLE_CONNECT_PROTOCOL"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: invalid SETTINGS_ENABLE_CONNECT_PROTOCOL"); } if (!session->server && session->remote_settings.enable_connect_protocol && entry->value == 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: server attempted to disable " - "SETTINGS_ENABLE_CONNECT_PROTOCOL"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: server attempted to disable " + "SETTINGS_ENABLE_CONNECT_PROTOCOL"); } session->remote_settings.enable_connect_protocol = entry->value; @@ -4934,15 +4432,15 @@ if (entry->value != 0 && entry->value != 1) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_NO_RFC7540_PRIORITIES"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: invalid SETTINGS_NO_RFC7540_PRIORITIES"); } if (session->remote_settings.no_rfc7540_priorities != UINT32_MAX && session->remote_settings.no_rfc7540_priorities != entry->value) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: SETTINGS_NO_RFC7540_PRIORITIES cannot be changed"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: SETTINGS_NO_RFC7540_PRIORITIES cannot be changed"); } session->remote_settings.no_rfc7540_priorities = entry->value; @@ -4953,12 +4451,6 @@ if (session->remote_settings.no_rfc7540_priorities == UINT32_MAX) { session->remote_settings.no_rfc7540_priorities = 0; - - if (session->server && session->pending_no_rfc7540_priorities && - (session->opt_flags & - NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES)) { - session->fallback_rfc7540_priorities = 1; - } } if (!noack && !session_is_closing(session)) { @@ -5019,20 +4511,19 @@ int rv; nghttp2_stream *stream; nghttp2_stream *promised_stream; - nghttp2_priority_spec pri_spec; if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream_id == 0"); } if (session->server || session->local_settings.enable_push == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: push disabled"); + session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: push disabled"); } if (!nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: invalid stream_id"); + session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: invalid stream_id"); } if (!session_allow_incoming_new_stream(session)) { @@ -5046,13 +4537,13 @@ illegal stream ID is subject to a connection error of type PROTOCOL_ERROR. */ return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "PUSH_PROMISE: invalid promised_stream_id"); + session, frame, NGHTTP2_ERR_PROTO, + "PUSH_PROMISE: invalid promised_stream_id"); } if (session_detect_idle_stream(session, frame->hd.stream_id)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream in idle"); + session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream in idle"); } session->last_recv_stream_id = frame->push_promise.promised_stream_id; @@ -5060,12 +4551,12 @@ if (!stream || stream->state == NGHTTP2_STREAM_CLOSING || !session->pending_enable_push || session->num_incoming_reserved_streams >= - session->max_incoming_reserved_streams) { + session->max_incoming_reserved_streams) { /* Currently, client does not retain closed stream, so we don't check NGHTTP2_SHUT_RD condition here. */ - - rv = nghttp2_session_add_rst_stream( - session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL); + rv = session_handle_invalid_stream2(session, + frame->push_promise.promised_stream_id, + NULL, NGHTTP2_ERR_PUSH_CANCEL); if (rv != 0) { return rv; } @@ -5074,24 +4565,17 @@ if (stream->shut_flags & NGHTTP2_SHUT_RD) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, - "PUSH_PROMISE: stream closed"); + session, frame, NGHTTP2_ERR_STREAM_CLOSED, "PUSH_PROMISE: stream closed"); } - nghttp2_priority_spec_init(&pri_spec, stream->stream_id, - NGHTTP2_DEFAULT_WEIGHT, 0); - promised_stream = nghttp2_session_open_stream( - session, frame->push_promise.promised_stream_id, NGHTTP2_STREAM_FLAG_NONE, - &pri_spec, NGHTTP2_STREAM_RESERVED, NULL); + session, frame->push_promise.promised_stream_id, NGHTTP2_STREAM_FLAG_NONE, + NGHTTP2_STREAM_RESERVED, NULL); if (!promised_stream) { return NGHTTP2_ERR_NOMEM; } - /* We don't call nghttp2_session_adjust_closed_stream(), since we - don't keep closed stream in client side */ - session->last_proc_stream_id = session->last_recv_stream_id; rv = session_call_on_begin_headers(session, frame); if (rv != 0) { @@ -5101,17 +4585,11 @@ } static int session_process_push_promise_frame(nghttp2_session *session) { - int rv; nghttp2_inbound_frame *iframe = &session->iframe; nghttp2_frame *frame = &iframe->frame; - rv = nghttp2_frame_unpack_push_promise_payload(&frame->push_promise, - iframe->sbuf.pos); - - if (rv != 0) { - return nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "PUSH_PROMISE: could not unpack"); - } + nghttp2_frame_unpack_push_promise_payload(&frame->push_promise, + iframe->sbuf.pos); return nghttp2_session_on_push_promise_received(session, frame); } @@ -5196,8 +4674,8 @@ /* Handle connection-level flow control */ if (frame->window_update.window_size_increment == 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "WINDOW_UPDATE: window_size_increment == 0"); + session, frame, NGHTTP2_ERR_PROTO, + "WINDOW_UPDATE: window_size_increment == 0"); } if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < @@ -5226,25 +4704,25 @@ } if (state_reserved_remote(session, stream)) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "WINDOW_UPADATE to reserved stream"); + session, frame, NGHTTP2_ERR_PROTO, "WINDOW_UPADATE to reserved stream"); } if (frame->window_update.window_size_increment == 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "WINDOW_UPDATE: window_size_increment == 0"); + session, frame, NGHTTP2_ERR_PROTO, + "WINDOW_UPDATE: window_size_increment == 0"); } if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < stream->remote_window_size) { - return session_handle_invalid_stream(session, frame, - NGHTTP2_ERR_FLOW_CONTROL); + return session_handle_invalid_connection( + session, frame, NGHTTP2_ERR_FLOW_CONTROL, + "WINDOW_UPDATE: window size overflow"); } stream->remote_window_size += frame->window_update.window_size_increment; if (stream->remote_window_size > 0 && nghttp2_stream_check_deferred_by_flow_control(stream)) { - rv = session_resume_deferred_stream_item( - session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); + session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); if (nghttp2_is_fatal(rv)) { return rv; @@ -5319,7 +4797,6 @@ nghttp2_frame *frame) { nghttp2_ext_priority_update *priority_update; nghttp2_stream *stream; - nghttp2_priority_spec pri_spec; nghttp2_extpri extpri; int rv; @@ -5335,8 +4812,8 @@ if (nghttp2_session_is_my_stream_id(session, priority_update->stream_id)) { if (session_detect_idle_stream(session, priority_update->stream_id)) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "PRIORITY_UPDATE: prioritizing idle push is not allowed"); + session, frame, NGHTTP2_ERR_PROTO, + "PRIORITY_UPDATE: prioritizing idle push is not allowed"); } /* TODO Ignore priority signal to a push stream for now */ @@ -5353,14 +4830,13 @@ if (session->num_idle_streams + session->num_incoming_streams >= session->local_settings.max_concurrent_streams) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "PRIORITY_UPDATE: max concurrent streams exceeded"); + session, frame, NGHTTP2_ERR_PROTO, + "PRIORITY_UPDATE: max concurrent streams exceeded"); } - nghttp2_priority_spec_default_init(&pri_spec); - stream = nghttp2_session_open_stream(session, priority_update->stream_id, - NGHTTP2_FLAG_NONE, &pri_spec, - NGHTTP2_STREAM_IDLE, NULL); + stream = + nghttp2_session_open_stream(session, priority_update->stream_id, + NGHTTP2_FLAG_NONE, NGHTTP2_STREAM_IDLE, NULL); if (!stream) { return NGHTTP2_ERR_NOMEM; } @@ -5394,8 +4870,8 @@ nghttp2_frame *frame = &iframe->frame; nghttp2_frame_unpack_altsvc_payload( - &frame->ext, nghttp2_get_uint16(iframe->sbuf.pos), iframe->lbuf.pos, - nghttp2_buf_len(&iframe->lbuf)); + &frame->ext, nghttp2_get_uint16(iframe->sbuf.pos), iframe->lbuf.pos, + nghttp2_buf_len(&iframe->lbuf)); /* nghttp2_frame_unpack_altsvc_payload steals buffer from iframe->lbuf */ @@ -5469,16 +4945,7 @@ if (session_enforce_http_messaging(session) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { if (nghttp2_http_on_remote_end_stream(stream) != 0) { - rv = nghttp2_session_add_rst_stream(session, stream->stream_id, - NGHTTP2_PROTOCOL_ERROR); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); - /* Don't call nghttp2_session_close_stream_if_shut_rdwr because - RST_STREAM has been submitted. */ - return 0; + return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR); } } @@ -5536,8 +5003,8 @@ rv = adjust_recv_window_size(&stream->recv_window_size, delta_size, stream->local_window_size); if (rv != 0) { - return nghttp2_session_add_rst_stream(session, stream->stream_id, - NGHTTP2_FLOW_CONTROL_ERROR); + return nghttp2_session_terminate_session(session, + NGHTTP2_FLOW_CONTROL_ERROR); } /* We don't have to send WINDOW_UPDATE if the data received is the last chunk in the incoming stream. */ @@ -5548,9 +5015,8 @@ stream->window_update_queued == 0 && nghttp2_should_send_window_update(stream->local_window_size, stream->recv_window_size)) { - rv = nghttp2_session_add_window_update(session, NGHTTP2_FLAG_NONE, - stream->stream_id, - stream->recv_window_size); + rv = nghttp2_session_add_window_update( + session, NGHTTP2_FLAG_NONE, stream->stream_id, stream->recv_window_size); if (rv != 0) { return rv; } @@ -5606,7 +5072,7 @@ /* recv_window_size may be smaller than consumed_size, because it may be decreased by negative value with nghttp2_submit_window_update(). */ - recv_size = nghttp2_min(*consumed_size_ptr, *recv_window_size_ptr); + recv_size = nghttp2_min_int32(*consumed_size_ptr, *recv_window_size_ptr); if (nghttp2_should_send_window_update(local_window_size, recv_size)) { rv = nghttp2_session_add_window_update(session, NGHTTP2_FLAG_NONE, @@ -5628,16 +5094,16 @@ nghttp2_stream *stream, size_t delta_size) { return session_update_consumed_size( - session, &stream->consumed_size, &stream->recv_window_size, - stream->window_update_queued, stream->stream_id, delta_size, - stream->local_window_size); + session, &stream->consumed_size, &stream->recv_window_size, + stream->window_update_queued, stream->stream_id, delta_size, + stream->local_window_size); } static int session_update_connection_consumed_size(nghttp2_session *session, size_t delta_size) { return session_update_consumed_size( - session, &session->consumed_size, &session->recv_window_size, - session->window_update_queued, 0, delta_size, session->local_window_size); + session, &session->consumed_size, &session->recv_window_size, + session->window_update_queued, 0, delta_size, session->local_window_size); } /* @@ -5729,7 +5195,7 @@ static size_t inbound_frame_payload_readlen(nghttp2_inbound_frame *iframe, const uint8_t *in, const uint8_t *last) { - return nghttp2_min((size_t)(last - in), iframe->payloadleft); + return nghttp2_min_size((size_t)(last - in), iframe->payloadleft); } /* @@ -5744,8 +5210,8 @@ const uint8_t *in, const uint8_t *last) { size_t readlen; - readlen = - nghttp2_min((size_t)(last - in), nghttp2_buf_mark_avail(&iframe->sbuf)); + readlen = nghttp2_min_size((size_t)(last - in), + nghttp2_buf_mark_avail(&iframe->sbuf)); iframe->sbuf.last = nghttp2_cpymem(iframe->sbuf.last, in, readlen); @@ -5823,7 +5289,7 @@ * Computes number of padding based on flags. This function returns * the calculated length if it succeeds, or -1. */ -static ssize_t inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) { +static nghttp2_ssize inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) { size_t padlen; /* 1 for Pad Length field */ @@ -5838,7 +5304,7 @@ iframe->padlen = padlen; - return (ssize_t)padlen; + return (nghttp2_ssize)padlen; } /* @@ -5847,11 +5313,11 @@ * |payloadleft| does not include |readlen|. If padding was started * strictly before this data chunk, this function returns -1. */ -static ssize_t inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe, - size_t payloadleft, - size_t readlen) { +static nghttp2_ssize +inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe, + size_t payloadleft, size_t readlen) { size_t trail_padlen = - nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen); + nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen); if (trail_padlen > payloadleft) { size_t padlen; @@ -5859,19 +5325,24 @@ if (readlen < padlen) { return -1; } - return (ssize_t)(readlen - padlen); + return (nghttp2_ssize)(readlen - padlen); } - return (ssize_t)(readlen); + return (nghttp2_ssize)(readlen); } static const uint8_t static_in[] = {0}; ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, size_t inlen) { + return (ssize_t)nghttp2_session_mem_recv2(session, in, inlen); +} + +nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + const uint8_t *in, size_t inlen) { const uint8_t *first, *last; nghttp2_inbound_frame *iframe = &session->iframe; size_t readlen; - ssize_t padlen; + nghttp2_ssize padlen; int rv; int busy = 0; nghttp2_frame_hd cont_hd; @@ -5892,22 +5363,14 @@ mem = &session->mem; - /* We may have idle streams more than we expect (e.g., - nghttp2_session_change_stream_priority() or - nghttp2_session_create_idle_stream()). Adjust them here. */ - rv = nghttp2_session_adjust_idle_stream(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - if (!nghttp2_session_want_read(session)) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } for (;;) { switch (iframe->state) { case NGHTTP2_IB_READ_CLIENT_MAGIC: - readlen = nghttp2_min(inlen, iframe->payloadleft); + readlen = nghttp2_min_size(inlen, iframe->payloadleft); if (memcmp(&NGHTTP2_CLIENT_MAGIC[NGHTTP2_CLIENT_MAGIC_LEN - iframe->payloadleft], @@ -5931,29 +5394,29 @@ in += readlen; if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return in - first; + return (nghttp2_ssize)(in - first); } if (iframe->sbuf.pos[3] != NGHTTP2_SETTINGS || (iframe->sbuf.pos[4] & NGHTTP2_FLAG_ACK)) { rv = session_call_error_callback( - session, NGHTTP2_ERR_SETTINGS_EXPECTED, - "Remote peer returned unexpected data while we expected " - "SETTINGS frame. Perhaps, peer does not support HTTP/2 " - "properly."); + session, NGHTTP2_ERR_SETTINGS_EXPECTED, + "Remote peer returned unexpected data while we expected " + "SETTINGS frame. Perhaps, peer does not support HTTP/2 " + "properly."); if (nghttp2_is_fatal(rv)) { return rv; } rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "SETTINGS expected"); + session, NGHTTP2_PROTOCOL_ERROR, "SETTINGS expected"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } iframe->state = NGHTTP2_IB_READ_HEAD; @@ -5968,7 +5431,7 @@ in += readlen; if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return in - first; + return (nghttp2_ssize)(in - first); } nghttp2_frame_unpack_frame_hd(&iframe->frame.hd, iframe->sbuf.pos); @@ -5983,13 +5446,13 @@ session->local_settings.max_frame_size); rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_FRAME_SIZE_ERROR, "too large frame size"); + session, NGHTTP2_FRAME_SIZE_ERROR, "too large frame size"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } switch (iframe->frame.hd.type) { @@ -5997,18 +5460,28 @@ DEBUGF("recv: DATA\n"); iframe->frame.hd.flags &= - (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PADDED); + (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PADDED); /* Check stream is open. If it is not open or closing, ignore payload. */ busy = 1; rv = session_on_data_received_fail_fast(session); if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (rv == NGHTTP2_ERR_IGN_PAYLOAD) { DEBUGF("recv: DATA not allowed stream_id=%d\n", iframe->frame.hd.stream_id); + + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + iframe->state = NGHTTP2_IB_IGN_DATA; break; } @@ -6020,13 +5493,13 @@ rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); if (rv < 0) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "DATA: insufficient padding space"); + session, NGHTTP2_PROTOCOL_ERROR, + "DATA: insufficient padding space"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (rv == 1) { @@ -6034,6 +5507,20 @@ break; } + /* Empty DATA frame without END_STREAM flag set is + suspicious. */ + if (iframe->payloadleft == 0 && + (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + } + iframe->state = NGHTTP2_IB_READ_DATA; break; } @@ -6042,18 +5529,18 @@ DEBUGF("recv: HEADERS\n"); iframe->frame.hd.flags &= - (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS | - NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_PRIORITY); + (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS | + NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_PRIORITY); rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); if (rv < 0) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "HEADERS: insufficient padding space"); + session, NGHTTP2_PROTOCOL_ERROR, + "HEADERS: insufficient padding space"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (rv == 1) { @@ -6096,12 +5583,12 @@ busy = 1; if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = nghttp2_session_add_rst_stream( - session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); + rv = session_handle_invalid_stream2( + session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6110,6 +5597,15 @@ } if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) { + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; break; } @@ -6130,6 +5626,18 @@ break; } + /* This is deprecated RFC 7540 priorities mechanism which is + very unpopular. We do not expect it is received so + frequently. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + iframe->state = NGHTTP2_IB_READ_NBYTE; inbound_frame_set_mark(iframe, NGHTTP2_PRIORITY_SPECLEN); @@ -6146,7 +5654,7 @@ DEBUGF("recv: WINDOW_UPDATE\n"); break; } -#endif /* DEBUGBUILD */ +#endif /* defined(DEBUGBUILD) */ iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; @@ -6188,20 +5696,20 @@ /* We allocate iv with additional one entry, to store the minimum header table size. */ iframe->max_niv = - iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1; + iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1; if (iframe->max_niv - 1 > session->max_settings) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_ENHANCE_YOUR_CALM, - "SETTINGS: too many setting entries"); + session, NGHTTP2_ENHANCE_YOUR_CALM, + "SETTINGS: too many setting entries"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) * - iframe->max_niv); + iframe->max_niv); if (!iframe->iv) { return NGHTTP2_ERR_NOMEM; @@ -6209,7 +5717,7 @@ min_header_table_size_entry = &iframe->iv[iframe->max_niv - 1]; min_header_table_size_entry->settings_id = - NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; + NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; min_header_table_size_entry->value = UINT32_MAX; inbound_frame_set_mark(iframe, NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH); @@ -6225,17 +5733,17 @@ DEBUGF("recv: PUSH_PROMISE\n"); iframe->frame.hd.flags &= - (NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_PADDED); + (NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_PADDED); rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); if (rv < 0) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "PUSH_PROMISE: insufficient padding space"); + session, NGHTTP2_PROTOCOL_ERROR, + "PUSH_PROMISE: insufficient padding space"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (rv == 1) { @@ -6290,20 +5798,29 @@ /* Receiving CONTINUATION in this state are subject to connection error of type PROTOCOL_ERROR */ rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "CONTINUATION: unexpected"); + session, NGHTTP2_PROTOCOL_ERROR, "CONTINUATION: unexpected"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; default: DEBUGF("recv: extension frame\n"); if (check_ext_type_set(session->user_recv_ext_types, iframe->frame.hd.type)) { if (!session->callbacks.unpack_extension_callback) { - /* Silently ignore unknown frame type. */ + /* Receiving too frequent unknown frames is suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + + /* Silently ignore unknown frame type. */ busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; @@ -6321,6 +5838,16 @@ case NGHTTP2_ALTSVC: if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) == 0) { + /* Receiving too frequent unknown frames is suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -6332,6 +5859,17 @@ iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc; if (session->server) { + /* Receiving too frequent ALTSVC from client is + suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -6351,6 +5889,16 @@ break; case NGHTTP2_ORIGIN: if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) { + /* Receiving too frequent unknown frames is suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -6362,6 +5910,17 @@ if (session->server || iframe->frame.hd.stream_id || (iframe->frame.hd.flags & 0xf0)) { + /* Receiving too frequent invalid frames is + suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -6388,6 +5947,16 @@ case NGHTTP2_PRIORITY_UPDATE: if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) { + /* Receiving too frequent unknown frames is suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -6397,16 +5966,16 @@ iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; iframe->frame.ext.payload = - &iframe->ext_frame_payload.priority_update; + &iframe->ext_frame_payload.priority_update; if (!session->server) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "PRIORITY_UPDATE is received from server"); + session, NGHTTP2_PROTOCOL_ERROR, + "PRIORITY_UPDATE is received from server"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (iframe->payloadleft < 4) { @@ -6415,8 +5984,18 @@ break; } - if (!session_no_rfc7540_pri_no_fallback(session) || - iframe->payloadleft > sizeof(iframe->raw_sbuf)) { + /* Receiving too frequent PRIORITY_UPDATE is + suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + + if (iframe->payloadleft > sizeof(iframe->raw_sbuf)) { busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; break; @@ -6429,6 +6008,16 @@ break; default: + /* Receiving too frequent unknown frames is suspicious. */ + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + busy = 1; iframe->state = NGHTTP2_IB_IGN_PAYLOAD; @@ -6464,11 +6053,11 @@ in += readlen; iframe->payloadleft -= readlen; - DEBUGF("recv: readlen=%zu, payloadleft=%zu, left=%zd\n", readlen, + DEBUGF("recv: readlen=%zu, payloadleft=%zu, left=%zu\n", readlen, iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf)); if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return in - first; + return (nghttp2_ssize)(in - first); } switch (iframe->frame.hd.type) { @@ -6480,11 +6069,11 @@ if (padlen < 0 || (size_t)padlen + pri_fieldlen > 1 + iframe->payloadleft) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: invalid padding"); + session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: invalid padding"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } iframe->frame.headers.padlen = (size_t)padlen; @@ -6511,12 +6100,12 @@ busy = 1; if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = nghttp2_session_add_rst_stream( - session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); + rv = session_handle_invalid_stream2( + session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6525,6 +6114,15 @@ } if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) { + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; break; } @@ -6533,18 +6131,6 @@ break; case NGHTTP2_PRIORITY: - if (!session_no_rfc7540_pri_no_fallback(session) && - session->remote_settings.no_rfc7540_priorities != 1) { - rv = session_process_priority_frame(session); - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; - } - } - session_inbound_frame_reset(session); break; @@ -6555,7 +6141,7 @@ } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } session_inbound_frame_reset(session); @@ -6566,14 +6152,13 @@ (iframe->frame.hd.flags & NGHTTP2_FLAG_PADDED)) { padlen = inbound_frame_compute_pad(iframe); if (padlen < 0 || (size_t)padlen + 4 /* promised stream id */ - > 1 + iframe->payloadleft) { + > 1 + iframe->payloadleft) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "PUSH_PROMISE: invalid padding"); + session, NGHTTP2_PROTOCOL_ERROR, "PUSH_PROMISE: invalid padding"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } iframe->frame.push_promise.padlen = (size_t)padlen; @@ -6599,13 +6184,13 @@ busy = 1; if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { - rv = nghttp2_session_add_rst_stream( - session, iframe->frame.push_promise.promised_stream_id, - NGHTTP2_INTERNAL_ERROR); + rv = session_handle_invalid_stream2( + session, iframe->frame.push_promise.promised_stream_id, NULL, + NGHTTP2_ERR_INTERNAL); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6628,7 +6213,7 @@ } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } session_inbound_frame_reset(session); @@ -6663,7 +6248,7 @@ } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } session_inbound_frame_reset(session); @@ -6684,7 +6269,7 @@ if (iframe->frame.hd.length > 2) { iframe->raw_lbuf = - nghttp2_mem_malloc(mem, iframe->frame.hd.length - 2); + nghttp2_mem_malloc(mem, iframe->frame.hd.length - 2); if (iframe->raw_lbuf == NULL) { return NGHTTP2_ERR_NOMEM; @@ -6721,7 +6306,7 @@ break; case NGHTTP2_IB_READ_HEADER_BLOCK: case NGHTTP2_IB_IGN_HEADER_BLOCK: { - ssize_t data_readlen; + nghttp2_ssize data_readlen; size_t trail_padlen; int final; #ifdef DEBUGBUILD @@ -6730,7 +6315,7 @@ } else { DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n"); } -#endif /* DEBUGBUILD */ +#endif /* defined(DEBUGBUILD) */ readlen = inbound_frame_payload_readlen(iframe, in, last); @@ -6738,7 +6323,7 @@ iframe->payloadleft - readlen); data_readlen = inbound_frame_effective_readlen( - iframe, iframe->payloadleft - readlen, readlen); + iframe, iframe->payloadleft - readlen, readlen); if (data_readlen == -1) { /* everything is padding */ @@ -6756,23 +6341,23 @@ DEBUGF("recv: block final=%d\n", final); rv = - inflate_header_block(session, &iframe->frame, &hd_proclen, - (uint8_t *)in, (size_t)data_readlen, final, - iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK); + inflate_header_block(session, &iframe->frame, &hd_proclen, + (uint8_t *)in, (size_t)data_readlen, final, + iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK); if (nghttp2_is_fatal(rv)) { return rv; } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (rv == NGHTTP2_ERR_PAUSE) { in += hd_proclen; iframe->payloadleft -= hd_proclen; - return in - first; + return (nghttp2_ssize)(in - first); } if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { @@ -6783,12 +6368,12 @@ iframe->payloadleft -= hd_proclen; /* Use promised stream ID for PUSH_PROMISE */ - rv = nghttp2_session_add_rst_stream( - session, - iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE - ? iframe->frame.push_promise.promised_stream_id - : iframe->frame.hd.stream_id, - NGHTTP2_INTERNAL_ERROR); + rv = session_handle_invalid_stream2( + session, + iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE + ? iframe->frame.push_promise.promised_stream_id + : iframe->frame.hd.stream_id, + NULL, NGHTTP2_ERR_INTERNAL); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6820,7 +6405,6 @@ } if ((iframe->frame.hd.flags & NGHTTP2_FLAG_END_HEADERS) == 0) { - inbound_frame_set_mark(iframe, NGHTTP2_FRAME_HDLEN); iframe->padlen = 0; @@ -6836,8 +6420,14 @@ if (nghttp2_is_fatal(rv)) { return rv; } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } } session_inbound_frame_reset(session); + + session->num_continuations = 0; } break; } @@ -6879,7 +6469,7 @@ assert(iframe->state == NGHTTP2_IB_IGN_ALL); - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; case NGHTTP2_IB_READ_SETTINGS: DEBUGF("recv: [IB_READ_SETTINGS]\n"); @@ -6909,7 +6499,7 @@ } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } session_inbound_frame_reset(session); @@ -6943,7 +6533,7 @@ } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } session_inbound_frame_reset(session); @@ -6957,13 +6547,17 @@ } else { fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n"); } -#endif /* DEBUGBUILD */ +#endif /* defined(DEBUGBUILD) */ + + if (++session->num_continuations > session->max_continuations) { + return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS; + } readlen = inbound_frame_buf_read(iframe, in, last); in += readlen; if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return in - first; + return (nghttp2_ssize)(in - first); } nghttp2_frame_unpack_frame_hd(&cont_hd, iframe->sbuf.pos); @@ -6979,20 +6573,20 @@ iframe->frame.hd.stream_id, NGHTTP2_CONTINUATION, cont_hd.stream_id, cont_hd.type); rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "unexpected non-CONTINUATION frame or stream_id is invalid"); + session, NGHTTP2_PROTOCOL_ERROR, + "unexpected non-CONTINUATION frame or stream_id is invalid"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } /* CONTINUATION won't bear NGHTTP2_PADDED flag */ iframe->frame.hd.flags = - (uint8_t)(iframe->frame.hd.flags | - (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS)); + (uint8_t)(iframe->frame.hd.flags | + (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS)); iframe->frame.hd.length += cont_hd.length; busy = 1; @@ -7021,7 +6615,7 @@ iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf)); if (nghttp2_buf_mark_avail(&iframe->sbuf)) { - return in - first; + return (nghttp2_ssize)(in - first); } /* Pad Length field is subject to flow control */ @@ -7031,30 +6625,34 @@ } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } /* Pad Length field is consumed immediately */ rv = - nghttp2_session_consume(session, iframe->frame.hd.stream_id, readlen); + nghttp2_session_consume(session, iframe->frame.hd.stream_id, readlen); if (nghttp2_is_fatal(rv)) { return rv; } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id); if (stream) { rv = nghttp2_session_update_recv_stream_window_size( - session, stream, readlen, - iframe->payloadleft || - (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); + session, stream, readlen, + iframe->payloadleft || + (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); if (nghttp2_is_fatal(rv)) { return rv; } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } } busy = 1; @@ -7062,15 +6660,29 @@ padlen = inbound_frame_compute_pad(iframe); if (padlen < 0) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "DATA: invalid padding"); + session, NGHTTP2_PROTOCOL_ERROR, "DATA: invalid padding"); if (nghttp2_is_fatal(rv)) { return rv; } - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } iframe->frame.data.padlen = (size_t)padlen; + /* Empty DATA frame without END_STREAM flag set is + suspicious. */ + if (iframe->payloadleft == 0 && + (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { + rv = session_update_glitch_ratelim(session); + if (rv != 0) { + return rv; + } + + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + } + iframe->state = NGHTTP2_IB_READ_DATA; break; @@ -7093,35 +6705,39 @@ iframe->payloadleft); if (readlen > 0) { - ssize_t data_readlen; + nghttp2_ssize data_readlen; - rv = nghttp2_session_update_recv_connection_window_size(session, - readlen); + rv = + nghttp2_session_update_recv_connection_window_size(session, readlen); if (nghttp2_is_fatal(rv)) { return rv; } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } rv = nghttp2_session_update_recv_stream_window_size( - session, stream, readlen, - iframe->payloadleft || - (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); + session, stream, readlen, + iframe->payloadleft || + (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); if (nghttp2_is_fatal(rv)) { return rv; } - data_readlen = inbound_frame_effective_readlen( - iframe, iframe->payloadleft, readlen); + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + + data_readlen = + inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen); if (data_readlen == -1) { /* everything is padding */ data_readlen = 0; } - padlen = (ssize_t)readlen - data_readlen; + padlen = (nghttp2_ssize)readlen - data_readlen; if (padlen > 0) { /* Padding is considered as "consumed" immediately */ @@ -7133,45 +6749,30 @@ } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } } - DEBUGF("recv: data_readlen=%zd\n", data_readlen); + DEBUGF("recv: data_readlen=%td\n", data_readlen); if (data_readlen > 0) { if (session_enforce_http_messaging(session)) { if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) { - if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { - /* Consume all data for connection immediately here */ - rv = session_update_connection_consumed_size( - session, (size_t)data_readlen); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - if (iframe->state == NGHTTP2_IB_IGN_DATA) { - return (ssize_t)inlen; - } - } - - rv = nghttp2_session_add_rst_stream( - session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR); + rv = nghttp2_session_terminate_session(session, + NGHTTP2_PROTOCOL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } - busy = 1; - iframe->state = NGHTTP2_IB_IGN_DATA; - break; + + return (nghttp2_ssize)inlen; } } if (session->callbacks.on_data_chunk_recv_callback) { rv = session->callbacks.on_data_chunk_recv_callback( - session, iframe->frame.hd.flags, iframe->frame.hd.stream_id, - in - readlen, (size_t)data_readlen, session->user_data); + session, iframe->frame.hd.flags, iframe->frame.hd.stream_id, + in - readlen, (size_t)data_readlen, session->user_data); if (rv == NGHTTP2_ERR_PAUSE) { - return in - first; + return (nghttp2_ssize)(in - first); } if (nghttp2_is_fatal(rv)) { @@ -7190,6 +6791,10 @@ return rv; } + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } + session_inbound_frame_reset(session); break; @@ -7206,18 +6811,17 @@ if (readlen > 0) { /* Update connection-level flow control window for ignored DATA frame too */ - rv = nghttp2_session_update_recv_connection_window_size(session, - readlen); + rv = + nghttp2_session_update_recv_connection_window_size(session, readlen); if (nghttp2_is_fatal(rv)) { return rv; } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { - /* Ignored DATA is considered as "consumed" immediately. */ rv = session_update_connection_consumed_size(session, readlen); @@ -7226,7 +6830,7 @@ } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } } } @@ -7239,7 +6843,7 @@ break; case NGHTTP2_IB_IGN_ALL: - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; case NGHTTP2_IB_READ_EXTENSION_PAYLOAD: DEBUGF("recv: [IB_READ_EXTENSION_PAYLOAD]\n"); @@ -7252,7 +6856,7 @@ if (readlen > 0) { rv = session_call_on_extension_chunk_recv_callback( - session, in - readlen, readlen); + session, in - readlen, readlen); if (nghttp2_is_fatal(rv)) { return rv; } @@ -7334,7 +6938,7 @@ } if (iframe->state == NGHTTP2_IB_IGN_ALL) { - return (ssize_t)inlen; + return (nghttp2_ssize)inlen; } session_inbound_frame_reset(session); @@ -7351,16 +6955,17 @@ assert(in == last); - return in - first; + return (nghttp2_ssize)(in - first); } int nghttp2_session_recv(nghttp2_session *session) { uint8_t buf[NGHTTP2_INBOUND_BUFFER_LENGTH]; while (1) { - ssize_t readlen; + nghttp2_ssize readlen; readlen = session_recv(session, buf, sizeof(buf)); if (readlen > 0) { - ssize_t proclen = nghttp2_session_mem_recv(session, buf, (size_t)readlen); + nghttp2_ssize proclen = + nghttp2_session_mem_recv2(session, buf, (size_t)readlen); if (proclen < 0) { return (int)proclen; } @@ -7423,9 +7028,7 @@ */ return session->aob.item || nghttp2_outbound_queue_top(&session->ob_urgent) || nghttp2_outbound_queue_top(&session->ob_reg) || - ((!nghttp2_pq_empty(&session->root.obq) || - !session_sched_empty(session)) && - session->remote_window_size > 0) || + (!session_sched_empty(session) && session->remote_window_size > 0) || (nghttp2_outbound_queue_top(&session->ob_syn) && !session_is_outgoing_concurrent_streams_max(session)); } @@ -7509,7 +7112,8 @@ /* last_stream_id must not be increased from the value previously sent */ - last_stream_id = nghttp2_min(last_stream_id, session->local_last_stream_id); + last_stream_id = + nghttp2_min_int32(last_stream_id, session->local_last_stream_id); nghttp2_frame_goaway_init(&frame->goaway, last_stream_id, error_code, opaque_data_copy, opaque_data_len); @@ -7523,6 +7127,9 @@ nghttp2_mem_free(mem, item); return rv; } + + session->goaway_flags |= NGHTTP2_GOAWAY_SUBMITTED; + return 0; } @@ -7699,8 +7306,8 @@ nghttp2_stream *stream) { int rv; uint32_t data_flags; - ssize_t payloadlen; - ssize_t padded_payloadlen; + nghttp2_ssize payloadlen; + nghttp2_ssize padded_payloadlen; nghttp2_buf *buf; size_t max_payloadlen; @@ -7708,19 +7315,26 @@ buf = &bufs->cur->buf; - if (session->callbacks.read_length_callback) { - - payloadlen = session->callbacks.read_length_callback( + if (session->callbacks.read_length_callback2 || + session->callbacks.read_length_callback) { + if (session->callbacks.read_length_callback2) { + payloadlen = session->callbacks.read_length_callback2( session, frame->hd.type, stream->stream_id, session->remote_window_size, stream->remote_window_size, session->remote_settings.max_frame_size, session->user_data); + } else { + payloadlen = (nghttp2_ssize)session->callbacks.read_length_callback( + session, frame->hd.type, stream->stream_id, session->remote_window_size, + stream->remote_window_size, session->remote_settings.max_frame_size, + session->user_data); + } - DEBUGF("send: read_length_callback=%zd\n", payloadlen); + DEBUGF("send: read_length_callback=%td\n", payloadlen); - payloadlen = nghttp2_session_enforce_flow_control_limits(session, stream, - payloadlen); + payloadlen = + nghttp2_session_enforce_flow_control_limits(session, stream, payloadlen); - DEBUGF("send: read_length_callback after flow control=%zd\n", payloadlen); + DEBUGF("send: read_length_callback after flow control=%td\n", payloadlen); if (payloadlen <= 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; @@ -7736,9 +7350,9 @@ DEBUGF("send: realloc buffer failed rv=%d", rv); /* If reallocation failed, old buffers are still in tact. So use safe limit. */ - payloadlen = (ssize_t)datamax; + payloadlen = (nghttp2_ssize)datamax; - DEBUGF("send: use safe limit payloadlen=%zd", payloadlen); + DEBUGF("send: use safe limit payloadlen=%td", payloadlen); } else { assert(&session->aob.framebufs == bufs); @@ -7752,9 +7366,23 @@ assert(nghttp2_buf_avail(buf) >= datamax); data_flags = NGHTTP2_DATA_FLAG_NONE; - payloadlen = aux_data->data_prd.read_callback( + switch (aux_data->dpw.version) { + case NGHTTP2_DATA_PROVIDER_V1: + payloadlen = (nghttp2_ssize)aux_data->dpw.data_prd.v1.read_callback( session, frame->hd.stream_id, buf->pos, datamax, &data_flags, - &aux_data->data_prd.source, session->user_data); + &aux_data->dpw.data_prd.source, session->user_data); + + break; + case NGHTTP2_DATA_PROVIDER_V2: + payloadlen = aux_data->dpw.data_prd.v2.read_callback( + session, frame->hd.stream_id, buf->pos, datamax, &data_flags, + &aux_data->dpw.data_prd.source, session->user_data); + + break; + default: + assert(0); + abort(); + } if (payloadlen == NGHTTP2_ERR_DEFERRED || payloadlen == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE || @@ -7799,10 +7427,11 @@ frame->hd.length = (size_t)payloadlen; frame->data.padlen = 0; - max_payloadlen = nghttp2_min(datamax, frame->hd.length + NGHTTP2_MAX_PADLEN); + max_payloadlen = + nghttp2_min_size(datamax, frame->hd.length + NGHTTP2_MAX_PADLEN); padded_payloadlen = - session_call_select_padding(session, frame, max_payloadlen); + session_call_select_padding(session, frame, max_payloadlen); if (nghttp2_is_fatal((int)padded_payloadlen)) { return (int)padded_payloadlen; @@ -7812,11 +7441,8 @@ nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); - rv = nghttp2_frame_add_pad(bufs, &frame->hd, frame->data.padlen, - aux_data->no_copy); - if (rv != 0) { - return rv; - } + nghttp2_frame_add_pad(bufs, &frame->hd, frame->data.padlen, + aux_data->no_copy); session_reschedule_stream(session, stream); @@ -7976,7 +7602,7 @@ /* stream->remote_window_size can be negative when SETTINGS_INITIAL_WINDOW_SIZE is changed. */ - return nghttp2_max(0, stream->remote_window_size); + return nghttp2_max_int32(0, stream->remote_window_size); } int32_t nghttp2_session_get_remote_window_size(nghttp2_session *session) { @@ -8042,7 +7668,6 @@ nghttp2_settings_entry *iv; size_t niv; int rv; - nghttp2_priority_spec pri_spec; nghttp2_mem *mem; mem = &session->mem; @@ -8079,18 +7704,13 @@ return rv; } - nghttp2_priority_spec_default_init(&pri_spec); - stream = nghttp2_session_open_stream( - session, 1, NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_OPENING, - session->server ? NULL : stream_user_data); + session, 1, NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_OPENING, + session->server ? NULL : stream_user_data); if (stream == NULL) { return NGHTTP2_ERR_NOMEM; } - /* We don't call nghttp2_session_adjust_closed_stream(), since this - should be the first stream open. */ - if (session->server) { nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); session->last_recv_stream_id = 1; @@ -8289,14 +7909,16 @@ nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session, int32_t stream_id) { if (stream_id == 0) { - return &session->root; + return &nghttp2_stream_root; } return nghttp2_session_get_stream_raw(session, stream_id); } nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) { - return &session->root; + (void)session; + + return &nghttp2_stream_root; } int nghttp2_session_check_server_session(nghttp2_session *session) { @@ -8304,77 +7926,22 @@ } int nghttp2_session_change_stream_priority( - nghttp2_session *session, int32_t stream_id, - const nghttp2_priority_spec *pri_spec) { - int rv; - nghttp2_stream *stream; - nghttp2_priority_spec pri_spec_copy; + nghttp2_session *session, int32_t stream_id, + const nghttp2_priority_spec *pri_spec) { + (void)session; + (void)stream_id; + (void)pri_spec; - if (session->pending_no_rfc7540_priorities == 1) { - return 0; - } - - if (stream_id == 0 || stream_id == pri_spec->stream_id) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - stream = nghttp2_session_get_stream_raw(session, stream_id); - if (!stream) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - pri_spec_copy = *pri_spec; - nghttp2_priority_spec_normalize_weight(&pri_spec_copy); - - rv = nghttp2_session_reprioritize_stream(session, stream, &pri_spec_copy); - - if (nghttp2_is_fatal(rv)) { - return rv; - } - - /* We don't intentionally call nghttp2_session_adjust_idle_stream() - so that idle stream created by this function, and existing ones - are kept for application. We will adjust number of idle stream - in nghttp2_session_mem_send or nghttp2_session_mem_recv is - called. */ return 0; } int nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id, const nghttp2_priority_spec *pri_spec) { - nghttp2_stream *stream; - nghttp2_priority_spec pri_spec_copy; + (void)session; + (void)stream_id; + (void)pri_spec; - if (session->pending_no_rfc7540_priorities == 1) { - return 0; - } - - if (stream_id == 0 || stream_id == pri_spec->stream_id || - !session_detect_idle_stream(session, stream_id)) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - stream = nghttp2_session_get_stream_raw(session, stream_id); - if (stream) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - pri_spec_copy = *pri_spec; - nghttp2_priority_spec_normalize_weight(&pri_spec_copy); - - stream = - nghttp2_session_open_stream(session, stream_id, NGHTTP2_STREAM_FLAG_NONE, - &pri_spec_copy, NGHTTP2_STREAM_IDLE, NULL); - if (!stream) { - return NGHTTP2_ERR_NOMEM; - } - - /* We don't intentionally call nghttp2_session_adjust_idle_stream() - so that idle stream created by this function, and existing ones - are kept for application. We will adjust number of idle stream - in nghttp2_session_mem_send or nghttp2_session_mem_recv is - called. */ return 0; } @@ -8393,8 +7960,8 @@ } int nghttp2_session_change_extpri_stream_priority( - nghttp2_session *session, int32_t stream_id, - const nghttp2_extpri *extpri_in, int ignore_client_signal) { + nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri_in, + int ignore_client_signal) { nghttp2_stream *stream; nghttp2_extpri extpri = *extpri_in; @@ -8426,3 +7993,30 @@ return session_update_stream_priority(session, stream, nghttp2_extpri_to_uint8(&extpri)); } + +int nghttp2_session_get_extpri_stream_priority(nghttp2_session *session, + nghttp2_extpri *extpri, + int32_t stream_id) { + nghttp2_stream *stream; + + if (!session->server) { + return NGHTTP2_ERR_INVALID_STATE; + } + + if (session->pending_no_rfc7540_priorities != 1) { + return 0; + } + + if (stream_id == 0) { + return NGHTTP2_ERR_INVALID_ARGUMENT; + } + + stream = nghttp2_session_get_stream_raw(session, stream_id); + if (!stream) { + return NGHTTP2_ERR_INVALID_ARGUMENT; + } + + nghttp2_extpri_from_uint8(extpri, stream->extpri); + + return 0; +}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_session.h b/Utilities/cmnghttp2/lib/nghttp2_session.h index 34d2d58..edbef80 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_session.h +++ b/Utilities/cmnghttp2/lib/nghttp2_session.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> #include "nghttp2_map.h" @@ -39,11 +39,14 @@ #include "nghttp2_buf.h" #include "nghttp2_callbacks.h" #include "nghttp2_mem.h" +#include "nghttp2_ratelim.h" /* The global variable for tests where we want to disable strict preface handling. */ extern int nghttp2_enable_strict_preface; +extern nghttp2_stream nghttp2_stream_root; + /* * Option flags. */ @@ -52,8 +55,6 @@ NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1, NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2, NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3, - NGHTTP2_OPTMASK_NO_CLOSED_STREAMS = 1 << 4, - NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 5, NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 6, } nghttp2_optmask; @@ -88,10 +89,6 @@ /* The default maximum number of incoming reserved streams */ #define NGHTTP2_MAX_INCOMING_RESERVED_STREAMS 200 -/* Even if we have less SETTINGS_MAX_CONCURRENT_STREAMS than this - number, we keep NGHTTP2_MIN_IDLE_STREAMS streams in idle state */ -#define NGHTTP2_MIN_IDLE_STREAMS 16 - /* The maximum number of items in outbound queue, which is considered as flooding caused by peer. All frames are not considered here. We only consider PING + ACK and SETTINGS + ACK. This is because @@ -105,6 +102,18 @@ /* The default value of maximum number of concurrent streams. */ #define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu +/* The default values for stream reset rate limiter. */ +#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000 +#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33 + +/* The default values for glitch rate limiter. */ +#define NGHTTP2_DEFAULT_GLITCH_BURST 1000 +#define NGHTTP2_DEFAULT_GLITCH_RATE 33 + +/* The default max number of CONTINUATION frames following an incoming + HEADER frame. */ +#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8 + /* Internal state when receiving incoming frame */ typedef enum { /* Receiving frame header */ @@ -178,7 +187,9 @@ /* Flag means GOAWAY was sent */ NGHTTP2_GOAWAY_SENT = 0x4, /* Flag means GOAWAY was received */ - NGHTTP2_GOAWAY_RECV = 0x8 + NGHTTP2_GOAWAY_RECV = 0x8, + /* Flag means GOAWAY has been submitted at least once */ + NGHTTP2_GOAWAY_SUBMITTED = 0x10 } nghttp2_goaway_flag; /* nghttp2_inflight_settings stores the SETTINGS entries which local @@ -194,8 +205,6 @@ struct nghttp2_session { nghttp2_map /* <nghttp2_stream*> */ streams; - /* root of dependency tree*/ - nghttp2_stream root; /* Queue for outbound urgent frames (PING and SETTINGS) */ nghttp2_outbound_queue ob_urgent; /* Queue for non-DATA frames */ @@ -218,23 +227,14 @@ /* Memory allocator */ nghttp2_mem mem; void *user_data; - /* Points to the latest incoming closed stream. NULL if there is no - closed stream. Only used when session is initialized as - server. */ - nghttp2_stream *closed_stream_head; - /* Points to the oldest incoming closed stream. NULL if there is no - closed stream. Only used when session is initialized as - server. */ - nghttp2_stream *closed_stream_tail; - /* Points to the latest idle stream. NULL if there is no idle - stream. Only used when session is initialized as server .*/ - nghttp2_stream *idle_stream_head; - /* Points to the oldest idle stream. NULL if there is no idle - stream. Only used when session is initialized as erver. */ - nghttp2_stream *idle_stream_tail; /* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not considered as in-flight. */ nghttp2_inflight_settings *inflight_settings_head; + /* Stream reset rate limiter. If receiving excessive amount of + stream resets, GOAWAY will be sent. */ + nghttp2_ratelim stream_reset_ratelim; + /* Rate limiter for all kinds of glitches. */ + nghttp2_ratelim glitch_ratelim; /* Sequential number across all streams to process streams in FIFO. */ uint64_t stream_seq; @@ -262,10 +262,9 @@ |closed_stream_head|. The current implementation only keeps incoming streams and session is initialized as server. */ size_t num_closed_streams; - /* The number of idle streams kept in |streams| hash. The idle - streams can be accessed through doubly linked list - |idle_stream_head|. The current implementation only keeps idle - streams if session is initialized as server. */ + /* The number of idle streams kept in |streams| hash. The current + implementation only keeps idle streams if session is initialized + as server. */ size_t num_idle_streams; /* The number of bytes allocated for nvbuf */ size_t nvbuflen; @@ -280,6 +279,12 @@ size_t max_send_header_block_length; /* The maximum number of settings accepted per SETTINGS frame. */ size_t max_settings; + /* The maximum number of CONTINUATION frames following an incoming + HEADER frame. */ + size_t max_continuations; + /* The number of CONTINUATION frames following an incoming HEADER + frame. This variable is reset when END_HEADERS flag is seen. */ + size_t num_continuations; /* Next Stream ID. Made unsigned int to detect >= (1 << 31). */ uint32_t next_stream_id; /* The last stream ID this session initiated. For client session, @@ -342,8 +347,6 @@ /* Unacked local SETTINGS_NO_RFC7540_PRIORITIES value, which is effective before it is acknowledged. */ uint8_t pending_no_rfc7540_priorities; - /* Turn on fallback to RFC 7540 priorities; for server use only. */ - uint8_t fallback_rfc7540_priorities; /* Nonzero if the session is server side. */ uint8_t server; /* Flags indicating GOAWAY is sent and/or received. The flags are @@ -406,13 +409,22 @@ nghttp2_outbound_item *item); /* + * This function wraps around nghttp2_session_add_rst_stream_continue + * with continue_without_stream = 1. + */ +int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, + uint32_t error_code); + +/* * Adds RST_STREAM frame for the stream |stream_id| with the error * code |error_code|. This is a convenient function built on top of * nghttp2_session_add_frame() to add RST_STREAM easily. * * This function simply returns 0 without adding RST_STREAM frame if * given stream is in NGHTTP2_STREAM_CLOSING state, because multiple - * RST_STREAM for a stream is redundant. + * RST_STREAM for a stream is redundant. It also returns 0 without + * adding the frame if |continue_without_stream| is nonzero, and + * stream was already gone. * * This function returns 0 if it succeeds, or one of the following * negative error codes: @@ -420,8 +432,10 @@ * NGHTTP2_ERR_NOMEM * Out of memory. */ -int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, - uint32_t error_code); +int nghttp2_session_add_rst_stream_continue(nghttp2_session *session, + int32_t stream_id, + uint32_t error_code, + int continue_without_stream); /* * Adds PING frame. This is a convenient function built on top of @@ -507,15 +521,9 @@ * * This function returns a pointer to created new stream object, or * NULL. - * - * This function adjusts neither the number of closed streams or idle - * streams. The caller should manually call - * nghttp2_session_adjust_closed_stream() or - * nghttp2_session_adjust_idle_stream() respectively. */ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, int32_t stream_id, uint8_t flags, - nghttp2_priority_spec *pri_spec, nghttp2_stream_state initial_state, void *stream_user_data); @@ -524,11 +532,6 @@ * is indicated by the |error_code|. When closing the stream, * on_stream_close_callback will be called. * - * If the session is initialized as server and |stream| is incoming - * stream, stream is just marked closed and this function calls - * nghttp2_session_keep_closed_stream() with |stream|. Otherwise, - * |stream| will be deleted from memory. - * * This function returns 0 if it succeeds, or one the following * negative error codes: * @@ -545,63 +548,9 @@ /* * Deletes |stream| from memory. After this function returns, stream * cannot be accessed. - * - * This function returns 0 if it succeeds, or one the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory */ -int nghttp2_session_destroy_stream(nghttp2_session *session, - nghttp2_stream *stream); - -/* - * Tries to keep incoming closed stream |stream|. Due to the - * limitation of maximum number of streams in memory, |stream| is not - * closed and just deleted from memory (see - * nghttp2_session_destroy_stream). - */ -void nghttp2_session_keep_closed_stream(nghttp2_session *session, - nghttp2_stream *stream); - -/* - * Appends |stream| to linked list |session->idle_stream_head|. We - * apply fixed limit for list size. To fit into that limit, one or - * more oldest streams are removed from list as necessary. - */ -void nghttp2_session_keep_idle_stream(nghttp2_session *session, - nghttp2_stream *stream); - -/* - * Detaches |stream| from idle streams linked list. - */ -void nghttp2_session_detach_idle_stream(nghttp2_session *session, - nghttp2_stream *stream); - -/* - * Deletes closed stream to ensure that number of incoming streams - * including active and closed is in the maximum number of allowed - * stream. - * - * This function returns 0 if it succeeds, or one the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_session_adjust_closed_stream(nghttp2_session *session); - -/* - * Deletes idle stream to ensure that number of idle streams is in - * certain limit. - * - * This function returns 0 if it succeeds, or one the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_session_adjust_idle_stream(nghttp2_session *session); +void nghttp2_session_destroy_stream(nghttp2_session *session, + nghttp2_stream *stream); /* * If further receptions and transmissions over the stream |stream_id| @@ -896,24 +845,6 @@ size_t niv); /* - * Re-prioritize |stream|. The new priority specification is - * |pri_spec|. Caller must ensure that stream->hd.stream_id != - * pri_spec->stream_id. - * - * This function does not adjust the number of idle streams. The - * caller should call nghttp2_session_adjust_idle_stream() later. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_session_reprioritize_stream(nghttp2_session *session, - nghttp2_stream *stream, - const nghttp2_priority_spec *pri_spec); - -/* * Terminates current |session| with the |error_code|. The |reason| * is NULL-terminated debug string. * @@ -961,4 +892,4 @@ size_t delta_size, int send_window_update); -#endif /* NGHTTP2_SESSION_H */ +#endif /* !defined(NGHTTP2_SESSION_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_stream.c b/Utilities/cmnghttp2/lib/nghttp2_stream.c index b3614a0..0f2d365 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_stream.c +++ b/Utilities/cmnghttp2/lib/nghttp2_stream.c
@@ -25,45 +25,17 @@ #include "nghttp2_stream.h" #include <assert.h> -#include <stdio.h> #include "nghttp2_session.h" #include "nghttp2_helper.h" #include "nghttp2_debug.h" #include "nghttp2_frame.h" -/* Maximum distance between any two stream's cycle in the same - priority queue. Imagine stream A's cycle is A, and stream B's - cycle is B, and A < B. The cycle is unsigned 32 bit integer, it - may get overflow. Because of how we calculate the next cycle - value, if B - A is less than or equals to - NGHTTP2_MAX_CYCLE_DISTANCE, A and B are in the same scale, in other - words, B is really greater than or equal to A. Otherwise, A is a - result of overflow, and it is actually A > B if we consider that - fact. */ -#define NGHTTP2_MAX_CYCLE_DISTANCE \ - ((uint64_t)NGHTTP2_MAX_FRAME_SIZE_MAX * 256 + 255) - -static int stream_less(const void *lhsx, const void *rhsx) { - const nghttp2_stream *lhs, *rhs; - - lhs = nghttp2_struct_of(lhsx, nghttp2_stream, pq_entry); - rhs = nghttp2_struct_of(rhsx, nghttp2_stream, pq_entry); - - if (lhs->cycle == rhs->cycle) { - return lhs->seq < rhs->seq; - } - - return rhs->cycle - lhs->cycle <= NGHTTP2_MAX_CYCLE_DISTANCE; -} - void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, uint8_t flags, nghttp2_stream_state initial_state, - int32_t weight, int32_t remote_initial_window_size, + int32_t remote_initial_window_size, int32_t local_initial_window_size, - void *stream_user_data, nghttp2_mem *mem) { - nghttp2_pq_init(&stream->obq, stream_less, mem); - + void *stream_user_data) { stream->stream_id = stream_id; stream->flags = flags; stream->state = initial_state; @@ -77,477 +49,62 @@ stream->recv_reduction = 0; stream->window_update_queued = 0; - stream->dep_prev = NULL; - stream->dep_next = NULL; - stream->sib_prev = NULL; - stream->sib_next = NULL; - - stream->closed_prev = NULL; stream->closed_next = NULL; - stream->weight = weight; - stream->sum_dep_weight = 0; - stream->http_flags = NGHTTP2_HTTP_FLAG_NONE; stream->content_length = -1; stream->recv_content_length = 0; stream->status_code = -1; stream->queued = 0; - stream->descendant_last_cycle = 0; stream->cycle = 0; stream->pending_penalty = 0; - stream->descendant_next_seq = 0; stream->seq = 0; stream->last_writelen = 0; stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY; } -void nghttp2_stream_free(nghttp2_stream *stream) { - nghttp2_pq_free(&stream->obq); - /* We don't free stream->item. If it is assigned to aob, then - active_outbound_item_reset() will delete it. Otherwise, - nghttp2_stream_close() or session_del() will delete it. */ -} +void nghttp2_stream_free(nghttp2_stream *stream) { (void)stream; } void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) { stream->shut_flags = (uint8_t)(stream->shut_flags | flag); } -/* - * Returns nonzero if |stream| is active. This function does not take - * into account its descendants. - */ -static int stream_active(nghttp2_stream *stream) { - return stream->item && - (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0; -} - -/* - * Returns nonzero if |stream| or one of its descendants is active - */ -static int stream_subtree_active(nghttp2_stream *stream) { - return stream_active(stream) || !nghttp2_pq_empty(&stream->obq); -} - -/* - * Returns next cycle for |stream|. - */ -static void stream_next_cycle(nghttp2_stream *stream, uint64_t last_cycle) { - uint64_t penalty; - - penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT + - stream->pending_penalty; - - stream->cycle = last_cycle + penalty / (uint32_t)stream->weight; - stream->pending_penalty = (uint32_t)(penalty % (uint32_t)stream->weight); -} - -static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) { - int rv; - - for (; dep_stream && !stream->queued; - stream = dep_stream, dep_stream = dep_stream->dep_prev) { - stream_next_cycle(stream, dep_stream->descendant_last_cycle); - stream->seq = dep_stream->descendant_next_seq++; - - DEBUGF("stream: stream=%d obq push cycle=%lu\n", stream->stream_id, - stream->cycle); - - DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id, - dep_stream->stream_id); - - rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); - if (rv != 0) { - return rv; - } - stream->queued = 1; - } - - return 0; -} - -/* - * Removes |stream| from parent's obq. If removal of |stream| makes - * parent's obq empty, and parent is not active, then parent is also - * removed. This process is repeated recursively. - */ -static void stream_obq_remove(nghttp2_stream *stream) { - nghttp2_stream *dep_stream; - - dep_stream = stream->dep_prev; - - if (!stream->queued) { - return; - } - - for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) { - DEBUGF("stream: remove stream %d from stream %d\n", stream->stream_id, - dep_stream->stream_id); - - nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); - - assert(stream->queued); - - stream->queued = 0; - stream->cycle = 0; - stream->pending_penalty = 0; - stream->descendant_last_cycle = 0; - stream->last_writelen = 0; - - if (stream_subtree_active(dep_stream)) { - return; - } - } -} - -/* - * Moves |stream| from |src|'s obq to |dest|'s obq. Removal from - * |src|'s obq is just done calling nghttp2_pq_remove(), so it does - * not recursively remove |src| and ancestors, like - * stream_obq_remove(). - */ -static int stream_obq_move(nghttp2_stream *dest, nghttp2_stream *src, - nghttp2_stream *stream) { - if (!stream->queued) { - return 0; - } - - DEBUGF("stream: remove stream %d from stream %d (move)\n", stream->stream_id, - src->stream_id); - - nghttp2_pq_remove(&src->obq, &stream->pq_entry); - stream->queued = 0; - - return stream_obq_push(dest, stream); -} - -void nghttp2_stream_reschedule(nghttp2_stream *stream) { - nghttp2_stream *dep_stream; - - assert(stream->queued); - - dep_stream = stream->dep_prev; - - for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) { - nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); - - stream_next_cycle(stream, dep_stream->descendant_last_cycle); - stream->seq = dep_stream->descendant_next_seq++; - - nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); - - DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id, - stream->cycle); - - dep_stream->last_writelen = stream->last_writelen; - } -} - -void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) { - nghttp2_stream *dep_stream; - uint64_t last_cycle; - int32_t old_weight; - uint64_t wlen_penalty; - - if (stream->weight == weight) { - return; - } - - old_weight = stream->weight; - stream->weight = weight; - - dep_stream = stream->dep_prev; - - if (!dep_stream) { - return; - } - - dep_stream->sum_dep_weight += weight - old_weight; - - if (!stream->queued) { - return; - } - - nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); - - wlen_penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT; - - /* Compute old stream->pending_penalty we used to calculate - stream->cycle */ - stream->pending_penalty = - (uint32_t)((stream->pending_penalty + (uint32_t)old_weight - - (wlen_penalty % (uint32_t)old_weight)) % - (uint32_t)old_weight); - - last_cycle = stream->cycle - - (wlen_penalty + stream->pending_penalty) / (uint32_t)old_weight; - - /* Now we have old stream->pending_penalty and new stream->weight in - place */ - stream_next_cycle(stream, last_cycle); - - if (dep_stream->descendant_last_cycle - stream->cycle <= - NGHTTP2_MAX_CYCLE_DISTANCE) { - stream->cycle = dep_stream->descendant_last_cycle; - } - - /* Continue to use same stream->seq */ - - nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); - - DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id, - stream->cycle); -} - -static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) { - for (; stream->sib_next; stream = stream->sib_next) - ; - - return stream; -} - -int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream, - int32_t weight) { - weight = stream->weight * weight / stream->sum_dep_weight; - - return nghttp2_max(1, weight); -} - -#ifdef STREAM_DEP_DEBUG - -static void ensure_inactive(nghttp2_stream *stream) { - nghttp2_stream *si; - - if (stream->queued) { - fprintf(stderr, "stream(%p)=%d, stream->queued = 1; want 0\n", stream, - stream->stream_id); - assert(0); - } - - if (stream_active(stream)) { - fprintf(stderr, "stream(%p)=%d, stream_active(stream) = 1; want 0\n", - stream, stream->stream_id); - assert(0); - } - - if (!nghttp2_pq_empty(&stream->obq)) { - fprintf(stderr, "stream(%p)=%d, nghttp2_pq_size() = %zu; want 0\n", stream, - stream->stream_id, nghttp2_pq_size(&stream->obq)); - assert(0); - } - - for (si = stream->dep_next; si; si = si->sib_next) { - ensure_inactive(si); - } -} - -static void check_queued(nghttp2_stream *stream) { - nghttp2_stream *si; - int queued; - - if (stream->queued) { - if (!stream_subtree_active(stream)) { - fprintf(stderr, - "stream(%p)=%d, stream->queued == 1, but " - "stream_active() == %d and nghttp2_pq_size(&stream->obq) = %zu\n", - stream, stream->stream_id, stream_active(stream), - nghttp2_pq_size(&stream->obq)); - assert(0); - } - if (!stream_active(stream)) { - queued = 0; - for (si = stream->dep_next; si; si = si->sib_next) { - if (si->queued) { - ++queued; - } - } - if (queued == 0) { - fprintf(stderr, - "stream(%p)=%d, stream->queued == 1, and " - "!stream_active(), but no descendants is queued\n", - stream, stream->stream_id); - assert(0); - } - } - - for (si = stream->dep_next; si; si = si->sib_next) { - check_queued(si); - } - } else { - if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) { - fprintf(stderr, - "stream(%p) = %d, stream->queued == 0, but " - "stream_active(stream) == %d and " - "nghttp2_pq_size(&stream->obq) = %zu\n", - stream, stream->stream_id, stream_active(stream), - nghttp2_pq_size(&stream->obq)); - assert(0); - } - for (si = stream->dep_next; si; si = si->sib_next) { - ensure_inactive(si); - } - } -} - -static void check_sum_dep(nghttp2_stream *stream) { - nghttp2_stream *si; - int32_t n = 0; - for (si = stream->dep_next; si; si = si->sib_next) { - n += si->weight; - } - if (n != stream->sum_dep_weight) { - fprintf(stderr, "stream(%p)=%d, sum_dep_weight = %d; want %d\n", stream, - stream->stream_id, n, stream->sum_dep_weight); - assert(0); - } - for (si = stream->dep_next; si; si = si->sib_next) { - check_sum_dep(si); - } -} - -static void check_dep_prev(nghttp2_stream *stream) { - nghttp2_stream *si; - for (si = stream->dep_next; si; si = si->sib_next) { - if (si->dep_prev != stream) { - fprintf(stderr, "si->dep_prev = %p; want %p\n", si->dep_prev, stream); - assert(0); - } - check_dep_prev(si); - } -} - -#endif /* STREAM_DEP_DEBUG */ - -#ifdef STREAM_DEP_DEBUG -static void validate_tree(nghttp2_stream *stream) { - nghttp2_stream *si; - - if (!stream) { - return; - } - - for (; stream->dep_prev; stream = stream->dep_prev) - ; - - assert(stream->stream_id == 0); - assert(!stream->queued); - - fprintf(stderr, "checking...\n"); - if (nghttp2_pq_empty(&stream->obq)) { - fprintf(stderr, "root obq empty\n"); - for (si = stream->dep_next; si; si = si->sib_next) { - ensure_inactive(si); - } - } else { - for (si = stream->dep_next; si; si = si->sib_next) { - check_queued(si); - } - } - - check_sum_dep(stream); - check_dep_prev(stream); -} -#else /* !STREAM_DEP_DEBUG */ -static void validate_tree(nghttp2_stream *stream) { (void)stream; } -#endif /* !STREAM_DEP_DEBUG*/ - -static int stream_update_dep_on_attach_item(nghttp2_stream *stream) { - int rv; - - rv = stream_obq_push(stream->dep_prev, stream); - if (rv != 0) { - return rv; - } - - validate_tree(stream); - return 0; -} - -static int stream_update_dep_on_detach_item(nghttp2_stream *stream) { - if (nghttp2_pq_empty(&stream->obq)) { - stream_obq_remove(stream); - } - - validate_tree(stream); - - return 0; -} - -int nghttp2_stream_attach_item(nghttp2_stream *stream, - nghttp2_outbound_item *item) { - int rv; - +void nghttp2_stream_attach_item(nghttp2_stream *stream, + nghttp2_outbound_item *item) { assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0); assert(stream->item == NULL); DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item); stream->item = item; - - if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { - return 0; - } - - rv = stream_update_dep_on_attach_item(stream); - if (rv != 0) { - /* This may relave stream->queued == 1, but stream->item == NULL. - But only consequence of this error is fatal one, and session - destruction. In that execution path, these inconsistency does - not matter. */ - stream->item = NULL; - return rv; - } - - return 0; } -int nghttp2_stream_detach_item(nghttp2_stream *stream) { +void nghttp2_stream_detach_item(nghttp2_stream *stream) { DEBUGF("stream: stream=%d detach item=%p\n", stream->stream_id, stream->item); stream->item = NULL; stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL); - - if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { - return 0; - } - - return stream_update_dep_on_detach_item(stream); } -int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) { +void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) { assert(stream->item); DEBUGF("stream: stream=%d defer item=%p cause=%02x\n", stream->stream_id, stream->item, flags); stream->flags |= flags; - - if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { - return 0; - } - - return stream_update_dep_on_detach_item(stream); } -int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) { +void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, + uint8_t flags) { assert(stream->item); DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id, stream->item, flags); stream->flags = (uint8_t)(stream->flags & ~flags); - - if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) { - return 0; - } - - if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) { - return 0; - } - - return stream_update_dep_on_attach_item(stream); } int nghttp2_stream_check_deferred_item(nghttp2_stream *stream) { @@ -573,16 +130,16 @@ } int nghttp2_stream_update_remote_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size) { + nghttp2_stream *stream, int32_t new_initial_window_size, + int32_t old_initial_window_size) { return update_initial_window_size(&stream->remote_window_size, new_initial_window_size, old_initial_window_size); } int nghttp2_stream_update_local_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size) { + nghttp2_stream *stream, int32_t new_initial_window_size, + int32_t old_initial_window_size) { return update_initial_window_size(&stream->local_window_size, new_initial_window_size, old_initial_window_size); @@ -593,373 +150,11 @@ stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH); } -int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream, - nghttp2_stream *target) { - for (; stream; stream = stream->dep_prev) { - if (stream == target) { - return 1; - } - } - return 0; -} - -int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream, - nghttp2_stream *stream) { - nghttp2_stream *si; - int rv; - - DEBUGF("stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream, - dep_stream->stream_id, stream, stream->stream_id); - - stream->sum_dep_weight = dep_stream->sum_dep_weight; - dep_stream->sum_dep_weight = stream->weight; - - if (dep_stream->dep_next) { - for (si = dep_stream->dep_next; si; si = si->sib_next) { - si->dep_prev = stream; - if (si->queued) { - rv = stream_obq_move(stream, dep_stream, si); - if (rv != 0) { - return rv; - } - } - } - - if (stream_subtree_active(stream)) { - rv = stream_obq_push(dep_stream, stream); - if (rv != 0) { - return rv; - } - } - - stream->dep_next = dep_stream->dep_next; - } - - dep_stream->dep_next = stream; - stream->dep_prev = dep_stream; - - validate_tree(stream); - - return 0; -} - -static void set_dep_prev(nghttp2_stream *stream, nghttp2_stream *dep) { - for (; stream; stream = stream->sib_next) { - stream->dep_prev = dep; - } -} - -static void link_dep(nghttp2_stream *dep_stream, nghttp2_stream *stream) { - dep_stream->dep_next = stream; - if (stream) { - stream->dep_prev = dep_stream; - } -} - -static void link_sib(nghttp2_stream *a, nghttp2_stream *b) { - a->sib_next = b; - if (b) { - b->sib_prev = a; - } -} - -static void insert_link_dep(nghttp2_stream *dep_stream, - nghttp2_stream *stream) { - nghttp2_stream *sib_next; - - assert(stream->sib_prev == NULL); - - sib_next = dep_stream->dep_next; - - link_sib(stream, sib_next); - - link_dep(dep_stream, stream); -} - -static void unlink_sib(nghttp2_stream *stream) { - nghttp2_stream *prev, *next, *dep_next; - - prev = stream->sib_prev; - dep_next = stream->dep_next; - - assert(prev); - - if (dep_next) { - /* - * prev--stream(--sib_next--...) - * | - * dep_next - */ - - link_sib(prev, dep_next); - - set_dep_prev(dep_next, stream->dep_prev); - - if (stream->sib_next) { - link_sib(stream_last_sib(dep_next), stream->sib_next); - } - } else { - /* - * prev--stream(--sib_next--...) - */ - next = stream->sib_next; - - prev->sib_next = next; - - if (next) { - next->sib_prev = prev; - } - } -} - -static void unlink_dep(nghttp2_stream *stream) { - nghttp2_stream *prev, *next, *dep_next; - - prev = stream->dep_prev; - dep_next = stream->dep_next; - - assert(prev); - - if (dep_next) { - /* - * prev - * | - * stream(--sib_next--...) - * | - * dep_next - */ - link_dep(prev, dep_next); - - set_dep_prev(dep_next, stream->dep_prev); - - if (stream->sib_next) { - link_sib(stream_last_sib(dep_next), stream->sib_next); - } - - } else if (stream->sib_next) { - /* - * prev - * | - * stream--sib_next - */ - next = stream->sib_next; - - next->sib_prev = NULL; - - link_dep(prev, next); - } else { - prev->dep_next = NULL; - } -} - -void nghttp2_stream_dep_add(nghttp2_stream *dep_stream, - nghttp2_stream *stream) { - DEBUGF("stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream, - dep_stream->stream_id, stream, stream->stream_id); - - dep_stream->sum_dep_weight += stream->weight; - - if (dep_stream->dep_next == NULL) { - link_dep(dep_stream, stream); - } else { - insert_link_dep(dep_stream, stream); - } - - validate_tree(stream); -} - -int nghttp2_stream_dep_remove(nghttp2_stream *stream) { - nghttp2_stream *dep_prev, *si; - int32_t sum_dep_weight_delta; - int rv; - - DEBUGF("stream: dep_remove stream(%p)=%d\n", stream, stream->stream_id); - - /* Distribute weight of |stream| to direct descendants */ - sum_dep_weight_delta = -stream->weight; - - for (si = stream->dep_next; si; si = si->sib_next) { - si->weight = nghttp2_stream_dep_distributed_weight(stream, si->weight); - - sum_dep_weight_delta += si->weight; - - if (si->queued) { - rv = stream_obq_move(stream->dep_prev, stream, si); - if (rv != 0) { - return rv; - } - } - } - - assert(stream->dep_prev); - - dep_prev = stream->dep_prev; - - dep_prev->sum_dep_weight += sum_dep_weight_delta; - - if (stream->queued) { - stream_obq_remove(stream); - } - - if (stream->sib_prev) { - unlink_sib(stream); - } else { - unlink_dep(stream); - } - - stream->sum_dep_weight = 0; - - stream->dep_prev = NULL; - stream->dep_next = NULL; - stream->sib_prev = NULL; - stream->sib_next = NULL; - - validate_tree(dep_prev); - - return 0; -} - -int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream, - nghttp2_stream *stream) { - nghttp2_stream *last_sib; - nghttp2_stream *dep_next; - nghttp2_stream *si; - int rv; - - DEBUGF("stream: dep_insert_subtree dep_stream(%p)=%d stream(%p)=%d\n", - dep_stream, dep_stream->stream_id, stream, stream->stream_id); - - stream->sum_dep_weight += dep_stream->sum_dep_weight; - dep_stream->sum_dep_weight = stream->weight; - - if (dep_stream->dep_next) { - dep_next = dep_stream->dep_next; - - link_dep(dep_stream, stream); - - if (stream->dep_next) { - last_sib = stream_last_sib(stream->dep_next); - - link_sib(last_sib, dep_next); - } else { - link_dep(stream, dep_next); - } - - for (si = dep_next; si; si = si->sib_next) { - si->dep_prev = stream; - if (si->queued) { - rv = stream_obq_move(stream, dep_stream, si); - if (rv != 0) { - return rv; - } - } - } - } else { - link_dep(dep_stream, stream); - } - - if (stream_subtree_active(stream)) { - rv = stream_obq_push(dep_stream, stream); - if (rv != 0) { - return rv; - } - } - - validate_tree(dep_stream); - - return 0; -} - -int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream, - nghttp2_stream *stream) { - int rv; - - DEBUGF("stream: dep_add_subtree dep_stream(%p)=%d stream(%p)=%d\n", - dep_stream, dep_stream->stream_id, stream, stream->stream_id); - - dep_stream->sum_dep_weight += stream->weight; - - if (dep_stream->dep_next) { - insert_link_dep(dep_stream, stream); - } else { - link_dep(dep_stream, stream); - } - - if (stream_subtree_active(stream)) { - rv = stream_obq_push(dep_stream, stream); - if (rv != 0) { - return rv; - } - } - - validate_tree(dep_stream); - - return 0; -} - -void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) { - nghttp2_stream *next, *dep_prev; - - DEBUGF("stream: dep_remove_subtree stream(%p)=%d\n", stream, - stream->stream_id); - - assert(stream->dep_prev); - - dep_prev = stream->dep_prev; - - if (stream->sib_prev) { - link_sib(stream->sib_prev, stream->sib_next); - } else { - next = stream->sib_next; - - link_dep(dep_prev, next); - - if (next) { - next->sib_prev = NULL; - } - } - - dep_prev->sum_dep_weight -= stream->weight; - - if (stream->queued) { - stream_obq_remove(stream); - } - - validate_tree(dep_prev); - - stream->sib_prev = NULL; - stream->sib_next = NULL; - stream->dep_prev = NULL; -} - -int nghttp2_stream_in_dep_tree(nghttp2_stream *stream) { - return stream->dep_prev || stream->dep_next || stream->sib_prev || - stream->sib_next; -} - -nghttp2_outbound_item * -nghttp2_stream_next_outbound_item(nghttp2_stream *stream) { - nghttp2_pq_entry *ent; - nghttp2_stream *si; - - for (;;) { - if (stream_active(stream)) { - /* Update ascendant's descendant_last_cycle here, so that we can - assure that new stream is scheduled based on it. */ - for (si = stream; si->dep_prev; si = si->dep_prev) { - si->dep_prev->descendant_last_cycle = si->cycle; - } - return stream->item; - } - ent = nghttp2_pq_top(&stream->obq); - if (!ent) { - return NULL; - } - stream = nghttp2_struct_of(ent, nghttp2_stream, pq_entry); - } -} - nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) { + if (stream == &nghttp2_stream_root) { + return NGHTTP2_STREAM_STATE_IDLE; + } + if (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) { return NGHTTP2_STREAM_STATE_CLOSED; } @@ -990,27 +185,39 @@ } nghttp2_stream *nghttp2_stream_get_parent(nghttp2_stream *stream) { - return stream->dep_prev; + (void)stream; + + return NULL; } nghttp2_stream *nghttp2_stream_get_next_sibling(nghttp2_stream *stream) { - return stream->sib_next; + (void)stream; + + return NULL; } nghttp2_stream *nghttp2_stream_get_previous_sibling(nghttp2_stream *stream) { - return stream->sib_prev; + (void)stream; + + return NULL; } nghttp2_stream *nghttp2_stream_get_first_child(nghttp2_stream *stream) { - return stream->dep_next; + (void)stream; + + return NULL; } int32_t nghttp2_stream_get_weight(nghttp2_stream *stream) { - return stream->weight; + (void)stream; + + return NGHTTP2_DEFAULT_WEIGHT; } int32_t nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream) { - return stream->sum_dep_weight; + (void)stream; + + return 0; } int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream) {
diff --git a/Utilities/cmnghttp2/lib/nghttp2_stream.h b/Utilities/cmnghttp2/lib/nghttp2_stream.h index 7a8e4c6..603209e 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_stream.h +++ b/Utilities/cmnghttp2/lib/nghttp2_stream.h
@@ -27,7 +27,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> #include "nghttp2_outbound_item.h" @@ -91,9 +91,6 @@ /* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and NGHTTP2_STREAM_FLAG_DEFERRED_USER. */ NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c, - /* Indicates that this stream is not subject to RFC7540 - priorities scheme. */ - NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES = 0x10, /* Ignore client RFC 9218 priority signal. */ NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES = 0x20, /* Indicates that RFC 9113 leading and trailing white spaces @@ -124,10 +121,9 @@ NGHTTP2_HTTP_FLAG_METH_HEAD = 1 << 8, NGHTTP2_HTTP_FLAG_METH_OPTIONS = 1 << 9, NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND = 1 << 10, - NGHTTP2_HTTP_FLAG_METH_ALL = NGHTTP2_HTTP_FLAG_METH_CONNECT | - NGHTTP2_HTTP_FLAG_METH_HEAD | - NGHTTP2_HTTP_FLAG_METH_OPTIONS | - NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND, + NGHTTP2_HTTP_FLAG_METH_ALL = + NGHTTP2_HTTP_FLAG_METH_CONNECT | NGHTTP2_HTTP_FLAG_METH_HEAD | + NGHTTP2_HTTP_FLAG_METH_OPTIONS | NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND, /* :path category */ /* path starts with "/" */ NGHTTP2_HTTP_FLAG_PATH_REGULAR = 1 << 11, @@ -147,39 +143,18 @@ } nghttp2_http_flag; struct nghttp2_stream { - /* Entry for dep_prev->obq */ + nghttp2_stream_state state; nghttp2_pq_entry pq_entry; - /* Priority Queue storing direct descendant (nghttp2_stream). Only - streams which itself has some data to send, or has a descendant - which has some data to sent. */ - nghttp2_pq obq; /* Content-Length of request/response body. -1 if unknown. */ int64_t content_length; /* Received body so far */ int64_t recv_content_length; - /* Base last_cycle for direct descendent streams. */ - uint64_t descendant_last_cycle; /* Next scheduled time to sent item */ uint64_t cycle; - /* Next seq used for direct descendant streams */ - uint64_t descendant_next_seq; /* Secondary key for prioritization to break a tie for cycle. This value is monotonically increased for single parent stream. */ uint64_t seq; - /* pointers to form dependency tree. If multiple streams depend on - a stream, only one stream (left most) has non-NULL dep_prev which - points to the stream it depends on. The remaining streams are - linked using sib_prev and sib_next. The stream which has - non-NULL dep_prev always NULL sib_prev. The right most stream - has NULL sib_next. If this stream is a root of dependency tree, - dep_prev and sib_prev are NULL. */ - nghttp2_stream *dep_prev, *dep_next; - nghttp2_stream *sib_prev, *sib_next; - /* When stream is kept after closure, it may be kept in doubly - linked list pointed by nghttp2_session closed_stream_head. - closed_next points to the next stream object if it is the element - of the list. */ - nghttp2_stream *closed_prev, *closed_next; + nghttp2_stream *closed_next; /* The arbitrary data provided by user for this stream. */ void *stream_user_data; /* Item to send */ @@ -206,13 +181,8 @@ NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */ int32_t local_window_size; - /* weight of this stream */ - int32_t weight; /* This is unpaid penalty (offset) when calculating cycle. */ uint32_t pending_penalty; - /* sum of weight of direct descendants */ - int32_t sum_dep_weight; - nghttp2_stream_state state; /* status code from remote server */ int16_t status_code; /* Bitwise OR of zero or more nghttp2_http_flag values */ @@ -240,9 +210,9 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, uint8_t flags, nghttp2_stream_state initial_state, - int32_t weight, int32_t remote_initial_window_size, + int32_t remote_initial_window_size, int32_t local_initial_window_size, - void *stream_user_data, nghttp2_mem *mem); + void *stream_user_data); void nghttp2_stream_free(nghttp2_stream *stream); @@ -258,14 +228,8 @@ * more of NGHTTP2_STREAM_FLAG_DEFERRED_USER and * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL. The |flags| indicates * the reason of this action. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory */ -int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags); +void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags); /* * Put back deferred data in this stream to active state. The |flags| @@ -274,14 +238,8 @@ * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and given masks are * cleared if they are set. So even if this function is called, if * one of flag is still set, data does not become active. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory */ -int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags); +void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags); /* * Returns nonzero if item is deferred by whatever reason. @@ -302,8 +260,8 @@ * overflow. */ int nghttp2_stream_update_remote_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size); + nghttp2_stream *stream, int32_t new_initial_window_size, + int32_t old_initial_window_size); /* * Updates the local window size with the new value @@ -314,8 +272,8 @@ * overflow. */ int nghttp2_stream_update_local_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size); + nghttp2_stream *stream, int32_t new_initial_window_size, + int32_t old_initial_window_size); /* * Call this function if promised stream |stream| is replied with @@ -325,129 +283,15 @@ void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream); /* - * Returns nonzero if |target| is an ancestor of |stream|. - */ -int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream, - nghttp2_stream *target); - -/* - * Computes distributed weight of a stream of the |weight| under the - * |stream| if |stream| is removed from a dependency tree. - */ -int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream, - int32_t weight); - -/* - * Makes the |stream| depend on the |dep_stream|. This dependency is - * exclusive. All existing direct descendants of |dep_stream| become - * the descendants of the |stream|. This function assumes - * |stream->item| is NULL. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream, - nghttp2_stream *stream); - -/* - * Makes the |stream| depend on the |dep_stream|. This dependency is - * not exclusive. This function assumes |stream->item| is NULL. - */ -void nghttp2_stream_dep_add(nghttp2_stream *dep_stream, nghttp2_stream *stream); - -/* - * Removes the |stream| from the current dependency tree. This - * function assumes |stream->item| is NULL. - */ -int nghttp2_stream_dep_remove(nghttp2_stream *stream); - -/* * Attaches |item| to |stream|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory */ -int nghttp2_stream_attach_item(nghttp2_stream *stream, - nghttp2_outbound_item *item); +void nghttp2_stream_attach_item(nghttp2_stream *stream, + nghttp2_outbound_item *item); /* * Detaches |stream->item|. This function does not free * |stream->item|. The caller must free it. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory */ -int nghttp2_stream_detach_item(nghttp2_stream *stream); +void nghttp2_stream_detach_item(nghttp2_stream *stream); -/* - * Makes the |stream| depend on the |dep_stream|. This dependency is - * exclusive. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream, - nghttp2_stream *stream); - -/* - * Makes the |stream| depend on the |dep_stream|. This dependency is - * not exclusive. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream, - nghttp2_stream *stream); - -/* - * Removes subtree whose root stream is |stream|. The - * effective_weight of streams in removed subtree is not updated. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory - */ -void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream); - -/* - * Returns nonzero if |stream| is in any dependency tree. - */ -int nghttp2_stream_in_dep_tree(nghttp2_stream *stream); - -/* - * Schedules transmission of |stream|'s item, assuming stream->item is - * attached, and stream->last_writelen was updated. - */ -void nghttp2_stream_reschedule(nghttp2_stream *stream); - -/* - * Changes |stream|'s weight to |weight|. If |stream| is queued, it - * will be rescheduled based on new weight. - */ -void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight); - -/* - * Returns a stream which has highest priority, updating - * descendant_last_cycle of selected stream's ancestors. - */ -nghttp2_outbound_item * -nghttp2_stream_next_outbound_item(nghttp2_stream *stream); - -#endif /* NGHTTP2_STREAM */ +#endif /* !defined(NGHTTP2_STREAM_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_submit.c b/Utilities/cmnghttp2/lib/nghttp2_submit.c index f5554eb..8a90f71 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_submit.c +++ b/Utilities/cmnghttp2/lib/nghttp2_submit.c
@@ -32,43 +32,13 @@ #include "nghttp2_helper.h" #include "nghttp2_priority_spec.h" -/* - * Detects the dependency error, that is stream attempted to depend on - * itself. If |stream_id| is -1, we use session->next_stream_id as - * stream ID. - * - * This function returns 0 if it succeeds, or one of the following - * error codes: - * - * NGHTTP2_ERR_INVALID_ARGUMENT - * Stream attempted to depend on itself. - */ -static int detect_self_dependency(nghttp2_session *session, int32_t stream_id, - const nghttp2_priority_spec *pri_spec) { - assert(pri_spec); - - if (stream_id == -1) { - if ((int32_t)session->next_stream_id == pri_spec->stream_id) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - return 0; - } - - if (stream_id == pri_spec->stream_id) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - return 0; -} - /* This function takes ownership of |nva_copy|. Regardless of the return value, the caller must not free |nva_copy| after this function returns. */ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_priority_spec *pri_spec, - nghttp2_nv *nva_copy, size_t nvlen, - const nghttp2_data_provider *data_prd, + int32_t stream_id, nghttp2_nv *nva_copy, + size_t nvlen, + const nghttp2_data_provider_wrap *dpw, void *stream_user_data) { int rv; uint8_t flags_copy; @@ -87,15 +57,15 @@ nghttp2_outbound_item_init(item); - if (data_prd != NULL && data_prd->read_callback != NULL) { - item->aux_data.headers.data_prd = *data_prd; + if (dpw != NULL && dpw->data_prd.read_callback != NULL) { + item->aux_data.headers.dpw = *dpw; } item->aux_data.headers.stream_user_data = stream_user_data; flags_copy = - (uint8_t)((flags & (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PRIORITY)) | - NGHTTP2_FLAG_END_HEADERS); + (uint8_t)((flags & (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PRIORITY)) | + NGHTTP2_FLAG_END_HEADERS); if (stream_id == -1) { if (session->next_stream_id > INT32_MAX) { @@ -114,8 +84,8 @@ frame = &item->frame; - nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, - pri_spec, nva_copy, nvlen); + nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, NULL, + nva_copy, nvlen); rv = nghttp2_session_add_item(session, item); @@ -141,31 +111,22 @@ static int32_t submit_headers_shared_nva(nghttp2_session *session, uint8_t flags, int32_t stream_id, - const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider *data_prd, + const nghttp2_data_provider_wrap *dpw, void *stream_user_data) { int rv; nghttp2_nv *nva_copy; - nghttp2_priority_spec copy_pri_spec; nghttp2_mem *mem; mem = &session->mem; - if (pri_spec) { - copy_pri_spec = *pri_spec; - nghttp2_priority_spec_normalize_weight(©_pri_spec); - } else { - nghttp2_priority_spec_default_init(©_pri_spec); - } - rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem); if (rv < 0) { return rv; } - return submit_headers_shared(session, flags, stream_id, ©_pri_spec, - nva_copy, nvlen, data_prd, stream_user_data); + return submit_headers_shared(session, flags, stream_id, nva_copy, nvlen, dpw, + stream_user_data); } int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id, @@ -175,8 +136,7 @@ } return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM, - stream_id, NULL, nva, nvlen, NULL, - NULL); + stream_id, nva, nvlen, NULL, NULL); } int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags, @@ -184,7 +144,7 @@ const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen, void *stream_user_data) { - int rv; + (void)pri_spec; if (stream_id == -1) { if (session->server) { @@ -196,20 +156,8 @@ flags &= NGHTTP2_FLAG_END_STREAM; - if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) && - session->remote_settings.no_rfc7540_priorities != 1) { - rv = detect_self_dependency(session, stream_id, pri_spec); - if (rv != 0) { - return rv; - } - - flags |= NGHTTP2_FLAG_PRIORITY; - } else { - pri_spec = NULL; - } - - return submit_headers_shared_nva(session, flags, stream_id, pri_spec, nva, - nvlen, NULL, stream_user_data); + return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, NULL, + stream_user_data); } int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags, @@ -221,51 +169,10 @@ int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags, int32_t stream_id, const nghttp2_priority_spec *pri_spec) { - int rv; - nghttp2_outbound_item *item; - nghttp2_frame *frame; - nghttp2_priority_spec copy_pri_spec; - nghttp2_mem *mem; + (void)session; (void)flags; - - mem = &session->mem; - - if (session->remote_settings.no_rfc7540_priorities == 1) { - return 0; - } - - if (stream_id == 0 || pri_spec == NULL) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (stream_id == pri_spec->stream_id) { - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - copy_pri_spec = *pri_spec; - - nghttp2_priority_spec_normalize_weight(©_pri_spec); - - item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item)); - - if (item == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - nghttp2_outbound_item_init(item); - - frame = &item->frame; - - nghttp2_frame_priority_init(&frame->priority, stream_id, ©_pri_spec); - - rv = nghttp2_session_add_item(session, item); - - if (rv != 0) { - nghttp2_frame_priority_free(&frame->priority); - nghttp2_mem_free(mem, item); - - return rv; - } + (void)stream_id; + (void)pri_spec; return 0; } @@ -278,7 +185,8 @@ return NGHTTP2_ERR_INVALID_ARGUMENT; } - return nghttp2_session_add_rst_stream(session, stream_id, error_code); + return nghttp2_session_add_rst_stream_continue( + session, stream_id, error_code, /* continue_without_stream = */ 0); } int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags, @@ -389,8 +297,8 @@ } if (stream_id == 0) { rv = nghttp2_adjust_local_window_size( - &session->local_window_size, &session->recv_window_size, - &session->recv_reduction, &window_size_increment); + &session->local_window_size, &session->recv_window_size, + &session->recv_reduction, &window_size_increment); if (rv != 0) { return rv; } @@ -401,8 +309,8 @@ } rv = nghttp2_adjust_local_window_size( - &stream->local_window_size, &stream->recv_window_size, - &stream->recv_reduction, &window_size_increment); + &stream->local_window_size, &stream->recv_window_size, + &stream->recv_reduction, &window_size_increment); if (rv != 0) { return rv; } @@ -411,10 +319,10 @@ if (window_size_increment > 0) { if (stream_id == 0) { session->consumed_size = - nghttp2_max(0, session->consumed_size - window_size_increment); + nghttp2_max_int32(0, session->consumed_size - window_size_increment); } else { stream->consumed_size = - nghttp2_max(0, stream->consumed_size - window_size_increment); + nghttp2_max_int32(0, stream->consumed_size - window_size_increment); } return nghttp2_session_add_window_update(session, 0, stream_id, @@ -444,13 +352,13 @@ if (window_size_increment < 0) { return nghttp2_adjust_local_window_size( - &session->local_window_size, &session->recv_window_size, - &session->recv_reduction, &window_size_increment); + &session->local_window_size, &session->recv_window_size, + &session->recv_reduction, &window_size_increment); } rv = nghttp2_increase_local_window_size( - &session->local_window_size, &session->recv_window_size, - &session->recv_reduction, &window_size_increment); + &session->local_window_size, &session->recv_window_size, + &session->recv_reduction, &window_size_increment); if (rv != 0) { return rv; @@ -477,13 +385,13 @@ if (window_size_increment < 0) { return nghttp2_adjust_local_window_size( - &stream->local_window_size, &stream->recv_window_size, - &stream->recv_reduction, &window_size_increment); + &stream->local_window_size, &stream->recv_window_size, + &stream->recv_reduction, &window_size_increment); } rv = nghttp2_increase_local_window_size( - &stream->local_window_size, &stream->recv_window_size, - &stream->recv_reduction, &window_size_increment); + &stream->local_window_size, &stream->recv_window_size, + &stream->recv_reduction, &window_size_increment); if (rv != 0) { return rv; @@ -579,7 +487,7 @@ return 0; fail_item_malloc: - free(buf); + nghttp2_mem_free(mem, buf); return rv; } @@ -614,7 +522,7 @@ /* The last nov is added for terminal NULL character. */ ov_copy = - nghttp2_mem_malloc(mem, nov * sizeof(nghttp2_origin_entry) + len + nov); + nghttp2_mem_malloc(mem, nov * sizeof(nghttp2_origin_entry) + len + nov); if (ov_copy == NULL) { return NGHTTP2_ERR_NOMEM; } @@ -662,7 +570,7 @@ return 0; fail_item_malloc: - free(ov_copy); + nghttp2_mem_free(mem, ov_copy); return rv; } @@ -734,23 +642,34 @@ return 0; fail_item_malloc: - free(buf); + nghttp2_mem_free(mem, buf); return rv; } -static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec, - const nghttp2_data_provider *data_prd) { +static uint8_t set_request_flags(const nghttp2_data_provider_wrap *dpw) { uint8_t flags = NGHTTP2_FLAG_NONE; - if (data_prd == NULL || data_prd->read_callback == NULL) { + if (dpw == NULL || dpw->data_prd.read_callback == NULL) { flags |= NGHTTP2_FLAG_END_STREAM; } - if (pri_spec) { - flags |= NGHTTP2_FLAG_PRIORITY; + return flags; +} + +static int32_t submit_request_shared(nghttp2_session *session, + const nghttp2_nv *nva, size_t nvlen, + const nghttp2_data_provider_wrap *dpw, + void *stream_user_data) { + uint8_t flags; + + if (session->server) { + return NGHTTP2_ERR_PROTO; } - return flags; + flags = set_request_flags(dpw); + + return submit_headers_shared_nva(session, flags, -1, nva, nvlen, dpw, + stream_user_data); } int32_t nghttp2_submit_request(nghttp2_session *session, @@ -758,40 +677,38 @@ const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd, void *stream_user_data) { - uint8_t flags; - int rv; + nghttp2_data_provider_wrap dpw; + (void)pri_spec; - if (session->server) { - return NGHTTP2_ERR_PROTO; - } - - if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) && - session->remote_settings.no_rfc7540_priorities != 1) { - rv = detect_self_dependency(session, -1, pri_spec); - if (rv != 0) { - return rv; - } - } else { - pri_spec = NULL; - } - - flags = set_request_flags(pri_spec, data_prd); - - return submit_headers_shared_nva(session, flags, -1, pri_spec, nva, nvlen, - data_prd, stream_user_data); + return submit_request_shared(session, nva, nvlen, + nghttp2_data_provider_wrap_v1(&dpw, data_prd), + stream_user_data); } -static uint8_t set_response_flags(const nghttp2_data_provider *data_prd) { +int32_t nghttp2_submit_request2(nghttp2_session *session, + const nghttp2_priority_spec *pri_spec, + const nghttp2_nv *nva, size_t nvlen, + const nghttp2_data_provider2 *data_prd, + void *stream_user_data) { + nghttp2_data_provider_wrap dpw; + (void)pri_spec; + + return submit_request_shared(session, nva, nvlen, + nghttp2_data_provider_wrap_v2(&dpw, data_prd), + stream_user_data); +} + +static uint8_t set_response_flags(const nghttp2_data_provider_wrap *dpw) { uint8_t flags = NGHTTP2_FLAG_NONE; - if (data_prd == NULL || data_prd->read_callback == NULL) { + if (dpw == NULL || dpw->data_prd.read_callback == NULL) { flags |= NGHTTP2_FLAG_END_STREAM; } return flags; } -int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, - const nghttp2_data_provider *data_prd) { +static int submit_response_shared(nghttp2_session *session, int32_t stream_id, + const nghttp2_nv *nva, size_t nvlen, + const nghttp2_data_provider_wrap *dpw) { uint8_t flags; if (stream_id <= 0) { @@ -802,14 +719,32 @@ return NGHTTP2_ERR_PROTO; } - flags = set_response_flags(data_prd); - return submit_headers_shared_nva(session, flags, stream_id, NULL, nva, nvlen, - data_prd, NULL); + flags = set_response_flags(dpw); + return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, dpw, + NULL); } -int nghttp2_submit_data(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const nghttp2_data_provider *data_prd) { +int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, + const nghttp2_nv *nva, size_t nvlen, + const nghttp2_data_provider *data_prd) { + nghttp2_data_provider_wrap dpw; + + return submit_response_shared(session, stream_id, nva, nvlen, + nghttp2_data_provider_wrap_v1(&dpw, data_prd)); +} + +int nghttp2_submit_response2(nghttp2_session *session, int32_t stream_id, + const nghttp2_nv *nva, size_t nvlen, + const nghttp2_data_provider2 *data_prd) { + nghttp2_data_provider_wrap dpw; + + return submit_response_shared(session, stream_id, nva, nvlen, + nghttp2_data_provider_wrap_v2(&dpw, data_prd)); +} + +int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags, + int32_t stream_id, + const nghttp2_data_provider_wrap *dpw) { int rv; nghttp2_outbound_item *item; nghttp2_frame *frame; @@ -832,7 +767,7 @@ frame = &item->frame; aux_data = &item->aux_data.data; - aux_data->data_prd = *data_prd; + aux_data->dpw = *dpw; aux_data->eof = 0; aux_data->flags = nflags; @@ -848,9 +783,37 @@ return 0; } +int nghttp2_submit_data(nghttp2_session *session, uint8_t flags, + int32_t stream_id, + const nghttp2_data_provider *data_prd) { + nghttp2_data_provider_wrap dpw; + + assert(data_prd); + + return nghttp2_submit_data_shared( + session, flags, stream_id, nghttp2_data_provider_wrap_v1(&dpw, data_prd)); +} + +int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags, + int32_t stream_id, + const nghttp2_data_provider2 *data_prd) { + nghttp2_data_provider_wrap dpw; + + assert(data_prd); + + return nghttp2_submit_data_shared( + session, flags, stream_id, nghttp2_data_provider_wrap_v2(&dpw, data_prd)); +} + ssize_t nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv) { + return (ssize_t)nghttp2_pack_settings_payload2(buf, buflen, iv, niv); +} + +nghttp2_ssize nghttp2_pack_settings_payload2(uint8_t *buf, size_t buflen, + const nghttp2_settings_entry *iv, + size_t niv) { if (!nghttp2_iv_check(iv, niv)) { return NGHTTP2_ERR_INVALID_ARGUMENT; } @@ -859,7 +822,7 @@ return NGHTTP2_ERR_INSUFF_BUFSIZE; } - return (ssize_t)nghttp2_frame_pack_settings_payload(buf, iv, niv); + return (nghttp2_ssize)nghttp2_frame_pack_settings_payload(buf, iv, niv); } int nghttp2_submit_extension(nghttp2_session *session, uint8_t type, @@ -875,7 +838,8 @@ return NGHTTP2_ERR_INVALID_ARGUMENT; } - if (!session->callbacks.pack_extension_callback) { + if (!session->callbacks.pack_extension_callback2 && + !session->callbacks.pack_extension_callback) { return NGHTTP2_ERR_INVALID_STATE; }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_submit.h b/Utilities/cmnghttp2/lib/nghttp2_submit.h index 74d702f..decf803 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_submit.h +++ b/Utilities/cmnghttp2/lib/nghttp2_submit.h
@@ -27,8 +27,14 @@ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> -#endif /* NGHTTP2_SUBMIT_H */ +#include "nghttp2_outbound_item.h" + +int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags, + int32_t stream_id, + const nghttp2_data_provider_wrap *dpw); + +#endif /* !defined(NGHTTP2_SUBMIT_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_time.c b/Utilities/cmnghttp2/lib/nghttp2_time.c new file mode 100644 index 0000000..18fd7bc --- /dev/null +++ b/Utilities/cmnghttp2/lib/nghttp2_time.c
@@ -0,0 +1,62 @@ +/* + * nghttp2 - HTTP/2 C Library + * + * Copyright (c) 2023 nghttp2 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "nghttp2_time.h" + +#ifdef HAVE_WINDOWS_H +# include <windows.h> +#endif /* defined(HAVE_WINDOWS_H) */ + +#include <time.h> + +#if !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__) +static uint64_t time_now_sec(void) { + time_t t = time(NULL); + + if (t == -1) { + return 0; + } + + return (uint64_t)t; +} +#endif /* !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__) */ + +#if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__) +uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; } +#elif defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC +uint64_t nghttp2_time_now_sec(void) { + struct timespec tp; + int rv = clock_gettime(CLOCK_MONOTONIC, &tp); + + if (rv == -1) { + return time_now_sec(); + } + + return (uint64_t)tp.tv_sec; +} +#else /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \ + (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */ +uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); } +#endif /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \ + (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_npn.h b/Utilities/cmnghttp2/lib/nghttp2_time.h similarity index 77% copy from Utilities/cmnghttp2/lib/nghttp2_npn.h copy to Utilities/cmnghttp2/lib/nghttp2_time.h index c6f1c04..a91e62a 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_npn.h +++ b/Utilities/cmnghttp2/lib/nghttp2_time.h
@@ -1,7 +1,7 @@ /* * nghttp2 - HTTP/2 C Library * - * Copyright (c) 2012 Tatsuhiro Tsujikawa + * Copyright (c) 2023 nghttp2 contributors * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -22,13 +22,17 @@ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef NGHTTP2_NPN_H -#define NGHTTP2_NPN_H +#ifndef NGHTTP2_TIME_H +#define NGHTTP2_TIME_H #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h> -#endif /* NGHTTP2_NPN_H */ +/* nghttp2_time_now_sec returns seconds from implementation-specific + timepoint. If it is unable to get seconds, it returns 0. */ +uint64_t nghttp2_time_now_sec(void); + +#endif /* !defined(NGHTTP2_TIME_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_version.c b/Utilities/cmnghttp2/lib/nghttp2_version.c index 4211f2c..39a49ff 100644 --- a/Utilities/cmnghttp2/lib/nghttp2_version.c +++ b/Utilities/cmnghttp2/lib/nghttp2_version.c
@@ -24,7 +24,7 @@ */ #ifdef HAVE_CONFIG_H # include <config.h> -#endif /* HAVE_CONFIG_H */ +#endif /* defined(HAVE_CONFIG_H) */ #include <nghttp2/nghttp2.h>
diff --git a/Utilities/cmnghttp2/lib/sfparse.c b/Utilities/cmnghttp2/lib/sfparse.c new file mode 100644 index 0000000..cee089d --- /dev/null +++ b/Utilities/cmnghttp2/lib/sfparse.c
@@ -0,0 +1,1787 @@ +/* + * sfparse + * + * Copyright (c) 2023 sfparse contributors + * Copyright (c) 2019 nghttp3 contributors + * Copyright (c) 2015 nghttp2 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "sfparse.h" + +#include <string.h> +#include <assert.h> +#include <stdlib.h> + +#ifdef __AVX2__ +# include <immintrin.h> +#endif /* __AVX2__ */ + +#define SFPARSE_STATE_DICT 0x08u +#define SFPARSE_STATE_LIST 0x10u +#define SFPARSE_STATE_ITEM 0x18u + +#define SFPARSE_STATE_INNER_LIST 0x04u + +#define SFPARSE_STATE_BEFORE 0x00u +#define SFPARSE_STATE_BEFORE_PARAMS 0x01u +#define SFPARSE_STATE_PARAMS 0x02u +#define SFPARSE_STATE_AFTER 0x03u + +#define SFPARSE_STATE_OP_MASK 0x03u + +#define SFPARSE_SET_STATE_AFTER(NAME) \ + (SFPARSE_STATE_##NAME | SFPARSE_STATE_AFTER) +#define SFPARSE_SET_STATE_BEFORE_PARAMS(NAME) \ + (SFPARSE_STATE_##NAME | SFPARSE_STATE_BEFORE_PARAMS) +#define SFPARSE_SET_STATE_INNER_LIST_BEFORE(NAME) \ + (SFPARSE_STATE_##NAME | SFPARSE_STATE_INNER_LIST | SFPARSE_STATE_BEFORE) + +#define SFPARSE_STATE_DICT_AFTER SFPARSE_SET_STATE_AFTER(DICT) +#define SFPARSE_STATE_DICT_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(DICT) +#define SFPARSE_STATE_DICT_INNER_LIST_BEFORE \ + SFPARSE_SET_STATE_INNER_LIST_BEFORE(DICT) + +#define SFPARSE_STATE_LIST_AFTER SFPARSE_SET_STATE_AFTER(LIST) +#define SFPARSE_STATE_LIST_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(LIST) +#define SFPARSE_STATE_LIST_INNER_LIST_BEFORE \ + SFPARSE_SET_STATE_INNER_LIST_BEFORE(LIST) + +#define SFPARSE_STATE_ITEM_AFTER SFPARSE_SET_STATE_AFTER(ITEM) +#define SFPARSE_STATE_ITEM_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(ITEM) +#define SFPARSE_STATE_ITEM_INNER_LIST_BEFORE \ + SFPARSE_SET_STATE_INNER_LIST_BEFORE(ITEM) + +#define SFPARSE_STATE_INITIAL 0x00u + +#define DIGIT_CASES \ + case '0': \ + case '1': \ + case '2': \ + case '3': \ + case '4': \ + case '5': \ + case '6': \ + case '7': \ + case '8': \ + case '9' + +#define LCALPHA_CASES \ + case 'a': \ + case 'b': \ + case 'c': \ + case 'd': \ + case 'e': \ + case 'f': \ + case 'g': \ + case 'h': \ + case 'i': \ + case 'j': \ + case 'k': \ + case 'l': \ + case 'm': \ + case 'n': \ + case 'o': \ + case 'p': \ + case 'q': \ + case 'r': \ + case 's': \ + case 't': \ + case 'u': \ + case 'v': \ + case 'w': \ + case 'x': \ + case 'y': \ + case 'z' + +#define UCALPHA_CASES \ + case 'A': \ + case 'B': \ + case 'C': \ + case 'D': \ + case 'E': \ + case 'F': \ + case 'G': \ + case 'H': \ + case 'I': \ + case 'J': \ + case 'K': \ + case 'L': \ + case 'M': \ + case 'N': \ + case 'O': \ + case 'P': \ + case 'Q': \ + case 'R': \ + case 'S': \ + case 'T': \ + case 'U': \ + case 'V': \ + case 'W': \ + case 'X': \ + case 'Y': \ + case 'Z' + +#define ALPHA_CASES \ + UCALPHA_CASES: \ + LCALPHA_CASES + +#define TOKEN_CASES \ + case '!': \ + case '#': \ + case '$': \ + case '%': \ + case '&': \ + case '\'': \ + case '*': \ + case '+': \ + case '-': \ + case '.': \ + case '/': \ + DIGIT_CASES: \ + case ':': \ + UCALPHA_CASES: \ + case '^': \ + case '_': \ + case '`': \ + LCALPHA_CASES: \ + case '|': \ + case '~' + +#define LCHEXALPHA_CASES \ + case 'a': \ + case 'b': \ + case 'c': \ + case 'd': \ + case 'e': \ + case 'f' + +#define X00_1F_CASES \ + case 0x00: \ + case 0x01: \ + case 0x02: \ + case 0x03: \ + case 0x04: \ + case 0x05: \ + case 0x06: \ + case 0x07: \ + case 0x08: \ + case 0x09: \ + case 0x0a: \ + case 0x0b: \ + case 0x0c: \ + case 0x0d: \ + case 0x0e: \ + case 0x0f: \ + case 0x10: \ + case 0x11: \ + case 0x12: \ + case 0x13: \ + case 0x14: \ + case 0x15: \ + case 0x16: \ + case 0x17: \ + case 0x18: \ + case 0x19: \ + case 0x1a: \ + case 0x1b: \ + case 0x1c: \ + case 0x1d: \ + case 0x1e: \ + case 0x1f + +#define X20_21_CASES \ + case ' ': \ + case '!' + +#define X23_5B_CASES \ + case '#': \ + case '$': \ + case '%': \ + case '&': \ + case '\'': \ + case '(': \ + case ')': \ + case '*': \ + case '+': \ + case ',': \ + case '-': \ + case '.': \ + case '/': \ + DIGIT_CASES: \ + case ':': \ + case ';': \ + case '<': \ + case '=': \ + case '>': \ + case '?': \ + case '@': \ + UCALPHA_CASES: \ + case '[' + +#define X5D_7E_CASES \ + case ']': \ + case '^': \ + case '_': \ + case '`': \ + LCALPHA_CASES: \ + case '{': \ + case '|': \ + case '}': \ + case '~' + +#define X7F_FF_CASES \ + case 0x7f: \ + case 0x80: \ + case 0x81: \ + case 0x82: \ + case 0x83: \ + case 0x84: \ + case 0x85: \ + case 0x86: \ + case 0x87: \ + case 0x88: \ + case 0x89: \ + case 0x8a: \ + case 0x8b: \ + case 0x8c: \ + case 0x8d: \ + case 0x8e: \ + case 0x8f: \ + case 0x90: \ + case 0x91: \ + case 0x92: \ + case 0x93: \ + case 0x94: \ + case 0x95: \ + case 0x96: \ + case 0x97: \ + case 0x98: \ + case 0x99: \ + case 0x9a: \ + case 0x9b: \ + case 0x9c: \ + case 0x9d: \ + case 0x9e: \ + case 0x9f: \ + case 0xa0: \ + case 0xa1: \ + case 0xa2: \ + case 0xa3: \ + case 0xa4: \ + case 0xa5: \ + case 0xa6: \ + case 0xa7: \ + case 0xa8: \ + case 0xa9: \ + case 0xaa: \ + case 0xab: \ + case 0xac: \ + case 0xad: \ + case 0xae: \ + case 0xaf: \ + case 0xb0: \ + case 0xb1: \ + case 0xb2: \ + case 0xb3: \ + case 0xb4: \ + case 0xb5: \ + case 0xb6: \ + case 0xb7: \ + case 0xb8: \ + case 0xb9: \ + case 0xba: \ + case 0xbb: \ + case 0xbc: \ + case 0xbd: \ + case 0xbe: \ + case 0xbf: \ + case 0xc0: \ + case 0xc1: \ + case 0xc2: \ + case 0xc3: \ + case 0xc4: \ + case 0xc5: \ + case 0xc6: \ + case 0xc7: \ + case 0xc8: \ + case 0xc9: \ + case 0xca: \ + case 0xcb: \ + case 0xcc: \ + case 0xcd: \ + case 0xce: \ + case 0xcf: \ + case 0xd0: \ + case 0xd1: \ + case 0xd2: \ + case 0xd3: \ + case 0xd4: \ + case 0xd5: \ + case 0xd6: \ + case 0xd7: \ + case 0xd8: \ + case 0xd9: \ + case 0xda: \ + case 0xdb: \ + case 0xdc: \ + case 0xdd: \ + case 0xde: \ + case 0xdf: \ + case 0xe0: \ + case 0xe1: \ + case 0xe2: \ + case 0xe3: \ + case 0xe4: \ + case 0xe5: \ + case 0xe6: \ + case 0xe7: \ + case 0xe8: \ + case 0xe9: \ + case 0xea: \ + case 0xeb: \ + case 0xec: \ + case 0xed: \ + case 0xee: \ + case 0xef: \ + case 0xf0: \ + case 0xf1: \ + case 0xf2: \ + case 0xf3: \ + case 0xf4: \ + case 0xf5: \ + case 0xf6: \ + case 0xf7: \ + case 0xf8: \ + case 0xf9: \ + case 0xfa: \ + case 0xfb: \ + case 0xfc: \ + case 0xfd: \ + case 0xfe: \ + case 0xff + +static int is_ws(uint8_t c) { + switch (c) { + case ' ': + case '\t': + return 1; + default: + return 0; + } +} + +#ifdef __AVX2__ +# ifdef _MSC_VER +# include <intrin.h> + +static int ctz(unsigned int v) { + unsigned long n; + + /* Assume that v is not 0. */ + _BitScanForward(&n, v); + + return (int)n; +} +# else /* !_MSC_VER */ +# define ctz __builtin_ctz +# endif /* !_MSC_VER */ +#endif /* __AVX2__ */ + +static int parser_eof(sfparse_parser *sfp) { return sfp->pos == sfp->end; } + +static void parser_discard_ows(sfparse_parser *sfp) { + for (; !parser_eof(sfp) && is_ws(*sfp->pos); ++sfp->pos) + ; +} + +static void parser_discard_sp(sfparse_parser *sfp) { + for (; !parser_eof(sfp) && *sfp->pos == ' '; ++sfp->pos) + ; +} + +static void parser_set_op_state(sfparse_parser *sfp, uint32_t op) { + sfp->state &= ~SFPARSE_STATE_OP_MASK; + sfp->state |= op; +} + +static void parser_unset_inner_list_state(sfparse_parser *sfp) { + sfp->state &= ~SFPARSE_STATE_INNER_LIST; +} + +#ifdef __AVX2__ +static const uint8_t *find_char_key(const uint8_t *first, const uint8_t *last) { + const __m256i us = _mm256_set1_epi8('_'); + const __m256i ds = _mm256_set1_epi8('-'); + const __m256i dot = _mm256_set1_epi8('.'); + const __m256i ast = _mm256_set1_epi8('*'); + const __m256i r0l = _mm256_set1_epi8('0' - 1); + const __m256i r0r = _mm256_set1_epi8('9' + 1); + const __m256i r1l = _mm256_set1_epi8('a' - 1); + const __m256i r1r = _mm256_set1_epi8('z' + 1); + __m256i s, x; + uint32_t m; + + for (; first != last; first += 32) { + s = _mm256_loadu_si256((void *)first); + + x = _mm256_cmpeq_epi8(s, us); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ds), x); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dot), x); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ast), x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)), + x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)), + x); + + m = ~(uint32_t)_mm256_movemask_epi8(x); + if (m) { + return first + ctz(m); + } + } + + return last; +} +#endif /* __AVX2__ */ + +static int parser_key(sfparse_parser *sfp, sfparse_vec *dest) { + const uint8_t *base; +#ifdef __AVX2__ + const uint8_t *last; +#endif /* __AVX2__ */ + + switch (*sfp->pos) { + case '*': + LCALPHA_CASES: + break; + default: + return SFPARSE_ERR_PARSE; + } + + base = sfp->pos++; + +#ifdef __AVX2__ + if (sfp->end - sfp->pos >= 32) { + last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); + + sfp->pos = find_char_key(sfp->pos, last); + if (sfp->pos != last) { + goto fin; + } + } +#endif /* __AVX2__ */ + + for (; !parser_eof(sfp); ++sfp->pos) { + switch (*sfp->pos) { + case '_': + case '-': + case '.': + case '*': + DIGIT_CASES: + LCALPHA_CASES: + continue; + } + + break; + } + +#ifdef __AVX2__ +fin: +#endif /* __AVX2__ */ + if (dest) { + dest->base = (uint8_t *)base; + dest->len = (size_t)(sfp->pos - dest->base); + } + + return 0; +} + +static int parser_number(sfparse_parser *sfp, sfparse_value *dest) { + int sign = 1; + int64_t value = 0; + size_t len = 0; + size_t fpos = 0; + + if (*sfp->pos == '-') { + ++sfp->pos; + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + sign = -1; + } + + assert(!parser_eof(sfp)); + + for (; !parser_eof(sfp); ++sfp->pos) { + switch (*sfp->pos) { + DIGIT_CASES: + if (++len > 15) { + return SFPARSE_ERR_PARSE; + } + + value *= 10; + value += *sfp->pos - '0'; + + continue; + } + + break; + } + + if (len == 0) { + return SFPARSE_ERR_PARSE; + } + + if (parser_eof(sfp) || *sfp->pos != '.') { + if (dest) { + dest->type = SFPARSE_TYPE_INTEGER; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + dest->integer = value * sign; + } + + return 0; + } + + /* decimal */ + + if (len > 12) { + return SFPARSE_ERR_PARSE; + } + + fpos = len; + + ++sfp->pos; + + for (; !parser_eof(sfp); ++sfp->pos) { + switch (*sfp->pos) { + DIGIT_CASES: + if (++len > 15) { + return SFPARSE_ERR_PARSE; + } + + value *= 10; + value += *sfp->pos - '0'; + + continue; + } + + break; + } + + if (fpos == len || len - fpos > 3) { + return SFPARSE_ERR_PARSE; + } + + if (dest) { + dest->type = SFPARSE_TYPE_DECIMAL; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + dest->decimal.numer = value * sign; + + switch (len - fpos) { + case 1: + dest->decimal.denom = 10; + + break; + case 2: + dest->decimal.denom = 100; + + break; + case 3: + dest->decimal.denom = 1000; + + break; + } + } + + return 0; +} + +static int parser_date(sfparse_parser *sfp, sfparse_value *dest) { + int rv; + sfparse_value val; + + /* The first byte has already been validated by the caller. */ + assert('@' == *sfp->pos); + + ++sfp->pos; + + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + rv = parser_number(sfp, &val); + if (rv != 0) { + return rv; + } + + if (val.type != SFPARSE_TYPE_INTEGER) { + return SFPARSE_ERR_PARSE; + } + + if (dest) { + *dest = val; + dest->type = SFPARSE_TYPE_DATE; + } + + return 0; +} + +#ifdef __AVX2__ +static const uint8_t *find_char_string(const uint8_t *first, + const uint8_t *last) { + const __m256i bs = _mm256_set1_epi8('\\'); + const __m256i dq = _mm256_set1_epi8('"'); + const __m256i del = _mm256_set1_epi8(0x7f); + const __m256i sp = _mm256_set1_epi8(' '); + __m256i s, x; + uint32_t m; + + for (; first != last; first += 32) { + s = _mm256_loadu_si256((void *)first); + + x = _mm256_cmpgt_epi8(sp, s); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, bs), x); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dq), x); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, del), x); + + m = (uint32_t)_mm256_movemask_epi8(x); + if (m) { + return first + ctz(m); + } + } + + return last; +} +#endif /* __AVX2__ */ + +static int parser_string(sfparse_parser *sfp, sfparse_value *dest) { + const uint8_t *base; +#ifdef __AVX2__ + const uint8_t *last; +#endif /* __AVX2__ */ + uint32_t flags = SFPARSE_VALUE_FLAG_NONE; + + /* The first byte has already been validated by the caller. */ + assert('"' == *sfp->pos); + + base = ++sfp->pos; + +#ifdef __AVX2__ + for (; sfp->end - sfp->pos >= 32; ++sfp->pos) { + last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); + + sfp->pos = find_char_string(sfp->pos, last); + if (sfp->pos == last) { + break; + } + + switch (*sfp->pos) { + case '\\': + ++sfp->pos; + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + switch (*sfp->pos) { + case '"': + case '\\': + flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING; + + break; + default: + return SFPARSE_ERR_PARSE; + } + + break; + case '"': + goto fin; + default: + return SFPARSE_ERR_PARSE; + } + } +#endif /* __AVX2__ */ + + for (; !parser_eof(sfp); ++sfp->pos) { + switch (*sfp->pos) { + X20_21_CASES: + X23_5B_CASES: + X5D_7E_CASES: + break; + case '\\': + ++sfp->pos; + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + switch (*sfp->pos) { + case '"': + case '\\': + flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING; + + break; + default: + return SFPARSE_ERR_PARSE; + } + + break; + case '"': + goto fin; + default: + return SFPARSE_ERR_PARSE; + } + } + + return SFPARSE_ERR_PARSE; + +fin: + if (dest) { + dest->type = SFPARSE_TYPE_STRING; + dest->flags = flags; + dest->vec.len = (size_t)(sfp->pos - base); + dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; + } + + ++sfp->pos; + + return 0; +} + +#ifdef __AVX2__ +static const uint8_t *find_char_token(const uint8_t *first, + const uint8_t *last) { + /* r0: !..:, excluding "(), + r1: A..Z + r2: ^..~, excluding {} */ + const __m256i r0l = _mm256_set1_epi8('!' - 1); + const __m256i r0r = _mm256_set1_epi8(':' + 1); + const __m256i dq = _mm256_set1_epi8('"'); + const __m256i prl = _mm256_set1_epi8('('); + const __m256i prr = _mm256_set1_epi8(')'); + const __m256i comma = _mm256_set1_epi8(','); + const __m256i r1l = _mm256_set1_epi8('A' - 1); + const __m256i r1r = _mm256_set1_epi8('Z' + 1); + const __m256i r2l = _mm256_set1_epi8('^' - 1); + const __m256i r2r = _mm256_set1_epi8('~' + 1); + const __m256i cbl = _mm256_set1_epi8('{'); + const __m256i cbr = _mm256_set1_epi8('}'); + __m256i s, x; + uint32_t m; + + for (; first != last; first += 32) { + s = _mm256_loadu_si256((void *)first); + + x = _mm256_andnot_si256( + _mm256_cmpeq_epi8(s, comma), + _mm256_andnot_si256( + _mm256_cmpeq_epi8(s, prr), + _mm256_andnot_si256( + _mm256_cmpeq_epi8(s, prl), + _mm256_andnot_si256(_mm256_cmpeq_epi8(s, dq), + _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), + _mm256_cmpgt_epi8(r0r, s)))))); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)), + x); + x = _mm256_or_si256( + _mm256_andnot_si256( + _mm256_cmpeq_epi8(s, cbr), + _mm256_andnot_si256(_mm256_cmpeq_epi8(s, cbl), + _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l), + _mm256_cmpgt_epi8(r2r, s)))), + x); + + m = ~(uint32_t)_mm256_movemask_epi8(x); + if (m) { + return first + ctz(m); + } + } + + return last; +} +#endif /* __AVX2__ */ + +static int parser_token(sfparse_parser *sfp, sfparse_value *dest) { + const uint8_t *base; +#ifdef __AVX2__ + const uint8_t *last; +#endif /* __AVX2__ */ + + /* The first byte has already been validated by the caller. */ + base = sfp->pos++; + +#ifdef __AVX2__ + if (sfp->end - sfp->pos >= 32) { + last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); + + sfp->pos = find_char_token(sfp->pos, last); + if (sfp->pos != last) { + goto fin; + } + } +#endif /* __AVX2__ */ + + for (; !parser_eof(sfp); ++sfp->pos) { + switch (*sfp->pos) { + TOKEN_CASES: + continue; + } + + break; + } + +#ifdef __AVX2__ +fin: +#endif /* __AVX2__ */ + if (dest) { + dest->type = SFPARSE_TYPE_TOKEN; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + dest->vec.base = (uint8_t *)base; + dest->vec.len = (size_t)(sfp->pos - base); + } + + return 0; +} + +#ifdef __AVX2__ +static const uint8_t *find_char_byteseq(const uint8_t *first, + const uint8_t *last) { + const __m256i pls = _mm256_set1_epi8('+'); + const __m256i fs = _mm256_set1_epi8('/'); + const __m256i r0l = _mm256_set1_epi8('0' - 1); + const __m256i r0r = _mm256_set1_epi8('9' + 1); + const __m256i r1l = _mm256_set1_epi8('A' - 1); + const __m256i r1r = _mm256_set1_epi8('Z' + 1); + const __m256i r2l = _mm256_set1_epi8('a' - 1); + const __m256i r2r = _mm256_set1_epi8('z' + 1); + __m256i s, x; + uint32_t m; + + for (; first != last; first += 32) { + s = _mm256_loadu_si256((void *)first); + + x = _mm256_cmpeq_epi8(s, pls); + x = _mm256_or_si256(_mm256_cmpeq_epi8(s, fs), x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)), + x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)), + x); + x = _mm256_or_si256( + _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l), _mm256_cmpgt_epi8(r2r, s)), + x); + + m = ~(uint32_t)_mm256_movemask_epi8(x); + if (m) { + return first + ctz(m); + } + } + + return last; +} +#endif /* __AVX2__ */ + +static int parser_byteseq(sfparse_parser *sfp, sfparse_value *dest) { + const uint8_t *base; +#ifdef __AVX2__ + const uint8_t *last; +#endif /* __AVX2__ */ + + /* The first byte has already been validated by the caller. */ + assert(':' == *sfp->pos); + + base = ++sfp->pos; + +#ifdef __AVX2__ + if (sfp->end - sfp->pos >= 32) { + last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu); + sfp->pos = find_char_byteseq(sfp->pos, last); + } +#endif /* __AVX2__ */ + + for (; !parser_eof(sfp); ++sfp->pos) { + switch (*sfp->pos) { + case '+': + case '/': + DIGIT_CASES: + ALPHA_CASES: + continue; + case '=': + switch ((sfp->pos - base) & 0x3) { + case 0: + case 1: + return SFPARSE_ERR_PARSE; + case 2: + ++sfp->pos; + + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + if (*sfp->pos == '=') { + ++sfp->pos; + } + + break; + case 3: + ++sfp->pos; + + break; + } + + if (parser_eof(sfp) || *sfp->pos != ':') { + return SFPARSE_ERR_PARSE; + } + + goto fin; + case ':': + if (((sfp->pos - base) & 0x3) == 1) { + return SFPARSE_ERR_PARSE; + } + + goto fin; + default: + return SFPARSE_ERR_PARSE; + } + } + + return SFPARSE_ERR_PARSE; + +fin: + if (dest) { + dest->type = SFPARSE_TYPE_BYTESEQ; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + dest->vec.len = (size_t)(sfp->pos - base); + dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; + } + + ++sfp->pos; + + return 0; +} + +static int parser_boolean(sfparse_parser *sfp, sfparse_value *dest) { + int b; + + /* The first byte has already been validated by the caller. */ + assert('?' == *sfp->pos); + + ++sfp->pos; + + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + switch (*sfp->pos) { + case '0': + b = 0; + + break; + case '1': + b = 1; + + break; + default: + return SFPARSE_ERR_PARSE; + } + + ++sfp->pos; + + if (dest) { + dest->type = SFPARSE_TYPE_BOOLEAN; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + dest->boolean = b; + } + + return 0; +} + +static int pctdecode(uint8_t *pc, const uint8_t **ppos) { + uint8_t c, b = **ppos; + + switch (b) { + DIGIT_CASES: + c = (uint8_t)((b - '0') << 4); + + break; + LCHEXALPHA_CASES: + c = (uint8_t)((b - 'a' + 10) << 4); + + break; + default: + return -1; + } + + b = *++*ppos; + + switch (b) { + DIGIT_CASES: + c |= (uint8_t)(b - '0'); + + break; + LCHEXALPHA_CASES: + c |= (uint8_t)(b - 'a' + 10); + + break; + default: + return -1; + } + + *pc = c; + ++*ppos; + + return 0; +} + +/* Start of utf8 dfa */ +/* Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de> + * See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. + * + * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#define UTF8_ACCEPT 0 +#define UTF8_REJECT 12 + +/* clang-format off */ +static const uint8_t utf8d[] = { + /* + * The first part of the table maps bytes to character classes that + * to reduce the size of the transition table and create bitmasks. + */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + + /* + * The second part is a transition table that maps a combination + * of a state of the automaton and a character class to a state. + */ + 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, + 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, + 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, + 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, + 12,36,12,12,12,12,12,12,12,12,12,12, +}; +/* clang-format on */ + +static void utf8_decode(uint32_t *state, uint8_t byte) { + *state = utf8d[256 + *state + utf8d[byte]]; +} + +/* End of utf8 dfa */ + +static int parser_dispstring(sfparse_parser *sfp, sfparse_value *dest) { + const uint8_t *base; + uint8_t c; + uint32_t utf8state = UTF8_ACCEPT; + + assert('%' == *sfp->pos); + + ++sfp->pos; + + if (parser_eof(sfp) || *sfp->pos != '"') { + return SFPARSE_ERR_PARSE; + } + + base = ++sfp->pos; + + for (; !parser_eof(sfp);) { + switch (*sfp->pos) { + X00_1F_CASES: + X7F_FF_CASES: + return SFPARSE_ERR_PARSE; + case '%': + ++sfp->pos; + + if (sfp->pos + 2 > sfp->end) { + return SFPARSE_ERR_PARSE; + } + + if (pctdecode(&c, &sfp->pos) != 0) { + return SFPARSE_ERR_PARSE; + } + + utf8_decode(&utf8state, c); + if (utf8state == UTF8_REJECT) { + return SFPARSE_ERR_PARSE; + } + + break; + case '"': + if (utf8state != UTF8_ACCEPT) { + return SFPARSE_ERR_PARSE; + } + + if (dest) { + dest->type = SFPARSE_TYPE_DISPSTRING; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + dest->vec.len = (size_t)(sfp->pos - base); + dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; + } + + ++sfp->pos; + + return 0; + default: + if (utf8state != UTF8_ACCEPT) { + return SFPARSE_ERR_PARSE; + } + + ++sfp->pos; + } + } + + return SFPARSE_ERR_PARSE; +} + +static int parser_bare_item(sfparse_parser *sfp, sfparse_value *dest) { + switch (*sfp->pos) { + case '"': + return parser_string(sfp, dest); + case '-': + DIGIT_CASES: + return parser_number(sfp, dest); + case '@': + return parser_date(sfp, dest); + case ':': + return parser_byteseq(sfp, dest); + case '?': + return parser_boolean(sfp, dest); + case '*': + ALPHA_CASES: + return parser_token(sfp, dest); + case '%': + return parser_dispstring(sfp, dest); + default: + return SFPARSE_ERR_PARSE; + } +} + +static int parser_skip_inner_list(sfparse_parser *sfp); + +int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key, + sfparse_value *dest_value) { + int rv; + + switch (sfp->state & SFPARSE_STATE_OP_MASK) { + case SFPARSE_STATE_BEFORE: + rv = parser_skip_inner_list(sfp); + if (rv != 0) { + return rv; + } + + /* fall through */ + case SFPARSE_STATE_BEFORE_PARAMS: + parser_set_op_state(sfp, SFPARSE_STATE_PARAMS); + + break; + case SFPARSE_STATE_PARAMS: + break; + default: + assert(0); + abort(); + } + + if (parser_eof(sfp) || *sfp->pos != ';') { + parser_set_op_state(sfp, SFPARSE_STATE_AFTER); + + return SFPARSE_ERR_EOF; + } + + ++sfp->pos; + + parser_discard_sp(sfp); + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + rv = parser_key(sfp, dest_key); + if (rv != 0) { + return rv; + } + + if (parser_eof(sfp) || *sfp->pos != '=') { + if (dest_value) { + dest_value->type = SFPARSE_TYPE_BOOLEAN; + dest_value->flags = SFPARSE_VALUE_FLAG_NONE; + dest_value->boolean = 1; + } + + return 0; + } + + ++sfp->pos; + + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + return parser_bare_item(sfp, dest_value); +} + +static int parser_skip_params(sfparse_parser *sfp) { + int rv; + + for (;;) { + rv = sfparse_parser_param(sfp, NULL, NULL); + switch (rv) { + case 0: + break; + case SFPARSE_ERR_EOF: + return 0; + case SFPARSE_ERR_PARSE: + return rv; + default: + assert(0); + abort(); + } + } +} + +int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest) { + int rv; + + switch (sfp->state & SFPARSE_STATE_OP_MASK) { + case SFPARSE_STATE_BEFORE: + parser_discard_sp(sfp); + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + break; + case SFPARSE_STATE_BEFORE_PARAMS: + rv = parser_skip_params(sfp); + if (rv != 0) { + return rv; + } + + /* Technically, we are entering SFPARSE_STATE_AFTER, but we will set + another state without reading the state. */ + /* parser_set_op_state(sfp, SFPARSE_STATE_AFTER); */ + + /* fall through */ + case SFPARSE_STATE_AFTER: + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + switch (*sfp->pos) { + case ' ': + parser_discard_sp(sfp); + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + break; + case ')': + break; + default: + return SFPARSE_ERR_PARSE; + } + + break; + default: + assert(0); + abort(); + } + + if (*sfp->pos == ')') { + ++sfp->pos; + + parser_unset_inner_list_state(sfp); + parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS); + + return SFPARSE_ERR_EOF; + } + + rv = parser_bare_item(sfp, dest); + if (rv != 0) { + return rv; + } + + parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS); + + return 0; +} + +static int parser_skip_inner_list(sfparse_parser *sfp) { + int rv; + + for (;;) { + rv = sfparse_parser_inner_list(sfp, NULL); + switch (rv) { + case 0: + break; + case SFPARSE_ERR_EOF: + return 0; + case SFPARSE_ERR_PARSE: + return rv; + default: + assert(0); + abort(); + } + } +} + +static int parser_next_key_or_item(sfparse_parser *sfp) { + parser_discard_ows(sfp); + + if (parser_eof(sfp)) { + return SFPARSE_ERR_EOF; + } + + if (*sfp->pos != ',') { + return SFPARSE_ERR_PARSE; + } + + ++sfp->pos; + + parser_discard_ows(sfp); + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + return 0; +} + +static int parser_dict_value(sfparse_parser *sfp, sfparse_value *dest) { + int rv; + + if (parser_eof(sfp) || *(sfp->pos) != '=') { + /* Boolean true */ + if (dest) { + dest->type = SFPARSE_TYPE_BOOLEAN; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + dest->boolean = 1; + } + + sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS; + + return 0; + } + + ++sfp->pos; + + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + if (*sfp->pos == '(') { + if (dest) { + dest->type = SFPARSE_TYPE_INNER_LIST; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + } + + ++sfp->pos; + + sfp->state = SFPARSE_STATE_DICT_INNER_LIST_BEFORE; + + return 0; + } + + rv = parser_bare_item(sfp, dest); + if (rv != 0) { + return rv; + } + + sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS; + + return 0; +} + +int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key, + sfparse_value *dest_value) { + int rv; + + switch (sfp->state) { + case SFPARSE_STATE_DICT_INNER_LIST_BEFORE: + rv = parser_skip_inner_list(sfp); + if (rv != 0) { + return rv; + } + + /* fall through */ + case SFPARSE_STATE_DICT_BEFORE_PARAMS: + rv = parser_skip_params(sfp); + if (rv != 0) { + return rv; + } + + /* fall through */ + case SFPARSE_STATE_DICT_AFTER: + rv = parser_next_key_or_item(sfp); + if (rv != 0) { + return rv; + } + + break; + case SFPARSE_STATE_INITIAL: + parser_discard_sp(sfp); + + if (parser_eof(sfp)) { + return SFPARSE_ERR_EOF; + } + + break; + default: + assert(0); + abort(); + } + + rv = parser_key(sfp, dest_key); + if (rv != 0) { + return rv; + } + + return parser_dict_value(sfp, dest_value); +} + +int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest) { + int rv; + + switch (sfp->state) { + case SFPARSE_STATE_LIST_INNER_LIST_BEFORE: + rv = parser_skip_inner_list(sfp); + if (rv != 0) { + return rv; + } + + /* fall through */ + case SFPARSE_STATE_LIST_BEFORE_PARAMS: + rv = parser_skip_params(sfp); + if (rv != 0) { + return rv; + } + + /* fall through */ + case SFPARSE_STATE_LIST_AFTER: + rv = parser_next_key_or_item(sfp); + if (rv != 0) { + return rv; + } + + break; + case SFPARSE_STATE_INITIAL: + parser_discard_sp(sfp); + + if (parser_eof(sfp)) { + return SFPARSE_ERR_EOF; + } + + break; + default: + assert(0); + abort(); + } + + if (*sfp->pos == '(') { + if (dest) { + dest->type = SFPARSE_TYPE_INNER_LIST; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + } + + ++sfp->pos; + + sfp->state = SFPARSE_STATE_LIST_INNER_LIST_BEFORE; + + return 0; + } + + rv = parser_bare_item(sfp, dest); + if (rv != 0) { + return rv; + } + + sfp->state = SFPARSE_STATE_LIST_BEFORE_PARAMS; + + return 0; +} + +int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest) { + int rv; + + switch (sfp->state) { + case SFPARSE_STATE_INITIAL: + parser_discard_sp(sfp); + + if (parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + break; + case SFPARSE_STATE_ITEM_INNER_LIST_BEFORE: + rv = parser_skip_inner_list(sfp); + if (rv != 0) { + return rv; + } + + /* fall through */ + case SFPARSE_STATE_ITEM_BEFORE_PARAMS: + rv = parser_skip_params(sfp); + if (rv != 0) { + return rv; + } + + /* fall through */ + case SFPARSE_STATE_ITEM_AFTER: + parser_discard_sp(sfp); + + if (!parser_eof(sfp)) { + return SFPARSE_ERR_PARSE; + } + + return SFPARSE_ERR_EOF; + default: + assert(0); + abort(); + } + + if (*sfp->pos == '(') { + if (dest) { + dest->type = SFPARSE_TYPE_INNER_LIST; + dest->flags = SFPARSE_VALUE_FLAG_NONE; + } + + ++sfp->pos; + + sfp->state = SFPARSE_STATE_ITEM_INNER_LIST_BEFORE; + + return 0; + } + + rv = parser_bare_item(sfp, dest); + if (rv != 0) { + return rv; + } + + sfp->state = SFPARSE_STATE_ITEM_BEFORE_PARAMS; + + return 0; +} + +void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data, + size_t datalen) { + if (datalen == 0) { + sfp->pos = sfp->end = NULL; + } else { + sfp->pos = data; + sfp->end = data + datalen; + } + + sfp->state = SFPARSE_STATE_INITIAL; +} + +void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src) { + const uint8_t *p, *q; + uint8_t *o; + size_t len, slen; + + if (src->len == 0) { + dest->len = 0; + + return; + } + + o = dest->base; + p = src->base; + len = src->len; + + for (;;) { + q = memchr(p, '\\', len); + if (q == NULL) { + memcpy(o, p, len); + o += len; + + dest->len = (size_t)(o - dest->base); + + return; + } + + slen = (size_t)(q - p); + memcpy(o, p, slen); + o += slen; + + p = q + 1; + *o++ = *p++; + len -= slen + 2; + } +} + +void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src) { + static const int index_tbl[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, + -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1}; + uint8_t *o; + const uint8_t *p, *end; + uint32_t n; + size_t i, left; + int idx; + + if (src->len == 0) { + dest->len = 0; + + return; + } + + o = dest->base; + p = src->base; + left = src->len & 0x3; + if (left == 0 && src->base[src->len - 1] == '=') { + left = 4; + } + end = src->base + src->len - left; + + for (; p != end;) { + n = 0; + + for (i = 1; i <= 4; ++i, ++p) { + idx = index_tbl[*p]; + + assert(idx != -1); + + n += (uint32_t)(idx << (24 - i * 6)); + } + + *o++ = (uint8_t)(n >> 16); + *o++ = (n >> 8) & 0xffu; + *o++ = n & 0xffu; + } + + switch (left) { + case 0: + goto fin; + case 1: + assert(0); + abort(); + case 3: + if (src->base[src->len - 1] == '=') { + left = 2; + } + + break; + case 4: + assert('=' == src->base[src->len - 1]); + + if (src->base[src->len - 2] == '=') { + left = 2; + } else { + left = 3; + } + + break; + } + + switch (left) { + case 2: + *o = (uint8_t)(index_tbl[*p++] << 2); + *o++ |= (uint8_t)(index_tbl[*p++] >> 4); + + break; + case 3: + n = (uint32_t)(index_tbl[*p++] << 10); + n += (uint32_t)(index_tbl[*p++] << 4); + n += (uint32_t)(index_tbl[*p++] >> 2); + *o++ = (n >> 8) & 0xffu; + *o++ = n & 0xffu; + + break; + } + +fin: + dest->len = (size_t)(o - dest->base); +} + +void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src) { + const uint8_t *p, *q; + uint8_t *o; + size_t len, slen; + + if (src->len == 0) { + dest->len = 0; + + return; + } + + o = dest->base; + p = src->base; + len = src->len; + + for (;;) { + q = memchr(p, '%', len); + if (q == NULL) { + memcpy(o, p, len); + o += len; + + dest->len = (size_t)(o - dest->base); + + return; + } + + slen = (size_t)(q - p); + memcpy(o, p, slen); + o += slen; + + p = q + 1; + + pctdecode(o++, &p); + + len -= slen + 3; + } +}
diff --git a/Utilities/cmnghttp2/lib/sfparse.h b/Utilities/cmnghttp2/lib/sfparse.h new file mode 100644 index 0000000..9341221 --- /dev/null +++ b/Utilities/cmnghttp2/lib/sfparse.h
@@ -0,0 +1,442 @@ +/* + * sfparse + * + * Copyright (c) 2023 sfparse contributors + * Copyright (c) 2019 nghttp3 contributors + * Copyright (c) 2015 nghttp2 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef SFPARSE_H +#define SFPARSE_H + +/* Define WIN32 when build target is Win32 API (borrowed from + libcurl) */ +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif /* (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) */ + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +#if defined(_MSC_VER) && (_MSC_VER < 1800) +/* MSVC < 2013 does not have inttypes.h because it is not C99 + compliant. See compiler macros and version number in + https://sourceforge.net/p/predef/wiki/Compilers/ */ +# include <stdint.h> +#else /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */ +# include <inttypes.h> +#endif /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */ +#include <sys/types.h> +#include <stddef.h> + +/** + * @enum + * + * :type:`sfparse_type` defines value type. + */ +typedef enum sfparse_type { + /** + * :enum:`SFPARSE_TYPE_BOOLEAN` indicates boolean type. + */ + SFPARSE_TYPE_BOOLEAN, + /** + * :enum:`SFPARSE_TYPE_INTEGER` indicates integer type. + */ + SFPARSE_TYPE_INTEGER, + /** + * :enum:`SFPARSE_TYPE_DECIMAL` indicates decimal type. + */ + SFPARSE_TYPE_DECIMAL, + /** + * :enum:`SFPARSE_TYPE_STRING` indicates string type. + */ + SFPARSE_TYPE_STRING, + /** + * :enum:`SFPARSE_TYPE_TOKEN` indicates token type. + */ + SFPARSE_TYPE_TOKEN, + /** + * :enum:`SFPARSE_TYPE_BYTESEQ` indicates byte sequence type. + */ + SFPARSE_TYPE_BYTESEQ, + /** + * :enum:`SFPARSE_TYPE_INNER_LIST` indicates inner list type. + */ + SFPARSE_TYPE_INNER_LIST, + /** + * :enum:`SFPARSE_TYPE_DATE` indicates date type. + */ + SFPARSE_TYPE_DATE, + /** + * :enum:`SFPARSE_TYPE_DISPSTRING` indicates display string type. + */ + SFPARSE_TYPE_DISPSTRING +} sfparse_type; + +/** + * @macro + * + * :macro:`SFPARSE_ERR_PARSE` indicates fatal parse error has + * occurred, and it is not possible to continue the processing. + */ +#define SFPARSE_ERR_PARSE -1 + +/** + * @macro + * + * :macro:`SFPARSE_ERR_EOF` indicates that there is nothing left to + * read. The context of this error varies depending on the function + * that returns this error code. + */ +#define SFPARSE_ERR_EOF -2 + +/** + * @struct + * + * :type:`sfparse_vec` stores sequence of bytes. + */ +typedef struct sfparse_vec { + /** + * :member:`base` points to the beginning of the sequence of bytes. + */ + uint8_t *base; + /** + * :member:`len` is the number of bytes contained in this sequence. + */ + size_t len; +} sfparse_vec; + +/** + * @macro + * + * :macro:`SFPARSE_VALUE_FLAG_NONE` indicates no flag set. + */ +#define SFPARSE_VALUE_FLAG_NONE 0x0u + +/** + * @macro + * + * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` indicates that a string + * contains escaped character(s). + */ +#define SFPARSE_VALUE_FLAG_ESCAPED_STRING 0x1u + +/** + * @struct + * + * :type:`sfparse_decimal` contains decimal value. + */ +typedef struct sfparse_decimal { + /** + * :member:`numer` contains numerator of the decimal value. + */ + int64_t numer; + /** + * :member:`denom` contains denominator of the decimal value. + */ + int64_t denom; +} sfparse_decimal; + +/** + * @struct + * + * :type:`sfparse_value` stores a Structured Field item. For Inner + * List, only type is set to + * :enum:`sfparse_type.SFPARSE_TYPE_INNER_LIST`. In order to read the + * items contained in an inner list, call `sfparse_parser_inner_list`. + */ +typedef struct sfparse_value { + /** + * :member:`type` is the type of the value contained in this + * particular object. + */ + sfparse_type type; + /** + * :member:`flags` is bitwise OR of one or more of + * :macro:`SFPARSE_VALUE_FLAG_* <SFPARSE_VALUE_FLAG_NONE>`. + */ + uint32_t flags; + /** + * @anonunion_start + * + * @sfparse_value_value + */ + union { + /** + * :member:`boolean` contains boolean value if :member:`type` == + * :enum:`sfparse_type.SFPARSE_TYPE_BOOLEAN`. 1 indicates true, + * and 0 indicates false. + */ + int boolean; + /** + * :member:`integer` contains integer value if :member:`type` is + * either :enum:`sfparse_type.SFPARSE_TYPE_INTEGER` or + * :enum:`sfparse_type.SFPARSE_TYPE_DATE`. + */ + int64_t integer; + /** + * :member:`decimal` contains decimal value if :member:`type` == + * :enum:`sfparse_type.SFPARSE_TYPE_DECIMAL`. + */ + sfparse_decimal decimal; + /** + * :member:`vec` contains sequence of bytes if :member:`type` is + * either :enum:`sfparse_type.SFPARSE_TYPE_STRING`, + * :enum:`sfparse_type.SFPARSE_TYPE_TOKEN`, + * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, or + * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`. + * + * For :enum:`sfparse_type.SFPARSE_TYPE_STRING`, this field + * contains one or more escaped characters if :member:`flags` has + * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` set. To unescape + * the string, use `sfparse_unescape`. + * + * For :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, this field + * contains base64 encoded string. To decode this byte string, + * use `sfparse_base64decode`. + * + * For :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`, this field + * may contain percent-encoded UTF-8 byte sequences. To decode + * it, use `sfparse_pctdecode`. + * + * If :member:`vec.len <sfparse_vec.len>` == 0, :member:`vec.base + * <sfparse_vec.base>` is guaranteed to be NULL. + */ + sfparse_vec vec; + /** + * @anonunion_end + */ + }; +} sfparse_value; + +/** + * @struct + * + * :type:`sfparse_parser` is the Structured Field Values parser. Use + * `sfparse_parser_init` to initialize it. + */ +typedef struct sfparse_parser { + /* all fields are private */ + const uint8_t *pos; + const uint8_t *end; + uint32_t state; +} sfparse_parser; + +/** + * @function + * + * `sfparse_parser_init` initializes |sfp| with the given data encoded + * in Structured Field Values pointed by |data| of length |datalen|. + */ +void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data, + size_t datalen); + +/** + * @function + * + * `sfparse_parser_param` reads a parameter. If this function returns + * 0, it stores parameter key and value in |dest_key| and |dest_value| + * respectively, if they are not NULL. + * + * This function does no effort to find duplicated keys. Same key may + * be reported more than once. + * + * Caller should keep calling this function until it returns negative + * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all parameters + * have read, and caller can continue to read rest of the values. If + * it returns :macro:`SFPARSE_ERR_PARSE`, it encountered fatal error + * while parsing field value. + */ +int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key, + sfparse_value *dest_value); + +/** + * @function + * + * `sfparse_parser_dict` reads the next dictionary key and value pair. + * If this function returns 0, it stores the key and value in + * |dest_key| and |dest_value| respectively, if they are not NULL. + * + * Caller can optionally read parameters attached to the pair by + * calling `sfparse_parser_param`. + * + * This function does no effort to find duplicated keys. Same key may + * be reported more than once. + * + * Caller should keep calling this function until it returns negative + * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all key and + * value pairs have been read, and there is nothing left to read. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * :macro:`SFPARSE_ERR_EOF` + * All values in the dictionary have read. + * :macro:`SFPARSE_ERR_PARSE` + * It encountered fatal error while parsing field value. + */ +int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key, + sfparse_value *dest_value); + +/** + * @function + * + * `sfparse_parser_list` reads the next list item. If this function + * returns 0, it stores the item in |dest| if it is not NULL. + * + * Caller can optionally read parameters attached to the item by + * calling `sfparse_parser_param`. + * + * Caller should keep calling this function until it returns negative + * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in + * the list have been read, and there is nothing left to read. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * :macro:`SFPARSE_ERR_EOF` + * All values in the list have read. + * :macro:`SFPARSE_ERR_PARSE` + * It encountered fatal error while parsing field value. + */ +int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest); + +/** + * @function + * + * `sfparse_parser_item` reads a single item. If this function + * returns 0, it stores the item in |dest| if it is not NULL. + * + * This function is only used for the field value that consists of a + * single item. + * + * Caller can optionally read parameters attached to the item by + * calling `sfparse_parser_param`. + * + * Caller should call this function again to make sure that there is + * nothing left to read. If this 2nd function call returns + * :macro:`SFPARSE_ERR_EOF`, all data have been processed + * successfully. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * :macro:`SFPARSE_ERR_EOF` + * There is nothing left to read. + * :macro:`SFPARSE_ERR_PARSE` + * It encountered fatal error while parsing field value. + */ +int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest); + +/** + * @function + * + * `sfparse_parser_inner_list` reads the next inner list item. If + * this function returns 0, it stores the item in |dest| if it is not + * NULL. + * + * Caller can optionally read parameters attached to the item by + * calling `sfparse_parser_param`. + * + * Caller should keep calling this function until it returns negative + * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in + * this inner list have been read, and caller can optionally read + * parameters attached to this inner list by calling + * `sfparse_parser_param`. Then caller can continue to read rest of + * the values. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * :macro:`SFPARSE_ERR_EOF` + * All values in the inner list have read. + * :macro:`SFPARSE_ERR_PARSE` + * It encountered fatal error while parsing field value. + */ +int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest); + +/** + * @function + * + * `sfparse_unescape` copies |src| to |dest| by removing escapes + * (``\``). |src| should be the pointer to + * :member:`sfparse_value.vec` of type + * :enum:`sfparse_type.SFPARSE_TYPE_STRING` produced by either + * `sfparse_parser_dict`, `sfparse_parser_list`, + * `sfparse_parser_inner_list`, `sfparse_parser_item`, or + * `sfparse_parser_param`, otherwise the behavior is undefined. + * + * :member:`dest->base <sfparse_vec.base>` must point to the buffer + * that has sufficient space to store the unescaped string. The + * memory areas pointed by :member:`dest->base <sfparse_vec.base>` and + * :member:`src->base <sfparse_vec.base>` must not overlap. + * + * This function sets the length of unescaped string to + * :member:`dest->len <sfparse_vec.len>`. + */ +void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src); + +/** + * @function + * + * `sfparse_base64decode` decodes Base64 encoded string |src| and + * writes the result into |dest|. |src| should be the pointer to + * :member:`sfparse_value.vec` of type + * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ` produced by either + * `sfparse_parser_dict`, `sfparse_parser_list`, + * `sfparse_parser_inner_list`, `sfparse_parser_item`, or + * `sfparse_parser_param`, otherwise the behavior is undefined. + * + * :member:`dest->base <sfparse_vec.base>` must point to the buffer + * that has sufficient space to store the decoded byte string. + * + * This function sets the length of decoded byte string to + * :member:`dest->len <sfparse_vec.len>`. + */ +void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src); + +/** + * @function + * + * `sfparse_pctdecode` decodes percent-encoded string |src| and writes + * the result into |dest|. |src| should be the pointer to + * :member:`sfparse_value.vec` of type + * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING` produced by either + * `sfparse_parser_dict`, `sfparse_parser_list`, + * `sfparse_parser_inner_list`, `sfparse_parser_item`, or + * `sfparse_parser_param`, otherwise the behavior is undefined. + * + * :member:`dest->base <sfparse_vec.base>` must point to the buffer + * that has sufficient space to store the decoded byte string. The + * memory areas pointed by :member:`dest->base <sfparse_vec.base>` and + * :member:`src->base <sfparse_vec.base>` must not overlap. + * + * This function sets the length of decoded byte string to + * :member:`dest->len <sfparse_vec.len>`. + */ +void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src); + +#ifdef __cplusplus +} +#endif /* defined(__cplusplus) */ + +#endif /* !defined(SFPARSE_H) */